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 middle::astconv_util::prohibit_type_params;
87 use middle::cstore::LOCAL_CRATE;
89 use middle::def_id::DefId;
91 use middle::infer::{TypeOrigin, 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::{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};
114 use std::cell::{Cell, Ref, RefCell};
115 use std::collections::{HashSet};
116 use std::mem::replace;
120 use syntax::attr::AttrMetaMethods;
121 use syntax::codemap::{self, Span, Spanned};
122 use syntax::parse::token::{self, InternedString};
124 use syntax::util::lev_distance::find_best_match_for_name;
126 use rustc_front::intravisit::{self, Visitor};
127 use rustc_front::hir;
128 use rustc_front::hir::Visibility;
129 use rustc_front::print::pprust;
130 use rustc_back::slice;
149 /// closures defined within the function. For example:
152 /// bar(move|| { ... })
155 /// Here, the function `foo()` and the closure passed to
156 /// `bar()` will each have their own `FnCtxt`, but they will
157 /// share the inherited fields.
158 pub struct Inherited<'a, 'tcx: 'a> {
159 infcx: infer::InferCtxt<'a, 'tcx>,
160 locals: RefCell<NodeMap<Ty<'tcx>>>,
162 tables: &'a RefCell<ty::Tables<'tcx>>,
164 // When we process a call like `c()` where `c` is a closure type,
165 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
166 // `FnOnce` closure. In that case, we defer full resolution of the
167 // call until upvar inference can kick in and make the
168 // decision. We keep these deferred resolutions grouped by the
169 // def-id of the closure, so that once we decide, we can easily go
170 // back and process them.
171 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
173 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
176 trait DeferredCallResolution<'tcx> {
177 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
180 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
182 /// When type-checking an expression, we propagate downward
183 /// whatever type hint we are able in the form of an `Expectation`.
184 #[derive(Copy, Clone, Debug)]
185 pub enum Expectation<'tcx> {
186 /// We know nothing about what type this expression should have.
189 /// This expression should have the type given (or some subtype)
190 ExpectHasType(Ty<'tcx>),
192 /// This expression will be cast to the `Ty`
193 ExpectCastableToType(Ty<'tcx>),
195 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
196 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
197 ExpectRvalueLikeUnsized(Ty<'tcx>),
200 impl<'tcx> Expectation<'tcx> {
201 // Disregard "castable to" expectations because they
202 // can lead us astray. Consider for example `if cond
203 // {22} else {c} as u8` -- if we propagate the
204 // "castable to u8" constraint to 22, it will pick the
205 // type 22u8, which is overly constrained (c might not
206 // be a u8). In effect, the problem is that the
207 // "castable to" expectation is not the tightest thing
208 // we can say, so we want to drop it in this case.
209 // The tightest thing we can say is "must unify with
210 // else branch". Note that in the case of a "has type"
211 // constraint, this limitation does not hold.
213 // If the expected type is just a type variable, then don't use
214 // an expected type. Otherwise, we might write parts of the type
215 // when checking the 'then' block which are incompatible with the
217 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
219 ExpectHasType(ety) => {
220 let ety = fcx.infcx().shallow_resolve(ety);
221 if !ety.is_ty_var() {
227 ExpectRvalueLikeUnsized(ety) => {
228 ExpectRvalueLikeUnsized(ety)
235 #[derive(Copy, Clone)]
236 pub struct UnsafetyState {
237 pub def: ast::NodeId,
238 pub unsafety: hir::Unsafety,
239 pub unsafe_push_count: u32,
244 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
245 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
248 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
249 match self.unsafety {
250 // If this unsafe, then if the outer function was already marked as
251 // unsafe we shouldn't attribute the unsafe'ness to the block. This
252 // way the block can be warned about instead of ignoring this
253 // extraneous block (functions are never warned about).
254 hir::Unsafety::Unsafe if self.from_fn => *self,
257 let (unsafety, def, count) = match blk.rules {
258 hir::PushUnsafeBlock(..) =>
259 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
260 hir::PopUnsafeBlock(..) =>
261 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
262 hir::UnsafeBlock(..) =>
263 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
264 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
265 (unsafety, self.def, self.unsafe_push_count),
267 UnsafetyState{ def: def,
269 unsafe_push_count: count,
277 pub struct FnCtxt<'a, 'tcx: 'a> {
278 body_id: ast::NodeId,
280 // This flag is set to true if, during the writeback phase, we encounter
281 // a type error in this function.
282 writeback_errors: Cell<bool>,
284 // Number of errors that had been reported when we started
285 // checking this function. On exit, if we find that *more* errors
286 // have been reported, we will skip regionck and other work that
287 // expects the types within the function to be consistent.
288 err_count_on_creation: usize,
290 ret_ty: ty::FnOutput<'tcx>,
292 ps: RefCell<UnsafetyState>,
294 inh: &'a Inherited<'a, 'tcx>,
296 ccx: &'a CrateCtxt<'a, 'tcx>,
299 impl<'a, 'tcx> Inherited<'a, 'tcx> {
300 fn new(tcx: &'a ty::ctxt<'tcx>,
301 tables: &'a RefCell<ty::Tables<'tcx>>,
302 param_env: ty::ParameterEnvironment<'a, 'tcx>)
303 -> Inherited<'a, 'tcx> {
306 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
307 locals: RefCell::new(NodeMap()),
309 deferred_call_resolutions: RefCell::new(DefIdMap()),
310 deferred_cast_checks: RefCell::new(Vec::new()),
314 fn normalize_associated_types_in<T>(&self,
316 body_id: ast::NodeId,
319 where T : TypeFoldable<'tcx> + HasTypeFlags
321 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
322 assoc::normalize_associated_types_in(&self.infcx,
331 // Used by check_const and check_enum_variants
332 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
333 inh: &'a Inherited<'a, 'tcx>,
334 rty: ty::FnOutput<'tcx>,
335 body_id: ast::NodeId)
336 -> FnCtxt<'a, 'tcx> {
339 writeback_errors: Cell::new(false),
340 err_count_on_creation: ccx.tcx.sess.err_count(),
342 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
348 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
349 tables: &'a RefCell<ty::Tables<'tcx>>)
350 -> Inherited<'a, 'tcx> {
351 // It's kind of a kludge to manufacture a fake function context
352 // and statement context, but we might as well do write the code only once
353 let param_env = ccx.tcx.empty_parameter_environment();
354 Inherited::new(ccx.tcx, &tables, param_env)
357 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
358 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
360 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
361 fn visit_item(&mut self, i: &'tcx hir::Item) {
362 check_item_type(self.ccx, i);
363 intravisit::walk_item(self, i);
366 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
368 hir::TyFixedLengthVec(_, ref expr) => {
369 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
374 intravisit::walk_ty(self, t);
378 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
379 fn visit_item(&mut self, i: &'tcx hir::Item) {
380 check_item_body(self.ccx, i);
384 pub fn check_wf_new(ccx: &CrateCtxt) {
385 ccx.tcx.sess.abort_if_new_errors(|| {
386 let krate = ccx.tcx.map.krate();
387 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
388 krate.visit_all_items(&mut visit);
392 pub fn check_item_types(ccx: &CrateCtxt) {
393 ccx.tcx.sess.abort_if_new_errors(|| {
394 let krate = ccx.tcx.map.krate();
395 let mut visit = CheckItemTypesVisitor { ccx: ccx };
396 krate.visit_all_items(&mut visit);
400 pub fn check_item_bodies(ccx: &CrateCtxt) {
401 ccx.tcx.sess.abort_if_new_errors(|| {
402 let krate = ccx.tcx.map.krate();
403 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
404 krate.visit_all_items(&mut visit);
408 pub fn check_drop_impls(ccx: &CrateCtxt) {
409 ccx.tcx.sess.abort_if_new_errors(|| {
410 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
411 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
413 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
414 if drop_impl_did.is_local() {
415 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
418 assert!(ccx.tcx.sess.has_errors());
426 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
427 decl: &'tcx hir::FnDecl,
428 body: &'tcx hir::Block,
432 param_env: ty::ParameterEnvironment<'a, 'tcx>)
435 ty::TyBareFn(_, ref fn_ty) => {
436 let tables = RefCell::new(ty::Tables::empty());
437 let inh = Inherited::new(ccx.tcx, &tables, param_env);
439 // Compute the fty from point of view of inside fn.
440 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
442 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
444 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
446 inh.normalize_associated_types_in(body.span,
450 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
451 decl, fn_id, body, &inh);
453 fcx.select_all_obligations_and_apply_defaults();
454 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
455 fcx.select_obligations_where_possible();
457 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
459 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
460 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
462 _ => ccx.tcx.sess.impossible_case(body.span,
463 "check_bare_fn: function type expected")
467 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
468 fcx: &'a FnCtxt<'a, 'tcx>
471 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
472 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
475 // infer the variable's type
476 let var_ty = self.fcx.infcx().next_ty_var();
477 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
481 // take type that the user specified
482 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
489 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
490 // Add explicitly-declared locals.
491 fn visit_local(&mut self, local: &'tcx hir::Local) {
492 let o_ty = match local.ty {
493 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
496 self.assign(local.span, local.id, o_ty);
497 debug!("Local variable {:?} is assigned type {}",
499 self.fcx.infcx().ty_to_string(
500 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
501 intravisit::walk_local(self, local);
504 // Add pattern bindings.
505 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
506 if let hir::PatIdent(_, ref path1, _) = p.node {
507 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
508 let var_ty = self.assign(p.span, p.id, None);
510 self.fcx.require_type_is_sized(var_ty, p.span,
511 traits::VariableType(p.id));
513 debug!("Pattern binding {} is assigned to {} with type {:?}",
515 self.fcx.infcx().ty_to_string(
516 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
520 intravisit::walk_pat(self, p);
523 fn visit_block(&mut self, b: &'tcx hir::Block) {
524 // non-obvious: the `blk` variable maps to region lb, so
525 // we have to keep this up-to-date. This
526 // is... unfortunate. It'd be nice to not need this.
527 intravisit::walk_block(self, b);
530 // Since an expr occurs as part of the type fixed size arrays we
531 // need to record the type for that node
532 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
534 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
535 self.visit_ty(&**ty);
536 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
538 hir::TyBareFn(ref function_declaration) => {
539 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
540 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
542 _ => intravisit::walk_ty(self, t)
546 // Don't descend into the bodies of nested closures
547 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
548 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
551 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
552 /// body and returns the function context used for that purpose, since in the case of a fn item
553 /// there is still a bit more to do.
556 /// * inherited: other fields inherited from the enclosing fn (if any)
557 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
558 unsafety: hir::Unsafety,
559 unsafety_id: ast::NodeId,
560 fn_sig: &ty::FnSig<'tcx>,
561 decl: &'tcx hir::FnDecl,
563 body: &'tcx hir::Block,
564 inherited: &'a Inherited<'a, 'tcx>)
568 let err_count_on_creation = tcx.sess.err_count();
570 let arg_tys = &fn_sig.inputs;
571 let ret_ty = fn_sig.output;
573 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
578 // Create the function context. This is either derived from scratch or,
579 // in the case of function expressions, based on the outer context.
582 writeback_errors: Cell::new(false),
583 err_count_on_creation: err_count_on_creation,
585 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
590 if let ty::FnConverging(ret_ty) = ret_ty {
591 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
594 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
596 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
599 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
601 // Add formal parameters.
602 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
603 // The type of the argument must be well-formed.
605 // NB -- this is now checked in wfcheck, but that
606 // currently only results in warnings, so we issue an
607 // old-style WF obligation here so that we still get the
608 // errors that we used to get.
609 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
611 // Create type variables for each argument.
612 pat_util::pat_bindings(
615 |_bm, pat_id, sp, _path| {
616 let var_ty = visit.assign(sp, pat_id, None);
617 fcx.require_type_is_sized(var_ty, sp,
618 traits::VariableType(pat_id));
621 // Check the pattern.
624 map: pat_id_map(&tcx.def_map, &*input.pat),
626 _match::check_pat(&pcx, &*input.pat, *arg_ty);
629 visit.visit_block(body);
632 check_block_with_expected(&fcx, body, match ret_ty {
633 ty::FnConverging(result_type) => ExpectHasType(result_type),
634 ty::FnDiverging => NoExpectation
637 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
638 fcx.write_ty(input.id, arg);
644 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
647 check_representable(tcx, span, id, "struct");
649 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
650 check_simd(tcx, span, id);
654 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
655 debug!("check_item_type(it.id={}, it.name={})",
657 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
658 let _indenter = indenter();
660 // Consts can play a role in type-checking, so they are included here.
661 hir::ItemStatic(_, _, ref e) |
662 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
663 hir::ItemEnum(ref enum_definition, _) => {
664 check_enum_variants(ccx,
666 &enum_definition.variants,
669 hir::ItemFn(..) => {} // entirely within check_item_body
670 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
671 debug!("ItemImpl {} with id {}", it.name, it.id);
672 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
673 Some(impl_trait_ref) => {
674 check_impl_items_against_trait(ccx,
682 hir::ItemTrait(_, ref generics, _, _) => {
683 check_trait_on_unimplemented(ccx, generics, it);
685 hir::ItemStruct(..) => {
686 check_struct(ccx, it.id, it.span);
688 hir::ItemTy(_, ref generics) => {
689 let pty_ty = ccx.tcx.node_id_to_type(it.id);
690 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
692 hir::ItemForeignMod(ref m) => {
693 if m.abi == abi::RustIntrinsic {
694 for item in &m.items {
695 intrinsic::check_intrinsic_type(ccx, item);
697 } else if m.abi == abi::PlatformIntrinsic {
698 for item in &m.items {
699 intrinsic::check_platform_intrinsic_type(ccx, item);
702 for item in &m.items {
703 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
704 if !pty.generics.types.is_empty() {
705 span_err!(ccx.tcx.sess, item.span, E0044,
706 "foreign items may not have type parameters");
707 span_help!(ccx.tcx.sess, item.span,
708 "consider using specialization instead of \
712 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
713 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
718 _ => {/* nothing to do */ }
722 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
723 debug!("check_item_body(it.id={}, it.name={})",
725 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
726 let _indenter = indenter();
728 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
729 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
730 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
731 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
733 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
734 debug!("ItemImpl {} with id {}", it.name, it.id);
736 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
738 for impl_item in impl_items {
739 match impl_item.node {
740 hir::ImplItemKind::Const(_, ref expr) => {
741 check_const(ccx, impl_item.span, &*expr, impl_item.id)
743 hir::ImplItemKind::Method(ref sig, ref body) => {
744 check_method_body(ccx, &impl_pty.generics, sig, body,
745 impl_item.id, impl_item.span);
747 hir::ImplItemKind::Type(_) => {
748 // Nothing to do here.
753 hir::ItemTrait(_, _, _, ref trait_items) => {
754 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
755 for trait_item in trait_items {
756 match trait_item.node {
757 hir::ConstTraitItem(_, Some(ref expr)) => {
758 check_const(ccx, trait_item.span, &*expr, trait_item.id)
760 hir::MethodTraitItem(ref sig, Some(ref body)) => {
761 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
763 check_method_body(ccx, &trait_def.generics, sig, body,
764 trait_item.id, trait_item.span);
766 hir::MethodTraitItem(ref sig, None) => {
767 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
769 hir::ConstTraitItem(_, None) |
770 hir::TypeTraitItem(..) => {
776 _ => {/* nothing to do */ }
780 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
782 constness: hir::Constness)
785 hir::Constness::NotConst => {
788 hir::Constness::Const => {
789 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
794 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
795 generics: &hir::Generics,
797 if let Some(ref attr) = item.attrs.iter().find(|a| {
798 a.check_name("rustc_on_unimplemented")
800 if let Some(ref istring) = attr.value_str() {
801 let parser = Parser::new(&istring);
802 let types = &*generics.ty_params;
803 for token in parser {
805 Piece::String(_) => (), // Normal string, no need to check it
806 Piece::NextArgument(a) => match a.position {
807 // `{Self}` is allowed
808 Position::ArgumentNamed(s) if s == "Self" => (),
809 // So is `{A}` if A is a type parameter
810 Position::ArgumentNamed(s) => match types.iter().find(|t| {
815 span_err!(ccx.tcx.sess, attr.span, E0230,
816 "there is no type parameter \
821 // `{:1}` and `{}` are not to be used
822 Position::ArgumentIs(_) | Position::ArgumentNext => {
823 span_err!(ccx.tcx.sess, attr.span, E0231,
824 "only named substitution \
825 parameters are allowed");
831 span_err!(ccx.tcx.sess, attr.span, E0232,
832 "this attribute must have a value, \
833 eg `#[rustc_on_unimplemented = \"foo\"]`")
838 /// Type checks a method body.
842 /// * `item_generics`: generics defined on the impl/trait that contains
844 /// * `self_bound`: bound for the `Self` type parameter, if any
845 /// * `method`: the method definition
846 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
847 item_generics: &ty::Generics<'tcx>,
848 sig: &'tcx hir::MethodSig,
849 body: &'tcx hir::Block,
850 id: ast::NodeId, span: Span) {
851 debug!("check_method_body(item_generics={:?}, id={})",
853 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
855 let fty = ccx.tcx.node_id_to_type(id);
856 debug!("check_method_body: fty={:?}", fty);
858 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
861 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
863 impl_trait_ref: &ty::TraitRef<'tcx>,
864 impl_items: &[hir::ImplItem]) {
865 // Locate trait methods
867 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
868 let mut overridden_associated_type = None;
870 // Check existing impl methods to see if they are both present in trait
871 // and compatible with trait signature
872 for impl_item in impl_items {
873 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
874 let ty_trait_item = trait_items.iter()
875 .find(|ac| ac.name() == ty_impl_item.name());
877 if let Some(ty_trait_item) = ty_trait_item {
878 match impl_item.node {
879 hir::ImplItemKind::Const(..) => {
880 let impl_const = match ty_impl_item {
881 ty::ConstTraitItem(ref cti) => cti,
882 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
885 // Find associated const definition.
886 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
887 compare_const_impl(ccx.tcx,
893 span_err!(tcx.sess, impl_item.span, E0323,
894 "item `{}` is an associated const, \
895 which doesn't match its trait `{:?}`",
900 hir::ImplItemKind::Method(ref sig, ref body) => {
901 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
903 let impl_method = match ty_impl_item {
904 ty::MethodTraitItem(ref mti) => mti,
905 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
908 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
909 compare_impl_method(ccx.tcx,
916 span_err!(tcx.sess, impl_item.span, E0324,
917 "item `{}` is an associated method, \
918 which doesn't match its trait `{:?}`",
923 hir::ImplItemKind::Type(_) => {
924 let impl_type = match ty_impl_item {
925 ty::TypeTraitItem(ref tti) => tti,
926 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
929 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
930 if let Some(_) = at.ty {
931 overridden_associated_type = Some(impl_item);
934 span_err!(tcx.sess, impl_item.span, E0325,
935 "item `{}` is an associated type, \
936 which doesn't match its trait `{:?}`",
945 // Check for missing items from trait
946 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
947 let mut missing_items = Vec::new();
948 let mut invalidated_items = Vec::new();
949 let associated_type_overridden = overridden_associated_type.is_some();
950 for trait_item in trait_items.iter() {
952 ty::ConstTraitItem(ref associated_const) => {
953 let is_implemented = impl_items.iter().any(|ii| {
955 hir::ImplItemKind::Const(..) => {
956 ii.name == associated_const.name
961 let is_provided = associated_const.has_value;
965 missing_items.push(associated_const.name);
966 } else if associated_type_overridden {
967 invalidated_items.push(associated_const.name);
971 ty::MethodTraitItem(ref trait_method) => {
973 impl_items.iter().any(|ii| {
975 hir::ImplItemKind::Method(..) => {
976 ii.name == trait_method.name
982 provided_methods.iter().any(|m| m.name == trait_method.name);
985 missing_items.push(trait_method.name);
986 } else if associated_type_overridden {
987 invalidated_items.push(trait_method.name);
991 ty::TypeTraitItem(ref associated_type) => {
992 let is_implemented = impl_items.iter().any(|ii| {
994 hir::ImplItemKind::Type(_) => {
995 ii.name == associated_type.name
1000 let is_provided = associated_type.ty.is_some();
1001 if !is_implemented {
1003 missing_items.push(associated_type.name);
1004 } else if associated_type_overridden {
1005 invalidated_items.push(associated_type.name);
1012 if !missing_items.is_empty() {
1013 span_err!(tcx.sess, impl_span, E0046,
1014 "not all trait items implemented, missing: `{}`",
1015 missing_items.iter()
1016 .map(|name| name.to_string())
1017 .collect::<Vec<_>>().join("`, `"))
1020 if !invalidated_items.is_empty() {
1021 let invalidator = overridden_associated_type.unwrap();
1022 span_err!(tcx.sess, invalidator.span, E0399,
1023 "the following trait items need to be reimplemented \
1024 as `{}` was overridden: `{}`",
1026 invalidated_items.iter()
1027 .map(|name| name.to_string())
1028 .collect::<Vec<_>>().join("`, `"))
1032 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1039 let tstr = fcx.infcx().ty_to_string(t_cast);
1040 fcx.type_error_message(span, |actual| {
1041 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1044 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1045 let mtstr = match mt {
1046 hir::MutMutable => "mut ",
1047 hir::MutImmutable => ""
1049 if t_cast.is_trait() {
1050 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1052 fcx.tcx().sess.span_suggestion(t_span,
1053 "try casting to a reference instead:",
1054 format!("&{}{}", mtstr, s));
1057 span_help!(fcx.tcx().sess, t_span,
1058 "did you mean `&{}{}`?", mtstr, tstr),
1061 span_help!(fcx.tcx().sess, span,
1062 "consider using an implicit coercion to `&{}{}` instead",
1067 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1069 fcx.tcx().sess.span_suggestion(t_span,
1070 "try casting to a `Box` instead:",
1071 format!("Box<{}>", s));
1074 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1078 span_help!(fcx.tcx().sess, e_span,
1079 "consider using a box or reference as appropriate");
1082 fcx.write_error(id);
1086 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1087 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1089 fn get_item_type_scheme(&self, _: Span, id: DefId)
1090 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1092 Ok(self.tcx().lookup_item_type(id))
1095 fn get_trait_def(&self, _: Span, id: DefId)
1096 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1098 Ok(self.tcx().lookup_trait_def(id))
1101 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1102 // all super predicates are ensured during collect pass
1106 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1107 Some(&self.inh.infcx.parameter_environment.free_substs)
1110 fn get_type_parameter_bounds(&self,
1112 node_id: ast::NodeId)
1113 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1115 let def = self.tcx().type_parameter_def(node_id);
1116 let r = self.inh.infcx.parameter_environment
1119 .filter_map(|predicate| {
1121 ty::Predicate::Trait(ref data) => {
1122 if data.0.self_ty().is_param(def.space, def.index) {
1123 Some(data.to_poly_trait_ref())
1137 fn trait_defines_associated_type_named(&self,
1138 trait_def_id: DefId,
1139 assoc_name: ast::Name)
1142 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1143 trait_def.associated_type_names.contains(&assoc_name)
1147 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1148 substs: Option<&mut subst::Substs<'tcx>>,
1149 space: Option<subst::ParamSpace>,
1150 span: Span) -> Ty<'tcx> {
1151 // Grab the default doing subsitution
1152 let default = ty_param_def.and_then(|def| {
1153 def.default.map(|ty| type_variable::Default {
1154 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1156 def_id: def.default_def_id
1160 let ty_var = self.infcx().next_ty_var_with_default(default);
1162 // Finally we add the type variable to the substs
1165 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1169 fn projected_ty_from_poly_trait_ref(&self,
1171 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1172 item_name: ast::Name)
1175 let (trait_ref, _) =
1176 self.infcx().replace_late_bound_regions_with_fresh_var(
1178 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1181 self.normalize_associated_type(span, trait_ref, item_name)
1184 fn projected_ty(&self,
1186 trait_ref: ty::TraitRef<'tcx>,
1187 item_name: ast::Name)
1190 self.normalize_associated_type(span, trait_ref, item_name)
1194 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1195 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1197 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1201 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1202 &self.inh.infcx.parameter_environment
1205 pub fn sess(&self) -> &Session {
1209 pub fn err_count_since_creation(&self) -> usize {
1210 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1213 /// Resolves type variables in `ty` if possible. Unlike the infcx
1214 /// version, this version will also select obligations if it seems
1215 /// useful, in an effort to get more type information.
1216 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1217 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1219 // No TyInfer()? Nothing needs doing.
1220 if !ty.has_infer_types() {
1221 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1225 // If `ty` is a type variable, see whether we already know what it is.
1226 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1227 if !ty.has_infer_types() {
1228 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1232 // If not, try resolving any new fcx obligations that have cropped up.
1233 self.select_new_obligations();
1234 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1235 if !ty.has_infer_types() {
1236 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1240 // If not, try resolving *all* pending obligations as much as
1241 // possible. This can help substantially when there are
1242 // indirect dependencies that don't seem worth tracking
1244 self.select_obligations_where_possible();
1245 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1247 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1251 fn record_deferred_call_resolution(&self,
1252 closure_def_id: DefId,
1253 r: DeferredCallResolutionHandler<'tcx>) {
1254 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1255 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1258 fn remove_deferred_call_resolutions(&self,
1259 closure_def_id: DefId)
1260 -> Vec<DeferredCallResolutionHandler<'tcx>>
1262 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1263 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1266 pub fn tag(&self) -> String {
1267 let self_ptr: *const FnCtxt = self;
1268 format!("{:?}", self_ptr)
1271 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1272 match self.inh.locals.borrow().get(&nid) {
1275 span_err!(self.tcx().sess, span, E0513,
1276 "no type for local variable {}",
1278 self.tcx().types.err
1284 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1285 debug!("write_ty({}, {:?}) in fcx {}",
1286 node_id, ty, self.tag());
1287 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1290 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1291 if !substs.substs.is_noop() {
1292 debug!("write_substs({}, {:?}) in fcx {}",
1297 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1301 pub fn write_autoderef_adjustment(&self,
1302 node_id: ast::NodeId,
1304 self.write_adjustment(
1306 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1314 pub fn write_adjustment(&self,
1315 node_id: ast::NodeId,
1316 adj: adjustment::AutoAdjustment<'tcx>) {
1317 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1319 if adj.is_identity() {
1323 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1326 /// Basically whenever we are converting from a type scheme into
1327 /// the fn body space, we always want to normalize associated
1328 /// types as well. This function combines the two.
1329 fn instantiate_type_scheme<T>(&self,
1331 substs: &Substs<'tcx>,
1334 where T : TypeFoldable<'tcx> + HasTypeFlags
1336 let value = value.subst(self.tcx(), substs);
1337 let result = self.normalize_associated_types_in(span, &value);
1338 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1345 /// As `instantiate_type_scheme`, but for the bounds found in a
1346 /// generic type scheme.
1347 fn instantiate_bounds(&self,
1349 substs: &Substs<'tcx>,
1350 bounds: &ty::GenericPredicates<'tcx>)
1351 -> ty::InstantiatedPredicates<'tcx>
1353 ty::InstantiatedPredicates {
1354 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1359 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1360 where T : TypeFoldable<'tcx> + HasTypeFlags
1362 self.inh.normalize_associated_types_in(span, self.body_id, value)
1365 fn normalize_associated_type(&self,
1367 trait_ref: ty::TraitRef<'tcx>,
1368 item_name: ast::Name)
1371 let cause = traits::ObligationCause::new(span,
1373 traits::ObligationCauseCode::MiscObligation);
1378 .normalize_projection_type(self.infcx(),
1380 trait_ref: trait_ref,
1381 item_name: item_name,
1386 /// Instantiates the type in `did` with the generics in `path` and returns
1387 /// it (registering the necessary trait obligations along the way).
1389 /// Note that this function is only intended to be used with type-paths,
1390 /// not with value-paths.
1391 pub fn instantiate_type(&self,
1396 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1398 self.tcx().lookup_item_type(did);
1399 let type_predicates =
1400 self.tcx().lookup_predicates(did);
1401 let substs = astconv::ast_path_substs_for_ty(self, self,
1403 PathParamMode::Optional,
1404 &type_scheme.generics,
1405 path.segments.last().unwrap());
1406 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1408 self.instantiate_bounds(path.span, &substs, &type_predicates);
1409 self.add_obligations_for_parameters(
1410 traits::ObligationCause::new(
1413 traits::ItemObligation(did)),
1416 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1419 /// Return the dict-like variant corresponding to a given `Def`.
1420 pub fn def_struct_variant(&self,
1423 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1425 let (adt, variant) = match def {
1426 def::DefVariant(enum_id, variant_id, _) => {
1427 let adt = self.tcx().lookup_adt_def(enum_id);
1428 (adt, adt.variant_with_id(variant_id))
1430 def::DefTy(did, _) | def::DefStruct(did) => {
1431 let typ = self.tcx().lookup_item_type(did);
1432 if let ty::TyStruct(adt, _) = typ.ty.sty {
1433 (adt, adt.struct_variant())
1441 let var_kind = variant.kind();
1442 if var_kind == ty::VariantKind::Struct {
1443 Some((adt, variant))
1444 } else if var_kind == ty::VariantKind::Unit {
1445 if !self.tcx().sess.features.borrow().braced_empty_structs {
1446 self.tcx().sess.span_err(span, "empty structs and enum variants \
1447 with braces are unstable");
1448 fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
1449 the crate features to enable");
1452 Some((adt, variant))
1458 pub fn write_nil(&self, node_id: ast::NodeId) {
1459 self.write_ty(node_id, self.tcx().mk_nil());
1461 pub fn write_error(&self, node_id: ast::NodeId) {
1462 self.write_ty(node_id, self.tcx().types.err);
1465 pub fn require_type_meets(&self,
1468 code: traits::ObligationCauseCode<'tcx>,
1469 bound: ty::BuiltinBound)
1471 self.register_builtin_bound(
1474 traits::ObligationCause::new(span, self.body_id, code));
1477 pub fn require_type_is_sized(&self,
1480 code: traits::ObligationCauseCode<'tcx>)
1482 self.require_type_meets(ty, span, code, ty::BoundSized);
1485 pub fn require_expr_have_sized_type(&self,
1487 code: traits::ObligationCauseCode<'tcx>)
1489 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1492 pub fn type_is_known_to_be_sized(&self,
1497 traits::type_known_to_meet_builtin_bound(self.infcx(),
1503 pub fn register_builtin_bound(&self,
1505 builtin_bound: ty::BuiltinBound,
1506 cause: traits::ObligationCause<'tcx>)
1508 self.inh.infcx.fulfillment_cx.borrow_mut()
1509 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1512 pub fn register_predicate(&self,
1513 obligation: traits::PredicateObligation<'tcx>)
1515 debug!("register_predicate({:?})",
1517 self.inh.infcx.fulfillment_cx
1519 .register_predicate_obligation(self.infcx(), obligation);
1522 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1523 let t = ast_ty_to_ty(self, self, ast_t);
1524 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1528 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1529 match self.inh.tables.borrow().node_types.get(&ex.id) {
1532 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1538 /// Apply `adjustment` to the type of `expr`
1539 pub fn adjust_expr_ty(&self,
1541 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1544 let raw_ty = self.expr_ty(expr);
1545 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1546 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1547 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1548 self.inh.tables.borrow().method_map.get(&method_call)
1549 .map(|method| resolve_ty(method.ty))
1553 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1554 match self.inh.tables.borrow().node_types.get(&id) {
1556 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1558 self.tcx().sess.bug(
1559 &format!("no type for node {}: {} in fcx {}",
1560 id, self.tcx().map.node_to_string(id),
1566 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1567 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1568 // it changes when we upgrade the snapshot compiler
1569 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1570 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1574 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1577 pub fn opt_node_ty_substs<F>(&self,
1580 F: FnOnce(&ty::ItemSubsts<'tcx>),
1582 match self.inh.tables.borrow().item_substs.get(&id) {
1588 pub fn mk_subty(&self,
1589 a_is_expected: bool,
1593 -> Result<(), TypeError<'tcx>> {
1594 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1597 pub fn mk_eqty(&self,
1598 a_is_expected: bool,
1602 -> Result<(), TypeError<'tcx>> {
1603 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1606 pub fn mk_subr(&self,
1607 origin: infer::SubregionOrigin<'tcx>,
1610 infer::mk_subr(self.infcx(), origin, sub, sup)
1613 pub fn type_error_message<M>(&self,
1616 actual_ty: Ty<'tcx>,
1617 err: Option<&TypeError<'tcx>>) where
1618 M: FnOnce(String) -> String,
1620 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1623 pub fn report_mismatched_types(&self,
1627 err: &TypeError<'tcx>) {
1628 self.infcx().report_mismatched_types(sp, e, a, err)
1631 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1632 /// outlive the region `r`.
1633 pub fn register_region_obligation(&self,
1636 cause: traits::ObligationCause<'tcx>)
1638 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1639 fulfillment_cx.register_region_obligation(ty, region, cause);
1642 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1643 /// outlive the region `r`.
1644 pub fn register_wf_obligation(&self,
1647 code: traits::ObligationCauseCode<'tcx>)
1649 // WF obligations never themselves fail, so no real need to give a detailed cause:
1650 let cause = traits::ObligationCause::new(span, self.body_id, code);
1651 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1654 pub fn register_old_wf_obligation(&self,
1657 code: traits::ObligationCauseCode<'tcx>)
1659 // Registers an "old-style" WF obligation that uses the
1660 // implicator code. This is basically a buggy version of
1661 // `register_wf_obligation` that is being kept around
1662 // temporarily just to help with phasing in the newer rules.
1664 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1665 let cause = traits::ObligationCause::new(span, self.body_id, code);
1666 self.register_region_obligation(ty, ty::ReEmpty, cause);
1669 /// Registers obligations that all types appearing in `substs` are well-formed.
1670 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1672 for &ty in &substs.types {
1673 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1677 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1678 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1679 /// trait/region obligations.
1681 /// For example, if there is a function:
1684 /// fn foo<'a,T:'a>(...)
1687 /// and a reference:
1693 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1694 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1695 pub fn add_obligations_for_parameters(&self,
1696 cause: traits::ObligationCause<'tcx>,
1697 predicates: &ty::InstantiatedPredicates<'tcx>)
1699 assert!(!predicates.has_escaping_regions());
1701 debug!("add_obligations_for_parameters(predicates={:?})",
1704 for obligation in traits::predicates_for_generics(cause, predicates) {
1705 self.register_predicate(obligation);
1709 // FIXME(arielb1): use this instead of field.ty everywhere
1710 pub fn field_ty(&self,
1712 field: ty::FieldDef<'tcx>,
1713 substs: &Substs<'tcx>)
1716 self.normalize_associated_types_in(span,
1717 &field.ty(self.tcx(), substs))
1720 // Only for fields! Returns <none> for methods>
1721 // Indifferent to privacy flags
1722 fn check_casts(&self) {
1723 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1724 for cast in deferred_cast_checks.drain(..) {
1729 /// Apply "fallbacks" to some types
1730 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1731 fn default_type_parameters(&self) {
1732 use middle::ty::error::UnconstrainedNumeric::Neither;
1733 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1734 for ty in &self.infcx().unsolved_variables() {
1735 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1736 if self.infcx().type_var_diverges(resolved) {
1737 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1739 match self.infcx().type_is_unconstrained_numeric(resolved) {
1740 UnconstrainedInt => {
1741 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1743 UnconstrainedFloat => {
1744 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1752 fn select_all_obligations_and_apply_defaults(&self) {
1753 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1754 self.new_select_all_obligations_and_apply_defaults();
1756 self.old_select_all_obligations_and_apply_defaults();
1760 // Implements old type inference fallback algorithm
1761 fn old_select_all_obligations_and_apply_defaults(&self) {
1762 self.select_obligations_where_possible();
1763 self.default_type_parameters();
1764 self.select_obligations_where_possible();
1767 fn new_select_all_obligations_and_apply_defaults(&self) {
1768 use middle::ty::error::UnconstrainedNumeric::Neither;
1769 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1771 // For the time being this errs on the side of being memory wasteful but provides better
1773 // let type_variables = self.infcx().type_variables.clone();
1775 // There is a possibility that this algorithm will have to run an arbitrary number of times
1776 // to terminate so we bound it by the compiler's recursion limit.
1777 for _ in 0..self.tcx().sess.recursion_limit.get() {
1778 // First we try to solve all obligations, it is possible that the last iteration
1779 // has made it possible to make more progress.
1780 self.select_obligations_where_possible();
1782 let mut conflicts = Vec::new();
1784 // Collect all unsolved type, integral and floating point variables.
1785 let unsolved_variables = self.inh.infcx.unsolved_variables();
1787 // We must collect the defaults *before* we do any unification. Because we have
1788 // directly attached defaults to the type variables any unification that occurs
1789 // will erase defaults causing conflicting defaults to be completely ignored.
1790 let default_map: FnvHashMap<_, _> =
1793 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1796 let mut unbound_tyvars = HashSet::new();
1798 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1800 // We loop over the unsolved variables, resolving them and if they are
1801 // and unconstrainted numberic type we add them to the set of unbound
1802 // variables. We do this so we only apply literal fallback to type
1803 // variables without defaults.
1804 for ty in &unsolved_variables {
1805 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1806 if self.infcx().type_var_diverges(resolved) {
1807 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1809 match self.infcx().type_is_unconstrained_numeric(resolved) {
1810 UnconstrainedInt | UnconstrainedFloat => {
1811 unbound_tyvars.insert(resolved);
1818 // We now remove any numeric types that also have defaults, and instead insert
1819 // the type variable with a defined fallback.
1820 for ty in &unsolved_variables {
1821 if let Some(_default) = default_map.get(ty) {
1822 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1824 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1827 match resolved.sty {
1828 ty::TyInfer(ty::TyVar(_)) => {
1829 unbound_tyvars.insert(ty);
1832 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1833 unbound_tyvars.insert(ty);
1834 if unbound_tyvars.contains(resolved) {
1835 unbound_tyvars.remove(resolved);
1844 // If there are no more fallbacks to apply at this point we have applied all possible
1845 // defaults and type inference will proceed as normal.
1846 if unbound_tyvars.is_empty() {
1850 // Finally we go through each of the unbound type variables and unify them with
1851 // the proper fallback, reporting a conflicting default error if any of the
1852 // unifications fail. We know it must be a conflicting default because the
1853 // variable would only be in `unbound_tyvars` and have a concrete value if
1854 // it had been solved by previously applying a default.
1856 // We wrap this in a transaction for error reporting, if we detect a conflict
1857 // we will rollback the inference context to its prior state so we can probe
1858 // for conflicts and correctly report them.
1861 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1862 for ty in &unbound_tyvars {
1863 if self.infcx().type_var_diverges(ty) {
1864 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1866 match self.infcx().type_is_unconstrained_numeric(ty) {
1867 UnconstrainedInt => {
1868 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1870 UnconstrainedFloat => {
1871 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1874 if let Some(default) = default_map.get(ty) {
1875 let default = default.clone();
1876 match infer::mk_eqty(self.infcx(), false,
1877 TypeOrigin::Misc(default.origin_span),
1881 conflicts.push((*ty, default));
1890 // If there are conflicts we rollback, otherwise commit
1891 if conflicts.len() > 0 {
1898 if conflicts.len() > 0 {
1899 // Loop through each conflicting default, figuring out the default that caused
1900 // a unification failure and then report an error for each.
1901 for (conflict, default) in conflicts {
1902 let conflicting_default =
1903 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1904 .unwrap_or(type_variable::Default {
1905 ty: self.infcx().next_ty_var(),
1906 origin_span: codemap::DUMMY_SP,
1907 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1910 // This is to ensure that we elimnate any non-determinism from the error
1911 // reporting by fixing an order, it doesn't matter what order we choose
1912 // just that it is consistent.
1913 let (first_default, second_default) =
1914 if default.def_id < conflicting_default.def_id {
1915 (default, conflicting_default)
1917 (conflicting_default, default)
1921 self.infcx().report_conflicting_default_types(
1922 first_default.origin_span,
1929 self.select_obligations_where_possible();
1932 // For use in error handling related to default type parameter fallback. We explicitly
1933 // apply the default that caused conflict first to a local version of the type variable
1934 // table then apply defaults until we find a conflict. That default must be the one
1935 // that caused conflict earlier.
1936 fn find_conflicting_default(&self,
1937 unbound_vars: &HashSet<Ty<'tcx>>,
1938 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1940 -> Option<type_variable::Default<'tcx>> {
1941 use middle::ty::error::UnconstrainedNumeric::Neither;
1942 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1944 // Ensure that we apply the conflicting default first
1945 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1946 unbound_tyvars.push(conflict);
1947 unbound_tyvars.extend(unbound_vars.iter());
1949 let mut result = None;
1950 // We run the same code as above applying defaults in order, this time when
1951 // we find the conflict we just return it for error reporting above.
1953 // We also run this inside snapshot that never commits so we can do error
1954 // reporting for more then one conflict.
1955 for ty in &unbound_tyvars {
1956 if self.infcx().type_var_diverges(ty) {
1957 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1959 match self.infcx().type_is_unconstrained_numeric(ty) {
1960 UnconstrainedInt => {
1961 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1963 UnconstrainedFloat => {
1964 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1967 if let Some(default) = default_map.get(ty) {
1968 let default = default.clone();
1969 match infer::mk_eqty(self.infcx(), false,
1970 TypeOrigin::Misc(default.origin_span),
1974 result = Some(default);
1986 fn select_all_obligations_or_error(&self) {
1987 debug!("select_all_obligations_or_error");
1989 // upvar inference should have ensured that all deferred call
1990 // resolutions are handled by now.
1991 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1993 self.select_all_obligations_and_apply_defaults();
1995 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1996 match fulfillment_cx.select_all_or_error(self.infcx()) {
1998 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2002 /// Select as many obligations as we can at present.
2003 fn select_obligations_where_possible(&self) {
2005 self.inh.infcx.fulfillment_cx
2007 .select_where_possible(self.infcx())
2010 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2014 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2015 /// to improve inference. You could just call
2016 /// `select_obligations_where_possible` except that it leads to repeated
2018 fn select_new_obligations(&self) {
2020 self.inh.infcx.fulfillment_cx
2022 .select_new_obligations(self.infcx())
2025 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2031 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2032 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2033 Some(self.base_object_lifetime_default(span))
2036 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2037 // RFC #599 specifies that object lifetime defaults take
2038 // precedence over other defaults. But within a fn body we
2039 // don't have a *default* region, rather we use inference to
2040 // find the *correct* region, which is strictly more general
2041 // (and anyway, within a fn body the right region may not even
2042 // be something the user can write explicitly, since it might
2043 // be some expression).
2044 self.infcx().next_region_var(infer::MiscVariable(span))
2047 fn anon_regions(&self, span: Span, count: usize)
2048 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2049 Ok((0..count).map(|_| {
2050 self.infcx().next_region_var(infer::MiscVariable(span))
2055 /// Whether `autoderef` requires types to resolve.
2056 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2057 pub enum UnresolvedTypeAction {
2058 /// Produce an error and return `TyError` whenever a type cannot
2059 /// be resolved (i.e. it is `TyInfer`).
2061 /// Go on without emitting any errors, and return the unresolved
2062 /// type. Useful for probing, e.g. in coercions.
2066 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2067 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2069 /// Note: this method does not modify the adjustments table. The caller is responsible for
2070 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2071 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2074 opt_expr: Option<&hir::Expr>,
2075 unresolved_type_action: UnresolvedTypeAction,
2076 mut lvalue_pref: LvaluePreference,
2078 -> (Ty<'tcx>, usize, Option<T>)
2079 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2081 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2086 let mut t = base_ty;
2087 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2088 let resolved_t = match unresolved_type_action {
2089 UnresolvedTypeAction::Error => {
2090 structurally_resolved_type(fcx, sp, t)
2092 UnresolvedTypeAction::Ignore => {
2093 // We can continue even when the type cannot be resolved
2094 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2095 // and `try_overloaded_deref` both simply return `None`
2096 // in such a case without producing spurious errors.
2097 fcx.resolve_type_vars_if_possible(t)
2100 if resolved_t.references_error() {
2101 return (resolved_t, autoderefs, None);
2104 match should_stop(resolved_t, autoderefs) {
2105 Some(x) => return (resolved_t, autoderefs, Some(x)),
2109 // Otherwise, deref if type is derefable:
2110 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2111 Some(mt) => Some(mt),
2114 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2116 // Super subtle: it might seem as though we should
2117 // pass `opt_expr` to `try_overloaded_deref`, so that
2118 // the (implicit) autoref of using an overloaded deref
2119 // would get added to the adjustment table. However we
2120 // do not do that, because it's kind of a
2121 // "meta-adjustment" -- instead, we just leave it
2122 // unrecorded and know that there "will be" an
2123 // autoref. regionck and other bits of the code base,
2124 // when they encounter an overloaded autoderef, have
2125 // to do some reconstructive surgery. This is a pretty
2126 // complex mess that is begging for a proper MIR.
2127 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2133 if mt.mutbl == hir::MutImmutable {
2134 lvalue_pref = NoPreference;
2137 None => return (resolved_t, autoderefs, None)
2141 // We've reached the recursion limit, error gracefully.
2142 span_err!(fcx.tcx().sess, sp, E0055,
2143 "reached the recursion limit while auto-dereferencing {:?}",
2145 (fcx.tcx().types.err, 0, None)
2148 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2150 method_call: Option<MethodCall>,
2151 base_expr: Option<&hir::Expr>,
2153 lvalue_pref: LvaluePreference)
2154 -> Option<ty::TypeAndMut<'tcx>>
2156 // Try DerefMut first, if preferred.
2157 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2158 (PreferMutLvalue, Some(trait_did)) => {
2159 method::lookup_in_trait(fcx, span, base_expr,
2160 token::intern("deref_mut"), trait_did,
2166 // Otherwise, fall back to Deref.
2167 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2168 (None, Some(trait_did)) => {
2169 method::lookup_in_trait(fcx, span, base_expr,
2170 token::intern("deref"), trait_did,
2173 (method, _) => method
2176 make_overloaded_lvalue_return_type(fcx, method_call, method)
2179 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2180 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2181 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2182 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2183 method_call: Option<MethodCall>,
2184 method: Option<MethodCallee<'tcx>>)
2185 -> Option<ty::TypeAndMut<'tcx>>
2189 // extract method return type, which will be &T;
2190 // all LB regions should have been instantiated during method lookup
2191 let ret_ty = method.ty.fn_ret();
2192 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2194 if let Some(method_call) = method_call {
2195 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2198 // method returns &T, but the type as visible to user is T, so deref
2199 ret_ty.builtin_deref(true, NoPreference)
2205 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2207 base_expr: &'tcx hir::Expr,
2210 lvalue_pref: LvaluePreference)
2211 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2213 // FIXME(#18741) -- this is almost but not quite the same as the
2214 // autoderef that normal method probing does. They could likely be
2217 let (ty, autoderefs, final_mt) = autoderef(fcx,
2221 UnresolvedTypeAction::Error,
2224 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2225 adj_ty, idx, false, lvalue_pref, idx_ty)
2228 if final_mt.is_some() {
2232 // After we have fully autoderef'd, if the resulting type is [T; n], then
2233 // do a final unsized coercion to yield [T].
2234 if let ty::TyArray(element_ty, _) = ty.sty {
2235 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2236 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2237 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2243 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2244 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2245 /// This loop implements one step in that search; the autoderef loop is implemented by
2246 /// `lookup_indexing`.
2247 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2248 method_call: MethodCall,
2250 base_expr: &'tcx hir::Expr,
2251 adjusted_ty: Ty<'tcx>,
2254 lvalue_pref: LvaluePreference,
2256 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2258 let tcx = fcx.tcx();
2259 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2260 autoderefs={}, unsize={}, index_ty={:?})",
2268 let input_ty = fcx.infcx().next_ty_var();
2270 // First, try built-in indexing.
2271 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2272 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2273 debug!("try_index_step: success, using built-in indexing");
2274 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2276 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2277 return Some((tcx.types.usize, ty));
2282 // Try `IndexMut` first, if preferred.
2283 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2284 (PreferMutLvalue, Some(trait_did)) => {
2285 method::lookup_in_trait_adjusted(fcx,
2288 token::intern("index_mut"),
2293 Some(vec![input_ty]))
2298 // Otherwise, fall back to `Index`.
2299 let method = match (method, tcx.lang_items.index_trait()) {
2300 (None, Some(trait_did)) => {
2301 method::lookup_in_trait_adjusted(fcx,
2304 token::intern("index"),
2309 Some(vec![input_ty]))
2311 (method, _) => method,
2314 // If some lookup succeeds, write callee into table and extract index/element
2315 // type from the method signature.
2316 // If some lookup succeeded, install method in table
2317 method.and_then(|method| {
2318 debug!("try_index_step: success, using overloaded indexing");
2319 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2320 map(|ret| (input_ty, ret.ty))
2324 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2326 method_fn_ty: Ty<'tcx>,
2327 callee_expr: &'tcx hir::Expr,
2328 args_no_rcvr: &'tcx [P<hir::Expr>],
2329 tuple_arguments: TupleArgumentsFlag,
2330 expected: Expectation<'tcx>)
2331 -> ty::FnOutput<'tcx> {
2332 if method_fn_ty.references_error() {
2333 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2335 let err_inputs = match tuple_arguments {
2336 DontTupleArguments => err_inputs,
2337 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2340 check_argument_types(fcx,
2347 ty::FnConverging(fcx.tcx().types.err)
2349 match method_fn_ty.sty {
2350 ty::TyBareFn(_, ref fty) => {
2351 // HACK(eddyb) ignore self in the definition (see above).
2352 let expected_arg_tys = expected_types_for_fn_args(fcx,
2356 &fty.sig.0.inputs[1..]);
2357 check_argument_types(fcx,
2359 &fty.sig.0.inputs[1..],
2360 &expected_arg_tys[..],
2367 fcx.tcx().sess.span_bug(callee_expr.span,
2368 "method without bare fn type");
2374 /// Generic function that factors out common logic from function calls, method calls and overloaded
2376 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2378 fn_inputs: &[Ty<'tcx>],
2379 expected_arg_tys: &[Ty<'tcx>],
2380 args: &'tcx [P<hir::Expr>],
2382 tuple_arguments: TupleArgumentsFlag) {
2383 let tcx = fcx.ccx.tcx;
2385 // Grab the argument types, supplying fresh type variables
2386 // if the wrong number of arguments were supplied
2387 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2393 // All the input types from the fn signature must outlive the call
2394 // so as to validate implied bounds.
2395 for &fn_input_ty in fn_inputs {
2396 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2399 let mut expected_arg_tys = expected_arg_tys;
2400 let expected_arg_count = fn_inputs.len();
2401 let formal_tys = if tuple_arguments == TupleArguments {
2402 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2403 match tuple_type.sty {
2404 ty::TyTuple(ref arg_types) => {
2405 if arg_types.len() != args.len() {
2406 span_err!(tcx.sess, sp, E0057,
2407 "this function takes {} parameter{} but {} parameter{} supplied",
2409 if arg_types.len() == 1 {""} else {"s"},
2411 if args.len() == 1 {" was"} else {"s were"});
2412 expected_arg_tys = &[];
2413 err_args(fcx.tcx(), args.len())
2415 expected_arg_tys = match expected_arg_tys.get(0) {
2416 Some(&ty) => match ty.sty {
2417 ty::TyTuple(ref tys) => &**tys,
2422 (*arg_types).clone()
2426 span_err!(tcx.sess, sp, E0059,
2427 "cannot use call notation; the first type parameter \
2428 for the function trait is neither a tuple nor unit");
2429 expected_arg_tys = &[];
2430 err_args(fcx.tcx(), args.len())
2433 } else if expected_arg_count == supplied_arg_count {
2435 } else if variadic {
2436 if supplied_arg_count >= expected_arg_count {
2439 span_err!(tcx.sess, sp, E0060,
2440 "this function takes at least {} parameter{} \
2441 but {} parameter{} supplied",
2443 if expected_arg_count == 1 {""} else {"s"},
2445 if supplied_arg_count == 1 {" was"} else {"s were"});
2446 expected_arg_tys = &[];
2447 err_args(fcx.tcx(), supplied_arg_count)
2450 span_err!(tcx.sess, sp, E0061,
2451 "this function takes {} parameter{} but {} parameter{} supplied",
2453 if expected_arg_count == 1 {""} else {"s"},
2455 if supplied_arg_count == 1 {" was"} else {"s were"});
2456 expected_arg_tys = &[];
2457 err_args(fcx.tcx(), supplied_arg_count)
2460 debug!("check_argument_types: formal_tys={:?}",
2461 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2463 // Check the arguments.
2464 // We do this in a pretty awful way: first we typecheck any arguments
2465 // that are not anonymous functions, then we typecheck the anonymous
2466 // functions. This is so that we have more information about the types
2467 // of arguments when we typecheck the functions. This isn't really the
2468 // right way to do this.
2469 let xs = [false, true];
2470 let mut any_diverges = false; // has any of the arguments diverged?
2471 let mut warned = false; // have we already warned about unreachable code?
2472 for check_blocks in &xs {
2473 let check_blocks = *check_blocks;
2474 debug!("check_blocks={}", check_blocks);
2476 // More awful hacks: before we check argument types, try to do
2477 // an "opportunistic" vtable resolution of any trait bounds on
2478 // the call. This helps coercions.
2480 fcx.select_new_obligations();
2483 // For variadic functions, we don't have a declared type for all of
2484 // the arguments hence we only do our usual type checking with
2485 // the arguments who's types we do know.
2486 let t = if variadic {
2488 } else if tuple_arguments == TupleArguments {
2493 for (i, arg) in args.iter().take(t).enumerate() {
2494 if any_diverges && !warned {
2498 .add_lint(lint::builtin::UNREACHABLE_CODE,
2501 "unreachable expression".to_string());
2504 let is_block = match arg.node {
2505 hir::ExprClosure(..) => true,
2509 if is_block == check_blocks {
2510 debug!("checking the argument");
2511 let formal_ty = formal_tys[i];
2513 // The special-cased logic below has three functions:
2514 // 1. Provide as good of an expected type as possible.
2515 let expected = expected_arg_tys.get(i).map(|&ty| {
2516 Expectation::rvalue_hint(fcx.tcx(), ty)
2519 check_expr_with_unifier(fcx,
2521 expected.unwrap_or(ExpectHasType(formal_ty)),
2523 // 2. Coerce to the most detailed type that could be coerced
2524 // to, which is `expected_ty` if `rvalue_hint` returns an
2525 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2526 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2527 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2529 // 3. Relate the expected type and the formal one,
2530 // if the expected type was used for the coercion.
2531 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2535 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2536 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2539 if any_diverges && !warned {
2540 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2544 .add_lint(lint::builtin::UNREACHABLE_CODE,
2547 "unreachable call".to_string());
2553 // We also need to make sure we at least write the ty of the other
2554 // arguments which we skipped above.
2556 for arg in args.iter().skip(expected_arg_count) {
2557 check_expr(fcx, &**arg);
2559 // There are a few types which get autopromoted when passed via varargs
2560 // in C but we just error out instead and require explicit casts.
2561 let arg_ty = structurally_resolved_type(fcx, arg.span,
2562 fcx.expr_ty(&**arg));
2564 ty::TyFloat(ast::TyF32) => {
2565 fcx.type_error_message(arg.span,
2567 format!("can't pass an {} to variadic \
2568 function, cast to c_double", t)
2571 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2572 fcx.type_error_message(arg.span, |t| {
2573 format!("can't pass {} to variadic \
2574 function, cast to c_int",
2578 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2579 fcx.type_error_message(arg.span, |t| {
2580 format!("can't pass {} to variadic \
2581 function, cast to c_uint",
2591 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2592 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2593 (0..len).map(|_| tcx.types.err).collect()
2596 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2597 call_expr: &hir::Expr,
2598 output: ty::FnOutput<'tcx>) {
2599 fcx.write_ty(call_expr.id, match output {
2600 ty::FnConverging(output_ty) => output_ty,
2601 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2605 // AST fragment checking
2606 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2608 expected: Expectation<'tcx>)
2611 let tcx = fcx.ccx.tcx;
2614 ast::LitStr(..) => tcx.mk_static_str(),
2615 ast::LitByteStr(ref v) => {
2616 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2617 tcx.mk_array(tcx.types.u8, v.len()))
2619 ast::LitByte(_) => tcx.types.u8,
2620 ast::LitChar(_) => tcx.types.char,
2621 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2622 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2623 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2624 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2626 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2627 ty::TyChar => Some(tcx.types.u8),
2628 ty::TyRawPtr(..) => Some(tcx.types.usize),
2629 ty::TyBareFn(..) => Some(tcx.types.usize),
2633 opt_ty.unwrap_or_else(
2634 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2636 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2637 ast::LitFloatUnsuffixed(_) => {
2638 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2640 ty::TyFloat(_) => Some(ty),
2644 opt_ty.unwrap_or_else(
2645 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2647 ast::LitBool(_) => tcx.types.bool
2651 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2652 expr: &'tcx hir::Expr,
2653 expected: Ty<'tcx>) {
2654 check_expr_with_unifier(
2655 fcx, expr, ExpectHasType(expected), NoPreference,
2656 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2659 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2660 expr: &'tcx hir::Expr,
2661 expected: Ty<'tcx>) {
2662 check_expr_with_unifier(
2663 fcx, expr, ExpectHasType(expected), NoPreference,
2664 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2667 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2668 expr: &'tcx hir::Expr,
2669 expected: Ty<'tcx>) {
2670 check_expr_with_unifier(
2671 fcx, expr, ExpectHasType(expected), NoPreference,
2672 || demand::coerce(fcx, expr.span, expected, expr));
2675 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2676 expected: Ty<'tcx>) {
2677 check_expr_with_unifier(
2678 fcx, expr, ExpectHasType(expected), NoPreference,
2682 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2683 expr: &'tcx hir::Expr,
2684 expected: Expectation<'tcx>) {
2685 check_expr_with_unifier(
2686 fcx, expr, expected, NoPreference,
2690 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2691 expr: &'tcx hir::Expr,
2692 expected: Expectation<'tcx>,
2693 lvalue_pref: LvaluePreference)
2695 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2698 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2699 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2702 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2703 lvalue_pref: LvaluePreference) {
2704 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2707 // determine the `self` type, using fresh variables for all variables
2708 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2709 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2711 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2712 span: Span, // (potential) receiver for this impl
2714 -> TypeAndSubsts<'tcx> {
2715 let tcx = fcx.tcx();
2717 let ity = tcx.lookup_item_type(did);
2718 let (tps, rps, raw_ty) =
2719 (ity.generics.types.get_slice(subst::TypeSpace),
2720 ity.generics.regions.get_slice(subst::TypeSpace),
2723 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2725 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2726 let mut substs = subst::Substs::new(
2727 VecPerParamSpace::empty(),
2728 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2729 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2730 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2732 TypeAndSubsts { substs: substs, ty: substd_ty }
2735 /// Controls whether the arguments are tupled. This is used for the call
2738 /// Tupling means that all call-side arguments are packed into a tuple and
2739 /// passed as a single parameter. For example, if tupling is enabled, this
2742 /// fn f(x: (isize, isize))
2744 /// Can be called as:
2751 #[derive(Clone, Eq, PartialEq)]
2752 enum TupleArgumentsFlag {
2757 /// Unifies the return type with the expected type early, for more coercions
2758 /// and forward type information on the argument expressions.
2759 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2761 expected_ret: Expectation<'tcx>,
2762 formal_ret: ty::FnOutput<'tcx>,
2763 formal_args: &[Ty<'tcx>])
2765 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2766 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2767 fcx.infcx().commit_regions_if_ok(|| {
2768 // Attempt to apply a subtyping relationship between the formal
2769 // return type (likely containing type variables if the function
2770 // is polymorphic) and the expected return type.
2771 // No argument expectations are produced if unification fails.
2772 let origin = TypeOrigin::Misc(call_span);
2773 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2774 // FIXME(#15760) can't use try! here, FromError doesn't default
2775 // to identity so the resulting type is not constrained.
2776 if let Err(e) = ures {
2780 // Record all the argument types, with the substitutions
2781 // produced from the above subtyping unification.
2782 Ok(formal_args.iter().map(|ty| {
2783 fcx.infcx().resolve_type_vars_if_possible(ty)
2789 }).unwrap_or(vec![]);
2790 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2791 formal_args, formal_ret,
2792 expected_args, expected_ret);
2797 /// If an expression has any sub-expressions that result in a type error,
2798 /// inspecting that expression's type with `ty.references_error()` will return
2799 /// true. Likewise, if an expression is known to diverge, inspecting its
2800 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2801 /// strict, _|_ can appear in the type of an expression that does not,
2802 /// itself, diverge: for example, fn() -> _|_.)
2803 /// Note that inspecting a type's structure *directly* may expose the fact
2804 /// that there are actually multiple representations for `TyError`, so avoid
2805 /// that when err needs to be handled differently.
2806 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2807 expr: &'tcx hir::Expr,
2808 expected: Expectation<'tcx>,
2809 lvalue_pref: LvaluePreference,
2813 debug!(">> typechecking: expr={:?} expected={:?}",
2816 // Checks a method call.
2817 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2818 expr: &'tcx hir::Expr,
2819 method_name: Spanned<ast::Name>,
2820 args: &'tcx [P<hir::Expr>],
2822 expected: Expectation<'tcx>,
2823 lvalue_pref: LvaluePreference) {
2824 let rcvr = &*args[0];
2825 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2827 // no need to check for bot/err -- callee does that
2828 let expr_t = structurally_resolved_type(fcx,
2830 fcx.expr_ty(&*rcvr));
2832 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2833 let fn_ty = match method::lookup(fcx,
2841 let method_ty = method.ty;
2842 let method_call = MethodCall::expr(expr.id);
2843 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2847 method::report_error(fcx, method_name.span, expr_t,
2848 method_name.node, Some(rcvr), error);
2849 fcx.write_error(expr.id);
2854 // Call the generic checker.
2855 let ret_ty = check_method_argument_types(fcx,
2863 write_call(fcx, expr, ret_ty);
2866 // A generic function for checking the then and else in an if
2868 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2869 cond_expr: &'tcx hir::Expr,
2870 then_blk: &'tcx hir::Block,
2871 opt_else_expr: Option<&'tcx hir::Expr>,
2874 expected: Expectation<'tcx>) {
2875 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2877 let expected = expected.adjust_for_branches(fcx);
2878 check_block_with_expected(fcx, then_blk, expected);
2879 let then_ty = fcx.node_ty(then_blk.id);
2881 let branches_ty = match opt_else_expr {
2882 Some(ref else_expr) => {
2883 check_expr_with_expectation(fcx, &**else_expr, expected);
2884 let else_ty = fcx.expr_ty(&**else_expr);
2885 infer::common_supertype(fcx.infcx(),
2886 TypeOrigin::IfExpression(sp),
2892 infer::common_supertype(fcx.infcx(),
2893 TypeOrigin::IfExpressionWithNoElse(sp),
2900 let cond_ty = fcx.expr_ty(cond_expr);
2901 let if_ty = if cond_ty.references_error() {
2907 fcx.write_ty(id, if_ty);
2910 // Check field access expressions
2911 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2912 expr: &'tcx hir::Expr,
2913 lvalue_pref: LvaluePreference,
2914 base: &'tcx hir::Expr,
2915 field: &Spanned<ast::Name>) {
2916 let tcx = fcx.ccx.tcx;
2917 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2918 let expr_t = structurally_resolved_type(fcx, expr.span,
2920 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2921 let (_, autoderefs, field_ty) = autoderef(fcx,
2925 UnresolvedTypeAction::Error,
2929 ty::TyStruct(base_def, substs) => {
2930 debug!("struct named {:?}", base_t);
2931 base_def.struct_variant()
2932 .find_field_named(field.node)
2933 .map(|f| fcx.field_ty(expr.span, f, substs))
2940 fcx.write_ty(expr.id, field_ty);
2941 fcx.write_autoderef_adjustment(base.id, autoderefs);
2947 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2948 fcx.type_error_message(
2951 format!("attempted to take value of method `{}` on type \
2952 `{}`", field.node, actual)
2956 tcx.sess.fileline_help(field.span,
2957 "maybe a `()` to call it is missing? \
2958 If not, try an anonymous function");
2960 fcx.type_error_message(
2963 format!("attempted access of field `{}` on \
2964 type `{}`, but no field with that \
2970 if let ty::TyStruct(def, _) = expr_t.sty {
2971 suggest_field_names(def.struct_variant(), field, tcx, vec![]);
2975 fcx.write_error(expr.id);
2978 // displays hints about the closest matches in field names
2979 fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
2980 field: &Spanned<ast::Name>,
2981 tcx: &ty::ctxt<'tcx>,
2982 skip : Vec<InternedString>) {
2983 let name = field.node.as_str();
2984 let names = variant.fields
2986 .filter_map(|ref field| {
2987 // ignore already set fields and private fields from non-local crates
2988 if skip.iter().any(|x| *x == field.name.as_str()) ||
2989 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2996 // only find fits with at least one matching letter
2997 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2998 tcx.sess.span_help(field.span,
2999 &format!("did you mean `{}`?", name));
3003 // Check tuple index expressions
3004 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3005 expr: &'tcx hir::Expr,
3006 lvalue_pref: LvaluePreference,
3007 base: &'tcx hir::Expr,
3008 idx: codemap::Spanned<usize>) {
3009 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3010 let expr_t = structurally_resolved_type(fcx, expr.span,
3012 let mut tuple_like = false;
3013 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3014 let (_, autoderefs, field_ty) = autoderef(fcx,
3018 UnresolvedTypeAction::Error,
3022 ty::TyStruct(base_def, substs) => {
3023 tuple_like = base_def.struct_variant().is_tuple_struct();
3025 debug!("tuple struct named {:?}", base_t);
3026 base_def.struct_variant()
3029 .map(|f| fcx.field_ty(expr.span, f, substs))
3034 ty::TyTuple(ref v) => {
3036 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3043 fcx.write_ty(expr.id, field_ty);
3044 fcx.write_autoderef_adjustment(base.id, autoderefs);
3049 fcx.type_error_message(
3053 format!("attempted out-of-bounds tuple index `{}` on \
3058 format!("attempted tuple index `{}` on type `{}`, but the \
3059 type was not a tuple or tuple struct",
3066 fcx.write_error(expr.id);
3069 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3071 variant: ty::VariantDef<'tcx>,
3073 skip_fields: &[hir::Field]) {
3074 fcx.type_error_message(
3076 |actual| if let ty::TyEnum(..) = ty.sty {
3077 format!("struct variant `{}::{}` has no field named `{}`",
3078 actual, variant.name.as_str(), field.name.node)
3080 format!("structure `{}` has no field named `{}`",
3081 actual, field.name.node)
3085 // prevent all specified fields from being suggested
3086 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3087 suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
3090 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3093 variant: ty::VariantDef<'tcx>,
3094 ast_fields: &'tcx [hir::Field],
3095 check_completeness: bool) {
3096 let tcx = fcx.ccx.tcx;
3097 let substs = match adt_ty.sty {
3098 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3099 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3102 let mut remaining_fields = FnvHashMap();
3103 for field in &variant.fields {
3104 remaining_fields.insert(field.name, field);
3107 let mut error_happened = false;
3109 // Typecheck each field.
3110 for field in ast_fields {
3111 let expected_field_type;
3113 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3114 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3116 error_happened = true;
3117 expected_field_type = tcx.types.err;
3118 if let Some(_) = variant.find_field_named(field.name.node) {
3119 span_err!(fcx.tcx().sess, field.name.span, E0062,
3120 "field `{}` specified more than once",
3123 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3127 // Make sure to give a type to the field even if there's
3128 // an error, so we can continue typechecking
3129 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3132 // Make sure the programmer specified all the fields.
3133 if check_completeness &&
3135 !remaining_fields.is_empty()
3137 span_err!(tcx.sess, span, E0063,
3138 "missing field{} {} in initializer of `{}`",
3139 if remaining_fields.len() == 1 {""} else {"s"},
3140 remaining_fields.keys()
3141 .map(|n| format!("`{}`", n))
3142 .collect::<Vec<_>>()
3149 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3151 fields: &'tcx [hir::Field],
3152 base_expr: &'tcx Option<P<hir::Expr>>) {
3153 // Make sure to still write the types
3154 // otherwise we might ICE
3155 fcx.write_error(id);
3156 for field in fields {
3157 check_expr(fcx, &*field.expr);
3160 Some(ref base) => check_expr(fcx, &**base),
3165 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3168 fields: &'tcx [hir::Field],
3169 base_expr: &'tcx Option<P<hir::Expr>>)
3171 let tcx = fcx.tcx();
3173 // Find the relevant variant
3174 let def = lookup_full_def(tcx, path.span, expr.id);
3175 if def == def::DefErr {
3176 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3179 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3180 Some((adt, variant)) => (adt, variant),
3182 span_err!(fcx.tcx().sess, path.span, E0071,
3183 "`{}` does not name a structure",
3184 pprust::path_to_string(path));
3185 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3190 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3191 fcx.write_ty(expr.id, expr_ty);
3193 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3194 base_expr.is_none());
3196 if let &Some(ref base_expr) = base_expr {
3197 check_expr_has_type(fcx, base_expr, expr_ty);
3198 if adt.adt_kind() == ty::AdtKind::Enum {
3199 span_err!(tcx.sess, base_expr.span, E0436,
3200 "functional record update syntax requires a struct");
3205 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3207 let tcx = fcx.ccx.tcx;
3210 hir::ExprBox(ref subexpr) => {
3211 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3213 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3217 check_expr_with_expectation(fcx, subexpr, expected_inner);
3218 let referent_ty = fcx.expr_ty(&**subexpr);
3219 fcx.write_ty(id, tcx.mk_box(referent_ty));
3222 hir::ExprLit(ref lit) => {
3223 let typ = check_lit(fcx, &**lit, expected);
3224 fcx.write_ty(id, typ);
3226 hir::ExprBinary(op, ref lhs, ref rhs) => {
3227 op::check_binop(fcx, expr, op, lhs, rhs);
3229 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3230 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3232 hir::ExprUnary(unop, ref oprnd) => {
3233 let expected_inner = match unop {
3234 hir::UnNot | hir::UnNeg => {
3241 let lvalue_pref = match unop {
3242 hir::UnDeref => lvalue_pref,
3245 check_expr_with_expectation_and_lvalue_pref(
3246 fcx, &**oprnd, expected_inner, lvalue_pref);
3247 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3249 if !oprnd_t.references_error() {
3252 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3253 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3255 None => match try_overloaded_deref(fcx, expr.span,
3256 Some(MethodCall::expr(expr.id)),
3257 Some(&**oprnd), oprnd_t, lvalue_pref) {
3260 fcx.type_error_message(expr.span, |actual| {
3261 format!("type `{}` cannot be \
3262 dereferenced", actual)
3270 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3272 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3273 oprnd_t = op::check_user_unop(fcx, "!", "not",
3274 tcx.lang_items.not_trait(),
3275 expr, &**oprnd, oprnd_t, unop);
3279 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3281 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3282 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3283 tcx.lang_items.neg_trait(),
3284 expr, &**oprnd, oprnd_t, unop);
3289 fcx.write_ty(id, oprnd_t);
3291 hir::ExprAddrOf(mutbl, ref oprnd) => {
3292 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3294 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3295 if fcx.tcx().expr_is_lval(&**oprnd) {
3296 // Lvalues may legitimately have unsized types.
3297 // For example, dereferences of a fat pointer and
3298 // the last field of a struct can be unsized.
3299 ExpectHasType(mt.ty)
3301 Expectation::rvalue_hint(tcx, mt.ty)
3307 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3308 check_expr_with_expectation_and_lvalue_pref(fcx,
3313 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3314 let oprnd_t = if tm.ty.references_error() {
3317 // Note: at this point, we cannot say what the best lifetime
3318 // is to use for resulting pointer. We want to use the
3319 // shortest lifetime possible so as to avoid spurious borrowck
3320 // errors. Moreover, the longest lifetime will depend on the
3321 // precise details of the value whose address is being taken
3322 // (and how long it is valid), which we don't know yet until type
3323 // inference is complete.
3325 // Therefore, here we simply generate a region variable. The
3326 // region inferencer will then select the ultimate value.
3327 // Finally, borrowck is charged with guaranteeing that the
3328 // value whose address was taken can actually be made to live
3329 // as long as it needs to live.
3330 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3331 tcx.mk_ref(tcx.mk_region(region), tm)
3333 fcx.write_ty(id, oprnd_t);
3335 hir::ExprPath(ref maybe_qself, ref path) => {
3336 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3337 fcx.to_ty(&qself.ty)
3340 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3342 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3343 // Create some fake resolution that can't possibly be a type.
3344 def::PathResolution {
3345 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3346 last_private: LastMod(AllPublic),
3347 depth: path.segments.len()
3350 tcx.sess.span_bug(expr.span,
3351 &format!("unbound path {:?}", expr))
3354 if let Some((opt_ty, segments, def)) =
3355 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3356 expr.span, expr.id) {
3357 if def != def::DefErr {
3358 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3361 instantiate_path(fcx,
3370 fcx.write_ty(id, fcx.tcx().types.err);
3374 // We always require that the type provided as the value for
3375 // a type parameter outlives the moment of instantiation.
3376 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3377 fcx.add_wf_bounds(&item_substs.substs, expr);
3380 hir::ExprInlineAsm(ref ia) => {
3381 for &(_, ref input) in &ia.inputs {
3382 check_expr(fcx, &**input);
3384 for out in &ia.outputs {
3385 check_expr(fcx, &*out.expr);
3389 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3390 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3391 hir::ExprRet(ref expr_opt) => {
3393 ty::FnConverging(result_type) => {
3396 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3397 result_type, fcx.tcx().mk_nil()) {
3398 span_err!(tcx.sess, expr.span, E0069,
3399 "`return;` in a function whose return type is \
3403 check_expr_coercable_to_type(fcx, &**e, result_type);
3407 ty::FnDiverging => {
3408 if let Some(ref e) = *expr_opt {
3409 check_expr(fcx, &**e);
3411 span_err!(tcx.sess, expr.span, E0166,
3412 "`return` in a function declared as diverging");
3415 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3417 hir::ExprAssign(ref lhs, ref rhs) => {
3418 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3420 let tcx = fcx.tcx();
3421 if !tcx.expr_is_lval(&**lhs) {
3422 span_err!(tcx.sess, expr.span, E0070,
3423 "invalid left-hand side expression");
3426 let lhs_ty = fcx.expr_ty(&**lhs);
3427 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3428 let rhs_ty = fcx.expr_ty(&**rhs);
3430 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3432 if lhs_ty.references_error() || rhs_ty.references_error() {
3433 fcx.write_error(id);
3438 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3439 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3440 id, expr.span, expected);
3442 hir::ExprWhile(ref cond, ref body, _) => {
3443 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3444 check_block_no_value(fcx, &**body);
3445 let cond_ty = fcx.expr_ty(&**cond);
3446 let body_ty = fcx.node_ty(body.id);
3447 if cond_ty.references_error() || body_ty.references_error() {
3448 fcx.write_error(id);
3454 hir::ExprLoop(ref body, _) => {
3455 check_block_no_value(fcx, &**body);
3456 if !may_break(tcx, expr.id, &**body) {
3457 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3462 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3463 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3465 hir::ExprClosure(capture, ref decl, ref body) => {
3466 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3468 hir::ExprBlock(ref b) => {
3469 check_block_with_expected(fcx, &**b, expected);
3470 fcx.write_ty(id, fcx.node_ty(b.id));
3472 hir::ExprCall(ref callee, ref args) => {
3473 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3475 // we must check that return type of called functions is WF:
3476 let ret_ty = fcx.expr_ty(expr);
3477 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3479 hir::ExprMethodCall(name, ref tps, ref args) => {
3480 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3481 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3482 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3484 fcx.write_error(id);
3487 hir::ExprCast(ref e, ref t) => {
3488 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3489 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3492 // Find the type of `e`. Supply hints based on the type we are casting to,
3494 let t_cast = fcx.to_ty(t);
3495 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3496 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3497 let t_expr = fcx.expr_ty(e);
3499 // Eagerly check for some obvious errors.
3500 if t_expr.references_error() {
3501 fcx.write_error(id);
3502 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3503 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3505 // Write a type for the whole expression, assuming everything is going
3507 fcx.write_ty(id, t_cast);
3509 // Defer other checks until we're done type checking.
3510 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3511 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3512 deferred_cast_checks.push(cast_check);
3515 hir::ExprType(ref e, ref t) => {
3516 let typ = fcx.to_ty(&**t);
3517 check_expr_eq_type(fcx, &**e, typ);
3518 fcx.write_ty(id, typ);
3520 hir::ExprVec(ref args) => {
3521 let uty = expected.to_option(fcx).and_then(|uty| {
3523 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3528 let typ = match uty {
3531 check_expr_coercable_to_type(fcx, &**e, uty);
3536 let t: Ty = fcx.infcx().next_ty_var();
3538 check_expr_has_type(fcx, &**e, t);
3543 let typ = tcx.mk_array(typ, args.len());
3544 fcx.write_ty(id, typ);
3546 hir::ExprRepeat(ref element, ref count_expr) => {
3547 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3548 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3550 let uty = match expected {
3551 ExpectHasType(uty) => {
3553 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3560 let (element_ty, t) = match uty {
3562 check_expr_coercable_to_type(fcx, &**element, uty);
3566 let t: Ty = fcx.infcx().next_ty_var();
3567 check_expr_has_type(fcx, &**element, t);
3568 (fcx.expr_ty(&**element), t)
3573 // For [foo, ..n] where n > 1, `foo` must have
3575 fcx.require_type_meets(
3582 if element_ty.references_error() {
3583 fcx.write_error(id);
3585 let t = tcx.mk_array(t, count);
3586 fcx.write_ty(id, t);
3589 hir::ExprTup(ref elts) => {
3590 let flds = expected.only_has_type(fcx).and_then(|ty| {
3592 ty::TyTuple(ref flds) => Some(&flds[..]),
3596 let mut err_field = false;
3598 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3599 let t = match flds {
3600 Some(ref fs) if i < fs.len() => {
3602 check_expr_coercable_to_type(fcx, &**e, ety);
3606 check_expr_with_expectation(fcx, &**e, NoExpectation);
3610 err_field = err_field || t.references_error();
3614 fcx.write_error(id);
3616 let typ = tcx.mk_tup(elt_ts);
3617 fcx.write_ty(id, typ);
3620 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3621 check_expr_struct(fcx, expr, path, fields, base_expr);
3623 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3625 hir::ExprField(ref base, ref field) => {
3626 check_field(fcx, expr, lvalue_pref, &**base, field);
3628 hir::ExprTupField(ref base, idx) => {
3629 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3631 hir::ExprIndex(ref base, ref idx) => {
3632 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3633 check_expr(fcx, &**idx);
3635 let base_t = fcx.expr_ty(&**base);
3636 let idx_t = fcx.expr_ty(&**idx);
3638 if base_t.references_error() {
3639 fcx.write_ty(id, base_t);
3640 } else if idx_t.references_error() {
3641 fcx.write_ty(id, idx_t);
3643 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3644 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3645 Some((index_ty, element_ty)) => {
3646 let idx_expr_ty = fcx.expr_ty(idx);
3647 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3648 fcx.write_ty(id, element_ty);
3651 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3652 fcx.type_error_message(
3655 format!("cannot index a value of type `{}`",
3660 fcx.write_ty(id, fcx.tcx().types.err);
3665 hir::ExprRange(ref start, ref end) => {
3666 let t_start = start.as_ref().map(|e| {
3667 check_expr(fcx, &**e);
3670 let t_end = end.as_ref().map(|e| {
3671 check_expr(fcx, &**e);
3675 let idx_type = match (t_start, t_end) {
3676 (Some(ty), None) | (None, Some(ty)) => {
3679 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3680 t_end.references_error()) => {
3681 Some(fcx.tcx().types.err)
3683 (Some(t_start), Some(t_end)) => {
3684 Some(infer::common_supertype(fcx.infcx(),
3685 TypeOrigin::RangeExpression(expr.span),
3693 // Note that we don't check the type of start/end satisfy any
3694 // bounds because right now the range structs do not have any. If we add
3695 // some bounds, then we'll need to check `t_start` against them here.
3697 let range_type = match idx_type {
3698 Some(idx_type) if idx_type.references_error() => {
3702 // Find the did from the appropriate lang item.
3703 let did = match (start, end) {
3704 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3705 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3706 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3708 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3712 if let Some(did) = did {
3713 let def = tcx.lookup_adt_def(did);
3714 let predicates = tcx.lookup_predicates(did);
3715 let substs = Substs::new_type(vec![idx_type], vec![]);
3716 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3717 fcx.add_obligations_for_parameters(
3718 traits::ObligationCause::new(expr.span,
3720 traits::ItemObligation(did)),
3723 tcx.mk_struct(def, tcx.mk_substs(substs))
3725 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3730 // Neither start nor end => RangeFull
3731 if let Some(did) = tcx.lang_items.range_full_struct() {
3733 tcx.lookup_adt_def(did),
3734 tcx.mk_substs(Substs::empty())
3737 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3743 fcx.write_ty(id, range_type);
3748 debug!("type of expr({}) {} is...", expr.id,
3749 pprust::expr_to_string(expr));
3750 debug!("... {:?}, expected is {:?}",
3757 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3758 path_res: def::PathResolution,
3759 opt_self_ty: Option<Ty<'tcx>>,
3760 path: &'a hir::Path,
3762 node_id: ast::NodeId)
3763 -> Option<(Option<Ty<'tcx>>,
3764 &'a [hir::PathSegment],
3768 // Associated constants can't depend on generic types.
3769 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3773 node_id: ast::NodeId) -> bool {
3775 def::DefAssociatedConst(..) => {
3776 if ty.has_param_types() || ty.has_self_ty() {
3777 span_err!(fcx.sess(), span, E0329,
3778 "Associated consts cannot depend \
3779 on type parameters or Self.");
3780 fcx.write_error(node_id);
3789 // If fully resolved already, we don't have to do anything.
3790 if path_res.depth == 0 {
3791 if let Some(ty) = opt_self_ty {
3792 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3797 Some((opt_self_ty, &path.segments, path_res.base_def))
3799 let mut def = path_res.base_def;
3800 let ty_segments = path.segments.split_last().unwrap().1;
3801 let base_ty_end = path.segments.len() - path_res.depth;
3802 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3803 PathParamMode::Optional,
3806 &ty_segments[..base_ty_end],
3807 &ty_segments[base_ty_end..]);
3808 let item_segment = path.segments.last().unwrap();
3809 let item_name = item_segment.identifier.name;
3810 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3812 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3815 // Write back the new resolution.
3816 fcx.ccx.tcx.def_map.borrow_mut()
3817 .insert(node_id, def::PathResolution {
3819 last_private: path_res.last_private.or(lp),
3822 Some((Some(ty), slice::ref_slice(item_segment), def))
3825 method::report_error(fcx, span, ty,
3826 item_name, None, error);
3827 fcx.write_error(node_id);
3834 impl<'tcx> Expectation<'tcx> {
3835 /// Provide an expectation for an rvalue expression given an *optional*
3836 /// hint, which is not required for type safety (the resulting type might
3837 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3838 /// is useful in determining the concrete type.
3840 /// The primary use case is where the expected type is a fat pointer,
3841 /// like `&[isize]`. For example, consider the following statement:
3843 /// let x: &[isize] = &[1, 2, 3];
3845 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3846 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3847 /// expectation `ExpectHasType([isize])`, that would be too strong --
3848 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3849 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3850 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3851 /// which still is useful, because it informs integer literals and the like.
3852 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3853 /// for examples of where this comes up,.
3854 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3855 match tcx.struct_tail(ty).sty {
3856 ty::TySlice(_) | ty::TyTrait(..) => {
3857 ExpectRvalueLikeUnsized(ty)
3859 _ => ExpectHasType(ty)
3863 // Resolves `expected` by a single level if it is a variable. If
3864 // there is no expected type or resolution is not possible (e.g.,
3865 // no constraints yet present), just returns `None`.
3866 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3871 ExpectCastableToType(t) => {
3872 ExpectCastableToType(
3873 fcx.infcx().resolve_type_vars_if_possible(&t))
3875 ExpectHasType(t) => {
3877 fcx.infcx().resolve_type_vars_if_possible(&t))
3879 ExpectRvalueLikeUnsized(t) => {
3880 ExpectRvalueLikeUnsized(
3881 fcx.infcx().resolve_type_vars_if_possible(&t))
3886 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3887 match self.resolve(fcx) {
3888 NoExpectation => None,
3889 ExpectCastableToType(ty) |
3891 ExpectRvalueLikeUnsized(ty) => Some(ty),
3895 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3896 match self.resolve(fcx) {
3897 ExpectHasType(ty) => Some(ty),
3903 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3904 local: &'tcx hir::Local,
3905 init: &'tcx hir::Expr)
3907 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3909 let local_ty = fcx.local_ty(init.span, local.id);
3910 if let Some(m) = ref_bindings {
3911 // Somewhat subtle: if we have a `ref` binding in the pattern,
3912 // we want to avoid introducing coercions for the RHS. This is
3913 // both because it helps preserve sanity and, in the case of
3914 // ref mut, for soundness (issue #23116). In particular, in
3915 // the latter case, we need to be clear that the type of the
3916 // referent for the reference that results is *equal to* the
3917 // type of the lvalue it is referencing, and not some
3918 // supertype thereof.
3919 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3920 let init_ty = fcx.expr_ty(init);
3921 demand::eqtype(fcx, init.span, init_ty, local_ty);
3923 check_expr_coercable_to_type(fcx, init, local_ty)
3927 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3928 let tcx = fcx.ccx.tcx;
3930 let t = fcx.local_ty(local.span, local.id);
3931 fcx.write_ty(local.id, t);
3933 if let Some(ref init) = local.init {
3934 check_decl_initializer(fcx, local, &**init);
3935 let init_ty = fcx.expr_ty(&**init);
3936 if init_ty.references_error() {
3937 fcx.write_ty(local.id, init_ty);
3941 let pcx = pat_ctxt {
3943 map: pat_id_map(&tcx.def_map, &*local.pat),
3945 _match::check_pat(&pcx, &*local.pat, t);
3946 let pat_ty = fcx.node_ty(local.pat.id);
3947 if pat_ty.references_error() {
3948 fcx.write_ty(local.id, pat_ty);
3952 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3954 let mut saw_bot = false;
3955 let mut saw_err = false;
3957 hir::StmtDecl(ref decl, id) => {
3960 hir::DeclLocal(ref l) => {
3961 check_decl_local(fcx, &**l);
3962 let l_t = fcx.node_ty(l.id);
3963 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3964 saw_err = saw_err || l_t.references_error();
3966 hir::DeclItem(_) => {/* ignore for now */ }
3969 hir::StmtExpr(ref expr, id) => {
3971 // Check with expected type of ()
3972 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3973 let expr_ty = fcx.expr_ty(&**expr);
3974 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3975 saw_err = saw_err || expr_ty.references_error();
3977 hir::StmtSemi(ref expr, id) => {
3979 check_expr(fcx, &**expr);
3980 let expr_ty = fcx.expr_ty(&**expr);
3981 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3982 saw_err |= expr_ty.references_error();
3986 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3989 fcx.write_error(node_id);
3992 fcx.write_nil(node_id)
3996 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3997 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3998 let blkty = fcx.node_ty(blk.id);
3999 if blkty.references_error() {
4000 fcx.write_error(blk.id);
4002 let nilty = fcx.tcx().mk_nil();
4003 demand::suptype(fcx, blk.span, nilty, blkty);
4007 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4008 blk: &'tcx hir::Block,
4009 expected: Expectation<'tcx>) {
4011 let mut fcx_ps = fcx.ps.borrow_mut();
4012 let unsafety_state = fcx_ps.recurse(blk);
4013 replace(&mut *fcx_ps, unsafety_state)
4016 let mut warned = false;
4017 let mut any_diverges = false;
4018 let mut any_err = false;
4019 for s in &blk.stmts {
4021 let s_id = ::rustc_front::util::stmt_id(s);
4022 let s_ty = fcx.node_ty(s_id);
4023 if any_diverges && !warned && match s.node {
4024 hir::StmtDecl(ref decl, _) => {
4026 hir::DeclLocal(_) => true,
4030 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4035 .add_lint(lint::builtin::UNREACHABLE_CODE,
4038 "unreachable statement".to_string());
4041 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4042 any_err = any_err || s_ty.references_error();
4045 None => if any_err {
4046 fcx.write_error(blk.id);
4047 } else if any_diverges {
4048 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4050 fcx.write_nil(blk.id);
4053 if any_diverges && !warned {
4057 .add_lint(lint::builtin::UNREACHABLE_CODE,
4060 "unreachable expression".to_string());
4062 let ety = match expected {
4063 ExpectHasType(ety) => {
4064 check_expr_coercable_to_type(fcx, &**e, ety);
4068 check_expr_with_expectation(fcx, &**e, expected);
4074 fcx.write_error(blk.id);
4075 } else if any_diverges {
4076 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4078 fcx.write_ty(blk.id, ety);
4083 *fcx.ps.borrow_mut() = prev;
4086 /// Checks a constant appearing in a type. At the moment this is just the
4087 /// length expression in a fixed-length vector, but someday it might be
4088 /// extended to type-level numeric literals.
4089 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4090 expr: &'tcx hir::Expr,
4091 expected_type: Ty<'tcx>) {
4092 let tables = RefCell::new(ty::Tables::empty());
4093 let inh = static_inherited_fields(ccx, &tables);
4094 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4095 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4098 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4102 let tables = RefCell::new(ty::Tables::empty());
4103 let inh = static_inherited_fields(ccx, &tables);
4104 let rty = ccx.tcx.node_id_to_type(id);
4105 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4106 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4107 check_const_with_ty(&fcx, sp, e, declty);
4110 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4114 // Gather locals in statics (because of block expressions).
4115 // This is technically unnecessary because locals in static items are forbidden,
4116 // but prevents type checking from blowing up before const checking can properly
4118 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4120 check_expr_with_hint(fcx, e, declty);
4121 demand::coerce(fcx, e.span, declty, e);
4123 fcx.select_all_obligations_and_apply_defaults();
4124 upvar::closure_analyze_const(&fcx, e);
4125 fcx.select_obligations_where_possible();
4127 fcx.select_all_obligations_or_error();
4129 regionck::regionck_expr(fcx, e);
4130 writeback::resolve_type_vars_in_expr(fcx, e);
4133 /// Checks whether a type can be represented in memory. In particular, it
4134 /// identifies types that contain themselves without indirection through a
4135 /// pointer, which would mean their size is unbounded.
4136 pub fn check_representable(tcx: &ty::ctxt,
4138 item_id: ast::NodeId,
4139 designation: &str) -> bool {
4140 let rty = tcx.node_id_to_type(item_id);
4142 // Check that it is possible to represent this type. This call identifies
4143 // (1) types that contain themselves and (2) types that contain a different
4144 // recursive type. It is only necessary to throw an error on those that
4145 // contain themselves. For case 2, there must be an inner type that will be
4146 // caught by case 1.
4147 match rty.is_representable(tcx, sp) {
4148 Representability::SelfRecursive => {
4149 span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
4150 tcx.sess.fileline_help(
4151 sp, "wrap the inner value in a box to make it representable");
4154 Representability::Representable | Representability::ContainsRecursive => (),
4159 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4160 let t = tcx.node_id_to_type(id);
4162 ty::TyStruct(def, substs) => {
4163 let fields = &def.struct_variant().fields;
4164 if fields.is_empty() {
4165 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4168 let e = fields[0].ty(tcx, substs);
4169 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4170 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4174 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4175 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4177 span_err!(tcx.sess, sp, E0077,
4178 "SIMD vector element type should be machine type");
4187 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4189 vs: &'tcx [hir::Variant],
4192 fn disr_in_range(ccx: &CrateCtxt,
4194 disr: ty::Disr) -> bool {
4195 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4197 ast::TyU8 => disr as u8 as Disr == disr,
4198 ast::TyU16 => disr as u16 as Disr == disr,
4199 ast::TyU32 => disr as u32 as Disr == disr,
4200 ast::TyU64 => disr as u64 as Disr == disr,
4201 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4204 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4206 ast::TyI8 => disr as i8 as Disr == disr,
4207 ast::TyI16 => disr as i16 as Disr == disr,
4208 ast::TyI32 => disr as i32 as Disr == disr,
4209 ast::TyI64 => disr as i64 as Disr == disr,
4210 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4214 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4215 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4219 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4220 vs: &'tcx [hir::Variant],
4222 hint: attr::ReprAttr) {
4223 #![allow(trivial_numeric_casts)]
4225 let rty = ccx.tcx.node_id_to_type(id);
4226 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4228 let tables = RefCell::new(ty::Tables::empty());
4229 let inh = static_inherited_fields(ccx, &tables);
4230 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4232 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4234 if let Some(ref e) = v.node.disr_expr {
4235 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4239 let def_id = ccx.tcx.map.local_def_id(id);
4241 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4242 for (v, variant) in vs.iter().zip(variants.iter()) {
4243 let current_disr_val = variant.disr_val;
4245 // Check for duplicate discriminant values
4246 match disr_vals.iter().position(|&x| x == current_disr_val) {
4248 span_err!(ccx.tcx.sess, v.span, E0081,
4249 "discriminant value `{}` already exists", disr_vals[i]);
4250 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4251 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
4252 "conflicting discriminant here")
4256 // Check for unrepresentable discriminant values
4258 attr::ReprAny | attr::ReprExtern => (),
4259 attr::ReprInt(sp, ity) => {
4260 if !disr_in_range(ccx, ity, current_disr_val) {
4261 span_err!(ccx.tcx.sess, v.span, E0082,
4262 "discriminant value outside specified type");
4263 span_note!(ccx.tcx.sess, sp,
4264 "discriminant type specified here");
4268 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4270 attr::ReprPacked => {
4271 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4274 disr_vals.push(current_disr_val);
4278 let def_id = ccx.tcx.map.local_def_id(id);
4279 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4281 if hint != attr::ReprAny && vs.len() <= 1 {
4283 span_err!(ccx.tcx.sess, sp, E0083,
4284 "unsupported representation for univariant enum");
4286 span_err!(ccx.tcx.sess, sp, E0084,
4287 "unsupported representation for zero-variant enum");
4291 do_check(ccx, vs, id, hint);
4293 check_representable(ccx.tcx, sp, id, "enum");
4296 // Returns the type parameter count and the type for the given definition.
4297 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4300 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4302 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4303 let typ = fcx.local_ty(sp, nid);
4304 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4305 ty::GenericPredicates::empty())
4307 def::DefFn(id, _) | def::DefMethod(id) |
4308 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4309 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4310 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4314 def::DefAssociatedTy(..) |
4316 def::DefTyParam(..) |
4318 def::DefForeignMod(..) |
4320 def::DefSelfTy(..) |
4322 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4327 // Instantiates the given path, which must refer to an item with the given
4328 // number of type parameters and type.
4329 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4330 segments: &[hir::PathSegment],
4331 type_scheme: TypeScheme<'tcx>,
4332 type_predicates: &ty::GenericPredicates<'tcx>,
4333 opt_self_ty: Option<Ty<'tcx>>,
4336 node_id: ast::NodeId) {
4337 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4343 // We need to extract the type parameters supplied by the user in
4344 // the path `path`. Due to the current setup, this is a bit of a
4345 // tricky-process; the problem is that resolve only tells us the
4346 // end-point of the path resolution, and not the intermediate steps.
4347 // Luckily, we can (at least for now) deduce the intermediate steps
4348 // just from the end-point.
4350 // There are basically four cases to consider:
4352 // 1. Reference to a *type*, such as a struct or enum:
4354 // mod a { struct Foo<T> { ... } }
4356 // Because we don't allow types to be declared within one
4357 // another, a path that leads to a type will always look like
4358 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4359 // that only the final segment can have type parameters, and
4360 // they are located in the TypeSpace.
4362 // *Note:* Generally speaking, references to types don't
4363 // actually pass through this function, but rather the
4364 // `ast_ty_to_ty` function in `astconv`. However, in the case
4365 // of struct patterns (and maybe literals) we do invoke
4366 // `instantiate_path` to get the general type of an instance of
4367 // a struct. (In these cases, there are actually no type
4368 // parameters permitted at present, but perhaps we will allow
4369 // them in the future.)
4371 // 1b. Reference to an enum variant or tuple-like struct:
4373 // struct foo<T>(...)
4374 // enum E<T> { foo(...) }
4376 // In these cases, the parameters are declared in the type
4379 // 2. Reference to a *fn item*:
4383 // In this case, the path will again always have the form
4384 // `a::b::foo::<T>` where only the final segment should have
4385 // type parameters. However, in this case, those parameters are
4386 // declared on a value, and hence are in the `FnSpace`.
4388 // 3. Reference to a *method*:
4390 // impl<A> SomeStruct<A> {
4394 // Here we can have a path like
4395 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4396 // may appear in two places. The penultimate segment,
4397 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4398 // final segment, `foo::<B>` contains parameters in fn space.
4400 // 4. Reference to an *associated const*:
4402 // impl<A> AnotherStruct<A> {
4403 // const FOO: B = BAR;
4406 // The path in this case will look like
4407 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4408 // only will have parameters in TypeSpace.
4410 // The first step then is to categorize the segments appropriately.
4412 assert!(!segments.is_empty());
4414 let mut ufcs_associated = None;
4415 let mut segment_spaces: Vec<_>;
4417 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4418 def::DefSelfTy(..) |
4419 def::DefStruct(..) |
4420 def::DefVariant(..) |
4422 def::DefAssociatedTy(..) |
4424 def::DefPrimTy(..) |
4425 def::DefTyParam(..) => {
4426 // Everything but the final segment should have no
4427 // parameters at all.
4428 segment_spaces = vec![None; segments.len() - 1];
4429 segment_spaces.push(Some(subst::TypeSpace));
4432 // Case 2. Reference to a top-level value.
4435 def::DefStatic(..) => {
4436 segment_spaces = vec![None; segments.len() - 1];
4437 segment_spaces.push(Some(subst::FnSpace));
4440 // Case 3. Reference to a method.
4441 def::DefMethod(def_id) => {
4442 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4444 ty::TraitContainer(trait_did) => {
4445 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4447 ty::ImplContainer(_) => {}
4450 if segments.len() >= 2 {
4451 segment_spaces = vec![None; segments.len() - 2];
4452 segment_spaces.push(Some(subst::TypeSpace));
4453 segment_spaces.push(Some(subst::FnSpace));
4455 // `<T>::method` will end up here, and so can `T::method`.
4456 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4457 segment_spaces = vec![Some(subst::FnSpace)];
4458 ufcs_associated = Some((container, self_ty));
4462 def::DefAssociatedConst(def_id) => {
4463 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4465 ty::TraitContainer(trait_did) => {
4466 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4468 ty::ImplContainer(_) => {}
4471 if segments.len() >= 2 {
4472 segment_spaces = vec![None; segments.len() - 2];
4473 segment_spaces.push(Some(subst::TypeSpace));
4474 segment_spaces.push(None);
4476 // `<T>::CONST` will end up here, and so can `T::CONST`.
4477 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4478 segment_spaces = vec![None];
4479 ufcs_associated = Some((container, self_ty));
4483 // Other cases. Various nonsense that really shouldn't show up
4484 // here. If they do, an error will have been reported
4485 // elsewhere. (I hope)
4487 def::DefForeignMod(..) |
4492 segment_spaces = vec![None; segments.len()];
4495 assert_eq!(segment_spaces.len(), segments.len());
4497 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4498 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4499 // type parameters are not mandatory.
4500 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4502 debug!("segment_spaces={:?}", segment_spaces);
4504 // Next, examine the definition, and determine how many type
4505 // parameters we expect from each space.
4506 let type_defs = &type_scheme.generics.types;
4507 let region_defs = &type_scheme.generics.regions;
4509 // Now that we have categorized what space the parameters for each
4510 // segment belong to, let's sort out the parameters that the user
4511 // provided (if any) into their appropriate spaces. We'll also report
4512 // errors if type parameters are provided in an inappropriate place.
4513 let mut substs = Substs::empty();
4514 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4517 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4521 push_explicit_parameters_from_segment_to_substs(fcx,
4531 if let Some(self_ty) = opt_self_ty {
4532 if type_defs.len(subst::SelfSpace) == 1 {
4533 substs.types.push(subst::SelfSpace, self_ty);
4537 // Now we have to compare the types that the user *actually*
4538 // provided against the types that were *expected*. If the user
4539 // did not provide any types, then we want to substitute inference
4540 // variables. If the user provided some types, we may still need
4541 // to add defaults. If the user provided *too many* types, that's
4543 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4544 adjust_type_parameters(fcx, span, space, type_defs,
4545 require_type_space, &mut substs);
4546 assert_eq!(substs.types.len(space), type_defs.len(space));
4548 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4549 assert_eq!(substs.regions().len(space), region_defs.len(space));
4552 // The things we are substituting into the type should not contain
4553 // escaping late-bound regions, and nor should the base type scheme.
4554 assert!(!substs.has_regions_escaping_depth(0));
4555 assert!(!type_scheme.has_escaping_regions());
4557 // Add all the obligations that are required, substituting and
4558 // normalized appropriately.
4559 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4560 fcx.add_obligations_for_parameters(
4561 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4564 // Substitute the values for the type parameters into the type of
4565 // the referenced item.
4566 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4569 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4570 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4571 // is inherent, there is no `Self` parameter, instead, the impl needs
4572 // type parameters, which we can infer by unifying the provided `Self`
4573 // with the substituted impl type.
4574 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4575 assert_eq!(substs.types.len(subst::TypeSpace),
4576 impl_scheme.generics.types.len(subst::TypeSpace));
4577 assert_eq!(substs.regions().len(subst::TypeSpace),
4578 impl_scheme.generics.regions.len(subst::TypeSpace));
4580 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4581 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4582 fcx.tcx().sess.span_bug(span,
4584 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4590 debug!("instantiate_path: type of {:?} is {:?}",
4593 fcx.write_ty(node_id, ty_substituted);
4594 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4597 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4598 /// parameters are provided, then reports an error and clears the output vector.
4600 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4601 /// use inference variables. This seems less likely to lead to derived errors.
4603 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4604 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4605 /// here because we can easily use the precise span of the N+1'th parameter.
4606 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4607 fcx: &FnCtxt<'a, 'tcx>,
4608 space: subst::ParamSpace,
4610 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4611 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4612 segment: &hir::PathSegment,
4613 substs: &mut Substs<'tcx>)
4615 match segment.parameters {
4616 hir::AngleBracketedParameters(ref data) => {
4617 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4618 fcx, space, type_defs, region_defs, data, substs);
4621 hir::ParenthesizedParameters(ref data) => {
4622 span_err!(fcx.tcx().sess, span, E0238,
4623 "parenthesized parameters may only be used with a trait");
4624 push_explicit_parenthesized_parameters_from_segment_to_substs(
4625 fcx, space, span, type_defs, data, substs);
4630 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4631 fcx: &FnCtxt<'a, 'tcx>,
4632 space: subst::ParamSpace,
4633 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4634 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4635 data: &hir::AngleBracketedParameterData,
4636 substs: &mut Substs<'tcx>)
4639 let type_count = type_defs.len(space);
4640 assert_eq!(substs.types.len(space), 0);
4641 for (i, typ) in data.types.iter().enumerate() {
4642 let t = fcx.to_ty(&**typ);
4644 substs.types.push(space, t);
4645 } else if i == type_count {
4646 span_err!(fcx.tcx().sess, typ.span, E0087,
4647 "too many type parameters provided: \
4648 expected at most {} parameter{}, \
4649 found {} parameter{}",
4651 if type_count == 1 {""} else {"s"},
4653 if data.types.len() == 1 {""} else {"s"});
4654 substs.types.truncate(space, 0);
4660 if !data.bindings.is_empty() {
4661 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4662 "unexpected binding of associated item in expression path \
4663 (only allowed in type paths)");
4667 let region_count = region_defs.len(space);
4668 assert_eq!(substs.regions().len(space), 0);
4669 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4670 let r = ast_region_to_region(fcx.tcx(), lifetime);
4671 if i < region_count {
4672 substs.mut_regions().push(space, r);
4673 } else if i == region_count {
4674 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4675 "too many lifetime parameters provided: \
4676 expected {} parameter{}, found {} parameter{}",
4678 if region_count == 1 {""} else {"s"},
4679 data.lifetimes.len(),
4680 if data.lifetimes.len() == 1 {""} else {"s"});
4681 substs.mut_regions().truncate(space, 0);
4689 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4690 /// but intended for `Foo(A,B) -> C` form. This expands to
4691 /// roughly the same thing as `Foo<(A,B),C>`. One important
4692 /// difference has to do with the treatment of anonymous
4693 /// regions, which are translated into bound regions (NYI).
4694 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4695 fcx: &FnCtxt<'a, 'tcx>,
4696 space: subst::ParamSpace,
4698 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4699 data: &hir::ParenthesizedParameterData,
4700 substs: &mut Substs<'tcx>)
4702 let type_count = type_defs.len(space);
4704 span_err!(fcx.tcx().sess, span, E0167,
4705 "parenthesized form always supplies 2 type parameters, \
4706 but only {} parameter(s) were expected",
4710 let input_tys: Vec<Ty> =
4711 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4713 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4715 if type_count >= 1 {
4716 substs.types.push(space, tuple_ty);
4719 let output_ty: Option<Ty> =
4720 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4723 output_ty.unwrap_or(fcx.tcx().mk_nil());
4725 if type_count >= 2 {
4726 substs.types.push(space, output_ty);
4730 fn adjust_type_parameters<'a, 'tcx>(
4731 fcx: &FnCtxt<'a, 'tcx>,
4734 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4735 require_type_space: bool,
4736 substs: &mut Substs<'tcx>)
4738 let provided_len = substs.types.len(space);
4739 let desired = defs.get_slice(space);
4740 let required_len = desired.iter()
4741 .take_while(|d| d.default.is_none())
4744 debug!("adjust_type_parameters(space={:?}, \
4753 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4754 assert!(provided_len <= desired.len());
4756 // Nothing specified at all: supply inference variables for
4758 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4759 substs.types.replace(space, Vec::new());
4760 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4764 // Too few parameters specified: report an error and use Err
4766 if provided_len < required_len {
4768 if desired.len() != required_len { "at least " } else { "" };
4769 span_err!(fcx.tcx().sess, span, E0089,
4770 "too few type parameters provided: expected {}{} parameter{}, \
4771 found {} parameter{}",
4772 qualifier, required_len,
4773 if required_len == 1 {""} else {"s"},
4775 if provided_len == 1 {""} else {"s"});
4776 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4780 // Otherwise, add in any optional parameters that the user
4781 // omitted. The case of *too many* parameters is handled
4783 // push_explicit_parameters_from_segment_to_substs(). Note
4784 // that the *default* type are expressed in terms of all prior
4785 // parameters, so we have to substitute as we go with the
4786 // partial substitution that we have built up.
4787 for i in provided_len..desired.len() {
4788 let default = desired[i].default.unwrap();
4789 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4790 substs.types.push(space, default);
4792 assert_eq!(substs.types.len(space), desired.len());
4794 debug!("Final substs: {:?}", substs);
4797 fn adjust_region_parameters(
4801 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4802 substs: &mut Substs)
4804 let provided_len = substs.mut_regions().len(space);
4805 let desired = defs.get_slice(space);
4807 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4808 assert!(provided_len <= desired.len());
4810 // If nothing was provided, just use inference variables.
4811 if provided_len == 0 {
4812 substs.mut_regions().replace(
4814 fcx.infcx().region_vars_for_defs(span, desired));
4818 // If just the right number were provided, everybody is happy.
4819 if provided_len == desired.len() {
4823 // Otherwise, too few were provided. Report an error and then
4824 // use inference variables.
4825 span_err!(fcx.tcx().sess, span, E0090,
4826 "too few lifetime parameters provided: expected {} parameter{}, \
4827 found {} parameter{}",
4829 if desired.len() == 1 {""} else {"s"},
4831 if provided_len == 1 {""} else {"s"});
4833 substs.mut_regions().replace(
4835 fcx.infcx().region_vars_for_defs(span, desired));
4839 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4843 where F: Fn() -> Ty<'tcx>
4845 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4848 let alternative = f();
4851 if alternative.is_ty_var() || alternative.references_error() {
4852 fcx.type_error_message(sp, |_actual| {
4853 "the type of this value must be known in this context".to_string()
4855 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4856 ty = fcx.tcx().types.err;
4858 demand::suptype(fcx, sp, alternative, ty);
4866 // Resolves `typ` by a single level if `typ` is a type variable. If no
4867 // resolution is possible, then an error is reported.
4868 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4873 structurally_resolve_type_or_else(fcx, sp, ty, || {
4878 // Returns true if b contains a break that can exit from b
4879 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4880 // First: is there an unlabeled break immediately
4882 (loop_query(&*b, |e| {
4884 hir::ExprBreak(None) => true,
4888 // Second: is there a labeled break with label
4889 // <id> nested anywhere inside the loop?
4890 (block_query(b, |e| {
4891 if let hir::ExprBreak(Some(_)) = e.node {
4892 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4899 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4900 tps: &[hir::TyParam],
4902 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4905 // make a vector of booleans initially false, set to true when used
4906 if tps.is_empty() { return; }
4907 let mut tps_used = vec![false; tps.len()];
4909 for leaf_ty in ty.walk() {
4910 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4911 debug!("Found use of ty param num {}", idx);
4912 tps_used[idx as usize] = true;
4916 for (i, b) in tps_used.iter().enumerate() {
4918 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4919 "type parameter `{}` is unused",