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::errors::DiagnosticBuilder;
123 use syntax::parse::token::{self, InternedString};
125 use syntax::util::lev_distance::find_best_match_for_name;
127 use rustc_front::intravisit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::Visibility;
130 use rustc_front::print::pprust;
131 use rustc_back::slice;
150 /// closures defined within the function. For example:
153 /// bar(move|| { ... })
156 /// Here, the function `foo()` and the closure passed to
157 /// `bar()` will each have their own `FnCtxt`, but they will
158 /// share the inherited fields.
159 pub struct Inherited<'a, 'tcx: 'a> {
160 infcx: infer::InferCtxt<'a, 'tcx>,
161 locals: RefCell<NodeMap<Ty<'tcx>>>,
163 tables: &'a RefCell<ty::Tables<'tcx>>,
165 // When we process a call like `c()` where `c` is a closure type,
166 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
167 // `FnOnce` closure. In that case, we defer full resolution of the
168 // call until upvar inference can kick in and make the
169 // decision. We keep these deferred resolutions grouped by the
170 // def-id of the closure, so that once we decide, we can easily go
171 // back and process them.
172 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
174 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
177 trait DeferredCallResolution<'tcx> {
178 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
181 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
183 /// When type-checking an expression, we propagate downward
184 /// whatever type hint we are able in the form of an `Expectation`.
185 #[derive(Copy, Clone, Debug)]
186 pub enum Expectation<'tcx> {
187 /// We know nothing about what type this expression should have.
190 /// This expression should have the type given (or some subtype)
191 ExpectHasType(Ty<'tcx>),
193 /// This expression will be cast to the `Ty`
194 ExpectCastableToType(Ty<'tcx>),
196 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
197 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
198 ExpectRvalueLikeUnsized(Ty<'tcx>),
201 impl<'tcx> Expectation<'tcx> {
202 // Disregard "castable to" expectations because they
203 // can lead us astray. Consider for example `if cond
204 // {22} else {c} as u8` -- if we propagate the
205 // "castable to u8" constraint to 22, it will pick the
206 // type 22u8, which is overly constrained (c might not
207 // be a u8). In effect, the problem is that the
208 // "castable to" expectation is not the tightest thing
209 // we can say, so we want to drop it in this case.
210 // The tightest thing we can say is "must unify with
211 // else branch". Note that in the case of a "has type"
212 // constraint, this limitation does not hold.
214 // If the expected type is just a type variable, then don't use
215 // an expected type. Otherwise, we might write parts of the type
216 // when checking the 'then' block which are incompatible with the
218 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
220 ExpectHasType(ety) => {
221 let ety = fcx.infcx().shallow_resolve(ety);
222 if !ety.is_ty_var() {
228 ExpectRvalueLikeUnsized(ety) => {
229 ExpectRvalueLikeUnsized(ety)
236 #[derive(Copy, Clone)]
237 pub struct UnsafetyState {
238 pub def: ast::NodeId,
239 pub unsafety: hir::Unsafety,
240 pub unsafe_push_count: u32,
245 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
246 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
249 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
250 match self.unsafety {
251 // If this unsafe, then if the outer function was already marked as
252 // unsafe we shouldn't attribute the unsafe'ness to the block. This
253 // way the block can be warned about instead of ignoring this
254 // extraneous block (functions are never warned about).
255 hir::Unsafety::Unsafe if self.from_fn => *self,
258 let (unsafety, def, count) = match blk.rules {
259 hir::PushUnsafeBlock(..) =>
260 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
261 hir::PopUnsafeBlock(..) =>
262 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
263 hir::UnsafeBlock(..) =>
264 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
265 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
266 (unsafety, self.def, self.unsafe_push_count),
268 UnsafetyState{ def: def,
270 unsafe_push_count: count,
278 pub struct FnCtxt<'a, 'tcx: 'a> {
279 body_id: ast::NodeId,
281 // This flag is set to true if, during the writeback phase, we encounter
282 // a type error in this function.
283 writeback_errors: Cell<bool>,
285 // Number of errors that had been reported when we started
286 // checking this function. On exit, if we find that *more* errors
287 // have been reported, we will skip regionck and other work that
288 // expects the types within the function to be consistent.
289 err_count_on_creation: usize,
291 ret_ty: ty::FnOutput<'tcx>,
293 ps: RefCell<UnsafetyState>,
295 inh: &'a Inherited<'a, 'tcx>,
297 ccx: &'a CrateCtxt<'a, 'tcx>,
300 impl<'a, 'tcx> Inherited<'a, 'tcx> {
301 fn new(tcx: &'a ty::ctxt<'tcx>,
302 tables: &'a RefCell<ty::Tables<'tcx>>,
303 param_env: ty::ParameterEnvironment<'a, 'tcx>)
304 -> Inherited<'a, 'tcx> {
307 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
308 locals: RefCell::new(NodeMap()),
310 deferred_call_resolutions: RefCell::new(DefIdMap()),
311 deferred_cast_checks: RefCell::new(Vec::new()),
315 fn normalize_associated_types_in<T>(&self,
317 body_id: ast::NodeId,
320 where T : TypeFoldable<'tcx> + HasTypeFlags
322 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
323 assoc::normalize_associated_types_in(&self.infcx,
332 // Used by check_const and check_enum_variants
333 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
334 inh: &'a Inherited<'a, 'tcx>,
335 rty: ty::FnOutput<'tcx>,
336 body_id: ast::NodeId)
337 -> FnCtxt<'a, 'tcx> {
340 writeback_errors: Cell::new(false),
341 err_count_on_creation: ccx.tcx.sess.err_count(),
343 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
349 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
350 tables: &'a RefCell<ty::Tables<'tcx>>)
351 -> Inherited<'a, 'tcx> {
352 // It's kind of a kludge to manufacture a fake function context
353 // and statement context, but we might as well do write the code only once
354 let param_env = ccx.tcx.empty_parameter_environment();
355 Inherited::new(ccx.tcx, &tables, param_env)
358 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
359 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
362 fn visit_item(&mut self, i: &'tcx hir::Item) {
363 check_item_type(self.ccx, i);
364 intravisit::walk_item(self, i);
367 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
369 hir::TyFixedLengthVec(_, ref expr) => {
370 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
375 intravisit::walk_ty(self, t);
379 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
380 fn visit_item(&mut self, i: &'tcx hir::Item) {
381 check_item_body(self.ccx, i);
385 pub fn check_wf_new(ccx: &CrateCtxt) {
386 ccx.tcx.sess.abort_if_new_errors(|| {
387 let krate = ccx.tcx.map.krate();
388 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
389 krate.visit_all_items(&mut visit);
393 pub fn check_item_types(ccx: &CrateCtxt) {
394 ccx.tcx.sess.abort_if_new_errors(|| {
395 let krate = ccx.tcx.map.krate();
396 let mut visit = CheckItemTypesVisitor { ccx: ccx };
397 krate.visit_all_items(&mut visit);
401 pub fn check_item_bodies(ccx: &CrateCtxt) {
402 ccx.tcx.sess.abort_if_new_errors(|| {
403 let krate = ccx.tcx.map.krate();
404 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
405 krate.visit_all_items(&mut visit);
409 pub fn check_drop_impls(ccx: &CrateCtxt) {
410 ccx.tcx.sess.abort_if_new_errors(|| {
411 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
412 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
414 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
415 if drop_impl_did.is_local() {
416 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
419 assert!(ccx.tcx.sess.has_errors());
427 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
428 decl: &'tcx hir::FnDecl,
429 body: &'tcx hir::Block,
433 param_env: ty::ParameterEnvironment<'a, 'tcx>)
436 ty::TyBareFn(_, ref fn_ty) => {
437 let tables = RefCell::new(ty::Tables::empty());
438 let inh = Inherited::new(ccx.tcx, &tables, param_env);
440 // Compute the fty from point of view of inside fn.
441 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
443 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
445 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
447 inh.normalize_associated_types_in(body.span,
451 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
452 decl, fn_id, body, &inh);
454 fcx.select_all_obligations_and_apply_defaults();
455 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
456 fcx.select_obligations_where_possible();
458 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
460 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
461 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
463 _ => ccx.tcx.sess.impossible_case(body.span,
464 "check_bare_fn: function type expected")
468 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
469 fcx: &'a FnCtxt<'a, 'tcx>
472 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
473 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
476 // infer the variable's type
477 let var_ty = self.fcx.infcx().next_ty_var();
478 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
482 // take type that the user specified
483 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
490 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
491 // Add explicitly-declared locals.
492 fn visit_local(&mut self, local: &'tcx hir::Local) {
493 let o_ty = match local.ty {
494 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
497 self.assign(local.span, local.id, o_ty);
498 debug!("Local variable {:?} is assigned type {}",
500 self.fcx.infcx().ty_to_string(
501 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
502 intravisit::walk_local(self, local);
505 // Add pattern bindings.
506 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
507 if let hir::PatIdent(_, ref path1, _) = p.node {
508 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
509 let var_ty = self.assign(p.span, p.id, None);
511 self.fcx.require_type_is_sized(var_ty, p.span,
512 traits::VariableType(p.id));
514 debug!("Pattern binding {} is assigned to {} with type {:?}",
516 self.fcx.infcx().ty_to_string(
517 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
521 intravisit::walk_pat(self, p);
524 fn visit_block(&mut self, b: &'tcx hir::Block) {
525 // non-obvious: the `blk` variable maps to region lb, so
526 // we have to keep this up-to-date. This
527 // is... unfortunate. It'd be nice to not need this.
528 intravisit::walk_block(self, b);
531 // Since an expr occurs as part of the type fixed size arrays we
532 // need to record the type for that node
533 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
535 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
536 self.visit_ty(&**ty);
537 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
539 hir::TyBareFn(ref function_declaration) => {
540 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
541 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
543 _ => intravisit::walk_ty(self, t)
547 // Don't descend into the bodies of nested closures
548 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
549 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
552 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
553 /// body and returns the function context used for that purpose, since in the case of a fn item
554 /// there is still a bit more to do.
557 /// * inherited: other fields inherited from the enclosing fn (if any)
558 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
559 unsafety: hir::Unsafety,
560 unsafety_id: ast::NodeId,
561 fn_sig: &ty::FnSig<'tcx>,
562 decl: &'tcx hir::FnDecl,
564 body: &'tcx hir::Block,
565 inherited: &'a Inherited<'a, 'tcx>)
569 let err_count_on_creation = tcx.sess.err_count();
571 let arg_tys = &fn_sig.inputs;
572 let ret_ty = fn_sig.output;
574 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
579 // Create the function context. This is either derived from scratch or,
580 // in the case of function expressions, based on the outer context.
583 writeback_errors: Cell::new(false),
584 err_count_on_creation: err_count_on_creation,
586 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
591 if let ty::FnConverging(ret_ty) = ret_ty {
592 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
595 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
597 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
600 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
602 // Add formal parameters.
603 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
604 // The type of the argument must be well-formed.
606 // NB -- this is now checked in wfcheck, but that
607 // currently only results in warnings, so we issue an
608 // old-style WF obligation here so that we still get the
609 // errors that we used to get.
610 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
612 // Create type variables for each argument.
613 pat_util::pat_bindings(
616 |_bm, pat_id, sp, _path| {
617 let var_ty = visit.assign(sp, pat_id, None);
618 fcx.require_type_is_sized(var_ty, sp,
619 traits::VariableType(pat_id));
622 // Check the pattern.
625 map: pat_id_map(&tcx.def_map, &*input.pat),
627 _match::check_pat(&pcx, &*input.pat, *arg_ty);
630 visit.visit_block(body);
633 check_block_with_expected(&fcx, body, match ret_ty {
634 ty::FnConverging(result_type) => ExpectHasType(result_type),
635 ty::FnDiverging => NoExpectation
638 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
639 fcx.write_ty(input.id, arg);
645 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
648 check_representable(tcx, span, id, "struct");
650 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
651 check_simd(tcx, span, id);
655 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
656 debug!("check_item_type(it.id={}, it.name={})",
658 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
659 let _indenter = indenter();
661 // Consts can play a role in type-checking, so they are included here.
662 hir::ItemStatic(_, _, ref e) |
663 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
664 hir::ItemEnum(ref enum_definition, _) => {
665 check_enum_variants(ccx,
667 &enum_definition.variants,
670 hir::ItemFn(..) => {} // entirely within check_item_body
671 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
672 debug!("ItemImpl {} with id {}", it.name, it.id);
673 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
674 Some(impl_trait_ref) => {
675 check_impl_items_against_trait(ccx,
683 hir::ItemTrait(_, ref generics, _, _) => {
684 check_trait_on_unimplemented(ccx, generics, it);
686 hir::ItemStruct(..) => {
687 check_struct(ccx, it.id, it.span);
689 hir::ItemTy(_, ref generics) => {
690 let pty_ty = ccx.tcx.node_id_to_type(it.id);
691 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
693 hir::ItemForeignMod(ref m) => {
694 if m.abi == abi::RustIntrinsic {
695 for item in &m.items {
696 intrinsic::check_intrinsic_type(ccx, item);
698 } else if m.abi == abi::PlatformIntrinsic {
699 for item in &m.items {
700 intrinsic::check_platform_intrinsic_type(ccx, item);
703 for item in &m.items {
704 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
705 if !pty.generics.types.is_empty() {
706 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
707 "foreign items may not have type parameters");
708 span_help!(&mut err, item.span,
709 "consider using specialization instead of \
714 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
715 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
720 _ => {/* nothing to do */ }
724 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
725 debug!("check_item_body(it.id={}, it.name={})",
727 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
728 let _indenter = indenter();
730 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
731 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
732 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
733 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
735 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
736 debug!("ItemImpl {} with id {}", it.name, it.id);
738 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
740 for impl_item in impl_items {
741 match impl_item.node {
742 hir::ImplItemKind::Const(_, ref expr) => {
743 check_const(ccx, impl_item.span, &*expr, impl_item.id)
745 hir::ImplItemKind::Method(ref sig, ref body) => {
746 check_method_body(ccx, &impl_pty.generics, sig, body,
747 impl_item.id, impl_item.span);
749 hir::ImplItemKind::Type(_) => {
750 // Nothing to do here.
755 hir::ItemTrait(_, _, _, ref trait_items) => {
756 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
757 for trait_item in trait_items {
758 match trait_item.node {
759 hir::ConstTraitItem(_, Some(ref expr)) => {
760 check_const(ccx, trait_item.span, &*expr, trait_item.id)
762 hir::MethodTraitItem(ref sig, Some(ref body)) => {
763 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
765 check_method_body(ccx, &trait_def.generics, sig, body,
766 trait_item.id, trait_item.span);
768 hir::MethodTraitItem(ref sig, None) => {
769 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
771 hir::ConstTraitItem(_, None) |
772 hir::TypeTraitItem(..) => {
778 _ => {/* nothing to do */ }
782 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
784 constness: hir::Constness)
787 hir::Constness::NotConst => {
790 hir::Constness::Const => {
791 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
796 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
797 generics: &hir::Generics,
799 if let Some(ref attr) = item.attrs.iter().find(|a| {
800 a.check_name("rustc_on_unimplemented")
802 if let Some(ref istring) = attr.value_str() {
803 let parser = Parser::new(&istring);
804 let types = &*generics.ty_params;
805 for token in parser {
807 Piece::String(_) => (), // Normal string, no need to check it
808 Piece::NextArgument(a) => match a.position {
809 // `{Self}` is allowed
810 Position::ArgumentNamed(s) if s == "Self" => (),
811 // So is `{A}` if A is a type parameter
812 Position::ArgumentNamed(s) => match types.iter().find(|t| {
817 span_err!(ccx.tcx.sess, attr.span, E0230,
818 "there is no type parameter \
823 // `{:1}` and `{}` are not to be used
824 Position::ArgumentIs(_) | Position::ArgumentNext => {
825 span_err!(ccx.tcx.sess, attr.span, E0231,
826 "only named substitution \
827 parameters are allowed");
833 span_err!(ccx.tcx.sess, attr.span, E0232,
834 "this attribute must have a value, \
835 eg `#[rustc_on_unimplemented = \"foo\"]`")
840 /// Type checks a method body.
844 /// * `item_generics`: generics defined on the impl/trait that contains
846 /// * `self_bound`: bound for the `Self` type parameter, if any
847 /// * `method`: the method definition
848 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
849 item_generics: &ty::Generics<'tcx>,
850 sig: &'tcx hir::MethodSig,
851 body: &'tcx hir::Block,
852 id: ast::NodeId, span: Span) {
853 debug!("check_method_body(item_generics={:?}, id={})",
855 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
857 let fty = ccx.tcx.node_id_to_type(id);
858 debug!("check_method_body: fty={:?}", fty);
860 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
863 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
865 impl_trait_ref: &ty::TraitRef<'tcx>,
866 impl_items: &[hir::ImplItem]) {
867 // Locate trait methods
869 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
870 let mut overridden_associated_type = None;
872 // Check existing impl methods to see if they are both present in trait
873 // and compatible with trait signature
874 for impl_item in impl_items {
875 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
876 let ty_trait_item = trait_items.iter()
877 .find(|ac| ac.name() == ty_impl_item.name());
879 if let Some(ty_trait_item) = ty_trait_item {
880 match impl_item.node {
881 hir::ImplItemKind::Const(..) => {
882 let impl_const = match ty_impl_item {
883 ty::ConstTraitItem(ref cti) => cti,
884 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
887 // Find associated const definition.
888 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
889 compare_const_impl(ccx.tcx,
895 span_err!(tcx.sess, impl_item.span, E0323,
896 "item `{}` is an associated const, \
897 which doesn't match its trait `{:?}`",
902 hir::ImplItemKind::Method(ref sig, ref body) => {
903 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
905 let impl_method = match ty_impl_item {
906 ty::MethodTraitItem(ref mti) => mti,
907 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
910 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
911 compare_impl_method(ccx.tcx,
918 span_err!(tcx.sess, impl_item.span, E0324,
919 "item `{}` is an associated method, \
920 which doesn't match its trait `{:?}`",
925 hir::ImplItemKind::Type(_) => {
926 let impl_type = match ty_impl_item {
927 ty::TypeTraitItem(ref tti) => tti,
928 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
931 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
932 if let Some(_) = at.ty {
933 overridden_associated_type = Some(impl_item);
936 span_err!(tcx.sess, impl_item.span, E0325,
937 "item `{}` is an associated type, \
938 which doesn't match its trait `{:?}`",
947 // Check for missing items from trait
948 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
949 let mut missing_items = Vec::new();
950 let mut invalidated_items = Vec::new();
951 let associated_type_overridden = overridden_associated_type.is_some();
952 for trait_item in trait_items.iter() {
954 ty::ConstTraitItem(ref associated_const) => {
955 let is_implemented = impl_items.iter().any(|ii| {
957 hir::ImplItemKind::Const(..) => {
958 ii.name == associated_const.name
963 let is_provided = associated_const.has_value;
967 missing_items.push(associated_const.name);
968 } else if associated_type_overridden {
969 invalidated_items.push(associated_const.name);
973 ty::MethodTraitItem(ref trait_method) => {
975 impl_items.iter().any(|ii| {
977 hir::ImplItemKind::Method(..) => {
978 ii.name == trait_method.name
984 provided_methods.iter().any(|m| m.name == trait_method.name);
987 missing_items.push(trait_method.name);
988 } else if associated_type_overridden {
989 invalidated_items.push(trait_method.name);
993 ty::TypeTraitItem(ref associated_type) => {
994 let is_implemented = impl_items.iter().any(|ii| {
996 hir::ImplItemKind::Type(_) => {
997 ii.name == associated_type.name
1002 let is_provided = associated_type.ty.is_some();
1003 if !is_implemented {
1005 missing_items.push(associated_type.name);
1006 } else if associated_type_overridden {
1007 invalidated_items.push(associated_type.name);
1014 if !missing_items.is_empty() {
1015 span_err!(tcx.sess, impl_span, E0046,
1016 "not all trait items implemented, missing: `{}`",
1017 missing_items.iter()
1018 .map(|name| name.to_string())
1019 .collect::<Vec<_>>().join("`, `"))
1022 if !invalidated_items.is_empty() {
1023 let invalidator = overridden_associated_type.unwrap();
1024 span_err!(tcx.sess, invalidator.span, E0399,
1025 "the following trait items need to be reimplemented \
1026 as `{}` was overridden: `{}`",
1028 invalidated_items.iter()
1029 .map(|name| name.to_string())
1030 .collect::<Vec<_>>().join("`, `"))
1034 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1041 let tstr = fcx.infcx().ty_to_string(t_cast);
1042 let mut err = fcx.type_error_struct(span, |actual| {
1043 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1046 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1047 let mtstr = match mt {
1048 hir::MutMutable => "mut ",
1049 hir::MutImmutable => ""
1051 if t_cast.is_trait() {
1052 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1054 err.span_suggestion(t_span,
1055 "try casting to a reference instead:",
1056 format!("&{}{}", mtstr, s));
1059 span_help!(err, t_span,
1060 "did you mean `&{}{}`?", mtstr, tstr),
1063 span_help!(err, span,
1064 "consider using an implicit coercion to `&{}{}` instead",
1069 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1071 err.span_suggestion(t_span,
1072 "try casting to a `Box` instead:",
1073 format!("Box<{}>", s));
1076 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1080 span_help!(err, e_span,
1081 "consider using a box or reference as appropriate");
1085 fcx.write_error(id);
1089 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1090 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1092 fn get_item_type_scheme(&self, _: Span, id: DefId)
1093 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1095 Ok(self.tcx().lookup_item_type(id))
1098 fn get_trait_def(&self, _: Span, id: DefId)
1099 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1101 Ok(self.tcx().lookup_trait_def(id))
1104 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1105 // all super predicates are ensured during collect pass
1109 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1110 Some(&self.inh.infcx.parameter_environment.free_substs)
1113 fn get_type_parameter_bounds(&self,
1115 node_id: ast::NodeId)
1116 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1118 let def = self.tcx().type_parameter_def(node_id);
1119 let r = self.inh.infcx.parameter_environment
1122 .filter_map(|predicate| {
1124 ty::Predicate::Trait(ref data) => {
1125 if data.0.self_ty().is_param(def.space, def.index) {
1126 Some(data.to_poly_trait_ref())
1140 fn trait_defines_associated_type_named(&self,
1141 trait_def_id: DefId,
1142 assoc_name: ast::Name)
1145 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1146 trait_def.associated_type_names.contains(&assoc_name)
1150 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1151 substs: Option<&mut subst::Substs<'tcx>>,
1152 space: Option<subst::ParamSpace>,
1153 span: Span) -> Ty<'tcx> {
1154 // Grab the default doing subsitution
1155 let default = ty_param_def.and_then(|def| {
1156 def.default.map(|ty| type_variable::Default {
1157 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1159 def_id: def.default_def_id
1163 let ty_var = self.infcx().next_ty_var_with_default(default);
1165 // Finally we add the type variable to the substs
1168 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1172 fn projected_ty_from_poly_trait_ref(&self,
1174 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1175 item_name: ast::Name)
1178 let (trait_ref, _) =
1179 self.infcx().replace_late_bound_regions_with_fresh_var(
1181 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1184 self.normalize_associated_type(span, trait_ref, item_name)
1187 fn projected_ty(&self,
1189 trait_ref: ty::TraitRef<'tcx>,
1190 item_name: ast::Name)
1193 self.normalize_associated_type(span, trait_ref, item_name)
1197 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1198 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1200 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1204 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1205 &self.inh.infcx.parameter_environment
1208 pub fn sess(&self) -> &Session {
1212 pub fn err_count_since_creation(&self) -> usize {
1213 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1216 /// Resolves type variables in `ty` if possible. Unlike the infcx
1217 /// version, this version will also select obligations if it seems
1218 /// useful, in an effort to get more type information.
1219 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1220 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1222 // No TyInfer()? Nothing needs doing.
1223 if !ty.has_infer_types() {
1224 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1228 // If `ty` is a type variable, see whether we already know what it is.
1229 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1230 if !ty.has_infer_types() {
1231 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1235 // If not, try resolving any new fcx obligations that have cropped up.
1236 self.select_new_obligations();
1237 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1238 if !ty.has_infer_types() {
1239 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1243 // If not, try resolving *all* pending obligations as much as
1244 // possible. This can help substantially when there are
1245 // indirect dependencies that don't seem worth tracking
1247 self.select_obligations_where_possible();
1248 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1250 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1254 fn record_deferred_call_resolution(&self,
1255 closure_def_id: DefId,
1256 r: DeferredCallResolutionHandler<'tcx>) {
1257 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1258 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1261 fn remove_deferred_call_resolutions(&self,
1262 closure_def_id: DefId)
1263 -> Vec<DeferredCallResolutionHandler<'tcx>>
1265 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1266 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1269 pub fn tag(&self) -> String {
1270 let self_ptr: *const FnCtxt = self;
1271 format!("{:?}", self_ptr)
1274 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1275 match self.inh.locals.borrow().get(&nid) {
1278 span_err!(self.tcx().sess, span, E0513,
1279 "no type for local variable {}",
1281 self.tcx().types.err
1287 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1288 debug!("write_ty({}, {:?}) in fcx {}",
1289 node_id, ty, self.tag());
1290 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1293 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1294 if !substs.substs.is_noop() {
1295 debug!("write_substs({}, {:?}) in fcx {}",
1300 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1304 pub fn write_autoderef_adjustment(&self,
1305 node_id: ast::NodeId,
1307 self.write_adjustment(
1309 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1317 pub fn write_adjustment(&self,
1318 node_id: ast::NodeId,
1319 adj: adjustment::AutoAdjustment<'tcx>) {
1320 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1322 if adj.is_identity() {
1326 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1329 /// Basically whenever we are converting from a type scheme into
1330 /// the fn body space, we always want to normalize associated
1331 /// types as well. This function combines the two.
1332 fn instantiate_type_scheme<T>(&self,
1334 substs: &Substs<'tcx>,
1337 where T : TypeFoldable<'tcx> + HasTypeFlags
1339 let value = value.subst(self.tcx(), substs);
1340 let result = self.normalize_associated_types_in(span, &value);
1341 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1348 /// As `instantiate_type_scheme`, but for the bounds found in a
1349 /// generic type scheme.
1350 fn instantiate_bounds(&self,
1352 substs: &Substs<'tcx>,
1353 bounds: &ty::GenericPredicates<'tcx>)
1354 -> ty::InstantiatedPredicates<'tcx>
1356 ty::InstantiatedPredicates {
1357 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1362 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1363 where T : TypeFoldable<'tcx> + HasTypeFlags
1365 self.inh.normalize_associated_types_in(span, self.body_id, value)
1368 fn normalize_associated_type(&self,
1370 trait_ref: ty::TraitRef<'tcx>,
1371 item_name: ast::Name)
1374 let cause = traits::ObligationCause::new(span,
1376 traits::ObligationCauseCode::MiscObligation);
1381 .normalize_projection_type(self.infcx(),
1383 trait_ref: trait_ref,
1384 item_name: item_name,
1389 /// Instantiates the type in `did` with the generics in `path` and returns
1390 /// it (registering the necessary trait obligations along the way).
1392 /// Note that this function is only intended to be used with type-paths,
1393 /// not with value-paths.
1394 pub fn instantiate_type(&self,
1399 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1401 self.tcx().lookup_item_type(did);
1402 let type_predicates =
1403 self.tcx().lookup_predicates(did);
1404 let substs = astconv::ast_path_substs_for_ty(self, self,
1406 PathParamMode::Optional,
1407 &type_scheme.generics,
1408 path.segments.last().unwrap());
1409 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1411 self.instantiate_bounds(path.span, &substs, &type_predicates);
1412 self.add_obligations_for_parameters(
1413 traits::ObligationCause::new(
1416 traits::ItemObligation(did)),
1419 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1422 /// Return the dict-like variant corresponding to a given `Def`.
1423 pub fn def_struct_variant(&self,
1426 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1428 let (adt, variant) = match def {
1429 def::DefVariant(enum_id, variant_id, _) => {
1430 let adt = self.tcx().lookup_adt_def(enum_id);
1431 (adt, adt.variant_with_id(variant_id))
1433 def::DefTy(did, _) | def::DefStruct(did) => {
1434 let typ = self.tcx().lookup_item_type(did);
1435 if let ty::TyStruct(adt, _) = typ.ty.sty {
1436 (adt, adt.struct_variant())
1444 let var_kind = variant.kind();
1445 if var_kind == ty::VariantKind::Struct {
1446 Some((adt, variant))
1447 } else if var_kind == ty::VariantKind::Unit {
1448 if !self.tcx().sess.features.borrow().braced_empty_structs {
1449 let mut err = self.tcx().sess.struct_span_err(span,
1450 "empty structs and enum variants \
1451 with braces are unstable");
1452 fileline_help!(&mut err, span, "add #![feature(braced_empty_structs)] to \
1453 the crate features to enable");
1457 Some((adt, variant))
1463 pub fn write_nil(&self, node_id: ast::NodeId) {
1464 self.write_ty(node_id, self.tcx().mk_nil());
1466 pub fn write_error(&self, node_id: ast::NodeId) {
1467 self.write_ty(node_id, self.tcx().types.err);
1470 pub fn require_type_meets(&self,
1473 code: traits::ObligationCauseCode<'tcx>,
1474 bound: ty::BuiltinBound)
1476 self.register_builtin_bound(
1479 traits::ObligationCause::new(span, self.body_id, code));
1482 pub fn require_type_is_sized(&self,
1485 code: traits::ObligationCauseCode<'tcx>)
1487 self.require_type_meets(ty, span, code, ty::BoundSized);
1490 pub fn require_expr_have_sized_type(&self,
1492 code: traits::ObligationCauseCode<'tcx>)
1494 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1497 pub fn type_is_known_to_be_sized(&self,
1502 traits::type_known_to_meet_builtin_bound(self.infcx(),
1508 pub fn register_builtin_bound(&self,
1510 builtin_bound: ty::BuiltinBound,
1511 cause: traits::ObligationCause<'tcx>)
1513 self.inh.infcx.fulfillment_cx.borrow_mut()
1514 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1517 pub fn register_predicate(&self,
1518 obligation: traits::PredicateObligation<'tcx>)
1520 debug!("register_predicate({:?})",
1522 self.inh.infcx.fulfillment_cx
1524 .register_predicate_obligation(self.infcx(), obligation);
1527 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1528 let t = ast_ty_to_ty(self, self, ast_t);
1529 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1533 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1534 match self.inh.tables.borrow().node_types.get(&ex.id) {
1537 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1543 /// Apply `adjustment` to the type of `expr`
1544 pub fn adjust_expr_ty(&self,
1546 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1549 let raw_ty = self.expr_ty(expr);
1550 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1551 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1552 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1553 self.inh.tables.borrow().method_map.get(&method_call)
1554 .map(|method| resolve_ty(method.ty))
1558 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1559 match self.inh.tables.borrow().node_types.get(&id) {
1561 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1563 self.tcx().sess.bug(
1564 &format!("no type for node {}: {} in fcx {}",
1565 id, self.tcx().map.node_to_string(id),
1571 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1572 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1573 // it changes when we upgrade the snapshot compiler
1574 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1575 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1579 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1582 pub fn opt_node_ty_substs<F>(&self,
1585 F: FnOnce(&ty::ItemSubsts<'tcx>),
1587 match self.inh.tables.borrow().item_substs.get(&id) {
1593 pub fn mk_subty(&self,
1594 a_is_expected: bool,
1598 -> Result<(), TypeError<'tcx>> {
1599 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1602 pub fn mk_eqty(&self,
1603 a_is_expected: bool,
1607 -> Result<(), TypeError<'tcx>> {
1608 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1611 pub fn mk_subr(&self,
1612 origin: infer::SubregionOrigin<'tcx>,
1615 infer::mk_subr(self.infcx(), origin, sub, sup)
1618 pub fn type_error_message<M>(&self,
1621 actual_ty: Ty<'tcx>,
1622 err: Option<&TypeError<'tcx>>)
1623 where M: FnOnce(String) -> String,
1625 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1628 pub fn type_error_struct<M>(&self,
1631 actual_ty: Ty<'tcx>,
1632 err: Option<&TypeError<'tcx>>)
1633 -> DiagnosticBuilder<'tcx>
1634 where M: FnOnce(String) -> String,
1636 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1639 pub fn report_mismatched_types(&self,
1643 err: &TypeError<'tcx>) {
1644 self.infcx().report_mismatched_types(sp, e, a, err)
1647 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1648 /// outlive the region `r`.
1649 pub fn register_region_obligation(&self,
1652 cause: traits::ObligationCause<'tcx>)
1654 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1655 fulfillment_cx.register_region_obligation(ty, region, cause);
1658 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1659 /// outlive the region `r`.
1660 pub fn register_wf_obligation(&self,
1663 code: traits::ObligationCauseCode<'tcx>)
1665 // WF obligations never themselves fail, so no real need to give a detailed cause:
1666 let cause = traits::ObligationCause::new(span, self.body_id, code);
1667 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1670 pub fn register_old_wf_obligation(&self,
1673 code: traits::ObligationCauseCode<'tcx>)
1675 // Registers an "old-style" WF obligation that uses the
1676 // implicator code. This is basically a buggy version of
1677 // `register_wf_obligation` that is being kept around
1678 // temporarily just to help with phasing in the newer rules.
1680 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1681 let cause = traits::ObligationCause::new(span, self.body_id, code);
1682 self.register_region_obligation(ty, ty::ReEmpty, cause);
1685 /// Registers obligations that all types appearing in `substs` are well-formed.
1686 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1688 for &ty in &substs.types {
1689 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1693 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1694 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1695 /// trait/region obligations.
1697 /// For example, if there is a function:
1700 /// fn foo<'a,T:'a>(...)
1703 /// and a reference:
1709 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1710 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1711 pub fn add_obligations_for_parameters(&self,
1712 cause: traits::ObligationCause<'tcx>,
1713 predicates: &ty::InstantiatedPredicates<'tcx>)
1715 assert!(!predicates.has_escaping_regions());
1717 debug!("add_obligations_for_parameters(predicates={:?})",
1720 for obligation in traits::predicates_for_generics(cause, predicates) {
1721 self.register_predicate(obligation);
1725 // FIXME(arielb1): use this instead of field.ty everywhere
1726 pub fn field_ty(&self,
1728 field: ty::FieldDef<'tcx>,
1729 substs: &Substs<'tcx>)
1732 self.normalize_associated_types_in(span,
1733 &field.ty(self.tcx(), substs))
1736 // Only for fields! Returns <none> for methods>
1737 // Indifferent to privacy flags
1738 fn check_casts(&self) {
1739 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1740 for cast in deferred_cast_checks.drain(..) {
1745 /// Apply "fallbacks" to some types
1746 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1747 fn default_type_parameters(&self) {
1748 use middle::ty::error::UnconstrainedNumeric::Neither;
1749 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1750 for ty in &self.infcx().unsolved_variables() {
1751 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1752 if self.infcx().type_var_diverges(resolved) {
1753 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1755 match self.infcx().type_is_unconstrained_numeric(resolved) {
1756 UnconstrainedInt => {
1757 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1759 UnconstrainedFloat => {
1760 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1768 fn select_all_obligations_and_apply_defaults(&self) {
1769 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1770 self.new_select_all_obligations_and_apply_defaults();
1772 self.old_select_all_obligations_and_apply_defaults();
1776 // Implements old type inference fallback algorithm
1777 fn old_select_all_obligations_and_apply_defaults(&self) {
1778 self.select_obligations_where_possible();
1779 self.default_type_parameters();
1780 self.select_obligations_where_possible();
1783 fn new_select_all_obligations_and_apply_defaults(&self) {
1784 use middle::ty::error::UnconstrainedNumeric::Neither;
1785 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1787 // For the time being this errs on the side of being memory wasteful but provides better
1789 // let type_variables = self.infcx().type_variables.clone();
1791 // There is a possibility that this algorithm will have to run an arbitrary number of times
1792 // to terminate so we bound it by the compiler's recursion limit.
1793 for _ in 0..self.tcx().sess.recursion_limit.get() {
1794 // First we try to solve all obligations, it is possible that the last iteration
1795 // has made it possible to make more progress.
1796 self.select_obligations_where_possible();
1798 let mut conflicts = Vec::new();
1800 // Collect all unsolved type, integral and floating point variables.
1801 let unsolved_variables = self.inh.infcx.unsolved_variables();
1803 // We must collect the defaults *before* we do any unification. Because we have
1804 // directly attached defaults to the type variables any unification that occurs
1805 // will erase defaults causing conflicting defaults to be completely ignored.
1806 let default_map: FnvHashMap<_, _> =
1809 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1812 let mut unbound_tyvars = HashSet::new();
1814 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1816 // We loop over the unsolved variables, resolving them and if they are
1817 // and unconstrainted numberic type we add them to the set of unbound
1818 // variables. We do this so we only apply literal fallback to type
1819 // variables without defaults.
1820 for ty in &unsolved_variables {
1821 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1822 if self.infcx().type_var_diverges(resolved) {
1823 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1825 match self.infcx().type_is_unconstrained_numeric(resolved) {
1826 UnconstrainedInt | UnconstrainedFloat => {
1827 unbound_tyvars.insert(resolved);
1834 // We now remove any numeric types that also have defaults, and instead insert
1835 // the type variable with a defined fallback.
1836 for ty in &unsolved_variables {
1837 if let Some(_default) = default_map.get(ty) {
1838 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1840 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1843 match resolved.sty {
1844 ty::TyInfer(ty::TyVar(_)) => {
1845 unbound_tyvars.insert(ty);
1848 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1849 unbound_tyvars.insert(ty);
1850 if unbound_tyvars.contains(resolved) {
1851 unbound_tyvars.remove(resolved);
1860 // If there are no more fallbacks to apply at this point we have applied all possible
1861 // defaults and type inference will proceed as normal.
1862 if unbound_tyvars.is_empty() {
1866 // Finally we go through each of the unbound type variables and unify them with
1867 // the proper fallback, reporting a conflicting default error if any of the
1868 // unifications fail. We know it must be a conflicting default because the
1869 // variable would only be in `unbound_tyvars` and have a concrete value if
1870 // it had been solved by previously applying a default.
1872 // We wrap this in a transaction for error reporting, if we detect a conflict
1873 // we will rollback the inference context to its prior state so we can probe
1874 // for conflicts and correctly report them.
1877 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1878 for ty in &unbound_tyvars {
1879 if self.infcx().type_var_diverges(ty) {
1880 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1882 match self.infcx().type_is_unconstrained_numeric(ty) {
1883 UnconstrainedInt => {
1884 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1886 UnconstrainedFloat => {
1887 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1890 if let Some(default) = default_map.get(ty) {
1891 let default = default.clone();
1892 match infer::mk_eqty(self.infcx(), false,
1893 TypeOrigin::Misc(default.origin_span),
1897 conflicts.push((*ty, default));
1906 // If there are conflicts we rollback, otherwise commit
1907 if conflicts.len() > 0 {
1914 if conflicts.len() > 0 {
1915 // Loop through each conflicting default, figuring out the default that caused
1916 // a unification failure and then report an error for each.
1917 for (conflict, default) in conflicts {
1918 let conflicting_default =
1919 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1920 .unwrap_or(type_variable::Default {
1921 ty: self.infcx().next_ty_var(),
1922 origin_span: codemap::DUMMY_SP,
1923 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1926 // This is to ensure that we elimnate any non-determinism from the error
1927 // reporting by fixing an order, it doesn't matter what order we choose
1928 // just that it is consistent.
1929 let (first_default, second_default) =
1930 if default.def_id < conflicting_default.def_id {
1931 (default, conflicting_default)
1933 (conflicting_default, default)
1937 self.infcx().report_conflicting_default_types(
1938 first_default.origin_span,
1945 self.select_obligations_where_possible();
1948 // For use in error handling related to default type parameter fallback. We explicitly
1949 // apply the default that caused conflict first to a local version of the type variable
1950 // table then apply defaults until we find a conflict. That default must be the one
1951 // that caused conflict earlier.
1952 fn find_conflicting_default(&self,
1953 unbound_vars: &HashSet<Ty<'tcx>>,
1954 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1956 -> Option<type_variable::Default<'tcx>> {
1957 use middle::ty::error::UnconstrainedNumeric::Neither;
1958 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1960 // Ensure that we apply the conflicting default first
1961 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1962 unbound_tyvars.push(conflict);
1963 unbound_tyvars.extend(unbound_vars.iter());
1965 let mut result = None;
1966 // We run the same code as above applying defaults in order, this time when
1967 // we find the conflict we just return it for error reporting above.
1969 // We also run this inside snapshot that never commits so we can do error
1970 // reporting for more then one conflict.
1971 for ty in &unbound_tyvars {
1972 if self.infcx().type_var_diverges(ty) {
1973 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1975 match self.infcx().type_is_unconstrained_numeric(ty) {
1976 UnconstrainedInt => {
1977 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1979 UnconstrainedFloat => {
1980 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1983 if let Some(default) = default_map.get(ty) {
1984 let default = default.clone();
1985 match infer::mk_eqty(self.infcx(), false,
1986 TypeOrigin::Misc(default.origin_span),
1990 result = Some(default);
2002 fn select_all_obligations_or_error(&self) {
2003 debug!("select_all_obligations_or_error");
2005 // upvar inference should have ensured that all deferred call
2006 // resolutions are handled by now.
2007 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2009 self.select_all_obligations_and_apply_defaults();
2011 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2012 match fulfillment_cx.select_all_or_error(self.infcx()) {
2014 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2018 /// Select as many obligations as we can at present.
2019 fn select_obligations_where_possible(&self) {
2021 self.inh.infcx.fulfillment_cx
2023 .select_where_possible(self.infcx())
2026 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2030 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2031 /// to improve inference. You could just call
2032 /// `select_obligations_where_possible` except that it leads to repeated
2034 fn select_new_obligations(&self) {
2036 self.inh.infcx.fulfillment_cx
2038 .select_new_obligations(self.infcx())
2041 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2047 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2048 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2049 Some(self.base_object_lifetime_default(span))
2052 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2053 // RFC #599 specifies that object lifetime defaults take
2054 // precedence over other defaults. But within a fn body we
2055 // don't have a *default* region, rather we use inference to
2056 // find the *correct* region, which is strictly more general
2057 // (and anyway, within a fn body the right region may not even
2058 // be something the user can write explicitly, since it might
2059 // be some expression).
2060 self.infcx().next_region_var(infer::MiscVariable(span))
2063 fn anon_regions(&self, span: Span, count: usize)
2064 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2065 Ok((0..count).map(|_| {
2066 self.infcx().next_region_var(infer::MiscVariable(span))
2071 /// Whether `autoderef` requires types to resolve.
2072 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2073 pub enum UnresolvedTypeAction {
2074 /// Produce an error and return `TyError` whenever a type cannot
2075 /// be resolved (i.e. it is `TyInfer`).
2077 /// Go on without emitting any errors, and return the unresolved
2078 /// type. Useful for probing, e.g. in coercions.
2082 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2083 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2085 /// Note: this method does not modify the adjustments table. The caller is responsible for
2086 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2087 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2090 opt_expr: Option<&hir::Expr>,
2091 unresolved_type_action: UnresolvedTypeAction,
2092 mut lvalue_pref: LvaluePreference,
2094 -> (Ty<'tcx>, usize, Option<T>)
2095 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2097 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2102 let mut t = base_ty;
2103 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2104 let resolved_t = match unresolved_type_action {
2105 UnresolvedTypeAction::Error => {
2106 structurally_resolved_type(fcx, sp, t)
2108 UnresolvedTypeAction::Ignore => {
2109 // We can continue even when the type cannot be resolved
2110 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2111 // and `try_overloaded_deref` both simply return `None`
2112 // in such a case without producing spurious errors.
2113 fcx.resolve_type_vars_if_possible(t)
2116 if resolved_t.references_error() {
2117 return (resolved_t, autoderefs, None);
2120 match should_stop(resolved_t, autoderefs) {
2121 Some(x) => return (resolved_t, autoderefs, Some(x)),
2125 // Otherwise, deref if type is derefable:
2126 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2127 Some(mt) => Some(mt),
2130 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2132 // Super subtle: it might seem as though we should
2133 // pass `opt_expr` to `try_overloaded_deref`, so that
2134 // the (implicit) autoref of using an overloaded deref
2135 // would get added to the adjustment table. However we
2136 // do not do that, because it's kind of a
2137 // "meta-adjustment" -- instead, we just leave it
2138 // unrecorded and know that there "will be" an
2139 // autoref. regionck and other bits of the code base,
2140 // when they encounter an overloaded autoderef, have
2141 // to do some reconstructive surgery. This is a pretty
2142 // complex mess that is begging for a proper MIR.
2143 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2149 if mt.mutbl == hir::MutImmutable {
2150 lvalue_pref = NoPreference;
2153 None => return (resolved_t, autoderefs, None)
2157 // We've reached the recursion limit, error gracefully.
2158 span_err!(fcx.tcx().sess, sp, E0055,
2159 "reached the recursion limit while auto-dereferencing {:?}",
2161 (fcx.tcx().types.err, 0, None)
2164 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2166 method_call: Option<MethodCall>,
2167 base_expr: Option<&hir::Expr>,
2169 lvalue_pref: LvaluePreference)
2170 -> Option<ty::TypeAndMut<'tcx>>
2172 // Try DerefMut first, if preferred.
2173 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2174 (PreferMutLvalue, Some(trait_did)) => {
2175 method::lookup_in_trait(fcx, span, base_expr,
2176 token::intern("deref_mut"), trait_did,
2182 // Otherwise, fall back to Deref.
2183 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2184 (None, Some(trait_did)) => {
2185 method::lookup_in_trait(fcx, span, base_expr,
2186 token::intern("deref"), trait_did,
2189 (method, _) => method
2192 make_overloaded_lvalue_return_type(fcx, method_call, method)
2195 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2196 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2197 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2198 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2199 method_call: Option<MethodCall>,
2200 method: Option<MethodCallee<'tcx>>)
2201 -> Option<ty::TypeAndMut<'tcx>>
2205 // extract method return type, which will be &T;
2206 // all LB regions should have been instantiated during method lookup
2207 let ret_ty = method.ty.fn_ret();
2208 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2210 if let Some(method_call) = method_call {
2211 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2214 // method returns &T, but the type as visible to user is T, so deref
2215 ret_ty.builtin_deref(true, NoPreference)
2221 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2223 base_expr: &'tcx hir::Expr,
2226 lvalue_pref: LvaluePreference)
2227 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2229 // FIXME(#18741) -- this is almost but not quite the same as the
2230 // autoderef that normal method probing does. They could likely be
2233 let (ty, autoderefs, final_mt) = autoderef(fcx,
2237 UnresolvedTypeAction::Error,
2240 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2241 adj_ty, idx, false, lvalue_pref, idx_ty)
2244 if final_mt.is_some() {
2248 // After we have fully autoderef'd, if the resulting type is [T; n], then
2249 // do a final unsized coercion to yield [T].
2250 if let ty::TyArray(element_ty, _) = ty.sty {
2251 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2252 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2253 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2259 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2260 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2261 /// This loop implements one step in that search; the autoderef loop is implemented by
2262 /// `lookup_indexing`.
2263 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2264 method_call: MethodCall,
2266 base_expr: &'tcx hir::Expr,
2267 adjusted_ty: Ty<'tcx>,
2270 lvalue_pref: LvaluePreference,
2272 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2274 let tcx = fcx.tcx();
2275 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2276 autoderefs={}, unsize={}, index_ty={:?})",
2284 let input_ty = fcx.infcx().next_ty_var();
2286 // First, try built-in indexing.
2287 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2288 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2289 debug!("try_index_step: success, using built-in indexing");
2290 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2292 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2293 return Some((tcx.types.usize, ty));
2298 // Try `IndexMut` first, if preferred.
2299 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2300 (PreferMutLvalue, Some(trait_did)) => {
2301 method::lookup_in_trait_adjusted(fcx,
2304 token::intern("index_mut"),
2309 Some(vec![input_ty]))
2314 // Otherwise, fall back to `Index`.
2315 let method = match (method, tcx.lang_items.index_trait()) {
2316 (None, Some(trait_did)) => {
2317 method::lookup_in_trait_adjusted(fcx,
2320 token::intern("index"),
2325 Some(vec![input_ty]))
2327 (method, _) => method,
2330 // If some lookup succeeds, write callee into table and extract index/element
2331 // type from the method signature.
2332 // If some lookup succeeded, install method in table
2333 method.and_then(|method| {
2334 debug!("try_index_step: success, using overloaded indexing");
2335 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2336 map(|ret| (input_ty, ret.ty))
2340 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2342 method_fn_ty: Ty<'tcx>,
2343 callee_expr: &'tcx hir::Expr,
2344 args_no_rcvr: &'tcx [P<hir::Expr>],
2345 tuple_arguments: TupleArgumentsFlag,
2346 expected: Expectation<'tcx>)
2347 -> ty::FnOutput<'tcx> {
2348 if method_fn_ty.references_error() {
2349 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2351 let err_inputs = match tuple_arguments {
2352 DontTupleArguments => err_inputs,
2353 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2356 check_argument_types(fcx,
2363 ty::FnConverging(fcx.tcx().types.err)
2365 match method_fn_ty.sty {
2366 ty::TyBareFn(_, ref fty) => {
2367 // HACK(eddyb) ignore self in the definition (see above).
2368 let expected_arg_tys = expected_types_for_fn_args(fcx,
2372 &fty.sig.0.inputs[1..]);
2373 check_argument_types(fcx,
2375 &fty.sig.0.inputs[1..],
2376 &expected_arg_tys[..],
2383 fcx.tcx().sess.span_bug(callee_expr.span,
2384 "method without bare fn type");
2390 /// Generic function that factors out common logic from function calls, method calls and overloaded
2392 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2394 fn_inputs: &[Ty<'tcx>],
2395 expected_arg_tys: &[Ty<'tcx>],
2396 args: &'tcx [P<hir::Expr>],
2398 tuple_arguments: TupleArgumentsFlag) {
2399 let tcx = fcx.ccx.tcx;
2401 // Grab the argument types, supplying fresh type variables
2402 // if the wrong number of arguments were supplied
2403 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2409 // All the input types from the fn signature must outlive the call
2410 // so as to validate implied bounds.
2411 for &fn_input_ty in fn_inputs {
2412 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2415 let mut expected_arg_tys = expected_arg_tys;
2416 let expected_arg_count = fn_inputs.len();
2417 let formal_tys = if tuple_arguments == TupleArguments {
2418 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2419 match tuple_type.sty {
2420 ty::TyTuple(ref arg_types) => {
2421 if arg_types.len() != args.len() {
2422 span_err!(tcx.sess, sp, E0057,
2423 "this function takes {} parameter{} but {} parameter{} supplied",
2425 if arg_types.len() == 1 {""} else {"s"},
2427 if args.len() == 1 {" was"} else {"s were"});
2428 expected_arg_tys = &[];
2429 err_args(fcx.tcx(), args.len())
2431 expected_arg_tys = match expected_arg_tys.get(0) {
2432 Some(&ty) => match ty.sty {
2433 ty::TyTuple(ref tys) => &**tys,
2438 (*arg_types).clone()
2442 span_err!(tcx.sess, sp, E0059,
2443 "cannot use call notation; the first type parameter \
2444 for the function trait is neither a tuple nor unit");
2445 expected_arg_tys = &[];
2446 err_args(fcx.tcx(), args.len())
2449 } else if expected_arg_count == supplied_arg_count {
2451 } else if variadic {
2452 if supplied_arg_count >= expected_arg_count {
2455 span_err!(tcx.sess, sp, E0060,
2456 "this function takes at least {} parameter{} \
2457 but {} parameter{} supplied",
2459 if expected_arg_count == 1 {""} else {"s"},
2461 if supplied_arg_count == 1 {" was"} else {"s were"});
2462 expected_arg_tys = &[];
2463 err_args(fcx.tcx(), supplied_arg_count)
2466 span_err!(tcx.sess, sp, E0061,
2467 "this function takes {} parameter{} but {} parameter{} supplied",
2469 if expected_arg_count == 1 {""} else {"s"},
2471 if supplied_arg_count == 1 {" was"} else {"s were"});
2472 expected_arg_tys = &[];
2473 err_args(fcx.tcx(), supplied_arg_count)
2476 debug!("check_argument_types: formal_tys={:?}",
2477 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2479 // Check the arguments.
2480 // We do this in a pretty awful way: first we typecheck any arguments
2481 // that are not anonymous functions, then we typecheck the anonymous
2482 // functions. This is so that we have more information about the types
2483 // of arguments when we typecheck the functions. This isn't really the
2484 // right way to do this.
2485 let xs = [false, true];
2486 let mut any_diverges = false; // has any of the arguments diverged?
2487 let mut warned = false; // have we already warned about unreachable code?
2488 for check_blocks in &xs {
2489 let check_blocks = *check_blocks;
2490 debug!("check_blocks={}", check_blocks);
2492 // More awful hacks: before we check argument types, try to do
2493 // an "opportunistic" vtable resolution of any trait bounds on
2494 // the call. This helps coercions.
2496 fcx.select_new_obligations();
2499 // For variadic functions, we don't have a declared type for all of
2500 // the arguments hence we only do our usual type checking with
2501 // the arguments who's types we do know.
2502 let t = if variadic {
2504 } else if tuple_arguments == TupleArguments {
2509 for (i, arg) in args.iter().take(t).enumerate() {
2510 if any_diverges && !warned {
2514 .add_lint(lint::builtin::UNREACHABLE_CODE,
2517 "unreachable expression".to_string());
2520 let is_block = match arg.node {
2521 hir::ExprClosure(..) => true,
2525 if is_block == check_blocks {
2526 debug!("checking the argument");
2527 let formal_ty = formal_tys[i];
2529 // The special-cased logic below has three functions:
2530 // 1. Provide as good of an expected type as possible.
2531 let expected = expected_arg_tys.get(i).map(|&ty| {
2532 Expectation::rvalue_hint(fcx.tcx(), ty)
2535 check_expr_with_unifier(fcx,
2537 expected.unwrap_or(ExpectHasType(formal_ty)),
2539 // 2. Coerce to the most detailed type that could be coerced
2540 // to, which is `expected_ty` if `rvalue_hint` returns an
2541 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2542 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2543 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2545 // 3. Relate the expected type and the formal one,
2546 // if the expected type was used for the coercion.
2547 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2551 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2552 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2555 if any_diverges && !warned {
2556 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2560 .add_lint(lint::builtin::UNREACHABLE_CODE,
2563 "unreachable call".to_string());
2569 // We also need to make sure we at least write the ty of the other
2570 // arguments which we skipped above.
2572 for arg in args.iter().skip(expected_arg_count) {
2573 check_expr(fcx, &**arg);
2575 // There are a few types which get autopromoted when passed via varargs
2576 // in C but we just error out instead and require explicit casts.
2577 let arg_ty = structurally_resolved_type(fcx, arg.span,
2578 fcx.expr_ty(&**arg));
2580 ty::TyFloat(ast::TyF32) => {
2581 fcx.type_error_message(arg.span,
2583 format!("can't pass an {} to variadic \
2584 function, cast to c_double", t)
2587 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2588 fcx.type_error_message(arg.span, |t| {
2589 format!("can't pass {} to variadic \
2590 function, cast to c_int",
2594 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2595 fcx.type_error_message(arg.span, |t| {
2596 format!("can't pass {} to variadic \
2597 function, cast to c_uint",
2607 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2608 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2609 (0..len).map(|_| tcx.types.err).collect()
2612 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2613 call_expr: &hir::Expr,
2614 output: ty::FnOutput<'tcx>) {
2615 fcx.write_ty(call_expr.id, match output {
2616 ty::FnConverging(output_ty) => output_ty,
2617 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2621 // AST fragment checking
2622 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2624 expected: Expectation<'tcx>)
2627 let tcx = fcx.ccx.tcx;
2630 ast::LitStr(..) => tcx.mk_static_str(),
2631 ast::LitByteStr(ref v) => {
2632 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2633 tcx.mk_array(tcx.types.u8, v.len()))
2635 ast::LitByte(_) => tcx.types.u8,
2636 ast::LitChar(_) => tcx.types.char,
2637 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2638 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2639 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2640 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2642 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2643 ty::TyChar => Some(tcx.types.u8),
2644 ty::TyRawPtr(..) => Some(tcx.types.usize),
2645 ty::TyBareFn(..) => Some(tcx.types.usize),
2649 opt_ty.unwrap_or_else(
2650 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2652 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2653 ast::LitFloatUnsuffixed(_) => {
2654 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2656 ty::TyFloat(_) => Some(ty),
2660 opt_ty.unwrap_or_else(
2661 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2663 ast::LitBool(_) => tcx.types.bool
2667 fn check_expr_eq_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::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2675 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2676 expr: &'tcx hir::Expr,
2677 expected: Ty<'tcx>) {
2678 check_expr_with_unifier(
2679 fcx, expr, ExpectHasType(expected), NoPreference,
2680 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2683 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2684 expr: &'tcx hir::Expr,
2685 expected: Ty<'tcx>) {
2686 check_expr_with_unifier(
2687 fcx, expr, ExpectHasType(expected), NoPreference,
2688 || demand::coerce(fcx, expr.span, expected, expr));
2691 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2692 expected: Ty<'tcx>) {
2693 check_expr_with_unifier(
2694 fcx, expr, ExpectHasType(expected), NoPreference,
2698 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2699 expr: &'tcx hir::Expr,
2700 expected: Expectation<'tcx>) {
2701 check_expr_with_unifier(
2702 fcx, expr, expected, NoPreference,
2706 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2707 expr: &'tcx hir::Expr,
2708 expected: Expectation<'tcx>,
2709 lvalue_pref: LvaluePreference)
2711 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2714 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2715 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2718 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2719 lvalue_pref: LvaluePreference) {
2720 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2723 // determine the `self` type, using fresh variables for all variables
2724 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2725 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2727 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2728 span: Span, // (potential) receiver for this impl
2730 -> TypeAndSubsts<'tcx> {
2731 let tcx = fcx.tcx();
2733 let ity = tcx.lookup_item_type(did);
2734 let (tps, rps, raw_ty) =
2735 (ity.generics.types.get_slice(subst::TypeSpace),
2736 ity.generics.regions.get_slice(subst::TypeSpace),
2739 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2741 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2742 let mut substs = subst::Substs::new(
2743 VecPerParamSpace::empty(),
2744 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2745 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2746 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2748 TypeAndSubsts { substs: substs, ty: substd_ty }
2751 /// Controls whether the arguments are tupled. This is used for the call
2754 /// Tupling means that all call-side arguments are packed into a tuple and
2755 /// passed as a single parameter. For example, if tupling is enabled, this
2758 /// fn f(x: (isize, isize))
2760 /// Can be called as:
2767 #[derive(Clone, Eq, PartialEq)]
2768 enum TupleArgumentsFlag {
2773 /// Unifies the return type with the expected type early, for more coercions
2774 /// and forward type information on the argument expressions.
2775 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2777 expected_ret: Expectation<'tcx>,
2778 formal_ret: ty::FnOutput<'tcx>,
2779 formal_args: &[Ty<'tcx>])
2781 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2782 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2783 fcx.infcx().commit_regions_if_ok(|| {
2784 // Attempt to apply a subtyping relationship between the formal
2785 // return type (likely containing type variables if the function
2786 // is polymorphic) and the expected return type.
2787 // No argument expectations are produced if unification fails.
2788 let origin = TypeOrigin::Misc(call_span);
2789 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2790 // FIXME(#15760) can't use try! here, FromError doesn't default
2791 // to identity so the resulting type is not constrained.
2792 if let Err(e) = ures {
2796 // Record all the argument types, with the substitutions
2797 // produced from the above subtyping unification.
2798 Ok(formal_args.iter().map(|ty| {
2799 fcx.infcx().resolve_type_vars_if_possible(ty)
2805 }).unwrap_or(vec![]);
2806 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2807 formal_args, formal_ret,
2808 expected_args, expected_ret);
2813 /// If an expression has any sub-expressions that result in a type error,
2814 /// inspecting that expression's type with `ty.references_error()` will return
2815 /// true. Likewise, if an expression is known to diverge, inspecting its
2816 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2817 /// strict, _|_ can appear in the type of an expression that does not,
2818 /// itself, diverge: for example, fn() -> _|_.)
2819 /// Note that inspecting a type's structure *directly* may expose the fact
2820 /// that there are actually multiple representations for `TyError`, so avoid
2821 /// that when err needs to be handled differently.
2822 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2823 expr: &'tcx hir::Expr,
2824 expected: Expectation<'tcx>,
2825 lvalue_pref: LvaluePreference,
2829 debug!(">> typechecking: expr={:?} expected={:?}",
2832 // Checks a method call.
2833 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2834 expr: &'tcx hir::Expr,
2835 method_name: Spanned<ast::Name>,
2836 args: &'tcx [P<hir::Expr>],
2838 expected: Expectation<'tcx>,
2839 lvalue_pref: LvaluePreference) {
2840 let rcvr = &*args[0];
2841 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2843 // no need to check for bot/err -- callee does that
2844 let expr_t = structurally_resolved_type(fcx,
2846 fcx.expr_ty(&*rcvr));
2848 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2849 let fn_ty = match method::lookup(fcx,
2857 let method_ty = method.ty;
2858 let method_call = MethodCall::expr(expr.id);
2859 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2863 method::report_error(fcx, method_name.span, expr_t,
2864 method_name.node, Some(rcvr), error);
2865 fcx.write_error(expr.id);
2870 // Call the generic checker.
2871 let ret_ty = check_method_argument_types(fcx,
2879 write_call(fcx, expr, ret_ty);
2882 // A generic function for checking the then and else in an if
2884 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2885 cond_expr: &'tcx hir::Expr,
2886 then_blk: &'tcx hir::Block,
2887 opt_else_expr: Option<&'tcx hir::Expr>,
2890 expected: Expectation<'tcx>) {
2891 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2893 let expected = expected.adjust_for_branches(fcx);
2894 check_block_with_expected(fcx, then_blk, expected);
2895 let then_ty = fcx.node_ty(then_blk.id);
2897 let branches_ty = match opt_else_expr {
2898 Some(ref else_expr) => {
2899 check_expr_with_expectation(fcx, &**else_expr, expected);
2900 let else_ty = fcx.expr_ty(&**else_expr);
2901 infer::common_supertype(fcx.infcx(),
2902 TypeOrigin::IfExpression(sp),
2908 infer::common_supertype(fcx.infcx(),
2909 TypeOrigin::IfExpressionWithNoElse(sp),
2916 let cond_ty = fcx.expr_ty(cond_expr);
2917 let if_ty = if cond_ty.references_error() {
2923 fcx.write_ty(id, if_ty);
2926 // Check field access expressions
2927 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2928 expr: &'tcx hir::Expr,
2929 lvalue_pref: LvaluePreference,
2930 base: &'tcx hir::Expr,
2931 field: &Spanned<ast::Name>) {
2932 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2933 let expr_t = structurally_resolved_type(fcx, expr.span,
2935 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2936 let (_, autoderefs, field_ty) = autoderef(fcx,
2940 UnresolvedTypeAction::Error,
2944 ty::TyStruct(base_def, substs) => {
2945 debug!("struct named {:?}", base_t);
2946 base_def.struct_variant()
2947 .find_field_named(field.node)
2948 .map(|f| fcx.field_ty(expr.span, f, substs))
2955 fcx.write_ty(expr.id, field_ty);
2956 fcx.write_autoderef_adjustment(base.id, autoderefs);
2962 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2963 fcx.type_error_struct(field.span,
2965 format!("attempted to take value of method `{}` on type \
2966 `{}`", field.node, actual)
2969 .fileline_help(field.span,
2970 "maybe a `()` to call it is missing? \
2971 If not, try an anonymous function")
2974 let mut err = fcx.type_error_struct(
2977 format!("attempted access of field `{}` on \
2978 type `{}`, but no field with that \
2984 if let ty::TyStruct(def, _) = expr_t.sty {
2985 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2990 fcx.write_error(expr.id);
2993 // displays hints about the closest matches in field names
2994 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2995 variant: ty::VariantDef<'tcx>,
2996 field: &Spanned<ast::Name>,
2997 skip : Vec<InternedString>) {
2998 let name = field.node.as_str();
2999 let names = variant.fields
3001 .filter_map(|ref field| {
3002 // ignore already set fields and private fields from non-local crates
3003 if skip.iter().any(|x| *x == field.name.as_str()) ||
3004 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3011 // only find fits with at least one matching letter
3012 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3013 err.span_help(field.span,
3014 &format!("did you mean `{}`?", name));
3018 // Check tuple index expressions
3019 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3020 expr: &'tcx hir::Expr,
3021 lvalue_pref: LvaluePreference,
3022 base: &'tcx hir::Expr,
3023 idx: codemap::Spanned<usize>) {
3024 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3025 let expr_t = structurally_resolved_type(fcx, expr.span,
3027 let mut tuple_like = false;
3028 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3029 let (_, autoderefs, field_ty) = autoderef(fcx,
3033 UnresolvedTypeAction::Error,
3037 ty::TyStruct(base_def, substs) => {
3038 tuple_like = base_def.struct_variant().is_tuple_struct();
3040 debug!("tuple struct named {:?}", base_t);
3041 base_def.struct_variant()
3044 .map(|f| fcx.field_ty(expr.span, f, substs))
3049 ty::TyTuple(ref v) => {
3051 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3058 fcx.write_ty(expr.id, field_ty);
3059 fcx.write_autoderef_adjustment(base.id, autoderefs);
3064 fcx.type_error_message(
3068 format!("attempted out-of-bounds tuple index `{}` on \
3073 format!("attempted tuple index `{}` on type `{}`, but the \
3074 type was not a tuple or tuple struct",
3081 fcx.write_error(expr.id);
3084 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3086 variant: ty::VariantDef<'tcx>,
3088 skip_fields: &[hir::Field]) {
3089 let mut err = fcx.type_error_struct(
3091 |actual| if let ty::TyEnum(..) = ty.sty {
3092 format!("struct variant `{}::{}` has no field named `{}`",
3093 actual, variant.name.as_str(), field.name.node)
3095 format!("structure `{}` has no field named `{}`",
3096 actual, field.name.node)
3100 // prevent all specified fields from being suggested
3101 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3102 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3106 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3109 variant: ty::VariantDef<'tcx>,
3110 ast_fields: &'tcx [hir::Field],
3111 check_completeness: bool) {
3112 let tcx = fcx.ccx.tcx;
3113 let substs = match adt_ty.sty {
3114 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3115 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3118 let mut remaining_fields = FnvHashMap();
3119 for field in &variant.fields {
3120 remaining_fields.insert(field.name, field);
3123 let mut error_happened = false;
3125 // Typecheck each field.
3126 for field in ast_fields {
3127 let expected_field_type;
3129 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3130 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3132 error_happened = true;
3133 expected_field_type = tcx.types.err;
3134 if let Some(_) = variant.find_field_named(field.name.node) {
3135 span_err!(fcx.tcx().sess, field.name.span, E0062,
3136 "field `{}` specified more than once",
3139 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3143 // Make sure to give a type to the field even if there's
3144 // an error, so we can continue typechecking
3145 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3148 // Make sure the programmer specified all the fields.
3149 if check_completeness &&
3151 !remaining_fields.is_empty()
3153 span_err!(tcx.sess, span, E0063,
3154 "missing field{} {} in initializer of `{}`",
3155 if remaining_fields.len() == 1 {""} else {"s"},
3156 remaining_fields.keys()
3157 .map(|n| format!("`{}`", n))
3158 .collect::<Vec<_>>()
3165 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3167 fields: &'tcx [hir::Field],
3168 base_expr: &'tcx Option<P<hir::Expr>>) {
3169 // Make sure to still write the types
3170 // otherwise we might ICE
3171 fcx.write_error(id);
3172 for field in fields {
3173 check_expr(fcx, &*field.expr);
3176 Some(ref base) => check_expr(fcx, &**base),
3181 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3184 fields: &'tcx [hir::Field],
3185 base_expr: &'tcx Option<P<hir::Expr>>)
3187 let tcx = fcx.tcx();
3189 // Find the relevant variant
3190 let def = lookup_full_def(tcx, path.span, expr.id);
3191 if def == def::DefErr {
3192 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3195 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3196 Some((adt, variant)) => (adt, variant),
3198 span_err!(fcx.tcx().sess, path.span, E0071,
3199 "`{}` does not name a structure",
3200 pprust::path_to_string(path));
3201 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3206 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3207 fcx.write_ty(expr.id, expr_ty);
3209 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3210 base_expr.is_none());
3212 if let &Some(ref base_expr) = base_expr {
3213 check_expr_has_type(fcx, base_expr, expr_ty);
3214 if adt.adt_kind() == ty::AdtKind::Enum {
3215 span_err!(tcx.sess, base_expr.span, E0436,
3216 "functional record update syntax requires a struct");
3221 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3223 let tcx = fcx.ccx.tcx;
3226 hir::ExprBox(ref subexpr) => {
3227 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3229 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3233 check_expr_with_expectation(fcx, subexpr, expected_inner);
3234 let referent_ty = fcx.expr_ty(&**subexpr);
3235 fcx.write_ty(id, tcx.mk_box(referent_ty));
3238 hir::ExprLit(ref lit) => {
3239 let typ = check_lit(fcx, &**lit, expected);
3240 fcx.write_ty(id, typ);
3242 hir::ExprBinary(op, ref lhs, ref rhs) => {
3243 op::check_binop(fcx, expr, op, lhs, rhs);
3245 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3246 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3248 hir::ExprUnary(unop, ref oprnd) => {
3249 let expected_inner = match unop {
3250 hir::UnNot | hir::UnNeg => {
3257 let lvalue_pref = match unop {
3258 hir::UnDeref => lvalue_pref,
3261 check_expr_with_expectation_and_lvalue_pref(
3262 fcx, &**oprnd, expected_inner, lvalue_pref);
3263 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3265 if !oprnd_t.references_error() {
3268 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3269 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3271 None => match try_overloaded_deref(fcx, expr.span,
3272 Some(MethodCall::expr(expr.id)),
3273 Some(&**oprnd), oprnd_t, lvalue_pref) {
3276 fcx.type_error_message(expr.span, |actual| {
3277 format!("type `{}` cannot be \
3278 dereferenced", actual)
3286 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3288 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3289 oprnd_t = op::check_user_unop(fcx, "!", "not",
3290 tcx.lang_items.not_trait(),
3291 expr, &**oprnd, oprnd_t, unop);
3295 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3297 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3298 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3299 tcx.lang_items.neg_trait(),
3300 expr, &**oprnd, oprnd_t, unop);
3305 fcx.write_ty(id, oprnd_t);
3307 hir::ExprAddrOf(mutbl, ref oprnd) => {
3308 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3310 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3311 if fcx.tcx().expr_is_lval(&**oprnd) {
3312 // Lvalues may legitimately have unsized types.
3313 // For example, dereferences of a fat pointer and
3314 // the last field of a struct can be unsized.
3315 ExpectHasType(mt.ty)
3317 Expectation::rvalue_hint(tcx, mt.ty)
3323 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3324 check_expr_with_expectation_and_lvalue_pref(fcx,
3329 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3330 let oprnd_t = if tm.ty.references_error() {
3333 // Note: at this point, we cannot say what the best lifetime
3334 // is to use for resulting pointer. We want to use the
3335 // shortest lifetime possible so as to avoid spurious borrowck
3336 // errors. Moreover, the longest lifetime will depend on the
3337 // precise details of the value whose address is being taken
3338 // (and how long it is valid), which we don't know yet until type
3339 // inference is complete.
3341 // Therefore, here we simply generate a region variable. The
3342 // region inferencer will then select the ultimate value.
3343 // Finally, borrowck is charged with guaranteeing that the
3344 // value whose address was taken can actually be made to live
3345 // as long as it needs to live.
3346 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3347 tcx.mk_ref(tcx.mk_region(region), tm)
3349 fcx.write_ty(id, oprnd_t);
3351 hir::ExprPath(ref maybe_qself, ref path) => {
3352 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3353 fcx.to_ty(&qself.ty)
3356 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3358 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3359 // Create some fake resolution that can't possibly be a type.
3360 def::PathResolution {
3361 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3362 last_private: LastMod(AllPublic),
3363 depth: path.segments.len()
3366 tcx.sess.span_bug(expr.span,
3367 &format!("unbound path {:?}", expr))
3370 if let Some((opt_ty, segments, def)) =
3371 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3372 expr.span, expr.id) {
3373 if def != def::DefErr {
3374 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3377 instantiate_path(fcx,
3386 fcx.write_ty(id, fcx.tcx().types.err);
3390 // We always require that the type provided as the value for
3391 // a type parameter outlives the moment of instantiation.
3392 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3393 fcx.add_wf_bounds(&item_substs.substs, expr);
3396 hir::ExprInlineAsm(ref ia) => {
3397 for &(_, ref input) in &ia.inputs {
3398 check_expr(fcx, &**input);
3400 for out in &ia.outputs {
3401 check_expr(fcx, &*out.expr);
3405 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3406 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3407 hir::ExprRet(ref expr_opt) => {
3409 ty::FnConverging(result_type) => {
3412 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3413 result_type, fcx.tcx().mk_nil()) {
3414 span_err!(tcx.sess, expr.span, E0069,
3415 "`return;` in a function whose return type is \
3419 check_expr_coercable_to_type(fcx, &**e, result_type);
3423 ty::FnDiverging => {
3424 if let Some(ref e) = *expr_opt {
3425 check_expr(fcx, &**e);
3427 span_err!(tcx.sess, expr.span, E0166,
3428 "`return` in a function declared as diverging");
3431 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3433 hir::ExprAssign(ref lhs, ref rhs) => {
3434 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3436 let tcx = fcx.tcx();
3437 if !tcx.expr_is_lval(&**lhs) {
3438 span_err!(tcx.sess, expr.span, E0070,
3439 "invalid left-hand side expression");
3442 let lhs_ty = fcx.expr_ty(&**lhs);
3443 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3444 let rhs_ty = fcx.expr_ty(&**rhs);
3446 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3448 if lhs_ty.references_error() || rhs_ty.references_error() {
3449 fcx.write_error(id);
3454 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3455 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3456 id, expr.span, expected);
3458 hir::ExprWhile(ref cond, ref body, _) => {
3459 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3460 check_block_no_value(fcx, &**body);
3461 let cond_ty = fcx.expr_ty(&**cond);
3462 let body_ty = fcx.node_ty(body.id);
3463 if cond_ty.references_error() || body_ty.references_error() {
3464 fcx.write_error(id);
3470 hir::ExprLoop(ref body, _) => {
3471 check_block_no_value(fcx, &**body);
3472 if !may_break(tcx, expr.id, &**body) {
3473 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3478 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3479 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3481 hir::ExprClosure(capture, ref decl, ref body) => {
3482 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3484 hir::ExprBlock(ref b) => {
3485 check_block_with_expected(fcx, &**b, expected);
3486 fcx.write_ty(id, fcx.node_ty(b.id));
3488 hir::ExprCall(ref callee, ref args) => {
3489 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3491 // we must check that return type of called functions is WF:
3492 let ret_ty = fcx.expr_ty(expr);
3493 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3495 hir::ExprMethodCall(name, ref tps, ref args) => {
3496 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3497 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3498 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3500 fcx.write_error(id);
3503 hir::ExprCast(ref e, ref t) => {
3504 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3505 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3508 // Find the type of `e`. Supply hints based on the type we are casting to,
3510 let t_cast = fcx.to_ty(t);
3511 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3512 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3513 let t_expr = fcx.expr_ty(e);
3515 // Eagerly check for some obvious errors.
3516 if t_expr.references_error() {
3517 fcx.write_error(id);
3518 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3519 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3521 // Write a type for the whole expression, assuming everything is going
3523 fcx.write_ty(id, t_cast);
3525 // Defer other checks until we're done type checking.
3526 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3527 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3528 deferred_cast_checks.push(cast_check);
3531 hir::ExprType(ref e, ref t) => {
3532 let typ = fcx.to_ty(&**t);
3533 check_expr_eq_type(fcx, &**e, typ);
3534 fcx.write_ty(id, typ);
3536 hir::ExprVec(ref args) => {
3537 let uty = expected.to_option(fcx).and_then(|uty| {
3539 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3544 let typ = match uty {
3547 check_expr_coercable_to_type(fcx, &**e, uty);
3552 let t: Ty = fcx.infcx().next_ty_var();
3554 check_expr_has_type(fcx, &**e, t);
3559 let typ = tcx.mk_array(typ, args.len());
3560 fcx.write_ty(id, typ);
3562 hir::ExprRepeat(ref element, ref count_expr) => {
3563 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3564 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3566 let uty = match expected {
3567 ExpectHasType(uty) => {
3569 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3576 let (element_ty, t) = match uty {
3578 check_expr_coercable_to_type(fcx, &**element, uty);
3582 let t: Ty = fcx.infcx().next_ty_var();
3583 check_expr_has_type(fcx, &**element, t);
3584 (fcx.expr_ty(&**element), t)
3589 // For [foo, ..n] where n > 1, `foo` must have
3591 fcx.require_type_meets(
3598 if element_ty.references_error() {
3599 fcx.write_error(id);
3601 let t = tcx.mk_array(t, count);
3602 fcx.write_ty(id, t);
3605 hir::ExprTup(ref elts) => {
3606 let flds = expected.only_has_type(fcx).and_then(|ty| {
3608 ty::TyTuple(ref flds) => Some(&flds[..]),
3612 let mut err_field = false;
3614 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3615 let t = match flds {
3616 Some(ref fs) if i < fs.len() => {
3618 check_expr_coercable_to_type(fcx, &**e, ety);
3622 check_expr_with_expectation(fcx, &**e, NoExpectation);
3626 err_field = err_field || t.references_error();
3630 fcx.write_error(id);
3632 let typ = tcx.mk_tup(elt_ts);
3633 fcx.write_ty(id, typ);
3636 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3637 check_expr_struct(fcx, expr, path, fields, base_expr);
3639 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3641 hir::ExprField(ref base, ref field) => {
3642 check_field(fcx, expr, lvalue_pref, &**base, field);
3644 hir::ExprTupField(ref base, idx) => {
3645 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3647 hir::ExprIndex(ref base, ref idx) => {
3648 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3649 check_expr(fcx, &**idx);
3651 let base_t = fcx.expr_ty(&**base);
3652 let idx_t = fcx.expr_ty(&**idx);
3654 if base_t.references_error() {
3655 fcx.write_ty(id, base_t);
3656 } else if idx_t.references_error() {
3657 fcx.write_ty(id, idx_t);
3659 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3660 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3661 Some((index_ty, element_ty)) => {
3662 let idx_expr_ty = fcx.expr_ty(idx);
3663 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3664 fcx.write_ty(id, element_ty);
3667 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3668 fcx.type_error_message(
3671 format!("cannot index a value of type `{}`",
3676 fcx.write_ty(id, fcx.tcx().types.err);
3681 hir::ExprRange(ref start, ref end) => {
3682 let t_start = start.as_ref().map(|e| {
3683 check_expr(fcx, &**e);
3686 let t_end = end.as_ref().map(|e| {
3687 check_expr(fcx, &**e);
3691 let idx_type = match (t_start, t_end) {
3692 (Some(ty), None) | (None, Some(ty)) => {
3695 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3696 t_end.references_error()) => {
3697 Some(fcx.tcx().types.err)
3699 (Some(t_start), Some(t_end)) => {
3700 Some(infer::common_supertype(fcx.infcx(),
3701 TypeOrigin::RangeExpression(expr.span),
3709 // Note that we don't check the type of start/end satisfy any
3710 // bounds because right now the range structs do not have any. If we add
3711 // some bounds, then we'll need to check `t_start` against them here.
3713 let range_type = match idx_type {
3714 Some(idx_type) if idx_type.references_error() => {
3718 // Find the did from the appropriate lang item.
3719 let did = match (start, end) {
3720 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3721 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3722 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3724 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3728 if let Some(did) = did {
3729 let def = tcx.lookup_adt_def(did);
3730 let predicates = tcx.lookup_predicates(did);
3731 let substs = Substs::new_type(vec![idx_type], vec![]);
3732 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3733 fcx.add_obligations_for_parameters(
3734 traits::ObligationCause::new(expr.span,
3736 traits::ItemObligation(did)),
3739 tcx.mk_struct(def, tcx.mk_substs(substs))
3741 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3746 // Neither start nor end => RangeFull
3747 if let Some(did) = tcx.lang_items.range_full_struct() {
3749 tcx.lookup_adt_def(did),
3750 tcx.mk_substs(Substs::empty())
3753 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3759 fcx.write_ty(id, range_type);
3764 debug!("type of expr({}) {} is...", expr.id,
3765 pprust::expr_to_string(expr));
3766 debug!("... {:?}, expected is {:?}",
3773 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3774 path_res: def::PathResolution,
3775 opt_self_ty: Option<Ty<'tcx>>,
3776 path: &'a hir::Path,
3778 node_id: ast::NodeId)
3779 -> Option<(Option<Ty<'tcx>>,
3780 &'a [hir::PathSegment],
3784 // Associated constants can't depend on generic types.
3785 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3789 node_id: ast::NodeId) -> bool {
3791 def::DefAssociatedConst(..) => {
3792 if ty.has_param_types() || ty.has_self_ty() {
3793 span_err!(fcx.sess(), span, E0329,
3794 "Associated consts cannot depend \
3795 on type parameters or Self.");
3796 fcx.write_error(node_id);
3805 // If fully resolved already, we don't have to do anything.
3806 if path_res.depth == 0 {
3807 if let Some(ty) = opt_self_ty {
3808 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3813 Some((opt_self_ty, &path.segments, path_res.base_def))
3815 let mut def = path_res.base_def;
3816 let ty_segments = path.segments.split_last().unwrap().1;
3817 let base_ty_end = path.segments.len() - path_res.depth;
3818 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3819 PathParamMode::Optional,
3822 &ty_segments[..base_ty_end],
3823 &ty_segments[base_ty_end..]);
3824 let item_segment = path.segments.last().unwrap();
3825 let item_name = item_segment.identifier.name;
3826 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3828 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3831 // Write back the new resolution.
3832 fcx.ccx.tcx.def_map.borrow_mut()
3833 .insert(node_id, def::PathResolution {
3835 last_private: path_res.last_private.or(lp),
3838 Some((Some(ty), slice::ref_slice(item_segment), def))
3841 method::report_error(fcx, span, ty,
3842 item_name, None, error);
3843 fcx.write_error(node_id);
3850 impl<'tcx> Expectation<'tcx> {
3851 /// Provide an expectation for an rvalue expression given an *optional*
3852 /// hint, which is not required for type safety (the resulting type might
3853 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3854 /// is useful in determining the concrete type.
3856 /// The primary use case is where the expected type is a fat pointer,
3857 /// like `&[isize]`. For example, consider the following statement:
3859 /// let x: &[isize] = &[1, 2, 3];
3861 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3862 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3863 /// expectation `ExpectHasType([isize])`, that would be too strong --
3864 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3865 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3866 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3867 /// which still is useful, because it informs integer literals and the like.
3868 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3869 /// for examples of where this comes up,.
3870 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3871 match tcx.struct_tail(ty).sty {
3872 ty::TySlice(_) | ty::TyTrait(..) => {
3873 ExpectRvalueLikeUnsized(ty)
3875 _ => ExpectHasType(ty)
3879 // Resolves `expected` by a single level if it is a variable. If
3880 // there is no expected type or resolution is not possible (e.g.,
3881 // no constraints yet present), just returns `None`.
3882 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3887 ExpectCastableToType(t) => {
3888 ExpectCastableToType(
3889 fcx.infcx().resolve_type_vars_if_possible(&t))
3891 ExpectHasType(t) => {
3893 fcx.infcx().resolve_type_vars_if_possible(&t))
3895 ExpectRvalueLikeUnsized(t) => {
3896 ExpectRvalueLikeUnsized(
3897 fcx.infcx().resolve_type_vars_if_possible(&t))
3902 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3903 match self.resolve(fcx) {
3904 NoExpectation => None,
3905 ExpectCastableToType(ty) |
3907 ExpectRvalueLikeUnsized(ty) => Some(ty),
3911 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3912 match self.resolve(fcx) {
3913 ExpectHasType(ty) => Some(ty),
3919 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3920 local: &'tcx hir::Local,
3921 init: &'tcx hir::Expr)
3923 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3925 let local_ty = fcx.local_ty(init.span, local.id);
3926 if let Some(m) = ref_bindings {
3927 // Somewhat subtle: if we have a `ref` binding in the pattern,
3928 // we want to avoid introducing coercions for the RHS. This is
3929 // both because it helps preserve sanity and, in the case of
3930 // ref mut, for soundness (issue #23116). In particular, in
3931 // the latter case, we need to be clear that the type of the
3932 // referent for the reference that results is *equal to* the
3933 // type of the lvalue it is referencing, and not some
3934 // supertype thereof.
3935 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3936 let init_ty = fcx.expr_ty(init);
3937 demand::eqtype(fcx, init.span, init_ty, local_ty);
3939 check_expr_coercable_to_type(fcx, init, local_ty)
3943 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3944 let tcx = fcx.ccx.tcx;
3946 let t = fcx.local_ty(local.span, local.id);
3947 fcx.write_ty(local.id, t);
3949 if let Some(ref init) = local.init {
3950 check_decl_initializer(fcx, local, &**init);
3951 let init_ty = fcx.expr_ty(&**init);
3952 if init_ty.references_error() {
3953 fcx.write_ty(local.id, init_ty);
3957 let pcx = pat_ctxt {
3959 map: pat_id_map(&tcx.def_map, &*local.pat),
3961 _match::check_pat(&pcx, &*local.pat, t);
3962 let pat_ty = fcx.node_ty(local.pat.id);
3963 if pat_ty.references_error() {
3964 fcx.write_ty(local.id, pat_ty);
3968 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3970 let mut saw_bot = false;
3971 let mut saw_err = false;
3973 hir::StmtDecl(ref decl, id) => {
3976 hir::DeclLocal(ref l) => {
3977 check_decl_local(fcx, &**l);
3978 let l_t = fcx.node_ty(l.id);
3979 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3980 saw_err = saw_err || l_t.references_error();
3982 hir::DeclItem(_) => {/* ignore for now */ }
3985 hir::StmtExpr(ref expr, id) => {
3987 // Check with expected type of ()
3988 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3989 let expr_ty = fcx.expr_ty(&**expr);
3990 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3991 saw_err = saw_err || expr_ty.references_error();
3993 hir::StmtSemi(ref expr, id) => {
3995 check_expr(fcx, &**expr);
3996 let expr_ty = fcx.expr_ty(&**expr);
3997 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3998 saw_err |= expr_ty.references_error();
4002 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
4005 fcx.write_error(node_id);
4008 fcx.write_nil(node_id)
4012 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
4013 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
4014 let blkty = fcx.node_ty(blk.id);
4015 if blkty.references_error() {
4016 fcx.write_error(blk.id);
4018 let nilty = fcx.tcx().mk_nil();
4019 demand::suptype(fcx, blk.span, nilty, blkty);
4023 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4024 blk: &'tcx hir::Block,
4025 expected: Expectation<'tcx>) {
4027 let mut fcx_ps = fcx.ps.borrow_mut();
4028 let unsafety_state = fcx_ps.recurse(blk);
4029 replace(&mut *fcx_ps, unsafety_state)
4032 let mut warned = false;
4033 let mut any_diverges = false;
4034 let mut any_err = false;
4035 for s in &blk.stmts {
4037 let s_id = ::rustc_front::util::stmt_id(s);
4038 let s_ty = fcx.node_ty(s_id);
4039 if any_diverges && !warned && match s.node {
4040 hir::StmtDecl(ref decl, _) => {
4042 hir::DeclLocal(_) => true,
4046 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4051 .add_lint(lint::builtin::UNREACHABLE_CODE,
4054 "unreachable statement".to_string());
4057 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4058 any_err = any_err || s_ty.references_error();
4061 None => if any_err {
4062 fcx.write_error(blk.id);
4063 } else if any_diverges {
4064 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4066 fcx.write_nil(blk.id);
4069 if any_diverges && !warned {
4073 .add_lint(lint::builtin::UNREACHABLE_CODE,
4076 "unreachable expression".to_string());
4078 let ety = match expected {
4079 ExpectHasType(ety) => {
4080 check_expr_coercable_to_type(fcx, &**e, ety);
4084 check_expr_with_expectation(fcx, &**e, expected);
4090 fcx.write_error(blk.id);
4091 } else if any_diverges {
4092 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4094 fcx.write_ty(blk.id, ety);
4099 *fcx.ps.borrow_mut() = prev;
4102 /// Checks a constant appearing in a type. At the moment this is just the
4103 /// length expression in a fixed-length vector, but someday it might be
4104 /// extended to type-level numeric literals.
4105 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4106 expr: &'tcx hir::Expr,
4107 expected_type: Ty<'tcx>) {
4108 let tables = RefCell::new(ty::Tables::empty());
4109 let inh = static_inherited_fields(ccx, &tables);
4110 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4111 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4114 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4118 let tables = RefCell::new(ty::Tables::empty());
4119 let inh = static_inherited_fields(ccx, &tables);
4120 let rty = ccx.tcx.node_id_to_type(id);
4121 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4122 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4123 check_const_with_ty(&fcx, sp, e, declty);
4126 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4130 // Gather locals in statics (because of block expressions).
4131 // This is technically unnecessary because locals in static items are forbidden,
4132 // but prevents type checking from blowing up before const checking can properly
4134 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4136 check_expr_with_hint(fcx, e, declty);
4137 demand::coerce(fcx, e.span, declty, e);
4139 fcx.select_all_obligations_and_apply_defaults();
4140 upvar::closure_analyze_const(&fcx, e);
4141 fcx.select_obligations_where_possible();
4143 fcx.select_all_obligations_or_error();
4145 regionck::regionck_expr(fcx, e);
4146 writeback::resolve_type_vars_in_expr(fcx, e);
4149 /// Checks whether a type can be represented in memory. In particular, it
4150 /// identifies types that contain themselves without indirection through a
4151 /// pointer, which would mean their size is unbounded.
4152 pub fn check_representable(tcx: &ty::ctxt,
4154 item_id: ast::NodeId,
4155 designation: &str) -> bool {
4156 let rty = tcx.node_id_to_type(item_id);
4158 // Check that it is possible to represent this type. This call identifies
4159 // (1) types that contain themselves and (2) types that contain a different
4160 // recursive type. It is only necessary to throw an error on those that
4161 // contain themselves. For case 2, there must be an inner type that will be
4162 // caught by case 1.
4163 match rty.is_representable(tcx, sp) {
4164 Representability::SelfRecursive => {
4165 struct_span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation)
4166 .fileline_help(sp, "wrap the inner value in a box to make it representable")
4170 Representability::Representable | Representability::ContainsRecursive => (),
4175 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4176 let t = tcx.node_id_to_type(id);
4178 ty::TyStruct(def, substs) => {
4179 let fields = &def.struct_variant().fields;
4180 if fields.is_empty() {
4181 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4184 let e = fields[0].ty(tcx, substs);
4185 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4186 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4190 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4191 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4193 span_err!(tcx.sess, sp, E0077,
4194 "SIMD vector element type should be machine type");
4203 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4205 vs: &'tcx [hir::Variant],
4208 fn disr_in_range(ccx: &CrateCtxt,
4210 disr: ty::Disr) -> bool {
4211 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4213 ast::TyU8 => disr as u8 as Disr == disr,
4214 ast::TyU16 => disr as u16 as Disr == disr,
4215 ast::TyU32 => disr as u32 as Disr == disr,
4216 ast::TyU64 => disr as u64 as Disr == disr,
4217 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4220 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4222 ast::TyI8 => disr as i8 as Disr == disr,
4223 ast::TyI16 => disr as i16 as Disr == disr,
4224 ast::TyI32 => disr as i32 as Disr == disr,
4225 ast::TyI64 => disr as i64 as Disr == disr,
4226 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4230 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4231 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4235 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4236 vs: &'tcx [hir::Variant],
4238 hint: attr::ReprAttr) {
4239 #![allow(trivial_numeric_casts)]
4241 let rty = ccx.tcx.node_id_to_type(id);
4242 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4244 let tables = RefCell::new(ty::Tables::empty());
4245 let inh = static_inherited_fields(ccx, &tables);
4246 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4248 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4250 if let Some(ref e) = v.node.disr_expr {
4251 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4255 let def_id = ccx.tcx.map.local_def_id(id);
4257 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4258 for (v, variant) in vs.iter().zip(variants.iter()) {
4259 let current_disr_val = variant.disr_val;
4261 // Check for duplicate discriminant values
4262 match disr_vals.iter().position(|&x| x == current_disr_val) {
4264 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4265 "discriminant value `{}` already exists", disr_vals[i]);
4266 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4267 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4268 "conflicting discriminant here");
4273 // Check for unrepresentable discriminant values
4275 attr::ReprAny | attr::ReprExtern => (),
4276 attr::ReprInt(sp, ity) => {
4277 if !disr_in_range(ccx, ity, current_disr_val) {
4278 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4279 "discriminant value outside specified type");
4280 span_note!(&mut err, sp,
4281 "discriminant type specified here");
4286 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4288 attr::ReprPacked => {
4289 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4292 disr_vals.push(current_disr_val);
4296 let def_id = ccx.tcx.map.local_def_id(id);
4297 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4299 if hint != attr::ReprAny && vs.len() <= 1 {
4301 span_err!(ccx.tcx.sess, sp, E0083,
4302 "unsupported representation for univariant enum");
4304 span_err!(ccx.tcx.sess, sp, E0084,
4305 "unsupported representation for zero-variant enum");
4309 do_check(ccx, vs, id, hint);
4311 check_representable(ccx.tcx, sp, id, "enum");
4314 // Returns the type parameter count and the type for the given definition.
4315 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4318 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4320 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4321 let typ = fcx.local_ty(sp, nid);
4322 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4323 ty::GenericPredicates::empty())
4325 def::DefFn(id, _) | def::DefMethod(id) |
4326 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4327 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4328 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4332 def::DefAssociatedTy(..) |
4334 def::DefTyParam(..) |
4336 def::DefForeignMod(..) |
4338 def::DefSelfTy(..) |
4340 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4345 // Instantiates the given path, which must refer to an item with the given
4346 // number of type parameters and type.
4347 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4348 segments: &[hir::PathSegment],
4349 type_scheme: TypeScheme<'tcx>,
4350 type_predicates: &ty::GenericPredicates<'tcx>,
4351 opt_self_ty: Option<Ty<'tcx>>,
4354 node_id: ast::NodeId) {
4355 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4361 // We need to extract the type parameters supplied by the user in
4362 // the path `path`. Due to the current setup, this is a bit of a
4363 // tricky-process; the problem is that resolve only tells us the
4364 // end-point of the path resolution, and not the intermediate steps.
4365 // Luckily, we can (at least for now) deduce the intermediate steps
4366 // just from the end-point.
4368 // There are basically four cases to consider:
4370 // 1. Reference to a *type*, such as a struct or enum:
4372 // mod a { struct Foo<T> { ... } }
4374 // Because we don't allow types to be declared within one
4375 // another, a path that leads to a type will always look like
4376 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4377 // that only the final segment can have type parameters, and
4378 // they are located in the TypeSpace.
4380 // *Note:* Generally speaking, references to types don't
4381 // actually pass through this function, but rather the
4382 // `ast_ty_to_ty` function in `astconv`. However, in the case
4383 // of struct patterns (and maybe literals) we do invoke
4384 // `instantiate_path` to get the general type of an instance of
4385 // a struct. (In these cases, there are actually no type
4386 // parameters permitted at present, but perhaps we will allow
4387 // them in the future.)
4389 // 1b. Reference to an enum variant or tuple-like struct:
4391 // struct foo<T>(...)
4392 // enum E<T> { foo(...) }
4394 // In these cases, the parameters are declared in the type
4397 // 2. Reference to a *fn item*:
4401 // In this case, the path will again always have the form
4402 // `a::b::foo::<T>` where only the final segment should have
4403 // type parameters. However, in this case, those parameters are
4404 // declared on a value, and hence are in the `FnSpace`.
4406 // 3. Reference to a *method*:
4408 // impl<A> SomeStruct<A> {
4412 // Here we can have a path like
4413 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4414 // may appear in two places. The penultimate segment,
4415 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4416 // final segment, `foo::<B>` contains parameters in fn space.
4418 // 4. Reference to an *associated const*:
4420 // impl<A> AnotherStruct<A> {
4421 // const FOO: B = BAR;
4424 // The path in this case will look like
4425 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4426 // only will have parameters in TypeSpace.
4428 // The first step then is to categorize the segments appropriately.
4430 assert!(!segments.is_empty());
4432 let mut ufcs_associated = None;
4433 let mut segment_spaces: Vec<_>;
4435 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4436 def::DefSelfTy(..) |
4437 def::DefStruct(..) |
4438 def::DefVariant(..) |
4440 def::DefAssociatedTy(..) |
4442 def::DefPrimTy(..) |
4443 def::DefTyParam(..) => {
4444 // Everything but the final segment should have no
4445 // parameters at all.
4446 segment_spaces = vec![None; segments.len() - 1];
4447 segment_spaces.push(Some(subst::TypeSpace));
4450 // Case 2. Reference to a top-level value.
4453 def::DefStatic(..) => {
4454 segment_spaces = vec![None; segments.len() - 1];
4455 segment_spaces.push(Some(subst::FnSpace));
4458 // Case 3. Reference to a method.
4459 def::DefMethod(def_id) => {
4460 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4462 ty::TraitContainer(trait_did) => {
4463 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4465 ty::ImplContainer(_) => {}
4468 if segments.len() >= 2 {
4469 segment_spaces = vec![None; segments.len() - 2];
4470 segment_spaces.push(Some(subst::TypeSpace));
4471 segment_spaces.push(Some(subst::FnSpace));
4473 // `<T>::method` will end up here, and so can `T::method`.
4474 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4475 segment_spaces = vec![Some(subst::FnSpace)];
4476 ufcs_associated = Some((container, self_ty));
4480 def::DefAssociatedConst(def_id) => {
4481 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4483 ty::TraitContainer(trait_did) => {
4484 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4486 ty::ImplContainer(_) => {}
4489 if segments.len() >= 2 {
4490 segment_spaces = vec![None; segments.len() - 2];
4491 segment_spaces.push(Some(subst::TypeSpace));
4492 segment_spaces.push(None);
4494 // `<T>::CONST` will end up here, and so can `T::CONST`.
4495 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4496 segment_spaces = vec![None];
4497 ufcs_associated = Some((container, self_ty));
4501 // Other cases. Various nonsense that really shouldn't show up
4502 // here. If they do, an error will have been reported
4503 // elsewhere. (I hope)
4505 def::DefForeignMod(..) |
4510 segment_spaces = vec![None; segments.len()];
4513 assert_eq!(segment_spaces.len(), segments.len());
4515 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4516 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4517 // type parameters are not mandatory.
4518 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4520 debug!("segment_spaces={:?}", segment_spaces);
4522 // Next, examine the definition, and determine how many type
4523 // parameters we expect from each space.
4524 let type_defs = &type_scheme.generics.types;
4525 let region_defs = &type_scheme.generics.regions;
4527 // Now that we have categorized what space the parameters for each
4528 // segment belong to, let's sort out the parameters that the user
4529 // provided (if any) into their appropriate spaces. We'll also report
4530 // errors if type parameters are provided in an inappropriate place.
4531 let mut substs = Substs::empty();
4532 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4535 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4539 push_explicit_parameters_from_segment_to_substs(fcx,
4549 if let Some(self_ty) = opt_self_ty {
4550 if type_defs.len(subst::SelfSpace) == 1 {
4551 substs.types.push(subst::SelfSpace, self_ty);
4555 // Now we have to compare the types that the user *actually*
4556 // provided against the types that were *expected*. If the user
4557 // did not provide any types, then we want to substitute inference
4558 // variables. If the user provided some types, we may still need
4559 // to add defaults. If the user provided *too many* types, that's
4561 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4562 adjust_type_parameters(fcx, span, space, type_defs,
4563 require_type_space, &mut substs);
4564 assert_eq!(substs.types.len(space), type_defs.len(space));
4566 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4567 assert_eq!(substs.regions().len(space), region_defs.len(space));
4570 // The things we are substituting into the type should not contain
4571 // escaping late-bound regions, and nor should the base type scheme.
4572 assert!(!substs.has_regions_escaping_depth(0));
4573 assert!(!type_scheme.has_escaping_regions());
4575 // Add all the obligations that are required, substituting and
4576 // normalized appropriately.
4577 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4578 fcx.add_obligations_for_parameters(
4579 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4582 // Substitute the values for the type parameters into the type of
4583 // the referenced item.
4584 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4587 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4588 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4589 // is inherent, there is no `Self` parameter, instead, the impl needs
4590 // type parameters, which we can infer by unifying the provided `Self`
4591 // with the substituted impl type.
4592 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4593 assert_eq!(substs.types.len(subst::TypeSpace),
4594 impl_scheme.generics.types.len(subst::TypeSpace));
4595 assert_eq!(substs.regions().len(subst::TypeSpace),
4596 impl_scheme.generics.regions.len(subst::TypeSpace));
4598 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4599 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4600 fcx.tcx().sess.span_bug(span,
4602 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4608 debug!("instantiate_path: type of {:?} is {:?}",
4611 fcx.write_ty(node_id, ty_substituted);
4612 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4615 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4616 /// parameters are provided, then reports an error and clears the output vector.
4618 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4619 /// use inference variables. This seems less likely to lead to derived errors.
4621 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4622 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4623 /// here because we can easily use the precise span of the N+1'th parameter.
4624 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4625 fcx: &FnCtxt<'a, 'tcx>,
4626 space: subst::ParamSpace,
4628 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4629 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4630 segment: &hir::PathSegment,
4631 substs: &mut Substs<'tcx>)
4633 match segment.parameters {
4634 hir::AngleBracketedParameters(ref data) => {
4635 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4636 fcx, space, type_defs, region_defs, data, substs);
4639 hir::ParenthesizedParameters(ref data) => {
4640 span_err!(fcx.tcx().sess, span, E0238,
4641 "parenthesized parameters may only be used with a trait");
4642 push_explicit_parenthesized_parameters_from_segment_to_substs(
4643 fcx, space, span, type_defs, data, substs);
4648 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4649 fcx: &FnCtxt<'a, 'tcx>,
4650 space: subst::ParamSpace,
4651 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4652 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4653 data: &hir::AngleBracketedParameterData,
4654 substs: &mut Substs<'tcx>)
4657 let type_count = type_defs.len(space);
4658 assert_eq!(substs.types.len(space), 0);
4659 for (i, typ) in data.types.iter().enumerate() {
4660 let t = fcx.to_ty(&**typ);
4662 substs.types.push(space, t);
4663 } else if i == type_count {
4664 span_err!(fcx.tcx().sess, typ.span, E0087,
4665 "too many type parameters provided: \
4666 expected at most {} parameter{}, \
4667 found {} parameter{}",
4669 if type_count == 1 {""} else {"s"},
4671 if data.types.len() == 1 {""} else {"s"});
4672 substs.types.truncate(space, 0);
4678 if !data.bindings.is_empty() {
4679 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4680 "unexpected binding of associated item in expression path \
4681 (only allowed in type paths)");
4685 let region_count = region_defs.len(space);
4686 assert_eq!(substs.regions().len(space), 0);
4687 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4688 let r = ast_region_to_region(fcx.tcx(), lifetime);
4689 if i < region_count {
4690 substs.mut_regions().push(space, r);
4691 } else if i == region_count {
4692 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4693 "too many lifetime parameters provided: \
4694 expected {} parameter{}, found {} parameter{}",
4696 if region_count == 1 {""} else {"s"},
4697 data.lifetimes.len(),
4698 if data.lifetimes.len() == 1 {""} else {"s"});
4699 substs.mut_regions().truncate(space, 0);
4707 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4708 /// but intended for `Foo(A,B) -> C` form. This expands to
4709 /// roughly the same thing as `Foo<(A,B),C>`. One important
4710 /// difference has to do with the treatment of anonymous
4711 /// regions, which are translated into bound regions (NYI).
4712 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4713 fcx: &FnCtxt<'a, 'tcx>,
4714 space: subst::ParamSpace,
4716 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4717 data: &hir::ParenthesizedParameterData,
4718 substs: &mut Substs<'tcx>)
4720 let type_count = type_defs.len(space);
4722 span_err!(fcx.tcx().sess, span, E0167,
4723 "parenthesized form always supplies 2 type parameters, \
4724 but only {} parameter(s) were expected",
4728 let input_tys: Vec<Ty> =
4729 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4731 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4733 if type_count >= 1 {
4734 substs.types.push(space, tuple_ty);
4737 let output_ty: Option<Ty> =
4738 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4741 output_ty.unwrap_or(fcx.tcx().mk_nil());
4743 if type_count >= 2 {
4744 substs.types.push(space, output_ty);
4748 fn adjust_type_parameters<'a, 'tcx>(
4749 fcx: &FnCtxt<'a, 'tcx>,
4752 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4753 require_type_space: bool,
4754 substs: &mut Substs<'tcx>)
4756 let provided_len = substs.types.len(space);
4757 let desired = defs.get_slice(space);
4758 let required_len = desired.iter()
4759 .take_while(|d| d.default.is_none())
4762 debug!("adjust_type_parameters(space={:?}, \
4771 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4772 assert!(provided_len <= desired.len());
4774 // Nothing specified at all: supply inference variables for
4776 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4777 substs.types.replace(space, Vec::new());
4778 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4782 // Too few parameters specified: report an error and use Err
4784 if provided_len < required_len {
4786 if desired.len() != required_len { "at least " } else { "" };
4787 span_err!(fcx.tcx().sess, span, E0089,
4788 "too few type parameters provided: expected {}{} parameter{}, \
4789 found {} parameter{}",
4790 qualifier, required_len,
4791 if required_len == 1 {""} else {"s"},
4793 if provided_len == 1 {""} else {"s"});
4794 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4798 // Otherwise, add in any optional parameters that the user
4799 // omitted. The case of *too many* parameters is handled
4801 // push_explicit_parameters_from_segment_to_substs(). Note
4802 // that the *default* type are expressed in terms of all prior
4803 // parameters, so we have to substitute as we go with the
4804 // partial substitution that we have built up.
4805 for i in provided_len..desired.len() {
4806 let default = desired[i].default.unwrap();
4807 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4808 substs.types.push(space, default);
4810 assert_eq!(substs.types.len(space), desired.len());
4812 debug!("Final substs: {:?}", substs);
4815 fn adjust_region_parameters(
4819 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4820 substs: &mut Substs)
4822 let provided_len = substs.mut_regions().len(space);
4823 let desired = defs.get_slice(space);
4825 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4826 assert!(provided_len <= desired.len());
4828 // If nothing was provided, just use inference variables.
4829 if provided_len == 0 {
4830 substs.mut_regions().replace(
4832 fcx.infcx().region_vars_for_defs(span, desired));
4836 // If just the right number were provided, everybody is happy.
4837 if provided_len == desired.len() {
4841 // Otherwise, too few were provided. Report an error and then
4842 // use inference variables.
4843 span_err!(fcx.tcx().sess, span, E0090,
4844 "too few lifetime parameters provided: expected {} parameter{}, \
4845 found {} parameter{}",
4847 if desired.len() == 1 {""} else {"s"},
4849 if provided_len == 1 {""} else {"s"});
4851 substs.mut_regions().replace(
4853 fcx.infcx().region_vars_for_defs(span, desired));
4857 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4861 where F: Fn() -> Ty<'tcx>
4863 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4866 let alternative = f();
4869 if alternative.is_ty_var() || alternative.references_error() {
4870 fcx.type_error_message(sp, |_actual| {
4871 "the type of this value must be known in this context".to_string()
4873 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4874 ty = fcx.tcx().types.err;
4876 demand::suptype(fcx, sp, alternative, ty);
4884 // Resolves `typ` by a single level if `typ` is a type variable. If no
4885 // resolution is possible, then an error is reported.
4886 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4891 structurally_resolve_type_or_else(fcx, sp, ty, || {
4896 // Returns true if b contains a break that can exit from b
4897 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4898 // First: is there an unlabeled break immediately
4900 (loop_query(&*b, |e| {
4902 hir::ExprBreak(None) => true,
4906 // Second: is there a labeled break with label
4907 // <id> nested anywhere inside the loop?
4908 (block_query(b, |e| {
4909 if let hir::ExprBreak(Some(_)) = e.node {
4910 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4917 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4918 tps: &[hir::TyParam],
4920 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4923 // make a vector of booleans initially false, set to true when used
4924 if tps.is_empty() { return; }
4925 let mut tps_used = vec![false; tps.len()];
4927 for leaf_ty in ty.walk() {
4928 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4929 debug!("Found use of ty param num {}", idx);
4930 tps_used[idx as usize] = true;
4934 for (i, b) in tps_used.iter().enumerate() {
4936 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4937 "type parameter `{}` is unused",