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 fmt_macros::{Parser, Piece, Position};
86 use metadata::cstore::LOCAL_CRATE;
87 use middle::astconv_util::prohibit_type_params;
89 use middle::def_id::DefId;
91 use middle::infer::type_variable;
92 use middle::pat_util::{self, pat_id_map};
93 use middle::privacy::{AllPublic, LastMod};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::util::Representability;
105 use require_c_abi_if_variadic;
106 use rscope::{ElisionFailureInfo, RegionScope};
107 use session::Session;
108 use {CrateCtxt, lookup_full_def};
111 use util::common::{block_query, ErrorReported, indenter, loop_query};
112 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
113 use util::lev_distance::lev_distance;
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::owned_slice::OwnedSlice;
124 use syntax::parse::token::{self, InternedString};
127 use rustc_front::visit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::Visibility;
130 use rustc_front::hir::{Item, ItemImpl};
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
152 /// closures defined within the function. For example:
155 /// bar(move|| { ... })
158 /// Here, the function `foo()` and the closure passed to
159 /// `bar()` will each have their own `FnCtxt`, but they will
160 /// share the inherited fields.
161 pub struct Inherited<'a, 'tcx: 'a> {
162 infcx: infer::InferCtxt<'a, 'tcx>,
163 locals: RefCell<NodeMap<Ty<'tcx>>>,
165 tables: &'a RefCell<ty::Tables<'tcx>>,
167 // When we process a call like `c()` where `c` is a closure type,
168 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
169 // `FnOnce` closure. In that case, we defer full resolution of the
170 // call until upvar inference can kick in and make the
171 // decision. We keep these deferred resolutions grouped by the
172 // def-id of the closure, so that once we decide, we can easily go
173 // back and process them.
174 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
176 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
179 trait DeferredCallResolution<'tcx> {
180 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
183 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
185 /// When type-checking an expression, we propagate downward
186 /// whatever type hint we are able in the form of an `Expectation`.
187 #[derive(Copy, Clone, Debug)]
188 pub enum Expectation<'tcx> {
189 /// We know nothing about what type this expression should have.
192 /// This expression should have the type given (or some subtype)
193 ExpectHasType(Ty<'tcx>),
195 /// This expression will be cast to the `Ty`
196 ExpectCastableToType(Ty<'tcx>),
198 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
199 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
200 ExpectRvalueLikeUnsized(Ty<'tcx>),
203 impl<'tcx> Expectation<'tcx> {
204 // Disregard "castable to" expectations because they
205 // can lead us astray. Consider for example `if cond
206 // {22} else {c} as u8` -- if we propagate the
207 // "castable to u8" constraint to 22, it will pick the
208 // type 22u8, which is overly constrained (c might not
209 // be a u8). In effect, the problem is that the
210 // "castable to" expectation is not the tightest thing
211 // we can say, so we want to drop it in this case.
212 // The tightest thing we can say is "must unify with
213 // else branch". Note that in the case of a "has type"
214 // constraint, this limitation does not hold.
216 // If the expected type is just a type variable, then don't use
217 // an expected type. Otherwise, we might write parts of the type
218 // when checking the 'then' block which are incompatible with the
220 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
222 ExpectHasType(ety) => {
223 let ety = fcx.infcx().shallow_resolve(ety);
224 if !ety.is_ty_var() {
230 ExpectRvalueLikeUnsized(ety) => {
231 ExpectRvalueLikeUnsized(ety)
238 #[derive(Copy, Clone)]
239 pub struct UnsafetyState {
240 pub def: ast::NodeId,
241 pub unsafety: hir::Unsafety,
242 pub unsafe_push_count: u32,
247 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
248 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
251 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
252 match self.unsafety {
253 // If this unsafe, then if the outer function was already marked as
254 // unsafe we shouldn't attribute the unsafe'ness to the block. This
255 // way the block can be warned about instead of ignoring this
256 // extraneous block (functions are never warned about).
257 hir::Unsafety::Unsafe if self.from_fn => *self,
260 let (unsafety, def, count) = match blk.rules {
261 hir::PushUnsafeBlock(..) =>
262 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
263 hir::PopUnsafeBlock(..) =>
264 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
265 hir::UnsafeBlock(..) =>
266 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
267 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
268 (unsafety, self.def, self.unsafe_push_count),
270 UnsafetyState{ def: def,
272 unsafe_push_count: count,
280 pub struct FnCtxt<'a, 'tcx: 'a> {
281 body_id: ast::NodeId,
283 // This flag is set to true if, during the writeback phase, we encounter
284 // a type error in this function.
285 writeback_errors: Cell<bool>,
287 // Number of errors that had been reported when we started
288 // checking this function. On exit, if we find that *more* errors
289 // have been reported, we will skip regionck and other work that
290 // expects the types within the function to be consistent.
291 err_count_on_creation: usize,
293 ret_ty: ty::FnOutput<'tcx>,
295 ps: RefCell<UnsafetyState>,
297 inh: &'a Inherited<'a, 'tcx>,
299 ccx: &'a CrateCtxt<'a, 'tcx>,
302 impl<'a, 'tcx> Inherited<'a, 'tcx> {
303 fn new(tcx: &'a ty::ctxt<'tcx>,
304 tables: &'a RefCell<ty::Tables<'tcx>>,
305 param_env: ty::ParameterEnvironment<'a, 'tcx>)
306 -> Inherited<'a, 'tcx> {
309 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
310 locals: RefCell::new(NodeMap()),
312 deferred_call_resolutions: RefCell::new(DefIdMap()),
313 deferred_cast_checks: RefCell::new(Vec::new()),
317 fn normalize_associated_types_in<T>(&self,
319 body_id: ast::NodeId,
322 where T : TypeFoldable<'tcx> + HasTypeFlags
324 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
325 assoc::normalize_associated_types_in(&self.infcx,
334 // Used by check_const and check_enum_variants
335 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
336 inh: &'a Inherited<'a, 'tcx>,
337 rty: ty::FnOutput<'tcx>,
338 body_id: ast::NodeId)
339 -> FnCtxt<'a, 'tcx> {
342 writeback_errors: Cell::new(false),
343 err_count_on_creation: ccx.tcx.sess.err_count(),
345 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
351 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
352 tables: &'a RefCell<ty::Tables<'tcx>>)
353 -> Inherited<'a, 'tcx> {
354 // It's kind of a kludge to manufacture a fake function context
355 // and statement context, but we might as well do write the code only once
356 let param_env = ccx.tcx.empty_parameter_environment();
357 Inherited::new(ccx.tcx, &tables, param_env)
360 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
363 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
364 fn visit_item(&mut self, i: &'tcx hir::Item) {
365 check_item_type(self.ccx, i);
366 visit::walk_item(self, i);
369 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
371 hir::TyFixedLengthVec(_, ref expr) => {
372 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
377 visit::walk_ty(self, t);
381 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
382 fn visit_item(&mut self, i: &'tcx hir::Item) {
383 check_item_body(self.ccx, i);
384 visit::walk_item(self, i);
388 pub fn check_wf_old(ccx: &CrateCtxt) {
389 // FIXME(#25759). The new code below is much more reliable but (for now)
390 // only generates warnings. So as to ensure that we continue
391 // getting errors where we used to get errors, we run the old wf
392 // code first and abort if it encounters any errors. If no abort
393 // comes, we run the new code and issue warnings.
394 let krate = ccx.tcx.map.krate();
395 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
396 visit::walk_crate(&mut visit, krate);
398 // If types are not well-formed, it leads to all manner of errors
399 // downstream, so stop reporting errors at this point.
400 ccx.tcx.sess.abort_if_errors();
403 pub fn check_wf_new(ccx: &CrateCtxt) {
404 let krate = ccx.tcx.map.krate();
405 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
406 visit::walk_crate(&mut visit, krate);
408 // If types are not well-formed, it leads to all manner of errors
409 // downstream, so stop reporting errors at this point.
410 ccx.tcx.sess.abort_if_errors();
413 pub fn check_item_types(ccx: &CrateCtxt) {
414 let krate = ccx.tcx.map.krate();
415 let mut visit = CheckItemTypesVisitor { ccx: ccx };
416 visit::walk_crate(&mut visit, krate);
417 ccx.tcx.sess.abort_if_errors();
420 pub fn check_item_bodies(ccx: &CrateCtxt) {
421 let krate = ccx.tcx.map.krate();
422 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
423 visit::walk_crate(&mut visit, krate);
425 ccx.tcx.sess.abort_if_errors();
428 pub fn check_drop_impls(ccx: &CrateCtxt) {
429 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
430 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
432 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
433 if drop_impl_did.is_local() {
434 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
437 assert!(ccx.tcx.sess.has_errors());
443 ccx.tcx.sess.abort_if_errors();
446 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
447 decl: &'tcx hir::FnDecl,
448 body: &'tcx hir::Block,
452 param_env: ty::ParameterEnvironment<'a, 'tcx>)
455 ty::TyBareFn(_, ref fn_ty) => {
456 let tables = RefCell::new(ty::Tables::empty());
457 let inh = Inherited::new(ccx.tcx, &tables, param_env);
459 // Compute the fty from point of view of inside fn.
460 let fn_scope = ccx.tcx.region_maps.item_extent(body.id);
462 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
464 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
466 inh.normalize_associated_types_in(body.span,
470 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
471 decl, fn_id, body, &inh);
473 fcx.select_all_obligations_and_apply_defaults();
474 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
475 fcx.select_obligations_where_possible();
477 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
479 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
480 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
482 _ => ccx.tcx.sess.impossible_case(body.span,
483 "check_bare_fn: function type expected")
487 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
488 fcx: &'a FnCtxt<'a, 'tcx>
491 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
492 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
495 // infer the variable's type
496 let var_ty = self.fcx.infcx().next_ty_var();
497 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
501 // take type that the user specified
502 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
509 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
510 // Add explicitly-declared locals.
511 fn visit_local(&mut self, local: &'tcx hir::Local) {
512 let o_ty = match local.ty {
513 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
516 self.assign(local.span, local.id, o_ty);
517 debug!("Local variable {:?} is assigned type {}",
519 self.fcx.infcx().ty_to_string(
520 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
521 visit::walk_local(self, local);
524 // Add pattern bindings.
525 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
526 if let hir::PatIdent(_, ref path1, _) = p.node {
527 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
528 let var_ty = self.assign(p.span, p.id, None);
530 self.fcx.require_type_is_sized(var_ty, p.span,
531 traits::VariableType(p.id));
533 debug!("Pattern binding {} is assigned to {} with type {:?}",
535 self.fcx.infcx().ty_to_string(
536 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
540 visit::walk_pat(self, p);
543 fn visit_block(&mut self, b: &'tcx hir::Block) {
544 // non-obvious: the `blk` variable maps to region lb, so
545 // we have to keep this up-to-date. This
546 // is... unfortunate. It'd be nice to not need this.
547 visit::walk_block(self, b);
550 // Since an expr occurs as part of the type fixed size arrays we
551 // need to record the type for that node
552 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
554 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
555 self.visit_ty(&**ty);
556 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
558 hir::TyBareFn(ref function_declaration) => {
559 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
560 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
562 _ => visit::walk_ty(self, t)
566 // Don't descend into fns and items
567 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
568 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
569 fn visit_item(&mut self, _: &hir::Item) { }
573 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
574 /// body and returns the function context used for that purpose, since in the case of a fn item
575 /// there is still a bit more to do.
578 /// * inherited: other fields inherited from the enclosing fn (if any)
579 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
580 unsafety: hir::Unsafety,
581 unsafety_id: ast::NodeId,
582 fn_sig: &ty::FnSig<'tcx>,
583 decl: &'tcx hir::FnDecl,
585 body: &'tcx hir::Block,
586 inherited: &'a Inherited<'a, 'tcx>)
590 let err_count_on_creation = tcx.sess.err_count();
592 let arg_tys = &fn_sig.inputs;
593 let ret_ty = fn_sig.output;
595 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
600 // Create the function context. This is either derived from scratch or,
601 // in the case of function expressions, based on the outer context.
604 writeback_errors: Cell::new(false),
605 err_count_on_creation: err_count_on_creation,
607 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
612 if let ty::FnConverging(ret_ty) = ret_ty {
613 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
616 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
618 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
621 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
623 // Add formal parameters.
624 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
625 // The type of the argument must be well-formed.
627 // NB -- this is now checked in wfcheck, but that
628 // currently only results in warnings, so we issue an
629 // old-style WF obligation here so that we still get the
630 // errors that we used to get.
631 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
633 // Create type variables for each argument.
634 pat_util::pat_bindings(
637 |_bm, pat_id, sp, _path| {
638 let var_ty = visit.assign(sp, pat_id, None);
639 fcx.require_type_is_sized(var_ty, sp,
640 traits::VariableType(pat_id));
643 // Check the pattern.
646 map: pat_id_map(&tcx.def_map, &*input.pat),
648 _match::check_pat(&pcx, &*input.pat, *arg_ty);
651 visit.visit_block(body);
654 check_block_with_expected(&fcx, body, match ret_ty {
655 ty::FnConverging(result_type) => ExpectHasType(result_type),
656 ty::FnDiverging => NoExpectation
659 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
660 fcx.write_ty(input.id, arg);
666 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
669 check_representable(tcx, span, id, "struct");
671 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
672 check_simd(tcx, span, id);
676 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
677 debug!("check_item_type(it.id={}, it.name={})",
679 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
680 let _indenter = indenter();
682 // Consts can play a role in type-checking, so they are included here.
683 hir::ItemStatic(_, _, ref e) |
684 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
685 hir::ItemEnum(ref enum_definition, _) => {
686 check_enum_variants(ccx,
688 &enum_definition.variants,
691 hir::ItemFn(..) => {} // entirely within check_item_body
692 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
693 debug!("ItemImpl {} with id {}", it.name, it.id);
694 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
695 Some(impl_trait_ref) => {
696 check_impl_items_against_trait(ccx,
704 hir::ItemTrait(_, ref generics, _, _) => {
705 check_trait_on_unimplemented(ccx, generics, it);
707 hir::ItemStruct(..) => {
708 check_struct(ccx, it.id, it.span);
710 hir::ItemTy(ref t, ref generics) => {
711 let pty_ty = ccx.tcx.node_id_to_type(it.id);
712 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
714 hir::ItemForeignMod(ref m) => {
715 if m.abi == abi::RustIntrinsic {
716 for item in &m.items {
717 intrinsic::check_intrinsic_type(ccx, &**item);
719 } else if m.abi == abi::PlatformIntrinsic {
720 for item in &m.items {
721 intrinsic::check_platform_intrinsic_type(ccx, &**item);
724 for item in &m.items {
725 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
726 if !pty.generics.types.is_empty() {
727 span_err!(ccx.tcx.sess, item.span, E0044,
728 "foreign items may not have type parameters");
729 span_help!(ccx.tcx.sess, item.span,
730 "consider using specialization instead of \
734 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
735 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
740 _ => {/* nothing to do */ }
744 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
745 debug!("check_item_body(it.id={}, it.name={})",
747 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
748 let _indenter = indenter();
750 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
751 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
752 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
753 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
755 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
756 debug!("ItemImpl {} with id {}", it.name, it.id);
758 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
760 for impl_item in impl_items {
761 match impl_item.node {
762 hir::ImplItemKind::Const(_, ref expr) => {
763 check_const(ccx, impl_item.span, &*expr, impl_item.id)
765 hir::ImplItemKind::Method(ref sig, ref body) => {
766 check_method_body(ccx, &impl_pty.generics, sig, body,
767 impl_item.id, impl_item.span);
769 hir::ImplItemKind::Type(_) => {
770 // Nothing to do here.
775 hir::ItemTrait(_, _, _, ref trait_items) => {
776 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
777 for trait_item in trait_items {
778 match trait_item.node {
779 hir::ConstTraitItem(_, Some(ref expr)) => {
780 check_const(ccx, trait_item.span, &*expr, trait_item.id)
782 hir::MethodTraitItem(ref sig, Some(ref body)) => {
783 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
785 check_method_body(ccx, &trait_def.generics, sig, body,
786 trait_item.id, trait_item.span);
788 hir::MethodTraitItem(ref sig, None) => {
789 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
791 hir::ConstTraitItem(_, None) |
792 hir::TypeTraitItem(..) => {
798 _ => {/* nothing to do */ }
802 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
804 constness: hir::Constness)
807 hir::Constness::NotConst => {
810 hir::Constness::Const => {
811 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
816 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
817 generics: &hir::Generics,
819 if let Some(ref attr) = item.attrs.iter().find(|a| {
820 a.check_name("rustc_on_unimplemented")
822 if let Some(ref istring) = attr.value_str() {
823 let parser = Parser::new(&istring);
824 let types = &*generics.ty_params;
825 for token in parser {
827 Piece::String(_) => (), // Normal string, no need to check it
828 Piece::NextArgument(a) => match a.position {
829 // `{Self}` is allowed
830 Position::ArgumentNamed(s) if s == "Self" => (),
831 // So is `{A}` if A is a type parameter
832 Position::ArgumentNamed(s) => match types.iter().find(|t| {
837 span_err!(ccx.tcx.sess, attr.span, E0230,
838 "there is no type parameter \
843 // `{:1}` and `{}` are not to be used
844 Position::ArgumentIs(_) | Position::ArgumentNext => {
845 span_err!(ccx.tcx.sess, attr.span, E0231,
846 "only named substitution \
847 parameters are allowed");
853 span_err!(ccx.tcx.sess, attr.span, E0232,
854 "this attribute must have a value, \
855 eg `#[rustc_on_unimplemented = \"foo\"]`")
860 /// Type checks a method body.
864 /// * `item_generics`: generics defined on the impl/trait that contains
866 /// * `self_bound`: bound for the `Self` type parameter, if any
867 /// * `method`: the method definition
868 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
869 item_generics: &ty::Generics<'tcx>,
870 sig: &'tcx hir::MethodSig,
871 body: &'tcx hir::Block,
872 id: ast::NodeId, span: Span) {
873 debug!("check_method_body(item_generics={:?}, id={})",
875 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
877 let fty = ccx.tcx.node_id_to_type(id);
878 debug!("check_method_body: fty={:?}", fty);
880 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
883 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
885 impl_trait_ref: &ty::TraitRef<'tcx>,
886 impl_items: &[P<hir::ImplItem>]) {
887 // Locate trait methods
889 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
890 let mut overridden_associated_type = None;
892 // Check existing impl methods to see if they are both present in trait
893 // and compatible with trait signature
894 for impl_item in impl_items {
895 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
896 let ty_trait_item = trait_items.iter()
897 .find(|ac| ac.name() == ty_impl_item.name())
899 // This is checked by resolve
900 tcx.sess.span_bug(impl_item.span,
901 &format!("impl-item `{}` is not a member of `{:?}`",
905 match impl_item.node {
906 hir::ImplItemKind::Const(..) => {
907 let impl_const = match ty_impl_item {
908 ty::ConstTraitItem(ref cti) => cti,
909 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
912 // Find associated const definition.
913 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
914 compare_const_impl(ccx.tcx,
920 span_err!(tcx.sess, impl_item.span, E0323,
921 "item `{}` is an associated const, \
922 which doesn't match its trait `{:?}`",
927 hir::ImplItemKind::Method(ref sig, ref body) => {
928 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
930 let impl_method = match ty_impl_item {
931 ty::MethodTraitItem(ref mti) => mti,
932 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
935 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
936 compare_impl_method(ccx.tcx,
943 span_err!(tcx.sess, impl_item.span, E0324,
944 "item `{}` is an associated method, \
945 which doesn't match its trait `{:?}`",
950 hir::ImplItemKind::Type(_) => {
951 let impl_type = match ty_impl_item {
952 ty::TypeTraitItem(ref tti) => tti,
953 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
956 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
957 if let Some(_) = at.ty {
958 overridden_associated_type = Some(impl_item);
961 span_err!(tcx.sess, impl_item.span, E0325,
962 "item `{}` is an associated type, \
963 which doesn't match its trait `{:?}`",
971 // Check for missing items from trait
972 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
973 let mut missing_items = Vec::new();
974 let mut invalidated_items = Vec::new();
975 let associated_type_overridden = overridden_associated_type.is_some();
976 for trait_item in trait_items.iter() {
978 ty::ConstTraitItem(ref associated_const) => {
979 let is_implemented = impl_items.iter().any(|ii| {
981 hir::ImplItemKind::Const(..) => {
982 ii.name == associated_const.name
987 let is_provided = associated_const.has_value;
991 missing_items.push(associated_const.name);
992 } else if associated_type_overridden {
993 invalidated_items.push(associated_const.name);
997 ty::MethodTraitItem(ref trait_method) => {
999 impl_items.iter().any(|ii| {
1001 hir::ImplItemKind::Method(..) => {
1002 ii.name == trait_method.name
1008 provided_methods.iter().any(|m| m.name == trait_method.name);
1009 if !is_implemented {
1011 missing_items.push(trait_method.name);
1012 } else if associated_type_overridden {
1013 invalidated_items.push(trait_method.name);
1017 ty::TypeTraitItem(ref associated_type) => {
1018 let is_implemented = impl_items.iter().any(|ii| {
1020 hir::ImplItemKind::Type(_) => {
1021 ii.name == associated_type.name
1026 let is_provided = associated_type.ty.is_some();
1027 if !is_implemented {
1029 missing_items.push(associated_type.name);
1030 } else if associated_type_overridden {
1031 invalidated_items.push(associated_type.name);
1038 if !missing_items.is_empty() {
1039 span_err!(tcx.sess, impl_span, E0046,
1040 "not all trait items implemented, missing: `{}`",
1041 missing_items.iter()
1042 .map(|name| name.to_string())
1043 .collect::<Vec<_>>().join("`, `"))
1046 if !invalidated_items.is_empty() {
1047 let invalidator = overridden_associated_type.unwrap();
1048 span_err!(tcx.sess, invalidator.span, E0399,
1049 "the following trait items need to be reimplemented \
1050 as `{}` was overridden: `{}`",
1052 invalidated_items.iter()
1053 .map(|name| name.to_string())
1054 .collect::<Vec<_>>().join("`, `"))
1058 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1065 let tstr = fcx.infcx().ty_to_string(t_cast);
1066 fcx.type_error_message(span, |actual| {
1067 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1070 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1071 let mtstr = match mt {
1072 hir::MutMutable => "mut ",
1073 hir::MutImmutable => ""
1075 if t_cast.is_trait() {
1076 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1078 fcx.tcx().sess.span_suggestion(t_span,
1079 "try casting to a reference instead:",
1080 format!("&{}{}", mtstr, s));
1083 span_help!(fcx.tcx().sess, t_span,
1084 "did you mean `&{}{}`?", mtstr, tstr),
1087 span_help!(fcx.tcx().sess, span,
1088 "consider using an implicit coercion to `&{}{}` instead",
1093 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1095 fcx.tcx().sess.span_suggestion(t_span,
1096 "try casting to a `Box` instead:",
1097 format!("Box<{}>", s));
1100 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1104 span_help!(fcx.tcx().sess, e_span,
1105 "consider using a box or reference as appropriate");
1108 fcx.write_error(id);
1112 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1113 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1115 fn get_item_type_scheme(&self, _: Span, id: DefId)
1116 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1118 Ok(self.tcx().lookup_item_type(id))
1121 fn get_trait_def(&self, _: Span, id: DefId)
1122 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1124 Ok(self.tcx().lookup_trait_def(id))
1127 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1128 // all super predicates are ensured during collect pass
1132 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1133 Some(&self.inh.infcx.parameter_environment.free_substs)
1136 fn get_type_parameter_bounds(&self,
1138 node_id: ast::NodeId)
1139 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1141 let def = self.tcx().type_parameter_def(node_id);
1142 let r = self.inh.infcx.parameter_environment
1145 .filter_map(|predicate| {
1147 ty::Predicate::Trait(ref data) => {
1148 if data.0.self_ty().is_param(def.space, def.index) {
1149 Some(data.to_poly_trait_ref())
1163 fn trait_defines_associated_type_named(&self,
1164 trait_def_id: DefId,
1165 assoc_name: ast::Name)
1168 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1169 trait_def.associated_type_names.contains(&assoc_name)
1173 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1174 substs: Option<&mut subst::Substs<'tcx>>,
1175 space: Option<subst::ParamSpace>,
1176 span: Span) -> Ty<'tcx> {
1177 // Grab the default doing subsitution
1178 let default = ty_param_def.and_then(|def| {
1179 def.default.map(|ty| type_variable::Default {
1180 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1182 def_id: def.default_def_id
1186 let ty_var = self.infcx().next_ty_var_with_default(default);
1188 // Finally we add the type variable to the substs
1191 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1195 fn projected_ty_from_poly_trait_ref(&self,
1197 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1198 item_name: ast::Name)
1201 let (trait_ref, _) =
1202 self.infcx().replace_late_bound_regions_with_fresh_var(
1204 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1207 self.normalize_associated_type(span, trait_ref, item_name)
1210 fn projected_ty(&self,
1212 trait_ref: ty::TraitRef<'tcx>,
1213 item_name: ast::Name)
1216 self.normalize_associated_type(span, trait_ref, item_name)
1220 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1221 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1223 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1227 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1228 &self.inh.infcx.parameter_environment
1231 pub fn sess(&self) -> &Session {
1235 pub fn err_count_since_creation(&self) -> usize {
1236 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1239 /// Resolves type variables in `ty` if possible. Unlike the infcx
1240 /// version, this version will also select obligations if it seems
1241 /// useful, in an effort to get more type information.
1242 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1243 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1245 // No TyInfer()? Nothing needs doing.
1246 if !ty.has_infer_types() {
1247 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1251 // If `ty` is a type variable, see whether we already know what it is.
1252 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1253 if !ty.has_infer_types() {
1254 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1258 // If not, try resolving any new fcx obligations that have cropped up.
1259 self.select_new_obligations();
1260 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1261 if !ty.has_infer_types() {
1262 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1266 // If not, try resolving *all* pending obligations as much as
1267 // possible. This can help substantially when there are
1268 // indirect dependencies that don't seem worth tracking
1270 self.select_obligations_where_possible();
1271 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1273 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1277 fn record_deferred_call_resolution(&self,
1278 closure_def_id: DefId,
1279 r: DeferredCallResolutionHandler<'tcx>) {
1280 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1281 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1284 fn remove_deferred_call_resolutions(&self,
1285 closure_def_id: DefId)
1286 -> Vec<DeferredCallResolutionHandler<'tcx>>
1288 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1289 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1292 pub fn tag(&self) -> String {
1293 let self_ptr: *const FnCtxt = self;
1294 format!("{:?}", self_ptr)
1297 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1298 match self.inh.locals.borrow().get(&nid) {
1301 span_err!(self.tcx().sess, span, E0513,
1302 "no type for local variable {}",
1304 self.tcx().types.err
1310 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1311 debug!("write_ty({}, {:?}) in fcx {}",
1312 node_id, ty, self.tag());
1313 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1316 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1317 if !substs.substs.is_noop() {
1318 debug!("write_substs({}, {:?}) in fcx {}",
1323 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1327 pub fn write_autoderef_adjustment(&self,
1328 node_id: ast::NodeId,
1330 self.write_adjustment(
1332 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1340 pub fn write_adjustment(&self,
1341 node_id: ast::NodeId,
1342 adj: adjustment::AutoAdjustment<'tcx>) {
1343 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1345 if adj.is_identity() {
1349 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1352 /// Basically whenever we are converting from a type scheme into
1353 /// the fn body space, we always want to normalize associated
1354 /// types as well. This function combines the two.
1355 fn instantiate_type_scheme<T>(&self,
1357 substs: &Substs<'tcx>,
1360 where T : TypeFoldable<'tcx> + HasTypeFlags
1362 let value = value.subst(self.tcx(), substs);
1363 let result = self.normalize_associated_types_in(span, &value);
1364 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1371 /// As `instantiate_type_scheme`, but for the bounds found in a
1372 /// generic type scheme.
1373 fn instantiate_bounds(&self,
1375 substs: &Substs<'tcx>,
1376 bounds: &ty::GenericPredicates<'tcx>)
1377 -> ty::InstantiatedPredicates<'tcx>
1379 ty::InstantiatedPredicates {
1380 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1385 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1386 where T : TypeFoldable<'tcx> + HasTypeFlags
1388 self.inh.normalize_associated_types_in(span, self.body_id, value)
1391 fn normalize_associated_type(&self,
1393 trait_ref: ty::TraitRef<'tcx>,
1394 item_name: ast::Name)
1397 let cause = traits::ObligationCause::new(span,
1399 traits::ObligationCauseCode::MiscObligation);
1404 .normalize_projection_type(self.infcx(),
1406 trait_ref: trait_ref,
1407 item_name: item_name,
1412 /// Instantiates the type in `did` with the generics in `path` and returns
1413 /// it (registering the necessary trait obligations along the way).
1415 /// Note that this function is only intended to be used with type-paths,
1416 /// not with value-paths.
1417 pub fn instantiate_type(&self,
1422 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1424 self.tcx().lookup_item_type(did);
1425 let type_predicates =
1426 self.tcx().lookup_predicates(did);
1427 let substs = astconv::ast_path_substs_for_ty(self, self,
1429 PathParamMode::Optional,
1430 &type_scheme.generics,
1431 path.segments.last().unwrap());
1432 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1434 self.instantiate_bounds(path.span, &substs, &type_predicates);
1435 self.add_obligations_for_parameters(
1436 traits::ObligationCause::new(
1439 traits::ItemObligation(did)),
1442 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1445 /// Return the dict-like variant corresponding to a given `Def`.
1446 pub fn def_struct_variant(&self,
1449 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1451 let (adt, variant) = match def {
1452 def::DefVariant(enum_id, variant_id, true) => {
1453 let adt = self.tcx().lookup_adt_def(enum_id);
1454 (adt, adt.variant_with_id(variant_id))
1456 def::DefTy(did, _) | def::DefStruct(did) => {
1457 let typ = self.tcx().lookup_item_type(did);
1458 if let ty::TyStruct(adt, _) = typ.ty.sty {
1459 (adt, adt.struct_variant())
1467 let var_kind = variant.kind();
1468 if var_kind == ty::VariantKind::Struct {
1469 Some((adt, variant))
1470 } else if var_kind == ty::VariantKind::Unit {
1471 if !self.tcx().sess.features.borrow().braced_empty_structs {
1472 self.tcx().sess.span_err(span, "empty structs and enum variants \
1473 with braces are unstable");
1474 fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
1475 the crate features to enable");
1478 Some((adt, variant))
1484 pub fn write_nil(&self, node_id: ast::NodeId) {
1485 self.write_ty(node_id, self.tcx().mk_nil());
1487 pub fn write_error(&self, node_id: ast::NodeId) {
1488 self.write_ty(node_id, self.tcx().types.err);
1491 pub fn require_type_meets(&self,
1494 code: traits::ObligationCauseCode<'tcx>,
1495 bound: ty::BuiltinBound)
1497 self.register_builtin_bound(
1500 traits::ObligationCause::new(span, self.body_id, code));
1503 pub fn require_type_is_sized(&self,
1506 code: traits::ObligationCauseCode<'tcx>)
1508 self.require_type_meets(ty, span, code, ty::BoundSized);
1511 pub fn require_expr_have_sized_type(&self,
1513 code: traits::ObligationCauseCode<'tcx>)
1515 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1518 pub fn type_is_known_to_be_sized(&self,
1523 traits::type_known_to_meet_builtin_bound(self.infcx(),
1529 pub fn register_builtin_bound(&self,
1531 builtin_bound: ty::BuiltinBound,
1532 cause: traits::ObligationCause<'tcx>)
1534 self.inh.infcx.fulfillment_cx.borrow_mut()
1535 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1538 pub fn register_predicate(&self,
1539 obligation: traits::PredicateObligation<'tcx>)
1541 debug!("register_predicate({:?})",
1543 self.inh.infcx.fulfillment_cx
1545 .register_predicate_obligation(self.infcx(), obligation);
1548 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1549 let t = ast_ty_to_ty(self, self, ast_t);
1550 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1554 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1555 match self.inh.tables.borrow().node_types.get(&ex.id) {
1558 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1564 /// Apply `adjustment` to the type of `expr`
1565 pub fn adjust_expr_ty(&self,
1567 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1570 let raw_ty = self.expr_ty(expr);
1571 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1572 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1573 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1574 self.inh.tables.borrow().method_map.get(&method_call)
1575 .map(|method| resolve_ty(method.ty))
1579 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1580 match self.inh.tables.borrow().node_types.get(&id) {
1582 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1584 self.tcx().sess.bug(
1585 &format!("no type for node {}: {} in fcx {}",
1586 id, self.tcx().map.node_to_string(id),
1592 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1593 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1594 // it changes when we upgrade the snapshot compiler
1595 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1596 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1600 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1603 pub fn opt_node_ty_substs<F>(&self,
1606 F: FnOnce(&ty::ItemSubsts<'tcx>),
1608 match self.inh.tables.borrow().item_substs.get(&id) {
1614 pub fn mk_subty(&self,
1615 a_is_expected: bool,
1616 origin: infer::TypeOrigin,
1619 -> Result<(), TypeError<'tcx>> {
1620 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1623 pub fn mk_eqty(&self,
1624 a_is_expected: bool,
1625 origin: infer::TypeOrigin,
1628 -> Result<(), TypeError<'tcx>> {
1629 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1632 pub fn mk_subr(&self,
1633 origin: infer::SubregionOrigin<'tcx>,
1636 infer::mk_subr(self.infcx(), origin, sub, sup)
1639 pub fn type_error_message<M>(&self,
1642 actual_ty: Ty<'tcx>,
1643 err: Option<&TypeError<'tcx>>) where
1644 M: FnOnce(String) -> String,
1646 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1649 pub fn report_mismatched_types(&self,
1653 err: &TypeError<'tcx>) {
1654 self.infcx().report_mismatched_types(sp, e, a, err)
1657 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1658 /// outlive the region `r`.
1659 pub fn register_region_obligation(&self,
1662 cause: traits::ObligationCause<'tcx>)
1664 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1665 fulfillment_cx.register_region_obligation(ty, region, cause);
1668 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1669 /// outlive the region `r`.
1670 pub fn register_wf_obligation(&self,
1673 code: traits::ObligationCauseCode<'tcx>)
1675 // WF obligations never themselves fail, so no real need to give a detailed cause:
1676 let cause = traits::ObligationCause::new(span, self.body_id, code);
1677 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1680 pub fn register_old_wf_obligation(&self,
1683 code: traits::ObligationCauseCode<'tcx>)
1685 // Registers an "old-style" WF obligation that uses the
1686 // implicator code. This is basically a buggy version of
1687 // `register_wf_obligation` that is being kept around
1688 // temporarily just to help with phasing in the newer rules.
1690 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1691 let cause = traits::ObligationCause::new(span, self.body_id, code);
1692 self.register_region_obligation(ty, ty::ReEmpty, cause);
1695 /// Registers obligations that all types appearing in `substs` are well-formed.
1696 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1698 for &ty in &substs.types {
1699 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1703 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1704 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1705 /// trait/region obligations.
1707 /// For example, if there is a function:
1710 /// fn foo<'a,T:'a>(...)
1713 /// and a reference:
1719 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1720 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1721 pub fn add_obligations_for_parameters(&self,
1722 cause: traits::ObligationCause<'tcx>,
1723 predicates: &ty::InstantiatedPredicates<'tcx>)
1725 assert!(!predicates.has_escaping_regions());
1727 debug!("add_obligations_for_parameters(predicates={:?})",
1730 for obligation in traits::predicates_for_generics(cause, predicates) {
1731 self.register_predicate(obligation);
1735 // FIXME(arielb1): use this instead of field.ty everywhere
1736 pub fn field_ty(&self,
1738 field: ty::FieldDef<'tcx>,
1739 substs: &Substs<'tcx>)
1742 self.normalize_associated_types_in(span,
1743 &field.ty(self.tcx(), substs))
1746 // Only for fields! Returns <none> for methods>
1747 // Indifferent to privacy flags
1748 fn check_casts(&self) {
1749 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1750 for cast in deferred_cast_checks.drain(..) {
1755 /// Apply "fallbacks" to some types
1756 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1757 fn default_type_parameters(&self) {
1758 use middle::ty::error::UnconstrainedNumeric::Neither;
1759 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1760 for ty in &self.infcx().unsolved_variables() {
1761 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1762 if self.infcx().type_var_diverges(resolved) {
1763 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1765 match self.infcx().type_is_unconstrained_numeric(resolved) {
1766 UnconstrainedInt => {
1767 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1769 UnconstrainedFloat => {
1770 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1778 fn select_all_obligations_and_apply_defaults(&self) {
1779 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1780 self.new_select_all_obligations_and_apply_defaults();
1782 self.old_select_all_obligations_and_apply_defaults();
1786 // Implements old type inference fallback algorithm
1787 fn old_select_all_obligations_and_apply_defaults(&self) {
1788 self.select_obligations_where_possible();
1789 self.default_type_parameters();
1790 self.select_obligations_where_possible();
1793 fn new_select_all_obligations_and_apply_defaults(&self) {
1794 use middle::ty::error::UnconstrainedNumeric::Neither;
1795 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1797 // For the time being this errs on the side of being memory wasteful but provides better
1799 // let type_variables = self.infcx().type_variables.clone();
1801 // There is a possibility that this algorithm will have to run an arbitrary number of times
1802 // to terminate so we bound it by the compiler's recursion limit.
1803 for _ in 0..self.tcx().sess.recursion_limit.get() {
1804 // First we try to solve all obligations, it is possible that the last iteration
1805 // has made it possible to make more progress.
1806 self.select_obligations_where_possible();
1808 let mut conflicts = Vec::new();
1810 // Collect all unsolved type, integral and floating point variables.
1811 let unsolved_variables = self.inh.infcx.unsolved_variables();
1813 // We must collect the defaults *before* we do any unification. Because we have
1814 // directly attached defaults to the type variables any unification that occurs
1815 // will erase defaults causing conflicting defaults to be completely ignored.
1816 let default_map: FnvHashMap<_, _> =
1819 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1822 let mut unbound_tyvars = HashSet::new();
1824 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1826 // We loop over the unsolved variables, resolving them and if they are
1827 // and unconstrainted numberic type we add them to the set of unbound
1828 // variables. We do this so we only apply literal fallback to type
1829 // variables without defaults.
1830 for ty in &unsolved_variables {
1831 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1832 if self.infcx().type_var_diverges(resolved) {
1833 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1835 match self.infcx().type_is_unconstrained_numeric(resolved) {
1836 UnconstrainedInt | UnconstrainedFloat => {
1837 unbound_tyvars.insert(resolved);
1844 // We now remove any numeric types that also have defaults, and instead insert
1845 // the type variable with a defined fallback.
1846 for ty in &unsolved_variables {
1847 if let Some(_default) = default_map.get(ty) {
1848 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1850 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1853 match resolved.sty {
1854 ty::TyInfer(ty::TyVar(_)) => {
1855 unbound_tyvars.insert(ty);
1858 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1859 unbound_tyvars.insert(ty);
1860 if unbound_tyvars.contains(resolved) {
1861 unbound_tyvars.remove(resolved);
1870 // If there are no more fallbacks to apply at this point we have applied all possible
1871 // defaults and type inference will proceed as normal.
1872 if unbound_tyvars.is_empty() {
1876 // Finally we go through each of the unbound type variables and unify them with
1877 // the proper fallback, reporting a conflicting default error if any of the
1878 // unifications fail. We know it must be a conflicting default because the
1879 // variable would only be in `unbound_tyvars` and have a concrete value if
1880 // it had been solved by previously applying a default.
1882 // We wrap this in a transaction for error reporting, if we detect a conflict
1883 // we will rollback the inference context to its prior state so we can probe
1884 // for conflicts and correctly report them.
1887 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1888 for ty in &unbound_tyvars {
1889 if self.infcx().type_var_diverges(ty) {
1890 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1892 match self.infcx().type_is_unconstrained_numeric(ty) {
1893 UnconstrainedInt => {
1894 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1896 UnconstrainedFloat => {
1897 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1900 if let Some(default) = default_map.get(ty) {
1901 let default = default.clone();
1902 match infer::mk_eqty(self.infcx(), false,
1903 infer::Misc(default.origin_span),
1907 conflicts.push((*ty, default));
1916 // If there are conflicts we rollback, otherwise commit
1917 if conflicts.len() > 0 {
1924 if conflicts.len() > 0 {
1925 // Loop through each conflicting default, figuring out the default that caused
1926 // a unification failure and then report an error for each.
1927 for (conflict, default) in conflicts {
1928 let conflicting_default =
1929 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1930 .unwrap_or(type_variable::Default {
1931 ty: self.infcx().next_ty_var(),
1932 origin_span: codemap::DUMMY_SP,
1933 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1936 // This is to ensure that we elimnate any non-determinism from the error
1937 // reporting by fixing an order, it doesn't matter what order we choose
1938 // just that it is consistent.
1939 let (first_default, second_default) =
1940 if default.def_id < conflicting_default.def_id {
1941 (default, conflicting_default)
1943 (conflicting_default, default)
1947 self.infcx().report_conflicting_default_types(
1948 first_default.origin_span,
1955 self.select_obligations_where_possible();
1958 // For use in error handling related to default type parameter fallback. We explicitly
1959 // apply the default that caused conflict first to a local version of the type variable
1960 // table then apply defaults until we find a conflict. That default must be the one
1961 // that caused conflict earlier.
1962 fn find_conflicting_default(&self,
1963 unbound_vars: &HashSet<Ty<'tcx>>,
1964 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1966 -> Option<type_variable::Default<'tcx>> {
1967 use middle::ty::error::UnconstrainedNumeric::Neither;
1968 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1970 // Ensure that we apply the conflicting default first
1971 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1972 unbound_tyvars.push(conflict);
1973 unbound_tyvars.extend(unbound_vars.iter());
1975 let mut result = None;
1976 // We run the same code as above applying defaults in order, this time when
1977 // we find the conflict we just return it for error reporting above.
1979 // We also run this inside snapshot that never commits so we can do error
1980 // reporting for more then one conflict.
1981 for ty in &unbound_tyvars {
1982 if self.infcx().type_var_diverges(ty) {
1983 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1985 match self.infcx().type_is_unconstrained_numeric(ty) {
1986 UnconstrainedInt => {
1987 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1989 UnconstrainedFloat => {
1990 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1993 if let Some(default) = default_map.get(ty) {
1994 let default = default.clone();
1995 match infer::mk_eqty(self.infcx(), false,
1996 infer::Misc(default.origin_span),
2000 result = Some(default);
2012 fn select_all_obligations_or_error(&self) {
2013 debug!("select_all_obligations_or_error");
2015 // upvar inference should have ensured that all deferred call
2016 // resolutions are handled by now.
2017 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2019 self.select_all_obligations_and_apply_defaults();
2021 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2022 match fulfillment_cx.select_all_or_error(self.infcx()) {
2024 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2028 /// Select as many obligations as we can at present.
2029 fn select_obligations_where_possible(&self) {
2031 self.inh.infcx.fulfillment_cx
2033 .select_where_possible(self.infcx())
2036 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2040 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2041 /// to improve inference. You could just call
2042 /// `select_obligations_where_possible` except that it leads to repeated
2044 fn select_new_obligations(&self) {
2046 self.inh.infcx.fulfillment_cx
2048 .select_new_obligations(self.infcx())
2051 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2057 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2058 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2059 Some(self.base_object_lifetime_default(span))
2062 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2063 // RFC #599 specifies that object lifetime defaults take
2064 // precedence over other defaults. But within a fn body we
2065 // don't have a *default* region, rather we use inference to
2066 // find the *correct* region, which is strictly more general
2067 // (and anyway, within a fn body the right region may not even
2068 // be something the user can write explicitly, since it might
2069 // be some expression).
2070 self.infcx().next_region_var(infer::MiscVariable(span))
2073 fn anon_regions(&self, span: Span, count: usize)
2074 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2075 Ok((0..count).map(|_| {
2076 self.infcx().next_region_var(infer::MiscVariable(span))
2081 /// Whether `autoderef` requires types to resolve.
2082 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2083 pub enum UnresolvedTypeAction {
2084 /// Produce an error and return `TyError` whenever a type cannot
2085 /// be resolved (i.e. it is `TyInfer`).
2087 /// Go on without emitting any errors, and return the unresolved
2088 /// type. Useful for probing, e.g. in coercions.
2092 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2093 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2095 /// Note: this method does not modify the adjustments table. The caller is responsible for
2096 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2097 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2100 opt_expr: Option<&hir::Expr>,
2101 unresolved_type_action: UnresolvedTypeAction,
2102 mut lvalue_pref: LvaluePreference,
2104 -> (Ty<'tcx>, usize, Option<T>)
2105 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2107 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2112 let mut t = base_ty;
2113 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2114 let resolved_t = match unresolved_type_action {
2115 UnresolvedTypeAction::Error => {
2116 structurally_resolved_type(fcx, sp, t)
2118 UnresolvedTypeAction::Ignore => {
2119 // We can continue even when the type cannot be resolved
2120 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2121 // and `try_overloaded_deref` both simply return `None`
2122 // in such a case without producing spurious errors.
2123 fcx.resolve_type_vars_if_possible(t)
2126 if resolved_t.references_error() {
2127 return (resolved_t, autoderefs, None);
2130 match should_stop(resolved_t, autoderefs) {
2131 Some(x) => return (resolved_t, autoderefs, Some(x)),
2135 // Otherwise, deref if type is derefable:
2136 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2137 Some(mt) => Some(mt),
2140 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2142 // Super subtle: it might seem as though we should
2143 // pass `opt_expr` to `try_overloaded_deref`, so that
2144 // the (implicit) autoref of using an overloaded deref
2145 // would get added to the adjustment table. However we
2146 // do not do that, because it's kind of a
2147 // "meta-adjustment" -- instead, we just leave it
2148 // unrecorded and know that there "will be" an
2149 // autoref. regionck and other bits of the code base,
2150 // when they encounter an overloaded autoderef, have
2151 // to do some reconstructive surgery. This is a pretty
2152 // complex mess that is begging for a proper MIR.
2153 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2159 if mt.mutbl == hir::MutImmutable {
2160 lvalue_pref = NoPreference;
2163 None => return (resolved_t, autoderefs, None)
2167 // We've reached the recursion limit, error gracefully.
2168 span_err!(fcx.tcx().sess, sp, E0055,
2169 "reached the recursion limit while auto-dereferencing {:?}",
2171 (fcx.tcx().types.err, 0, None)
2174 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2176 method_call: Option<MethodCall>,
2177 base_expr: Option<&hir::Expr>,
2179 lvalue_pref: LvaluePreference)
2180 -> Option<ty::TypeAndMut<'tcx>>
2182 // Try DerefMut first, if preferred.
2183 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2184 (PreferMutLvalue, Some(trait_did)) => {
2185 method::lookup_in_trait(fcx, span, base_expr,
2186 token::intern("deref_mut"), trait_did,
2192 // Otherwise, fall back to Deref.
2193 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2194 (None, Some(trait_did)) => {
2195 method::lookup_in_trait(fcx, span, base_expr,
2196 token::intern("deref"), trait_did,
2199 (method, _) => method
2202 make_overloaded_lvalue_return_type(fcx, method_call, method)
2205 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2206 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2207 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2208 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2209 method_call: Option<MethodCall>,
2210 method: Option<MethodCallee<'tcx>>)
2211 -> Option<ty::TypeAndMut<'tcx>>
2215 // extract method return type, which will be &T;
2216 // all LB regions should have been instantiated during method lookup
2217 let ret_ty = method.ty.fn_ret();
2218 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2220 if let Some(method_call) = method_call {
2221 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2224 // method returns &T, but the type as visible to user is T, so deref
2225 ret_ty.builtin_deref(true, NoPreference)
2231 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2233 base_expr: &'tcx hir::Expr,
2236 lvalue_pref: LvaluePreference)
2237 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2239 // FIXME(#18741) -- this is almost but not quite the same as the
2240 // autoderef that normal method probing does. They could likely be
2243 let (ty, autoderefs, final_mt) = autoderef(fcx,
2247 UnresolvedTypeAction::Error,
2250 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2251 adj_ty, idx, false, lvalue_pref, idx_ty)
2254 if final_mt.is_some() {
2258 // After we have fully autoderef'd, if the resulting type is [T; n], then
2259 // do a final unsized coercion to yield [T].
2260 if let ty::TyArray(element_ty, _) = ty.sty {
2261 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2262 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2263 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2269 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2270 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2271 /// This loop implements one step in that search; the autoderef loop is implemented by
2272 /// `lookup_indexing`.
2273 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2274 method_call: MethodCall,
2276 base_expr: &'tcx hir::Expr,
2277 adjusted_ty: Ty<'tcx>,
2280 lvalue_pref: LvaluePreference,
2282 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2284 let tcx = fcx.tcx();
2285 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2286 autoderefs={}, unsize={}, index_ty={:?})",
2294 let input_ty = fcx.infcx().next_ty_var();
2296 // First, try built-in indexing.
2297 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2298 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2299 debug!("try_index_step: success, using built-in indexing");
2300 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2302 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2303 return Some((tcx.types.usize, ty));
2308 // Try `IndexMut` first, if preferred.
2309 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2310 (PreferMutLvalue, Some(trait_did)) => {
2311 method::lookup_in_trait_adjusted(fcx,
2314 token::intern("index_mut"),
2319 Some(vec![input_ty]))
2324 // Otherwise, fall back to `Index`.
2325 let method = match (method, tcx.lang_items.index_trait()) {
2326 (None, Some(trait_did)) => {
2327 method::lookup_in_trait_adjusted(fcx,
2330 token::intern("index"),
2335 Some(vec![input_ty]))
2337 (method, _) => method,
2340 // If some lookup succeeds, write callee into table and extract index/element
2341 // type from the method signature.
2342 // If some lookup succeeded, install method in table
2343 method.and_then(|method| {
2344 debug!("try_index_step: success, using overloaded indexing");
2345 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2346 map(|ret| (input_ty, ret.ty))
2350 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2352 method_fn_ty: Ty<'tcx>,
2353 callee_expr: &'tcx hir::Expr,
2354 args_no_rcvr: &'tcx [P<hir::Expr>],
2355 tuple_arguments: TupleArgumentsFlag,
2356 expected: Expectation<'tcx>)
2357 -> ty::FnOutput<'tcx> {
2358 if method_fn_ty.references_error() {
2359 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2361 let err_inputs = match tuple_arguments {
2362 DontTupleArguments => err_inputs,
2363 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2366 check_argument_types(fcx,
2373 ty::FnConverging(fcx.tcx().types.err)
2375 match method_fn_ty.sty {
2376 ty::TyBareFn(_, ref fty) => {
2377 // HACK(eddyb) ignore self in the definition (see above).
2378 let expected_arg_tys = expected_types_for_fn_args(fcx,
2382 &fty.sig.0.inputs[1..]);
2383 check_argument_types(fcx,
2385 &fty.sig.0.inputs[1..],
2386 &expected_arg_tys[..],
2393 fcx.tcx().sess.span_bug(callee_expr.span,
2394 "method without bare fn type");
2400 /// Generic function that factors out common logic from function calls, method calls and overloaded
2402 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2404 fn_inputs: &[Ty<'tcx>],
2405 expected_arg_tys: &[Ty<'tcx>],
2406 args: &'tcx [P<hir::Expr>],
2408 tuple_arguments: TupleArgumentsFlag) {
2409 let tcx = fcx.ccx.tcx;
2411 // Grab the argument types, supplying fresh type variables
2412 // if the wrong number of arguments were supplied
2413 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2419 // All the input types from the fn signature must outlive the call
2420 // so as to validate implied bounds.
2421 for &fn_input_ty in fn_inputs {
2422 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2425 let mut expected_arg_tys = expected_arg_tys;
2426 let expected_arg_count = fn_inputs.len();
2427 let formal_tys = if tuple_arguments == TupleArguments {
2428 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2429 match tuple_type.sty {
2430 ty::TyTuple(ref arg_types) => {
2431 if arg_types.len() != args.len() {
2432 span_err!(tcx.sess, sp, E0057,
2433 "this function takes {} parameter{} but {} parameter{} supplied",
2435 if arg_types.len() == 1 {""} else {"s"},
2437 if args.len() == 1 {" was"} else {"s were"});
2438 expected_arg_tys = &[];
2439 err_args(fcx.tcx(), args.len())
2441 expected_arg_tys = match expected_arg_tys.get(0) {
2442 Some(&ty) => match ty.sty {
2443 ty::TyTuple(ref tys) => &**tys,
2448 (*arg_types).clone()
2452 span_err!(tcx.sess, sp, E0059,
2453 "cannot use call notation; the first type parameter \
2454 for the function trait is neither a tuple nor unit");
2455 expected_arg_tys = &[];
2456 err_args(fcx.tcx(), args.len())
2459 } else if expected_arg_count == supplied_arg_count {
2461 } else if variadic {
2462 if supplied_arg_count >= expected_arg_count {
2465 span_err!(tcx.sess, sp, E0060,
2466 "this function takes at least {} parameter{} \
2467 but {} parameter{} supplied",
2469 if expected_arg_count == 1 {""} else {"s"},
2471 if supplied_arg_count == 1 {" was"} else {"s were"});
2472 expected_arg_tys = &[];
2473 err_args(fcx.tcx(), supplied_arg_count)
2476 span_err!(tcx.sess, sp, E0061,
2477 "this function takes {} parameter{} but {} parameter{} supplied",
2479 if expected_arg_count == 1 {""} else {"s"},
2481 if supplied_arg_count == 1 {" was"} else {"s were"});
2482 expected_arg_tys = &[];
2483 err_args(fcx.tcx(), supplied_arg_count)
2486 debug!("check_argument_types: formal_tys={:?}",
2487 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2489 // Check the arguments.
2490 // We do this in a pretty awful way: first we typecheck any arguments
2491 // that are not anonymous functions, then we typecheck the anonymous
2492 // functions. This is so that we have more information about the types
2493 // of arguments when we typecheck the functions. This isn't really the
2494 // right way to do this.
2495 let xs = [false, true];
2496 for check_blocks in &xs {
2497 let check_blocks = *check_blocks;
2498 debug!("check_blocks={}", check_blocks);
2500 // More awful hacks: before we check argument types, try to do
2501 // an "opportunistic" vtable resolution of any trait bounds on
2502 // the call. This helps coercions.
2504 fcx.select_new_obligations();
2507 // For variadic functions, we don't have a declared type for all of
2508 // the arguments hence we only do our usual type checking with
2509 // the arguments who's types we do know.
2510 let t = if variadic {
2512 } else if tuple_arguments == TupleArguments {
2517 for (i, arg) in args.iter().take(t).enumerate() {
2518 let is_block = match arg.node {
2519 hir::ExprClosure(..) => true,
2523 if is_block == check_blocks {
2524 debug!("checking the argument");
2525 let formal_ty = formal_tys[i];
2527 // The special-cased logic below has three functions:
2528 // 1. Provide as good of an expected type as possible.
2529 let expected = expected_arg_tys.get(i).map(|&ty| {
2530 Expectation::rvalue_hint(fcx.tcx(), ty)
2533 check_expr_with_unifier(fcx,
2535 expected.unwrap_or(ExpectHasType(formal_ty)),
2537 // 2. Coerce to the most detailed type that could be coerced
2538 // to, which is `expected_ty` if `rvalue_hint` returns an
2539 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2540 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2541 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2543 // 3. Relate the expected type and the formal one,
2544 // if the expected type was used for the coercion.
2545 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2551 // We also need to make sure we at least write the ty of the other
2552 // arguments which we skipped above.
2554 for arg in args.iter().skip(expected_arg_count) {
2555 check_expr(fcx, &**arg);
2557 // There are a few types which get autopromoted when passed via varargs
2558 // in C but we just error out instead and require explicit casts.
2559 let arg_ty = structurally_resolved_type(fcx, arg.span,
2560 fcx.expr_ty(&**arg));
2562 ty::TyFloat(ast::TyF32) => {
2563 fcx.type_error_message(arg.span,
2565 format!("can't pass an {} to variadic \
2566 function, cast to c_double", t)
2569 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2570 fcx.type_error_message(arg.span, |t| {
2571 format!("can't pass {} to variadic \
2572 function, cast to c_int",
2576 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2577 fcx.type_error_message(arg.span, |t| {
2578 format!("can't pass {} to variadic \
2579 function, cast to c_uint",
2589 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2590 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2591 (0..len).map(|_| tcx.types.err).collect()
2594 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2595 call_expr: &hir::Expr,
2596 output: ty::FnOutput<'tcx>) {
2597 fcx.write_ty(call_expr.id, match output {
2598 ty::FnConverging(output_ty) => output_ty,
2599 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2603 // AST fragment checking
2604 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2606 expected: Expectation<'tcx>)
2609 let tcx = fcx.ccx.tcx;
2612 ast::LitStr(..) => tcx.mk_static_str(),
2613 ast::LitByteStr(ref v) => {
2614 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2615 tcx.mk_array(tcx.types.u8, v.len()))
2617 ast::LitByte(_) => tcx.types.u8,
2618 ast::LitChar(_) => tcx.types.char,
2619 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2620 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2621 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2622 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2624 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2625 ty::TyChar => Some(tcx.types.u8),
2626 ty::TyRawPtr(..) => Some(tcx.types.usize),
2627 ty::TyBareFn(..) => Some(tcx.types.usize),
2631 opt_ty.unwrap_or_else(
2632 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2634 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2635 ast::LitFloatUnsuffixed(_) => {
2636 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2638 ty::TyFloat(_) => Some(ty),
2642 opt_ty.unwrap_or_else(
2643 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2645 ast::LitBool(_) => tcx.types.bool
2649 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2650 expr: &'tcx hir::Expr,
2651 expected: Ty<'tcx>) {
2652 check_expr_with_unifier(
2653 fcx, expr, ExpectHasType(expected), NoPreference,
2654 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2657 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2658 expr: &'tcx hir::Expr,
2659 expected: Ty<'tcx>) {
2660 check_expr_with_unifier(
2661 fcx, expr, ExpectHasType(expected), NoPreference,
2662 || demand::coerce(fcx, expr.span, expected, expr));
2665 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2666 expected: Ty<'tcx>) {
2667 check_expr_with_unifier(
2668 fcx, expr, ExpectHasType(expected), NoPreference,
2672 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2673 expr: &'tcx hir::Expr,
2674 expected: Expectation<'tcx>) {
2675 check_expr_with_unifier(
2676 fcx, expr, expected, NoPreference,
2680 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2681 expr: &'tcx hir::Expr,
2682 expected: Expectation<'tcx>,
2683 lvalue_pref: LvaluePreference)
2685 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2688 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2689 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2692 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2693 lvalue_pref: LvaluePreference) {
2694 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2697 // determine the `self` type, using fresh variables for all variables
2698 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2699 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2701 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2702 span: Span, // (potential) receiver for this impl
2704 -> TypeAndSubsts<'tcx> {
2705 let tcx = fcx.tcx();
2707 let ity = tcx.lookup_item_type(did);
2708 let (tps, rps, raw_ty) =
2709 (ity.generics.types.get_slice(subst::TypeSpace),
2710 ity.generics.regions.get_slice(subst::TypeSpace),
2713 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2715 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2716 let mut substs = subst::Substs::new(
2717 VecPerParamSpace::empty(),
2718 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2719 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2720 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2722 TypeAndSubsts { substs: substs, ty: substd_ty }
2725 /// Controls whether the arguments are tupled. This is used for the call
2728 /// Tupling means that all call-side arguments are packed into a tuple and
2729 /// passed as a single parameter. For example, if tupling is enabled, this
2732 /// fn f(x: (isize, isize))
2734 /// Can be called as:
2741 #[derive(Clone, Eq, PartialEq)]
2742 enum TupleArgumentsFlag {
2747 /// Unifies the return type with the expected type early, for more coercions
2748 /// and forward type information on the argument expressions.
2749 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2751 expected_ret: Expectation<'tcx>,
2752 formal_ret: ty::FnOutput<'tcx>,
2753 formal_args: &[Ty<'tcx>])
2755 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2756 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2757 fcx.infcx().commit_regions_if_ok(|| {
2758 // Attempt to apply a subtyping relationship between the formal
2759 // return type (likely containing type variables if the function
2760 // is polymorphic) and the expected return type.
2761 // No argument expectations are produced if unification fails.
2762 let origin = infer::Misc(call_span);
2763 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2764 // FIXME(#15760) can't use try! here, FromError doesn't default
2765 // to identity so the resulting type is not constrained.
2766 if let Err(e) = ures {
2770 // Record all the argument types, with the substitutions
2771 // produced from the above subtyping unification.
2772 Ok(formal_args.iter().map(|ty| {
2773 fcx.infcx().resolve_type_vars_if_possible(ty)
2779 }).unwrap_or(vec![]);
2780 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2781 formal_args, formal_ret,
2782 expected_args, expected_ret);
2787 /// If an expression has any sub-expressions that result in a type error,
2788 /// inspecting that expression's type with `ty.references_error()` will return
2789 /// true. Likewise, if an expression is known to diverge, inspecting its
2790 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2791 /// strict, _|_ can appear in the type of an expression that does not,
2792 /// itself, diverge: for example, fn() -> _|_.)
2793 /// Note that inspecting a type's structure *directly* may expose the fact
2794 /// that there are actually multiple representations for `TyError`, so avoid
2795 /// that when err needs to be handled differently.
2796 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2797 expr: &'tcx hir::Expr,
2798 expected: Expectation<'tcx>,
2799 lvalue_pref: LvaluePreference,
2803 debug!(">> typechecking: expr={:?} expected={:?}",
2806 // Checks a method call.
2807 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2808 expr: &'tcx hir::Expr,
2809 method_name: Spanned<ast::Name>,
2810 args: &'tcx [P<hir::Expr>],
2812 expected: Expectation<'tcx>,
2813 lvalue_pref: LvaluePreference) {
2814 let rcvr = &*args[0];
2815 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2817 // no need to check for bot/err -- callee does that
2818 let expr_t = structurally_resolved_type(fcx,
2820 fcx.expr_ty(&*rcvr));
2822 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2823 let fn_ty = match method::lookup(fcx,
2831 let method_ty = method.ty;
2832 let method_call = MethodCall::expr(expr.id);
2833 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2837 method::report_error(fcx, method_name.span, expr_t,
2838 method_name.node, Some(rcvr), error);
2839 fcx.write_error(expr.id);
2844 // Call the generic checker.
2845 let ret_ty = check_method_argument_types(fcx,
2853 write_call(fcx, expr, ret_ty);
2856 // A generic function for checking the then and else in an if
2858 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2859 cond_expr: &'tcx hir::Expr,
2860 then_blk: &'tcx hir::Block,
2861 opt_else_expr: Option<&'tcx hir::Expr>,
2864 expected: Expectation<'tcx>) {
2865 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2867 let expected = expected.adjust_for_branches(fcx);
2868 check_block_with_expected(fcx, then_blk, expected);
2869 let then_ty = fcx.node_ty(then_blk.id);
2871 let branches_ty = match opt_else_expr {
2872 Some(ref else_expr) => {
2873 check_expr_with_expectation(fcx, &**else_expr, expected);
2874 let else_ty = fcx.expr_ty(&**else_expr);
2875 infer::common_supertype(fcx.infcx(),
2876 infer::IfExpression(sp),
2882 infer::common_supertype(fcx.infcx(),
2883 infer::IfExpressionWithNoElse(sp),
2890 let cond_ty = fcx.expr_ty(cond_expr);
2891 let if_ty = if cond_ty.references_error() {
2897 fcx.write_ty(id, if_ty);
2900 // Check field access expressions
2901 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2902 expr: &'tcx hir::Expr,
2903 lvalue_pref: LvaluePreference,
2904 base: &'tcx hir::Expr,
2905 field: &Spanned<ast::Name>) {
2906 let tcx = fcx.ccx.tcx;
2907 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2908 let expr_t = structurally_resolved_type(fcx, expr.span,
2910 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2911 let (_, autoderefs, field_ty) = autoderef(fcx,
2915 UnresolvedTypeAction::Error,
2919 ty::TyStruct(base_def, substs) => {
2920 debug!("struct named {:?}", base_t);
2921 base_def.struct_variant()
2922 .find_field_named(field.node)
2923 .map(|f| fcx.field_ty(expr.span, f, substs))
2930 fcx.write_ty(expr.id, field_ty);
2931 fcx.write_autoderef_adjustment(base.id, autoderefs);
2937 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2938 fcx.type_error_message(
2941 format!("attempted to take value of method `{}` on type \
2942 `{}`", field.node, actual)
2946 tcx.sess.fileline_help(field.span,
2947 "maybe a `()` to call it is missing? \
2948 If not, try an anonymous function");
2950 fcx.type_error_message(
2953 format!("attempted access of field `{}` on \
2954 type `{}`, but no field with that \
2960 if let ty::TyStruct(def, _) = expr_t.sty {
2961 suggest_field_names(def.struct_variant(), field, tcx, vec![]);
2965 fcx.write_error(expr.id);
2968 // displays hints about the closest matches in field names
2969 fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
2970 field: &Spanned<ast::Name>,
2971 tcx: &ty::ctxt<'tcx>,
2972 skip : Vec<InternedString>) {
2973 let name = field.node.as_str();
2974 // only find fits with at least one matching letter
2975 let mut best_dist = name.len();
2976 let mut best = None;
2977 for elem in &variant.fields {
2978 let n = elem.name.as_str();
2979 // ignore already set fields
2980 if skip.iter().any(|x| *x == n) {
2983 // ignore private fields from non-local crates
2984 if variant.did.krate != LOCAL_CRATE && elem.vis != Visibility::Public {
2987 let dist = lev_distance(&n, &name);
2988 if dist < best_dist {
2993 if let Some(n) = best {
2994 tcx.sess.span_help(field.span,
2995 &format!("did you mean `{}`?", n));
2999 // Check tuple index expressions
3000 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3001 expr: &'tcx hir::Expr,
3002 lvalue_pref: LvaluePreference,
3003 base: &'tcx hir::Expr,
3004 idx: codemap::Spanned<usize>) {
3005 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3006 let expr_t = structurally_resolved_type(fcx, expr.span,
3008 let mut tuple_like = false;
3009 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3010 let (_, autoderefs, field_ty) = autoderef(fcx,
3014 UnresolvedTypeAction::Error,
3018 ty::TyStruct(base_def, substs) => {
3019 tuple_like = base_def.struct_variant().is_tuple_struct();
3021 debug!("tuple struct named {:?}", base_t);
3022 base_def.struct_variant()
3025 .map(|f| fcx.field_ty(expr.span, f, substs))
3030 ty::TyTuple(ref v) => {
3032 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3039 fcx.write_ty(expr.id, field_ty);
3040 fcx.write_autoderef_adjustment(base.id, autoderefs);
3045 fcx.type_error_message(
3049 format!("attempted out-of-bounds tuple index `{}` on \
3054 format!("attempted tuple index `{}` on type `{}`, but the \
3055 type was not a tuple or tuple struct",
3062 fcx.write_error(expr.id);
3065 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3067 variant: ty::VariantDef<'tcx>,
3069 skip_fields: &[hir::Field]) {
3070 fcx.type_error_message(
3072 |actual| if let ty::TyEnum(..) = ty.sty {
3073 format!("struct variant `{}::{}` has no field named `{}`",
3074 actual, variant.name.as_str(), field.name.node)
3076 format!("structure `{}` has no field named `{}`",
3077 actual, field.name.node)
3081 // prevent all specified fields from being suggested
3082 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3083 suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
3086 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3089 variant: ty::VariantDef<'tcx>,
3090 ast_fields: &'tcx [hir::Field],
3091 check_completeness: bool) {
3092 let tcx = fcx.ccx.tcx;
3093 let substs = match adt_ty.sty {
3094 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3095 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3098 let mut remaining_fields = FnvHashMap();
3099 for field in &variant.fields {
3100 remaining_fields.insert(field.name, field);
3103 let mut error_happened = false;
3105 // Typecheck each field.
3106 for field in ast_fields {
3107 let expected_field_type;
3109 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3110 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3112 error_happened = true;
3113 expected_field_type = tcx.types.err;
3114 if let Some(_) = variant.find_field_named(field.name.node) {
3115 span_err!(fcx.tcx().sess, field.name.span, E0062,
3116 "field `{}` specified more than once",
3119 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3123 // Make sure to give a type to the field even if there's
3124 // an error, so we can continue typechecking
3125 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3128 // Make sure the programmer specified all the fields.
3129 if check_completeness &&
3131 !remaining_fields.is_empty()
3133 span_err!(tcx.sess, span, E0063,
3134 "missing field{}: {}",
3135 if remaining_fields.len() == 1 {""} else {"s"},
3136 remaining_fields.keys()
3137 .map(|n| format!("`{}`", n))
3138 .collect::<Vec<_>>()
3144 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3146 fields: &'tcx [hir::Field],
3147 base_expr: &'tcx Option<P<hir::Expr>>) {
3148 // Make sure to still write the types
3149 // otherwise we might ICE
3150 fcx.write_error(id);
3151 for field in fields {
3152 check_expr(fcx, &*field.expr);
3155 Some(ref base) => check_expr(fcx, &**base),
3160 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3163 fields: &'tcx [hir::Field],
3164 base_expr: &'tcx Option<P<hir::Expr>>)
3166 let tcx = fcx.tcx();
3168 // Find the relevant variant
3169 let def = lookup_full_def(tcx, path.span, expr.id);
3170 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3171 Some((adt, variant)) => (adt, variant),
3173 span_err!(fcx.tcx().sess, path.span, E0071,
3174 "`{}` does not name a structure",
3175 pprust::path_to_string(path));
3176 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3181 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3182 fcx.write_ty(expr.id, expr_ty);
3184 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3185 base_expr.is_none());
3187 if let &Some(ref base_expr) = base_expr {
3188 check_expr_has_type(fcx, base_expr, expr_ty);
3189 if adt.adt_kind() == ty::AdtKind::Enum {
3190 span_err!(tcx.sess, base_expr.span, E0436,
3191 "functional record update syntax requires a struct");
3196 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3198 let tcx = fcx.ccx.tcx;
3201 hir::ExprBox(ref subexpr) => {
3202 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3204 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3208 check_expr_with_expectation(fcx, subexpr, expected_inner);
3209 let referent_ty = fcx.expr_ty(&**subexpr);
3210 fcx.write_ty(id, tcx.mk_box(referent_ty));
3213 hir::ExprLit(ref lit) => {
3214 let typ = check_lit(fcx, &**lit, expected);
3215 fcx.write_ty(id, typ);
3217 hir::ExprBinary(op, ref lhs, ref rhs) => {
3218 op::check_binop(fcx, expr, op, lhs, rhs);
3220 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3221 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3223 hir::ExprUnary(unop, ref oprnd) => {
3224 let expected_inner = match unop {
3225 hir::UnNot | hir::UnNeg => {
3232 let lvalue_pref = match unop {
3233 hir::UnDeref => lvalue_pref,
3236 check_expr_with_expectation_and_lvalue_pref(
3237 fcx, &**oprnd, expected_inner, lvalue_pref);
3238 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3240 if !oprnd_t.references_error() {
3243 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3244 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3246 None => match try_overloaded_deref(fcx, expr.span,
3247 Some(MethodCall::expr(expr.id)),
3248 Some(&**oprnd), oprnd_t, lvalue_pref) {
3251 fcx.type_error_message(expr.span, |actual| {
3252 format!("type `{}` cannot be \
3253 dereferenced", actual)
3261 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3263 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3264 oprnd_t = op::check_user_unop(fcx, "!", "not",
3265 tcx.lang_items.not_trait(),
3266 expr, &**oprnd, oprnd_t, unop);
3270 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3272 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3273 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3274 tcx.lang_items.neg_trait(),
3275 expr, &**oprnd, oprnd_t, unop);
3280 fcx.write_ty(id, oprnd_t);
3282 hir::ExprAddrOf(mutbl, ref oprnd) => {
3283 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3285 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3286 if fcx.tcx().expr_is_lval(&**oprnd) {
3287 // Lvalues may legitimately have unsized types.
3288 // For example, dereferences of a fat pointer and
3289 // the last field of a struct can be unsized.
3290 ExpectHasType(mt.ty)
3292 Expectation::rvalue_hint(tcx, mt.ty)
3298 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3299 check_expr_with_expectation_and_lvalue_pref(fcx,
3304 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3305 let oprnd_t = if tm.ty.references_error() {
3308 // Note: at this point, we cannot say what the best lifetime
3309 // is to use for resulting pointer. We want to use the
3310 // shortest lifetime possible so as to avoid spurious borrowck
3311 // errors. Moreover, the longest lifetime will depend on the
3312 // precise details of the value whose address is being taken
3313 // (and how long it is valid), which we don't know yet until type
3314 // inference is complete.
3316 // Therefore, here we simply generate a region variable. The
3317 // region inferencer will then select the ultimate value.
3318 // Finally, borrowck is charged with guaranteeing that the
3319 // value whose address was taken can actually be made to live
3320 // as long as it needs to live.
3321 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3322 tcx.mk_ref(tcx.mk_region(region), tm)
3324 fcx.write_ty(id, oprnd_t);
3326 hir::ExprPath(ref maybe_qself, ref path) => {
3327 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3328 fcx.to_ty(&qself.ty)
3331 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3333 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3334 // Create some fake resolution that can't possibly be a type.
3335 def::PathResolution {
3336 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3337 last_private: LastMod(AllPublic),
3338 depth: path.segments.len()
3341 tcx.sess.span_bug(expr.span,
3342 &format!("unbound path {:?}", expr))
3345 if let Some((opt_ty, segments, def)) =
3346 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3347 expr.span, expr.id) {
3348 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3351 instantiate_path(fcx,
3361 // We always require that the type provided as the value for
3362 // a type parameter outlives the moment of instantiation.
3363 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3364 fcx.add_wf_bounds(&item_substs.substs, expr);
3367 hir::ExprInlineAsm(ref ia) => {
3368 for &(_, ref input) in &ia.inputs {
3369 check_expr(fcx, &**input);
3371 for &(_, ref out, _) in &ia.outputs {
3372 check_expr(fcx, &**out);
3376 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3377 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3378 hir::ExprRet(ref expr_opt) => {
3380 ty::FnConverging(result_type) => {
3383 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3384 result_type, fcx.tcx().mk_nil()) {
3385 span_err!(tcx.sess, expr.span, E0069,
3386 "`return;` in a function whose return type is \
3390 check_expr_coercable_to_type(fcx, &**e, result_type);
3394 ty::FnDiverging => {
3395 if let Some(ref e) = *expr_opt {
3396 check_expr(fcx, &**e);
3398 span_err!(tcx.sess, expr.span, E0166,
3399 "`return` in a function declared as diverging");
3402 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3404 hir::ExprAssign(ref lhs, ref rhs) => {
3405 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3407 let tcx = fcx.tcx();
3408 if !tcx.expr_is_lval(&**lhs) {
3409 span_err!(tcx.sess, expr.span, E0070,
3410 "invalid left-hand side expression");
3413 let lhs_ty = fcx.expr_ty(&**lhs);
3414 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3415 let rhs_ty = fcx.expr_ty(&**rhs);
3417 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3419 if lhs_ty.references_error() || rhs_ty.references_error() {
3420 fcx.write_error(id);
3425 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3426 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3427 id, expr.span, expected);
3429 hir::ExprWhile(ref cond, ref body, _) => {
3430 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3431 check_block_no_value(fcx, &**body);
3432 let cond_ty = fcx.expr_ty(&**cond);
3433 let body_ty = fcx.node_ty(body.id);
3434 if cond_ty.references_error() || body_ty.references_error() {
3435 fcx.write_error(id);
3441 hir::ExprLoop(ref body, _) => {
3442 check_block_no_value(fcx, &**body);
3443 if !may_break(tcx, expr.id, &**body) {
3444 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3449 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3450 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3452 hir::ExprClosure(capture, ref decl, ref body) => {
3453 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3455 hir::ExprBlock(ref b) => {
3456 check_block_with_expected(fcx, &**b, expected);
3457 fcx.write_ty(id, fcx.node_ty(b.id));
3459 hir::ExprCall(ref callee, ref args) => {
3460 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3462 // we must check that return type of called functions is WF:
3463 let ret_ty = fcx.expr_ty(expr);
3464 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3466 hir::ExprMethodCall(name, ref tps, ref args) => {
3467 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3468 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3469 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3471 fcx.write_error(id);
3474 hir::ExprCast(ref e, ref t) => {
3475 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3476 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3479 // Find the type of `e`. Supply hints based on the type we are casting to,
3481 let t_cast = fcx.to_ty(t);
3482 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3483 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3484 let t_expr = fcx.expr_ty(e);
3486 // Eagerly check for some obvious errors.
3487 if t_expr.references_error() {
3488 fcx.write_error(id);
3489 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3490 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3492 // Write a type for the whole expression, assuming everything is going
3494 fcx.write_ty(id, t_cast);
3496 // Defer other checks until we're done type checking.
3497 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3498 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3499 deferred_cast_checks.push(cast_check);
3502 hir::ExprVec(ref args) => {
3503 let uty = expected.to_option(fcx).and_then(|uty| {
3505 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3510 let typ = match uty {
3513 check_expr_coercable_to_type(fcx, &**e, uty);
3518 let t: Ty = fcx.infcx().next_ty_var();
3520 check_expr_has_type(fcx, &**e, t);
3525 let typ = tcx.mk_array(typ, args.len());
3526 fcx.write_ty(id, typ);
3528 hir::ExprRepeat(ref element, ref count_expr) => {
3529 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3530 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3532 let uty = match expected {
3533 ExpectHasType(uty) => {
3535 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3542 let (element_ty, t) = match uty {
3544 check_expr_coercable_to_type(fcx, &**element, uty);
3548 let t: Ty = fcx.infcx().next_ty_var();
3549 check_expr_has_type(fcx, &**element, t);
3550 (fcx.expr_ty(&**element), t)
3555 // For [foo, ..n] where n > 1, `foo` must have
3557 fcx.require_type_meets(
3564 if element_ty.references_error() {
3565 fcx.write_error(id);
3567 let t = tcx.mk_array(t, count);
3568 fcx.write_ty(id, t);
3571 hir::ExprTup(ref elts) => {
3572 let flds = expected.only_has_type(fcx).and_then(|ty| {
3574 ty::TyTuple(ref flds) => Some(&flds[..]),
3578 let mut err_field = false;
3580 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3581 let t = match flds {
3582 Some(ref fs) if i < fs.len() => {
3584 check_expr_coercable_to_type(fcx, &**e, ety);
3588 check_expr_with_expectation(fcx, &**e, NoExpectation);
3592 err_field = err_field || t.references_error();
3596 fcx.write_error(id);
3598 let typ = tcx.mk_tup(elt_ts);
3599 fcx.write_ty(id, typ);
3602 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3603 check_expr_struct(fcx, expr, path, fields, base_expr);
3605 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3607 hir::ExprField(ref base, ref field) => {
3608 check_field(fcx, expr, lvalue_pref, &**base, field);
3610 hir::ExprTupField(ref base, idx) => {
3611 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3613 hir::ExprIndex(ref base, ref idx) => {
3614 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3615 check_expr(fcx, &**idx);
3617 let base_t = fcx.expr_ty(&**base);
3618 let idx_t = fcx.expr_ty(&**idx);
3620 if base_t.references_error() {
3621 fcx.write_ty(id, base_t);
3622 } else if idx_t.references_error() {
3623 fcx.write_ty(id, idx_t);
3625 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3626 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3627 Some((index_ty, element_ty)) => {
3628 let idx_expr_ty = fcx.expr_ty(idx);
3629 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3630 fcx.write_ty(id, element_ty);
3633 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3634 fcx.type_error_message(
3637 format!("cannot index a value of type `{}`",
3642 fcx.write_ty(id, fcx.tcx().types.err);
3647 hir::ExprRange(ref start, ref end) => {
3648 let t_start = start.as_ref().map(|e| {
3649 check_expr(fcx, &**e);
3652 let t_end = end.as_ref().map(|e| {
3653 check_expr(fcx, &**e);
3657 let idx_type = match (t_start, t_end) {
3658 (Some(ty), None) | (None, Some(ty)) => {
3661 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3662 t_end.references_error()) => {
3663 Some(fcx.tcx().types.err)
3665 (Some(t_start), Some(t_end)) => {
3666 Some(infer::common_supertype(fcx.infcx(),
3667 infer::RangeExpression(expr.span),
3675 // Note that we don't check the type of start/end satisfy any
3676 // bounds because right now the range structs do not have any. If we add
3677 // some bounds, then we'll need to check `t_start` against them here.
3679 let range_type = match idx_type {
3680 Some(idx_type) if idx_type.references_error() => {
3684 // Find the did from the appropriate lang item.
3685 let did = match (start, end) {
3686 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3687 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3688 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3690 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3694 if let Some(did) = did {
3695 let def = tcx.lookup_adt_def(did);
3696 let predicates = tcx.lookup_predicates(did);
3697 let substs = Substs::new_type(vec![idx_type], vec![]);
3698 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3699 fcx.add_obligations_for_parameters(
3700 traits::ObligationCause::new(expr.span,
3702 traits::ItemObligation(did)),
3705 tcx.mk_struct(def, tcx.mk_substs(substs))
3707 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3712 // Neither start nor end => RangeFull
3713 if let Some(did) = tcx.lang_items.range_full_struct() {
3715 tcx.lookup_adt_def(did),
3716 tcx.mk_substs(Substs::empty())
3719 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3725 fcx.write_ty(id, range_type);
3730 debug!("type of expr({}) {} is...", expr.id,
3731 pprust::expr_to_string(expr));
3732 debug!("... {:?}, expected is {:?}",
3739 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3740 path_res: def::PathResolution,
3741 opt_self_ty: Option<Ty<'tcx>>,
3742 path: &'a hir::Path,
3744 node_id: ast::NodeId)
3745 -> Option<(Option<Ty<'tcx>>,
3746 &'a [hir::PathSegment],
3750 // Associated constants can't depend on generic types.
3751 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3755 node_id: ast::NodeId) -> bool {
3757 def::DefAssociatedConst(..) => {
3758 if ty.has_param_types() || ty.has_self_ty() {
3759 span_err!(fcx.sess(), span, E0329,
3760 "Associated consts cannot depend \
3761 on type parameters or Self.");
3762 fcx.write_error(node_id);
3771 // If fully resolved already, we don't have to do anything.
3772 if path_res.depth == 0 {
3773 if let Some(ty) = opt_self_ty {
3774 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3779 Some((opt_self_ty, &path.segments, path_res.base_def))
3781 let mut def = path_res.base_def;
3782 let ty_segments = path.segments.split_last().unwrap().1;
3783 let base_ty_end = path.segments.len() - path_res.depth;
3784 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3785 PathParamMode::Optional,
3788 &ty_segments[..base_ty_end],
3789 &ty_segments[base_ty_end..]);
3790 let item_segment = path.segments.last().unwrap();
3791 let item_name = item_segment.identifier.name;
3792 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3794 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3797 // Write back the new resolution.
3798 fcx.ccx.tcx.def_map.borrow_mut()
3799 .insert(node_id, def::PathResolution {
3801 last_private: path_res.last_private.or(lp),
3804 Some((Some(ty), slice::ref_slice(item_segment), def))
3807 method::report_error(fcx, span, ty,
3808 item_name, None, error);
3809 fcx.write_error(node_id);
3816 impl<'tcx> Expectation<'tcx> {
3817 /// Provide an expectation for an rvalue expression given an *optional*
3818 /// hint, which is not required for type safety (the resulting type might
3819 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3820 /// is useful in determining the concrete type.
3822 /// The primary use case is where the expected type is a fat pointer,
3823 /// like `&[isize]`. For example, consider the following statement:
3825 /// let x: &[isize] = &[1, 2, 3];
3827 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3828 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3829 /// expectation `ExpectHasType([isize])`, that would be too strong --
3830 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3831 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3832 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3833 /// which still is useful, because it informs integer literals and the like.
3834 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3835 /// for examples of where this comes up,.
3836 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3837 match tcx.struct_tail(ty).sty {
3838 ty::TySlice(_) | ty::TyTrait(..) => {
3839 ExpectRvalueLikeUnsized(ty)
3841 _ => ExpectHasType(ty)
3845 // Resolves `expected` by a single level if it is a variable. If
3846 // there is no expected type or resolution is not possible (e.g.,
3847 // no constraints yet present), just returns `None`.
3848 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3853 ExpectCastableToType(t) => {
3854 ExpectCastableToType(
3855 fcx.infcx().resolve_type_vars_if_possible(&t))
3857 ExpectHasType(t) => {
3859 fcx.infcx().resolve_type_vars_if_possible(&t))
3861 ExpectRvalueLikeUnsized(t) => {
3862 ExpectRvalueLikeUnsized(
3863 fcx.infcx().resolve_type_vars_if_possible(&t))
3868 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3869 match self.resolve(fcx) {
3870 NoExpectation => None,
3871 ExpectCastableToType(ty) |
3873 ExpectRvalueLikeUnsized(ty) => Some(ty),
3877 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3878 match self.resolve(fcx) {
3879 ExpectHasType(ty) => Some(ty),
3885 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3886 local: &'tcx hir::Local,
3887 init: &'tcx hir::Expr)
3889 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3891 let local_ty = fcx.local_ty(init.span, local.id);
3892 if let Some(m) = ref_bindings {
3893 // Somewhat subtle: if we have a `ref` binding in the pattern,
3894 // we want to avoid introducing coercions for the RHS. This is
3895 // both because it helps preserve sanity and, in the case of
3896 // ref mut, for soundness (issue #23116). In particular, in
3897 // the latter case, we need to be clear that the type of the
3898 // referent for the reference that results is *equal to* the
3899 // type of the lvalue it is referencing, and not some
3900 // supertype thereof.
3901 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3902 let init_ty = fcx.expr_ty(init);
3903 demand::eqtype(fcx, init.span, init_ty, local_ty);
3905 check_expr_coercable_to_type(fcx, init, local_ty)
3909 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3910 let tcx = fcx.ccx.tcx;
3912 let t = fcx.local_ty(local.span, local.id);
3913 fcx.write_ty(local.id, t);
3915 if let Some(ref init) = local.init {
3916 check_decl_initializer(fcx, local, &**init);
3917 let init_ty = fcx.expr_ty(&**init);
3918 if init_ty.references_error() {
3919 fcx.write_ty(local.id, init_ty);
3923 let pcx = pat_ctxt {
3925 map: pat_id_map(&tcx.def_map, &*local.pat),
3927 _match::check_pat(&pcx, &*local.pat, t);
3928 let pat_ty = fcx.node_ty(local.pat.id);
3929 if pat_ty.references_error() {
3930 fcx.write_ty(local.id, pat_ty);
3934 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3936 let mut saw_bot = false;
3937 let mut saw_err = false;
3939 hir::StmtDecl(ref decl, id) => {
3942 hir::DeclLocal(ref l) => {
3943 check_decl_local(fcx, &**l);
3944 let l_t = fcx.node_ty(l.id);
3945 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3946 saw_err = saw_err || l_t.references_error();
3948 hir::DeclItem(_) => {/* ignore for now */ }
3951 hir::StmtExpr(ref expr, id) => {
3953 // Check with expected type of ()
3954 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3955 let expr_ty = fcx.expr_ty(&**expr);
3956 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3957 saw_err = saw_err || expr_ty.references_error();
3959 hir::StmtSemi(ref expr, id) => {
3961 check_expr(fcx, &**expr);
3962 let expr_ty = fcx.expr_ty(&**expr);
3963 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3964 saw_err |= expr_ty.references_error();
3968 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3971 fcx.write_error(node_id);
3974 fcx.write_nil(node_id)
3978 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3979 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3980 let blkty = fcx.node_ty(blk.id);
3981 if blkty.references_error() {
3982 fcx.write_error(blk.id);
3984 let nilty = fcx.tcx().mk_nil();
3985 demand::suptype(fcx, blk.span, nilty, blkty);
3989 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3990 blk: &'tcx hir::Block,
3991 expected: Expectation<'tcx>) {
3993 let mut fcx_ps = fcx.ps.borrow_mut();
3994 let unsafety_state = fcx_ps.recurse(blk);
3995 replace(&mut *fcx_ps, unsafety_state)
3998 let mut warned = false;
3999 let mut any_diverges = false;
4000 let mut any_err = false;
4001 for s in &blk.stmts {
4002 check_stmt(fcx, &**s);
4003 let s_id = ::rustc_front::util::stmt_id(&**s);
4004 let s_ty = fcx.node_ty(s_id);
4005 if any_diverges && !warned && match s.node {
4006 hir::StmtDecl(ref decl, _) => {
4008 hir::DeclLocal(_) => true,
4012 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4017 .add_lint(lint::builtin::UNREACHABLE_CODE,
4020 "unreachable statement".to_string());
4023 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4024 any_err = any_err || s_ty.references_error();
4027 None => if any_err {
4028 fcx.write_error(blk.id);
4029 } else if any_diverges {
4030 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4032 fcx.write_nil(blk.id);
4035 if any_diverges && !warned {
4039 .add_lint(lint::builtin::UNREACHABLE_CODE,
4042 "unreachable expression".to_string());
4044 let ety = match expected {
4045 ExpectHasType(ety) => {
4046 check_expr_coercable_to_type(fcx, &**e, ety);
4050 check_expr_with_expectation(fcx, &**e, expected);
4056 fcx.write_error(blk.id);
4057 } else if any_diverges {
4058 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4060 fcx.write_ty(blk.id, ety);
4065 *fcx.ps.borrow_mut() = prev;
4068 /// Checks a constant appearing in a type. At the moment this is just the
4069 /// length expression in a fixed-length vector, but someday it might be
4070 /// extended to type-level numeric literals.
4071 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4072 expr: &'tcx hir::Expr,
4073 expected_type: Ty<'tcx>) {
4074 let tables = RefCell::new(ty::Tables::empty());
4075 let inh = static_inherited_fields(ccx, &tables);
4076 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4077 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4080 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4084 let tables = RefCell::new(ty::Tables::empty());
4085 let inh = static_inherited_fields(ccx, &tables);
4086 let rty = ccx.tcx.node_id_to_type(id);
4087 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4088 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4089 check_const_with_ty(&fcx, sp, e, declty);
4092 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4096 // Gather locals in statics (because of block expressions).
4097 // This is technically unnecessary because locals in static items are forbidden,
4098 // but prevents type checking from blowing up before const checking can properly
4100 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4102 check_expr_with_hint(fcx, e, declty);
4103 demand::coerce(fcx, e.span, declty, e);
4105 fcx.select_all_obligations_and_apply_defaults();
4106 upvar::closure_analyze_const(&fcx, e);
4107 fcx.select_obligations_where_possible();
4109 fcx.select_all_obligations_or_error();
4111 regionck::regionck_expr(fcx, e);
4112 writeback::resolve_type_vars_in_expr(fcx, e);
4115 /// Checks whether a type can be represented in memory. In particular, it
4116 /// identifies types that contain themselves without indirection through a
4117 /// pointer, which would mean their size is unbounded.
4118 pub fn check_representable(tcx: &ty::ctxt,
4120 item_id: ast::NodeId,
4121 designation: &str) -> bool {
4122 let rty = tcx.node_id_to_type(item_id);
4124 // Check that it is possible to represent this type. This call identifies
4125 // (1) types that contain themselves and (2) types that contain a different
4126 // recursive type. It is only necessary to throw an error on those that
4127 // contain themselves. For case 2, there must be an inner type that will be
4128 // caught by case 1.
4129 match rty.is_representable(tcx, sp) {
4130 Representability::SelfRecursive => {
4131 span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
4132 tcx.sess.fileline_help(
4133 sp, "wrap the inner value in a box to make it representable");
4136 Representability::Representable | Representability::ContainsRecursive => (),
4141 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4142 let t = tcx.node_id_to_type(id);
4144 ty::TyStruct(def, substs) => {
4145 let fields = &def.struct_variant().fields;
4146 if fields.is_empty() {
4147 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4150 let e = fields[0].ty(tcx, substs);
4151 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4152 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4156 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4157 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4159 span_err!(tcx.sess, sp, E0077,
4160 "SIMD vector element type should be machine type");
4169 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4171 vs: &'tcx [P<hir::Variant>],
4174 fn disr_in_range(ccx: &CrateCtxt,
4176 disr: ty::Disr) -> bool {
4177 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4179 ast::TyU8 => disr as u8 as Disr == disr,
4180 ast::TyU16 => disr as u16 as Disr == disr,
4181 ast::TyU32 => disr as u32 as Disr == disr,
4182 ast::TyU64 => disr as u64 as Disr == disr,
4183 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4186 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4188 ast::TyI8 => disr as i8 as Disr == disr,
4189 ast::TyI16 => disr as i16 as Disr == disr,
4190 ast::TyI32 => disr as i32 as Disr == disr,
4191 ast::TyI64 => disr as i64 as Disr == disr,
4192 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4196 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4197 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4201 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4202 vs: &'tcx [P<hir::Variant>],
4204 hint: attr::ReprAttr) {
4205 #![allow(trivial_numeric_casts)]
4207 let rty = ccx.tcx.node_id_to_type(id);
4208 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4210 let tables = RefCell::new(ty::Tables::empty());
4211 let inh = static_inherited_fields(ccx, &tables);
4212 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4214 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4216 if let Some(ref e) = v.node.disr_expr {
4217 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4221 let def_id = ccx.tcx.map.local_def_id(id);
4223 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4224 for (v, variant) in vs.iter().zip(variants.iter()) {
4225 let current_disr_val = variant.disr_val;
4227 // Check for duplicate discriminant values
4228 match disr_vals.iter().position(|&x| x == current_disr_val) {
4230 span_err!(ccx.tcx.sess, v.span, E0081,
4231 "discriminant value `{}` already exists", disr_vals[i]);
4232 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4233 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
4234 "conflicting discriminant here")
4238 // Check for unrepresentable discriminant values
4240 attr::ReprAny | attr::ReprExtern => (),
4241 attr::ReprInt(sp, ity) => {
4242 if !disr_in_range(ccx, ity, current_disr_val) {
4243 span_err!(ccx.tcx.sess, v.span, E0082,
4244 "discriminant value outside specified type");
4245 span_note!(ccx.tcx.sess, sp,
4246 "discriminant type specified here");
4250 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4252 attr::ReprPacked => {
4253 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4256 disr_vals.push(current_disr_val);
4260 let def_id = ccx.tcx.map.local_def_id(id);
4261 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4263 if hint != attr::ReprAny && vs.len() <= 1 {
4265 span_err!(ccx.tcx.sess, sp, E0083,
4266 "unsupported representation for univariant enum");
4268 span_err!(ccx.tcx.sess, sp, E0084,
4269 "unsupported representation for zero-variant enum");
4273 do_check(ccx, vs, id, hint);
4275 check_representable(ccx.tcx, sp, id, "enum");
4278 // Returns the type parameter count and the type for the given definition.
4279 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4282 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4284 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4285 let typ = fcx.local_ty(sp, nid);
4286 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4287 ty::GenericPredicates::empty())
4289 def::DefFn(id, _) | def::DefMethod(id) |
4290 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4291 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4292 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4296 def::DefAssociatedTy(..) |
4298 def::DefTyParam(..) |
4300 def::DefForeignMod(..) |
4303 def::DefSelfTy(..) => {
4304 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4309 // Instantiates the given path, which must refer to an item with the given
4310 // number of type parameters and type.
4311 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4312 segments: &[hir::PathSegment],
4313 type_scheme: TypeScheme<'tcx>,
4314 type_predicates: &ty::GenericPredicates<'tcx>,
4315 opt_self_ty: Option<Ty<'tcx>>,
4318 node_id: ast::NodeId) {
4319 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4325 // We need to extract the type parameters supplied by the user in
4326 // the path `path`. Due to the current setup, this is a bit of a
4327 // tricky-process; the problem is that resolve only tells us the
4328 // end-point of the path resolution, and not the intermediate steps.
4329 // Luckily, we can (at least for now) deduce the intermediate steps
4330 // just from the end-point.
4332 // There are basically four cases to consider:
4334 // 1. Reference to a *type*, such as a struct or enum:
4336 // mod a { struct Foo<T> { ... } }
4338 // Because we don't allow types to be declared within one
4339 // another, a path that leads to a type will always look like
4340 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4341 // that only the final segment can have type parameters, and
4342 // they are located in the TypeSpace.
4344 // *Note:* Generally speaking, references to types don't
4345 // actually pass through this function, but rather the
4346 // `ast_ty_to_ty` function in `astconv`. However, in the case
4347 // of struct patterns (and maybe literals) we do invoke
4348 // `instantiate_path` to get the general type of an instance of
4349 // a struct. (In these cases, there are actually no type
4350 // parameters permitted at present, but perhaps we will allow
4351 // them in the future.)
4353 // 1b. Reference to an enum variant or tuple-like struct:
4355 // struct foo<T>(...)
4356 // enum E<T> { foo(...) }
4358 // In these cases, the parameters are declared in the type
4361 // 2. Reference to a *fn item*:
4365 // In this case, the path will again always have the form
4366 // `a::b::foo::<T>` where only the final segment should have
4367 // type parameters. However, in this case, those parameters are
4368 // declared on a value, and hence are in the `FnSpace`.
4370 // 3. Reference to a *method*:
4372 // impl<A> SomeStruct<A> {
4376 // Here we can have a path like
4377 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4378 // may appear in two places. The penultimate segment,
4379 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4380 // final segment, `foo::<B>` contains parameters in fn space.
4382 // 4. Reference to an *associated const*:
4384 // impl<A> AnotherStruct<A> {
4385 // const FOO: B = BAR;
4388 // The path in this case will look like
4389 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4390 // only will have parameters in TypeSpace.
4392 // The first step then is to categorize the segments appropriately.
4394 assert!(!segments.is_empty());
4396 let mut ufcs_associated = None;
4397 let mut segment_spaces: Vec<_>;
4399 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4400 def::DefSelfTy(..) |
4401 def::DefStruct(..) |
4402 def::DefVariant(..) |
4404 def::DefAssociatedTy(..) |
4406 def::DefPrimTy(..) |
4407 def::DefTyParam(..) => {
4408 // Everything but the final segment should have no
4409 // parameters at all.
4410 segment_spaces = vec![None; segments.len() - 1];
4411 segment_spaces.push(Some(subst::TypeSpace));
4414 // Case 2. Reference to a top-level value.
4417 def::DefStatic(..) => {
4418 segment_spaces = vec![None; segments.len() - 1];
4419 segment_spaces.push(Some(subst::FnSpace));
4422 // Case 3. Reference to a method.
4423 def::DefMethod(def_id) => {
4424 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4426 ty::TraitContainer(trait_did) => {
4427 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4429 ty::ImplContainer(_) => {}
4432 if segments.len() >= 2 {
4433 segment_spaces = vec![None; segments.len() - 2];
4434 segment_spaces.push(Some(subst::TypeSpace));
4435 segment_spaces.push(Some(subst::FnSpace));
4437 // `<T>::method` will end up here, and so can `T::method`.
4438 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4439 segment_spaces = vec![Some(subst::FnSpace)];
4440 ufcs_associated = Some((container, self_ty));
4444 def::DefAssociatedConst(def_id) => {
4445 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4447 ty::TraitContainer(trait_did) => {
4448 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4450 ty::ImplContainer(_) => {}
4453 if segments.len() >= 2 {
4454 segment_spaces = vec![None; segments.len() - 2];
4455 segment_spaces.push(Some(subst::TypeSpace));
4456 segment_spaces.push(None);
4458 // `<T>::CONST` will end up here, and so can `T::CONST`.
4459 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4460 segment_spaces = vec![None];
4461 ufcs_associated = Some((container, self_ty));
4465 // Other cases. Various nonsense that really shouldn't show up
4466 // here. If they do, an error will have been reported
4467 // elsewhere. (I hope)
4469 def::DefForeignMod(..) |
4473 def::DefUpvar(..) => {
4474 segment_spaces = vec![None; segments.len()];
4477 assert_eq!(segment_spaces.len(), segments.len());
4479 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4480 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4481 // type parameters are not mandatory.
4482 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4484 debug!("segment_spaces={:?}", segment_spaces);
4486 // Next, examine the definition, and determine how many type
4487 // parameters we expect from each space.
4488 let type_defs = &type_scheme.generics.types;
4489 let region_defs = &type_scheme.generics.regions;
4491 // Now that we have categorized what space the parameters for each
4492 // segment belong to, let's sort out the parameters that the user
4493 // provided (if any) into their appropriate spaces. We'll also report
4494 // errors if type parameters are provided in an inappropriate place.
4495 let mut substs = Substs::empty();
4496 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4499 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4503 push_explicit_parameters_from_segment_to_substs(fcx,
4513 if let Some(self_ty) = opt_self_ty {
4514 if type_defs.len(subst::SelfSpace) == 1 {
4515 substs.types.push(subst::SelfSpace, self_ty);
4519 // Now we have to compare the types that the user *actually*
4520 // provided against the types that were *expected*. If the user
4521 // did not provide any types, then we want to substitute inference
4522 // variables. If the user provided some types, we may still need
4523 // to add defaults. If the user provided *too many* types, that's
4525 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4526 adjust_type_parameters(fcx, span, space, type_defs,
4527 require_type_space, &mut substs);
4528 assert_eq!(substs.types.len(space), type_defs.len(space));
4530 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4531 assert_eq!(substs.regions().len(space), region_defs.len(space));
4534 // The things we are substituting into the type should not contain
4535 // escaping late-bound regions, and nor should the base type scheme.
4536 assert!(!substs.has_regions_escaping_depth(0));
4537 assert!(!type_scheme.has_escaping_regions());
4539 // Add all the obligations that are required, substituting and
4540 // normalized appropriately.
4541 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4542 fcx.add_obligations_for_parameters(
4543 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4546 // Substitute the values for the type parameters into the type of
4547 // the referenced item.
4548 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4551 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4552 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4553 // is inherent, there is no `Self` parameter, instead, the impl needs
4554 // type parameters, which we can infer by unifying the provided `Self`
4555 // with the substituted impl type.
4556 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4557 assert_eq!(substs.types.len(subst::TypeSpace),
4558 impl_scheme.generics.types.len(subst::TypeSpace));
4559 assert_eq!(substs.regions().len(subst::TypeSpace),
4560 impl_scheme.generics.regions.len(subst::TypeSpace));
4562 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4563 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4564 fcx.tcx().sess.span_bug(span,
4566 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4572 debug!("instantiate_path: type of {:?} is {:?}",
4575 fcx.write_ty(node_id, ty_substituted);
4576 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4579 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4580 /// parameters are provided, then reports an error and clears the output vector.
4582 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4583 /// use inference variables. This seems less likely to lead to derived errors.
4585 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4586 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4587 /// here because we can easily use the precise span of the N+1'th parameter.
4588 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4589 fcx: &FnCtxt<'a, 'tcx>,
4590 space: subst::ParamSpace,
4592 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4593 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4594 segment: &hir::PathSegment,
4595 substs: &mut Substs<'tcx>)
4597 match segment.parameters {
4598 hir::AngleBracketedParameters(ref data) => {
4599 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4600 fcx, space, type_defs, region_defs, data, substs);
4603 hir::ParenthesizedParameters(ref data) => {
4604 span_err!(fcx.tcx().sess, span, E0238,
4605 "parenthesized parameters may only be used with a trait");
4606 push_explicit_parenthesized_parameters_from_segment_to_substs(
4607 fcx, space, span, type_defs, data, substs);
4612 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4613 fcx: &FnCtxt<'a, 'tcx>,
4614 space: subst::ParamSpace,
4615 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4616 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4617 data: &hir::AngleBracketedParameterData,
4618 substs: &mut Substs<'tcx>)
4621 let type_count = type_defs.len(space);
4622 assert_eq!(substs.types.len(space), 0);
4623 for (i, typ) in data.types.iter().enumerate() {
4624 let t = fcx.to_ty(&**typ);
4626 substs.types.push(space, t);
4627 } else if i == type_count {
4628 span_err!(fcx.tcx().sess, typ.span, E0087,
4629 "too many type parameters provided: \
4630 expected at most {} parameter{}, \
4631 found {} parameter{}",
4633 if type_count == 1 {""} else {"s"},
4635 if data.types.len() == 1 {""} else {"s"});
4636 substs.types.truncate(space, 0);
4642 if !data.bindings.is_empty() {
4643 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4644 "unexpected binding of associated item in expression path \
4645 (only allowed in type paths)");
4649 let region_count = region_defs.len(space);
4650 assert_eq!(substs.regions().len(space), 0);
4651 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4652 let r = ast_region_to_region(fcx.tcx(), lifetime);
4653 if i < region_count {
4654 substs.mut_regions().push(space, r);
4655 } else if i == region_count {
4656 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4657 "too many lifetime parameters provided: \
4658 expected {} parameter{}, found {} parameter{}",
4660 if region_count == 1 {""} else {"s"},
4661 data.lifetimes.len(),
4662 if data.lifetimes.len() == 1 {""} else {"s"});
4663 substs.mut_regions().truncate(space, 0);
4671 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4672 /// but intended for `Foo(A,B) -> C` form. This expands to
4673 /// roughly the same thing as `Foo<(A,B),C>`. One important
4674 /// difference has to do with the treatment of anonymous
4675 /// regions, which are translated into bound regions (NYI).
4676 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4677 fcx: &FnCtxt<'a, 'tcx>,
4678 space: subst::ParamSpace,
4680 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4681 data: &hir::ParenthesizedParameterData,
4682 substs: &mut Substs<'tcx>)
4684 let type_count = type_defs.len(space);
4686 span_err!(fcx.tcx().sess, span, E0167,
4687 "parenthesized form always supplies 2 type parameters, \
4688 but only {} parameter(s) were expected",
4692 let input_tys: Vec<Ty> =
4693 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4695 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4697 if type_count >= 1 {
4698 substs.types.push(space, tuple_ty);
4701 let output_ty: Option<Ty> =
4702 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4705 output_ty.unwrap_or(fcx.tcx().mk_nil());
4707 if type_count >= 2 {
4708 substs.types.push(space, output_ty);
4712 fn adjust_type_parameters<'a, 'tcx>(
4713 fcx: &FnCtxt<'a, 'tcx>,
4716 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4717 require_type_space: bool,
4718 substs: &mut Substs<'tcx>)
4720 let provided_len = substs.types.len(space);
4721 let desired = defs.get_slice(space);
4722 let required_len = desired.iter()
4723 .take_while(|d| d.default.is_none())
4726 debug!("adjust_type_parameters(space={:?}, \
4735 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4736 assert!(provided_len <= desired.len());
4738 // Nothing specified at all: supply inference variables for
4740 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4741 substs.types.replace(space, Vec::new());
4742 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4746 // Too few parameters specified: report an error and use Err
4748 if provided_len < required_len {
4750 if desired.len() != required_len { "at least " } else { "" };
4751 span_err!(fcx.tcx().sess, span, E0089,
4752 "too few type parameters provided: expected {}{} parameter{}, \
4753 found {} parameter{}",
4754 qualifier, required_len,
4755 if required_len == 1 {""} else {"s"},
4757 if provided_len == 1 {""} else {"s"});
4758 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4762 // Otherwise, add in any optional parameters that the user
4763 // omitted. The case of *too many* parameters is handled
4765 // push_explicit_parameters_from_segment_to_substs(). Note
4766 // that the *default* type are expressed in terms of all prior
4767 // parameters, so we have to substitute as we go with the
4768 // partial substitution that we have built up.
4769 for i in provided_len..desired.len() {
4770 let default = desired[i].default.unwrap();
4771 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4772 substs.types.push(space, default);
4774 assert_eq!(substs.types.len(space), desired.len());
4776 debug!("Final substs: {:?}", substs);
4779 fn adjust_region_parameters(
4783 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4784 substs: &mut Substs)
4786 let provided_len = substs.mut_regions().len(space);
4787 let desired = defs.get_slice(space);
4789 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4790 assert!(provided_len <= desired.len());
4792 // If nothing was provided, just use inference variables.
4793 if provided_len == 0 {
4794 substs.mut_regions().replace(
4796 fcx.infcx().region_vars_for_defs(span, desired));
4800 // If just the right number were provided, everybody is happy.
4801 if provided_len == desired.len() {
4805 // Otherwise, too few were provided. Report an error and then
4806 // use inference variables.
4807 span_err!(fcx.tcx().sess, span, E0090,
4808 "too few lifetime parameters provided: expected {} parameter{}, \
4809 found {} parameter{}",
4811 if desired.len() == 1 {""} else {"s"},
4813 if provided_len == 1 {""} else {"s"});
4815 substs.mut_regions().replace(
4817 fcx.infcx().region_vars_for_defs(span, desired));
4821 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4825 where F: Fn() -> Ty<'tcx>
4827 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4830 let alternative = f();
4833 if alternative.is_ty_var() || alternative.references_error() {
4834 fcx.type_error_message(sp, |_actual| {
4835 "the type of this value must be known in this context".to_string()
4837 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4838 ty = fcx.tcx().types.err;
4840 demand::suptype(fcx, sp, alternative, ty);
4848 // Resolves `typ` by a single level if `typ` is a type variable. If no
4849 // resolution is possible, then an error is reported.
4850 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4855 structurally_resolve_type_or_else(fcx, sp, ty, || {
4860 // Returns true if b contains a break that can exit from b
4861 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4862 // First: is there an unlabeled break immediately
4864 (loop_query(&*b, |e| {
4866 hir::ExprBreak(None) => true,
4870 // Second: is there a labeled break with label
4871 // <id> nested anywhere inside the loop?
4872 (block_query(b, |e| {
4873 if let hir::ExprBreak(Some(_)) = e.node {
4874 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4881 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4883 tps: &OwnedSlice<hir::TyParam>,
4885 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4888 // make a vector of booleans initially false, set to true when used
4889 if tps.is_empty() { return; }
4890 let mut tps_used = vec![false; tps.len()];
4892 for leaf_ty in ty.walk() {
4893 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4894 debug!("Found use of ty param num {}", idx);
4895 tps_used[idx as usize] = true;
4899 for (i, b) in tps_used.iter().enumerate() {
4901 span_err!(ccx.tcx.sess, span, E0091,
4902 "type parameter `{}` is unused",