1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function). Inference is used to supply types wherever they are
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
26 - main: the main pass does the lion's share of the work: it
27 determines the types of all expressions, resolves
28 methods, checks for most invalid conditions, and so forth. In
29 some cases, where a type is unknown, it may create a type or region
30 variable and use that as the type of an expression.
32 In the process of checking, various constraints will be placed on
33 these type variables through the subtyping relationships requested
34 through the `demand` module. The `infer` module is in charge
35 of resolving those constraints.
37 - regionck: after main is complete, the regionck pass goes over all
38 types looking for regions and making sure that they did not escape
39 into places they are not in scope. This may also influence the
40 final assignments of the various region variables if there is some
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
46 - writeback: writes the final types within a function body, replacing
47 type variables with their final inferred types. These final types
48 are written into the `tcx.node_types` table, which should *never* contain
49 any reference to a type variable.
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.item_substs`. These types
56 may contain unresolved type variables. After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `ccx.tcx`.
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
68 n.b.: A type variable is not the same thing as a type parameter. A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract. When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`. This variable will
74 eventually be resolved to some concrete type (which might itself be
79 pub use self::Expectation::*;
80 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
83 use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
84 use check::_match::pat_ctxt;
85 use dep_graph::DepNode;
86 use fmt_macros::{Parser, Piece, Position};
87 use middle::astconv_util::prohibit_type_params;
88 use middle::cstore::LOCAL_CRATE;
89 use middle::def::{self, Def};
90 use middle::def_id::DefId;
92 use middle::infer::{TypeOrigin, type_variable};
93 use middle::pat_util::{self, pat_id_map};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, ToPolyTraitRef, Ty};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::util::Representability;
105 use require_c_abi_if_variadic;
106 use rscope::{ElisionFailureInfo, RegionScope};
107 use session::{Session, CompileResult};
108 use {CrateCtxt, lookup_full_def};
111 use util::common::{block_query, ErrorReported, indenter, loop_query};
112 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
114 use std::cell::{Cell, Ref, RefCell};
115 use std::collections::{HashSet};
116 use std::mem::replace;
117 use syntax::abi::Abi;
120 use syntax::attr::AttrMetaMethods;
121 use syntax::codemap::{self, Span, Spanned};
122 use syntax::errors::DiagnosticBuilder;
123 use syntax::parse::token::{self, InternedString, special_idents};
125 use syntax::util::lev_distance::find_best_match_for_name;
127 use rustc_front::intravisit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::{Visibility, PatKind};
130 use rustc_front::print::pprust;
131 use rustc_back::slice;
150 /// closures defined within the function. For example:
153 /// bar(move|| { ... })
156 /// Here, the function `foo()` and the closure passed to
157 /// `bar()` will each have their own `FnCtxt`, but they will
158 /// share the inherited fields.
159 pub struct Inherited<'a, 'tcx: 'a> {
160 infcx: infer::InferCtxt<'a, 'tcx>,
161 locals: RefCell<NodeMap<Ty<'tcx>>>,
163 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
165 tables: &'a RefCell<ty::Tables<'tcx>>,
167 // When we process a call like `c()` where `c` is a closure type,
168 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
169 // `FnOnce` closure. In that case, we defer full resolution of the
170 // call until upvar inference can kick in and make the
171 // decision. We keep these deferred resolutions grouped by the
172 // def-id of the closure, so that once we decide, we can easily go
173 // back and process them.
174 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
176 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
179 trait DeferredCallResolution<'tcx> {
180 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
183 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
185 /// When type-checking an expression, we propagate downward
186 /// whatever type hint we are able in the form of an `Expectation`.
187 #[derive(Copy, Clone, Debug)]
188 pub enum Expectation<'tcx> {
189 /// We know nothing about what type this expression should have.
192 /// This expression should have the type given (or some subtype)
193 ExpectHasType(Ty<'tcx>),
195 /// This expression will be cast to the `Ty`
196 ExpectCastableToType(Ty<'tcx>),
198 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
199 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
200 ExpectRvalueLikeUnsized(Ty<'tcx>),
203 impl<'tcx> Expectation<'tcx> {
204 // Disregard "castable to" expectations because they
205 // can lead us astray. Consider for example `if cond
206 // {22} else {c} as u8` -- if we propagate the
207 // "castable to u8" constraint to 22, it will pick the
208 // type 22u8, which is overly constrained (c might not
209 // be a u8). In effect, the problem is that the
210 // "castable to" expectation is not the tightest thing
211 // we can say, so we want to drop it in this case.
212 // The tightest thing we can say is "must unify with
213 // else branch". Note that in the case of a "has type"
214 // constraint, this limitation does not hold.
216 // If the expected type is just a type variable, then don't use
217 // an expected type. Otherwise, we might write parts of the type
218 // when checking the 'then' block which are incompatible with the
220 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
222 ExpectHasType(ety) => {
223 let ety = fcx.infcx().shallow_resolve(ety);
224 if !ety.is_ty_var() {
230 ExpectRvalueLikeUnsized(ety) => {
231 ExpectRvalueLikeUnsized(ety)
238 #[derive(Copy, Clone)]
239 pub struct UnsafetyState {
240 pub def: ast::NodeId,
241 pub unsafety: hir::Unsafety,
242 pub unsafe_push_count: u32,
247 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
248 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
251 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
252 match self.unsafety {
253 // If this unsafe, then if the outer function was already marked as
254 // unsafe we shouldn't attribute the unsafe'ness to the block. This
255 // way the block can be warned about instead of ignoring this
256 // extraneous block (functions are never warned about).
257 hir::Unsafety::Unsafe if self.from_fn => *self,
260 let (unsafety, def, count) = match blk.rules {
261 hir::PushUnsafeBlock(..) =>
262 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
263 hir::PopUnsafeBlock(..) =>
264 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
265 hir::UnsafeBlock(..) =>
266 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
267 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
268 (unsafety, self.def, self.unsafe_push_count),
270 UnsafetyState{ def: def,
272 unsafe_push_count: count,
280 pub struct FnCtxt<'a, 'tcx: 'a> {
281 body_id: ast::NodeId,
283 // This flag is set to true if, during the writeback phase, we encounter
284 // a type error in this function.
285 writeback_errors: Cell<bool>,
287 // Number of errors that had been reported when we started
288 // checking this function. On exit, if we find that *more* errors
289 // have been reported, we will skip regionck and other work that
290 // expects the types within the function to be consistent.
291 err_count_on_creation: usize,
293 ret_ty: ty::FnOutput<'tcx>,
295 ps: RefCell<UnsafetyState>,
297 inh: &'a Inherited<'a, 'tcx>,
299 ccx: &'a CrateCtxt<'a, 'tcx>,
302 impl<'a, 'tcx> Inherited<'a, 'tcx> {
303 fn new(tcx: &'a ty::ctxt<'tcx>,
304 tables: &'a RefCell<ty::Tables<'tcx>>,
305 param_env: ty::ParameterEnvironment<'a, 'tcx>)
306 -> Inherited<'a, 'tcx> {
309 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
310 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
311 locals: RefCell::new(NodeMap()),
313 deferred_call_resolutions: RefCell::new(DefIdMap()),
314 deferred_cast_checks: RefCell::new(Vec::new()),
318 fn normalize_associated_types_in<T>(&self,
320 body_id: ast::NodeId,
323 where T : TypeFoldable<'tcx>
325 assoc::normalize_associated_types_in(&self.infcx,
326 &mut self.fulfillment_cx.borrow_mut(),
334 // Used by check_const and check_enum_variants
335 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
336 inh: &'a Inherited<'a, 'tcx>,
337 rty: ty::FnOutput<'tcx>,
338 body_id: ast::NodeId)
339 -> FnCtxt<'a, 'tcx> {
342 writeback_errors: Cell::new(false),
343 err_count_on_creation: ccx.tcx.sess.err_count(),
345 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
351 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
352 tables: &'a RefCell<ty::Tables<'tcx>>)
353 -> Inherited<'a, 'tcx> {
354 // It's kind of a kludge to manufacture a fake function context
355 // and statement context, but we might as well do write the code only once
356 let param_env = ccx.tcx.empty_parameter_environment();
357 Inherited::new(ccx.tcx, &tables, param_env)
360 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
363 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
364 fn visit_item(&mut self, i: &'tcx hir::Item) {
365 check_item_type(self.ccx, i);
366 intravisit::walk_item(self, i);
369 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
371 hir::TyFixedLengthVec(_, ref expr) => {
372 check_const_in_type(self.ccx, &expr, self.ccx.tcx.types.usize);
377 intravisit::walk_ty(self, t);
381 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
382 fn visit_item(&mut self, i: &'tcx hir::Item) {
383 check_item_body(self.ccx, i);
387 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
388 ccx.tcx.sess.track_errors(|| {
389 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
390 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
394 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
395 ccx.tcx.sess.track_errors(|| {
396 let mut visit = CheckItemTypesVisitor { ccx: ccx };
397 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
401 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
402 ccx.tcx.sess.track_errors(|| {
403 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
404 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
408 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
409 ccx.tcx.sess.track_errors(|| {
410 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
411 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
412 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
414 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
415 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
416 if drop_impl_did.is_local() {
417 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
420 assert!(ccx.tcx.sess.has_errors());
428 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
429 decl: &'tcx hir::FnDecl,
430 body: &'tcx hir::Block,
434 param_env: ty::ParameterEnvironment<'a, 'tcx>)
437 ty::TyBareFn(_, ref fn_ty) => {
438 let tables = RefCell::new(ty::Tables::empty());
439 let inh = Inherited::new(ccx.tcx, &tables, param_env);
441 // Compute the fty from point of view of inside fn.
442 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
444 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
446 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
448 inh.normalize_associated_types_in(body.span,
452 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
453 decl, fn_id, body, &inh);
455 fcx.select_all_obligations_and_apply_defaults();
456 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
457 fcx.select_obligations_where_possible();
459 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
461 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
462 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
464 _ => ccx.tcx.sess.impossible_case(body.span,
465 "check_bare_fn: function type expected")
469 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
470 fcx: &'a FnCtxt<'a, 'tcx>
473 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
474 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
477 // infer the variable's type
478 let var_ty = self.fcx.infcx().next_ty_var();
479 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
483 // take type that the user specified
484 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
491 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
492 // Add explicitly-declared locals.
493 fn visit_local(&mut self, local: &'tcx hir::Local) {
494 let o_ty = match local.ty {
495 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
498 self.assign(local.span, local.id, o_ty);
499 debug!("Local variable {:?} is assigned type {}",
501 self.fcx.infcx().ty_to_string(
502 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
503 intravisit::walk_local(self, local);
506 // Add pattern bindings.
507 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
508 if let PatKind::Ident(_, ref path1, _) = p.node {
509 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
510 let var_ty = self.assign(p.span, p.id, None);
512 self.fcx.require_type_is_sized(var_ty, p.span,
513 traits::VariableType(p.id));
515 debug!("Pattern binding {} is assigned to {} with type {:?}",
517 self.fcx.infcx().ty_to_string(
518 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
522 intravisit::walk_pat(self, p);
525 fn visit_block(&mut self, b: &'tcx hir::Block) {
526 // non-obvious: the `blk` variable maps to region lb, so
527 // we have to keep this up-to-date. This
528 // is... unfortunate. It'd be nice to not need this.
529 intravisit::walk_block(self, b);
532 // Since an expr occurs as part of the type fixed size arrays we
533 // need to record the type for that node
534 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
536 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
538 check_expr_with_hint(self.fcx, &count_expr, self.fcx.tcx().types.usize);
540 hir::TyBareFn(ref function_declaration) => {
541 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
542 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
544 _ => intravisit::walk_ty(self, t)
548 // Don't descend into the bodies of nested closures
549 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
550 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
553 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
554 /// body and returns the function context used for that purpose, since in the case of a fn item
555 /// there is still a bit more to do.
558 /// * inherited: other fields inherited from the enclosing fn (if any)
559 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
560 unsafety: hir::Unsafety,
561 unsafety_id: ast::NodeId,
562 fn_sig: &ty::FnSig<'tcx>,
563 decl: &'tcx hir::FnDecl,
565 body: &'tcx hir::Block,
566 inherited: &'a Inherited<'a, 'tcx>)
570 let err_count_on_creation = tcx.sess.err_count();
572 let arg_tys = &fn_sig.inputs;
573 let ret_ty = fn_sig.output;
575 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
580 // Create the function context. This is either derived from scratch or,
581 // in the case of function expressions, based on the outer context.
584 writeback_errors: Cell::new(false),
585 err_count_on_creation: err_count_on_creation,
587 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
592 if let ty::FnConverging(ret_ty) = ret_ty {
593 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
596 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
598 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
601 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
603 // Add formal parameters.
604 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
605 // The type of the argument must be well-formed.
607 // NB -- this is now checked in wfcheck, but that
608 // currently only results in warnings, so we issue an
609 // old-style WF obligation here so that we still get the
610 // errors that we used to get.
611 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
613 // Create type variables for each argument.
614 pat_util::pat_bindings(
617 |_bm, pat_id, sp, _path| {
618 let var_ty = visit.assign(sp, pat_id, None);
619 fcx.require_type_is_sized(var_ty, sp,
620 traits::VariableType(pat_id));
623 // Check the pattern.
626 map: pat_id_map(&tcx.def_map, &input.pat),
628 _match::check_pat(&pcx, &input.pat, *arg_ty);
631 visit.visit_block(body);
634 check_block_with_expected(&fcx, body, match ret_ty {
635 ty::FnConverging(result_type) => ExpectHasType(result_type),
636 ty::FnDiverging => NoExpectation
639 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
640 fcx.write_ty(input.id, arg);
646 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
649 check_representable(tcx, span, id, "struct");
651 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
652 check_simd(tcx, span, id);
656 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
657 debug!("check_item_type(it.id={}, it.name={})",
659 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
660 let _indenter = indenter();
662 // Consts can play a role in type-checking, so they are included here.
663 hir::ItemStatic(_, _, ref e) |
664 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &e, it.id),
665 hir::ItemEnum(ref enum_definition, _) => {
666 check_enum_variants(ccx,
668 &enum_definition.variants,
671 hir::ItemFn(..) => {} // entirely within check_item_body
672 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
673 debug!("ItemImpl {} with id {}", it.name, it.id);
674 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
675 Some(impl_trait_ref) => {
676 check_impl_items_against_trait(ccx,
684 hir::ItemTrait(_, ref generics, _, _) => {
685 check_trait_on_unimplemented(ccx, generics, it);
687 hir::ItemStruct(..) => {
688 check_struct(ccx, it.id, it.span);
690 hir::ItemTy(_, ref generics) => {
691 let pty_ty = ccx.tcx.node_id_to_type(it.id);
692 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
694 hir::ItemForeignMod(ref m) => {
695 if m.abi == Abi::RustIntrinsic {
696 for item in &m.items {
697 intrinsic::check_intrinsic_type(ccx, item);
699 } else if m.abi == Abi::PlatformIntrinsic {
700 for item in &m.items {
701 intrinsic::check_platform_intrinsic_type(ccx, item);
704 for item in &m.items {
705 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
706 if !pty.generics.types.is_empty() {
707 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
708 "foreign items may not have type parameters");
709 span_help!(&mut err, item.span,
710 "consider using specialization instead of \
715 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
716 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
721 _ => {/* nothing to do */ }
725 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
726 debug!("check_item_body(it.id={}, it.name={})",
728 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
729 let _indenter = indenter();
731 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
732 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
733 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
734 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
736 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
737 debug!("ItemImpl {} with id {}", it.name, it.id);
739 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
741 for impl_item in impl_items {
742 match impl_item.node {
743 hir::ImplItemKind::Const(_, ref expr) => {
744 check_const(ccx, impl_item.span, &expr, impl_item.id)
746 hir::ImplItemKind::Method(ref sig, ref body) => {
747 check_method_body(ccx, &impl_pty.generics, sig, body,
748 impl_item.id, impl_item.span);
750 hir::ImplItemKind::Type(_) => {
751 // Nothing to do here.
756 hir::ItemTrait(_, _, _, ref trait_items) => {
757 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
758 for trait_item in trait_items {
759 match trait_item.node {
760 hir::ConstTraitItem(_, Some(ref expr)) => {
761 check_const(ccx, trait_item.span, &expr, trait_item.id)
763 hir::MethodTraitItem(ref sig, Some(ref body)) => {
764 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
766 check_method_body(ccx, &trait_def.generics, sig, body,
767 trait_item.id, trait_item.span);
769 hir::MethodTraitItem(ref sig, None) => {
770 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
772 hir::ConstTraitItem(_, None) |
773 hir::TypeTraitItem(..) => {
779 _ => {/* nothing to do */ }
783 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
785 constness: hir::Constness)
788 hir::Constness::NotConst => {
791 hir::Constness::Const => {
792 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
797 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
798 generics: &hir::Generics,
800 if let Some(ref attr) = item.attrs.iter().find(|a| {
801 a.check_name("rustc_on_unimplemented")
803 if let Some(ref istring) = attr.value_str() {
804 let parser = Parser::new(&istring);
805 let types = &generics.ty_params;
806 for token in parser {
808 Piece::String(_) => (), // Normal string, no need to check it
809 Piece::NextArgument(a) => match a.position {
810 // `{Self}` is allowed
811 Position::ArgumentNamed(s) if s == "Self" => (),
812 // So is `{A}` if A is a type parameter
813 Position::ArgumentNamed(s) => match types.iter().find(|t| {
818 span_err!(ccx.tcx.sess, attr.span, E0230,
819 "there is no type parameter \
824 // `{:1}` and `{}` are not to be used
825 Position::ArgumentIs(_) | Position::ArgumentNext => {
826 span_err!(ccx.tcx.sess, attr.span, E0231,
827 "only named substitution \
828 parameters are allowed");
834 span_err!(ccx.tcx.sess, attr.span, E0232,
835 "this attribute must have a value, \
836 eg `#[rustc_on_unimplemented = \"foo\"]`")
841 /// Type checks a method body.
845 /// * `item_generics`: generics defined on the impl/trait that contains
847 /// * `self_bound`: bound for the `Self` type parameter, if any
848 /// * `method`: the method definition
849 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
850 item_generics: &ty::Generics<'tcx>,
851 sig: &'tcx hir::MethodSig,
852 body: &'tcx hir::Block,
853 id: ast::NodeId, span: Span) {
854 debug!("check_method_body(item_generics={:?}, id={})",
856 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
858 let fty = ccx.tcx.node_id_to_type(id);
859 debug!("check_method_body: fty={:?}", fty);
861 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
864 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
866 impl_trait_ref: &ty::TraitRef<'tcx>,
867 impl_items: &[hir::ImplItem]) {
868 // Locate trait methods
870 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
871 let mut overridden_associated_type = None;
873 // Check existing impl methods to see if they are both present in trait
874 // and compatible with trait signature
875 for impl_item in impl_items {
876 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
877 let ty_trait_item = trait_items.iter()
878 .find(|ac| ac.name() == ty_impl_item.name());
880 if let Some(ty_trait_item) = ty_trait_item {
881 match impl_item.node {
882 hir::ImplItemKind::Const(..) => {
883 let impl_const = match ty_impl_item {
884 ty::ConstTraitItem(ref cti) => cti,
885 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
888 // Find associated const definition.
889 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
890 compare_const_impl(ccx.tcx,
896 span_err!(tcx.sess, impl_item.span, E0323,
897 "item `{}` is an associated const, \
898 which doesn't match its trait `{:?}`",
903 hir::ImplItemKind::Method(ref sig, ref body) => {
904 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
906 let impl_method = match ty_impl_item {
907 ty::MethodTraitItem(ref mti) => mti,
908 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
911 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
912 compare_impl_method(ccx.tcx,
919 span_err!(tcx.sess, impl_item.span, E0324,
920 "item `{}` is an associated method, \
921 which doesn't match its trait `{:?}`",
926 hir::ImplItemKind::Type(_) => {
927 let impl_type = match ty_impl_item {
928 ty::TypeTraitItem(ref tti) => tti,
929 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
932 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
933 if let Some(_) = at.ty {
934 overridden_associated_type = Some(impl_item);
937 span_err!(tcx.sess, impl_item.span, E0325,
938 "item `{}` is an associated type, \
939 which doesn't match its trait `{:?}`",
948 // Check for missing items from trait
949 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
950 let mut missing_items = Vec::new();
951 let mut invalidated_items = Vec::new();
952 let associated_type_overridden = overridden_associated_type.is_some();
953 for trait_item in trait_items.iter() {
955 ty::ConstTraitItem(ref associated_const) => {
956 let is_implemented = impl_items.iter().any(|ii| {
958 hir::ImplItemKind::Const(..) => {
959 ii.name == associated_const.name
964 let is_provided = associated_const.has_value;
968 missing_items.push(associated_const.name);
969 } else if associated_type_overridden {
970 invalidated_items.push(associated_const.name);
974 ty::MethodTraitItem(ref trait_method) => {
976 impl_items.iter().any(|ii| {
978 hir::ImplItemKind::Method(..) => {
979 ii.name == trait_method.name
985 provided_methods.iter().any(|m| m.name == trait_method.name);
988 missing_items.push(trait_method.name);
989 } else if associated_type_overridden {
990 invalidated_items.push(trait_method.name);
994 ty::TypeTraitItem(ref associated_type) => {
995 let is_implemented = impl_items.iter().any(|ii| {
997 hir::ImplItemKind::Type(_) => {
998 ii.name == associated_type.name
1003 let is_provided = associated_type.ty.is_some();
1004 if !is_implemented {
1006 missing_items.push(associated_type.name);
1007 } else if associated_type_overridden {
1008 invalidated_items.push(associated_type.name);
1015 if !missing_items.is_empty() {
1016 span_err!(tcx.sess, impl_span, E0046,
1017 "not all trait items implemented, missing: `{}`",
1018 missing_items.iter()
1019 .map(|name| name.to_string())
1020 .collect::<Vec<_>>().join("`, `"))
1023 if !invalidated_items.is_empty() {
1024 let invalidator = overridden_associated_type.unwrap();
1025 span_err!(tcx.sess, invalidator.span, E0399,
1026 "the following trait items need to be reimplemented \
1027 as `{}` was overridden: `{}`",
1029 invalidated_items.iter()
1030 .map(|name| name.to_string())
1031 .collect::<Vec<_>>().join("`, `"))
1035 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1042 if t_cast.references_error() || t_expr.references_error() {
1045 let tstr = fcx.infcx().ty_to_string(t_cast);
1046 let mut err = fcx.type_error_struct(span, |actual| {
1047 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1050 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1051 let mtstr = match mt {
1052 hir::MutMutable => "mut ",
1053 hir::MutImmutable => ""
1055 if t_cast.is_trait() {
1056 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1058 err.span_suggestion(t_span,
1059 "try casting to a reference instead:",
1060 format!("&{}{}", mtstr, s));
1063 span_help!(err, t_span,
1064 "did you mean `&{}{}`?", mtstr, tstr),
1067 span_help!(err, span,
1068 "consider using an implicit coercion to `&{}{}` instead",
1073 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1075 err.span_suggestion(t_span,
1076 "try casting to a `Box` instead:",
1077 format!("Box<{}>", s));
1080 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1084 span_help!(err, e_span,
1085 "consider using a box or reference as appropriate");
1089 fcx.write_error(id);
1093 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1094 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1096 fn get_item_type_scheme(&self, _: Span, id: DefId)
1097 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1099 Ok(self.tcx().lookup_item_type(id))
1102 fn get_trait_def(&self, _: Span, id: DefId)
1103 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1105 Ok(self.tcx().lookup_trait_def(id))
1108 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1109 // all super predicates are ensured during collect pass
1113 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1114 Some(&self.inh.infcx.parameter_environment.free_substs)
1117 fn get_type_parameter_bounds(&self,
1119 node_id: ast::NodeId)
1120 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1122 let def = self.tcx().type_parameter_def(node_id);
1123 let r = self.inh.infcx.parameter_environment
1126 .filter_map(|predicate| {
1128 ty::Predicate::Trait(ref data) => {
1129 if data.0.self_ty().is_param(def.space, def.index) {
1130 Some(data.to_poly_trait_ref())
1144 fn trait_defines_associated_type_named(&self,
1145 trait_def_id: DefId,
1146 assoc_name: ast::Name)
1149 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1150 trait_def.associated_type_names.contains(&assoc_name)
1154 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1155 substs: Option<&mut subst::Substs<'tcx>>,
1156 space: Option<subst::ParamSpace>,
1157 span: Span) -> Ty<'tcx> {
1158 // Grab the default doing subsitution
1159 let default = ty_param_def.and_then(|def| {
1160 def.default.map(|ty| type_variable::Default {
1161 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1163 def_id: def.default_def_id
1167 let ty_var = self.infcx().next_ty_var_with_default(default);
1169 // Finally we add the type variable to the substs
1172 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1176 fn projected_ty_from_poly_trait_ref(&self,
1178 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1179 item_name: ast::Name)
1182 let (trait_ref, _) =
1183 self.infcx().replace_late_bound_regions_with_fresh_var(
1185 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1188 self.normalize_associated_type(span, trait_ref, item_name)
1191 fn projected_ty(&self,
1193 trait_ref: ty::TraitRef<'tcx>,
1194 item_name: ast::Name)
1197 self.normalize_associated_type(span, trait_ref, item_name)
1201 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1202 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1204 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1208 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1209 &self.inh.infcx.parameter_environment
1212 pub fn sess(&self) -> &Session {
1216 pub fn err_count_since_creation(&self) -> usize {
1217 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1220 /// Resolves type variables in `ty` if possible. Unlike the infcx
1221 /// version, this version will also select obligations if it seems
1222 /// useful, in an effort to get more type information.
1223 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1224 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1226 // No TyInfer()? Nothing needs doing.
1227 if !ty.has_infer_types() {
1228 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1232 // If `ty` is a type variable, see whether we already know what it is.
1233 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1234 if !ty.has_infer_types() {
1235 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1239 // If not, try resolving pending obligations as much as
1240 // possible. This can help substantially when there are
1241 // indirect dependencies that don't seem worth tracking
1243 self.select_obligations_where_possible();
1244 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1246 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1250 fn record_deferred_call_resolution(&self,
1251 closure_def_id: DefId,
1252 r: DeferredCallResolutionHandler<'tcx>) {
1253 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1254 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1257 fn remove_deferred_call_resolutions(&self,
1258 closure_def_id: DefId)
1259 -> Vec<DeferredCallResolutionHandler<'tcx>>
1261 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1262 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1265 pub fn tag(&self) -> String {
1266 let self_ptr: *const FnCtxt = self;
1267 format!("{:?}", self_ptr)
1270 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1271 match self.inh.locals.borrow().get(&nid) {
1274 span_err!(self.tcx().sess, span, E0513,
1275 "no type for local variable {}",
1277 self.tcx().types.err
1283 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1284 debug!("write_ty({}, {:?}) in fcx {}",
1285 node_id, ty, self.tag());
1286 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1289 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1290 if !substs.substs.is_noop() {
1291 debug!("write_substs({}, {:?}) in fcx {}",
1296 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1300 pub fn write_autoderef_adjustment(&self,
1301 node_id: ast::NodeId,
1303 self.write_adjustment(
1305 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1313 pub fn write_adjustment(&self,
1314 node_id: ast::NodeId,
1315 adj: adjustment::AutoAdjustment<'tcx>) {
1316 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1318 if adj.is_identity() {
1322 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1325 /// Basically whenever we are converting from a type scheme into
1326 /// the fn body space, we always want to normalize associated
1327 /// types as well. This function combines the two.
1328 fn instantiate_type_scheme<T>(&self,
1330 substs: &Substs<'tcx>,
1333 where T : TypeFoldable<'tcx>
1335 let value = value.subst(self.tcx(), substs);
1336 let result = self.normalize_associated_types_in(span, &value);
1337 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1344 /// As `instantiate_type_scheme`, but for the bounds found in a
1345 /// generic type scheme.
1346 fn instantiate_bounds(&self,
1348 substs: &Substs<'tcx>,
1349 bounds: &ty::GenericPredicates<'tcx>)
1350 -> ty::InstantiatedPredicates<'tcx>
1352 ty::InstantiatedPredicates {
1353 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1358 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1359 where T : TypeFoldable<'tcx>
1361 self.inh.normalize_associated_types_in(span, self.body_id, value)
1364 fn normalize_associated_type(&self,
1366 trait_ref: ty::TraitRef<'tcx>,
1367 item_name: ast::Name)
1370 let cause = traits::ObligationCause::new(span,
1372 traits::ObligationCauseCode::MiscObligation);
1376 .normalize_projection_type(self.infcx(),
1378 trait_ref: trait_ref,
1379 item_name: item_name,
1384 /// Instantiates the type in `did` with the generics in `path` and returns
1385 /// it (registering the necessary trait obligations along the way).
1387 /// Note that this function is only intended to be used with type-paths,
1388 /// not with value-paths.
1389 pub fn instantiate_type(&self,
1394 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1396 self.tcx().lookup_item_type(did);
1397 let type_predicates =
1398 self.tcx().lookup_predicates(did);
1399 let substs = astconv::ast_path_substs_for_ty(self, self,
1401 PathParamMode::Optional,
1402 &type_scheme.generics,
1403 path.segments.last().unwrap());
1404 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1406 self.instantiate_bounds(path.span, &substs, &type_predicates);
1407 self.add_obligations_for_parameters(
1408 traits::ObligationCause::new(
1411 traits::ItemObligation(did)),
1414 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1417 /// Return the dict-like variant corresponding to a given `Def`.
1418 pub fn def_struct_variant(&self,
1421 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1423 let (adt, variant) = match def {
1424 Def::Variant(enum_id, variant_id) => {
1425 let adt = self.tcx().lookup_adt_def(enum_id);
1426 (adt, adt.variant_with_id(variant_id))
1428 Def::Struct(did) | Def::TyAlias(did) => {
1429 let typ = self.tcx().lookup_item_type(did);
1430 if let ty::TyStruct(adt, _) = typ.ty.sty {
1431 (adt, adt.struct_variant())
1439 let var_kind = variant.kind();
1440 if var_kind == ty::VariantKind::Struct {
1441 Some((adt, variant))
1442 } else if var_kind == ty::VariantKind::Unit {
1443 if !self.tcx().sess.features.borrow().braced_empty_structs {
1444 let mut err = self.tcx().sess.struct_span_err(span,
1445 "empty structs and enum variants \
1446 with braces are unstable");
1447 fileline_help!(&mut err, span, "add #![feature(braced_empty_structs)] to \
1448 the crate features to enable");
1452 Some((adt, variant))
1458 pub fn write_nil(&self, node_id: ast::NodeId) {
1459 self.write_ty(node_id, self.tcx().mk_nil());
1461 pub fn write_error(&self, node_id: ast::NodeId) {
1462 self.write_ty(node_id, self.tcx().types.err);
1465 pub fn require_type_meets(&self,
1468 code: traits::ObligationCauseCode<'tcx>,
1469 bound: ty::BuiltinBound)
1471 self.register_builtin_bound(
1474 traits::ObligationCause::new(span, self.body_id, code));
1477 pub fn require_type_is_sized(&self,
1480 code: traits::ObligationCauseCode<'tcx>)
1482 self.require_type_meets(ty, span, code, ty::BoundSized);
1485 pub fn require_expr_have_sized_type(&self,
1487 code: traits::ObligationCauseCode<'tcx>)
1489 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1492 pub fn type_is_known_to_be_sized(&self,
1497 traits::type_known_to_meet_builtin_bound(self.infcx(),
1503 pub fn register_builtin_bound(&self,
1505 builtin_bound: ty::BuiltinBound,
1506 cause: traits::ObligationCause<'tcx>)
1508 self.inh.fulfillment_cx.borrow_mut()
1509 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1512 pub fn register_predicate(&self,
1513 obligation: traits::PredicateObligation<'tcx>)
1515 debug!("register_predicate({:?})",
1517 self.inh.fulfillment_cx
1519 .register_predicate_obligation(self.infcx(), obligation);
1522 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1523 let t = ast_ty_to_ty(self, self, ast_t);
1524 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1528 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1529 match self.inh.tables.borrow().node_types.get(&ex.id) {
1532 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1538 /// Apply `adjustment` to the type of `expr`
1539 pub fn adjust_expr_ty(&self,
1541 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1544 let raw_ty = self.expr_ty(expr);
1545 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1546 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1547 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1548 self.inh.tables.borrow().method_map.get(&method_call)
1549 .map(|method| resolve_ty(method.ty))
1553 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1554 match self.inh.tables.borrow().node_types.get(&id) {
1556 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1558 self.tcx().sess.bug(
1559 &format!("no type for node {}: {} in fcx {}",
1560 id, self.tcx().map.node_to_string(id),
1566 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1567 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1568 // it changes when we upgrade the snapshot compiler
1569 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1570 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1574 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1577 pub fn opt_node_ty_substs<F>(&self,
1580 F: FnOnce(&ty::ItemSubsts<'tcx>),
1582 match self.inh.tables.borrow().item_substs.get(&id) {
1588 pub fn mk_subty(&self,
1589 a_is_expected: bool,
1593 -> Result<(), TypeError<'tcx>> {
1594 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1597 pub fn mk_eqty(&self,
1598 a_is_expected: bool,
1602 -> Result<(), TypeError<'tcx>> {
1603 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1606 pub fn mk_subr(&self,
1607 origin: infer::SubregionOrigin<'tcx>,
1610 infer::mk_subr(self.infcx(), origin, sub, sup)
1613 pub fn type_error_message<M>(&self,
1616 actual_ty: Ty<'tcx>,
1617 err: Option<&TypeError<'tcx>>)
1618 where M: FnOnce(String) -> String,
1620 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1623 pub fn type_error_struct<M>(&self,
1626 actual_ty: Ty<'tcx>,
1627 err: Option<&TypeError<'tcx>>)
1628 -> DiagnosticBuilder<'tcx>
1629 where M: FnOnce(String) -> String,
1631 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1634 pub fn report_mismatched_types(&self,
1638 err: &TypeError<'tcx>) {
1639 self.infcx().report_mismatched_types(sp, e, a, err)
1642 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1643 /// outlive the region `r`.
1644 pub fn register_region_obligation(&self,
1647 cause: traits::ObligationCause<'tcx>)
1649 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1650 fulfillment_cx.register_region_obligation(ty, region, cause);
1653 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1654 /// outlive the region `r`.
1655 pub fn register_wf_obligation(&self,
1658 code: traits::ObligationCauseCode<'tcx>)
1660 // WF obligations never themselves fail, so no real need to give a detailed cause:
1661 let cause = traits::ObligationCause::new(span, self.body_id, code);
1662 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1665 pub fn register_old_wf_obligation(&self,
1668 code: traits::ObligationCauseCode<'tcx>)
1670 // Registers an "old-style" WF obligation that uses the
1671 // implicator code. This is basically a buggy version of
1672 // `register_wf_obligation` that is being kept around
1673 // temporarily just to help with phasing in the newer rules.
1675 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1676 let cause = traits::ObligationCause::new(span, self.body_id, code);
1677 self.register_region_obligation(ty, ty::ReEmpty, cause);
1680 /// Registers obligations that all types appearing in `substs` are well-formed.
1681 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1683 for &ty in &substs.types {
1684 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1688 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1689 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1690 /// trait/region obligations.
1692 /// For example, if there is a function:
1695 /// fn foo<'a,T:'a>(...)
1698 /// and a reference:
1704 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1705 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1706 pub fn add_obligations_for_parameters(&self,
1707 cause: traits::ObligationCause<'tcx>,
1708 predicates: &ty::InstantiatedPredicates<'tcx>)
1710 assert!(!predicates.has_escaping_regions());
1712 debug!("add_obligations_for_parameters(predicates={:?})",
1715 for obligation in traits::predicates_for_generics(cause, predicates) {
1716 self.register_predicate(obligation);
1720 // FIXME(arielb1): use this instead of field.ty everywhere
1721 pub fn field_ty(&self,
1723 field: ty::FieldDef<'tcx>,
1724 substs: &Substs<'tcx>)
1727 self.normalize_associated_types_in(span,
1728 &field.ty(self.tcx(), substs))
1731 // Only for fields! Returns <none> for methods>
1732 // Indifferent to privacy flags
1733 fn check_casts(&self) {
1734 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1735 for cast in deferred_cast_checks.drain(..) {
1740 /// Apply "fallbacks" to some types
1741 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1742 fn default_type_parameters(&self) {
1743 use middle::ty::error::UnconstrainedNumeric::Neither;
1744 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1745 for ty in &self.infcx().unsolved_variables() {
1746 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1747 if self.infcx().type_var_diverges(resolved) {
1748 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1750 match self.infcx().type_is_unconstrained_numeric(resolved) {
1751 UnconstrainedInt => {
1752 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1754 UnconstrainedFloat => {
1755 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1763 fn select_all_obligations_and_apply_defaults(&self) {
1764 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1765 self.new_select_all_obligations_and_apply_defaults();
1767 self.old_select_all_obligations_and_apply_defaults();
1771 // Implements old type inference fallback algorithm
1772 fn old_select_all_obligations_and_apply_defaults(&self) {
1773 self.select_obligations_where_possible();
1774 self.default_type_parameters();
1775 self.select_obligations_where_possible();
1778 fn new_select_all_obligations_and_apply_defaults(&self) {
1779 use middle::ty::error::UnconstrainedNumeric::Neither;
1780 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1782 // For the time being this errs on the side of being memory wasteful but provides better
1784 // let type_variables = self.infcx().type_variables.clone();
1786 // There is a possibility that this algorithm will have to run an arbitrary number of times
1787 // to terminate so we bound it by the compiler's recursion limit.
1788 for _ in 0..self.tcx().sess.recursion_limit.get() {
1789 // First we try to solve all obligations, it is possible that the last iteration
1790 // has made it possible to make more progress.
1791 self.select_obligations_where_possible();
1793 let mut conflicts = Vec::new();
1795 // Collect all unsolved type, integral and floating point variables.
1796 let unsolved_variables = self.inh.infcx.unsolved_variables();
1798 // We must collect the defaults *before* we do any unification. Because we have
1799 // directly attached defaults to the type variables any unification that occurs
1800 // will erase defaults causing conflicting defaults to be completely ignored.
1801 let default_map: FnvHashMap<_, _> =
1804 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1807 let mut unbound_tyvars = HashSet::new();
1809 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1811 // We loop over the unsolved variables, resolving them and if they are
1812 // and unconstrainted numeric type we add them to the set of unbound
1813 // variables. We do this so we only apply literal fallback to type
1814 // variables without defaults.
1815 for ty in &unsolved_variables {
1816 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1817 if self.infcx().type_var_diverges(resolved) {
1818 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1820 match self.infcx().type_is_unconstrained_numeric(resolved) {
1821 UnconstrainedInt | UnconstrainedFloat => {
1822 unbound_tyvars.insert(resolved);
1829 // We now remove any numeric types that also have defaults, and instead insert
1830 // the type variable with a defined fallback.
1831 for ty in &unsolved_variables {
1832 if let Some(_default) = default_map.get(ty) {
1833 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1835 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1838 match resolved.sty {
1839 ty::TyInfer(ty::TyVar(_)) => {
1840 unbound_tyvars.insert(ty);
1843 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1844 unbound_tyvars.insert(ty);
1845 if unbound_tyvars.contains(resolved) {
1846 unbound_tyvars.remove(resolved);
1855 // If there are no more fallbacks to apply at this point we have applied all possible
1856 // defaults and type inference will proceed as normal.
1857 if unbound_tyvars.is_empty() {
1861 // Finally we go through each of the unbound type variables and unify them with
1862 // the proper fallback, reporting a conflicting default error if any of the
1863 // unifications fail. We know it must be a conflicting default because the
1864 // variable would only be in `unbound_tyvars` and have a concrete value if
1865 // it had been solved by previously applying a default.
1867 // We wrap this in a transaction for error reporting, if we detect a conflict
1868 // we will rollback the inference context to its prior state so we can probe
1869 // for conflicts and correctly report them.
1872 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1873 for ty in &unbound_tyvars {
1874 if self.infcx().type_var_diverges(ty) {
1875 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1877 match self.infcx().type_is_unconstrained_numeric(ty) {
1878 UnconstrainedInt => {
1879 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1881 UnconstrainedFloat => {
1882 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1885 if let Some(default) = default_map.get(ty) {
1886 let default = default.clone();
1887 match infer::mk_eqty(self.infcx(), false,
1888 TypeOrigin::Misc(default.origin_span),
1892 conflicts.push((*ty, default));
1901 // If there are conflicts we rollback, otherwise commit
1902 if conflicts.len() > 0 {
1909 if conflicts.len() > 0 {
1910 // Loop through each conflicting default, figuring out the default that caused
1911 // a unification failure and then report an error for each.
1912 for (conflict, default) in conflicts {
1913 let conflicting_default =
1914 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1915 .unwrap_or(type_variable::Default {
1916 ty: self.infcx().next_ty_var(),
1917 origin_span: codemap::DUMMY_SP,
1918 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1921 // This is to ensure that we elimnate any non-determinism from the error
1922 // reporting by fixing an order, it doesn't matter what order we choose
1923 // just that it is consistent.
1924 let (first_default, second_default) =
1925 if default.def_id < conflicting_default.def_id {
1926 (default, conflicting_default)
1928 (conflicting_default, default)
1932 self.infcx().report_conflicting_default_types(
1933 first_default.origin_span,
1940 self.select_obligations_where_possible();
1943 // For use in error handling related to default type parameter fallback. We explicitly
1944 // apply the default that caused conflict first to a local version of the type variable
1945 // table then apply defaults until we find a conflict. That default must be the one
1946 // that caused conflict earlier.
1947 fn find_conflicting_default(&self,
1948 unbound_vars: &HashSet<Ty<'tcx>>,
1949 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1951 -> Option<type_variable::Default<'tcx>> {
1952 use middle::ty::error::UnconstrainedNumeric::Neither;
1953 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1955 // Ensure that we apply the conflicting default first
1956 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1957 unbound_tyvars.push(conflict);
1958 unbound_tyvars.extend(unbound_vars.iter());
1960 let mut result = None;
1961 // We run the same code as above applying defaults in order, this time when
1962 // we find the conflict we just return it for error reporting above.
1964 // We also run this inside snapshot that never commits so we can do error
1965 // reporting for more then one conflict.
1966 for ty in &unbound_tyvars {
1967 if self.infcx().type_var_diverges(ty) {
1968 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1970 match self.infcx().type_is_unconstrained_numeric(ty) {
1971 UnconstrainedInt => {
1972 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1974 UnconstrainedFloat => {
1975 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1978 if let Some(default) = default_map.get(ty) {
1979 let default = default.clone();
1980 match infer::mk_eqty(self.infcx(), false,
1981 TypeOrigin::Misc(default.origin_span),
1985 result = Some(default);
1997 fn select_all_obligations_or_error(&self) {
1998 debug!("select_all_obligations_or_error");
2000 // upvar inference should have ensured that all deferred call
2001 // resolutions are handled by now.
2002 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2004 self.select_all_obligations_and_apply_defaults();
2006 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
2007 match fulfillment_cx.select_all_or_error(self.infcx()) {
2009 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2013 /// Select as many obligations as we can at present.
2014 fn select_obligations_where_possible(&self) {
2016 self.inh.fulfillment_cx
2018 .select_where_possible(self.infcx())
2021 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2025 fn private_item_is_visible(&self, def_id: DefId) -> bool {
2026 match self.tcx().map.as_local_node_id(def_id) {
2027 Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2028 None => false, // Private items from other crates are never visible
2033 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2034 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2035 Some(self.base_object_lifetime_default(span))
2038 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2039 // RFC #599 specifies that object lifetime defaults take
2040 // precedence over other defaults. But within a fn body we
2041 // don't have a *default* region, rather we use inference to
2042 // find the *correct* region, which is strictly more general
2043 // (and anyway, within a fn body the right region may not even
2044 // be something the user can write explicitly, since it might
2045 // be some expression).
2046 self.infcx().next_region_var(infer::MiscVariable(span))
2049 fn anon_regions(&self, span: Span, count: usize)
2050 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2051 Ok((0..count).map(|_| {
2052 self.infcx().next_region_var(infer::MiscVariable(span))
2057 /// Whether `autoderef` requires types to resolve.
2058 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2059 pub enum UnresolvedTypeAction {
2060 /// Produce an error and return `TyError` whenever a type cannot
2061 /// be resolved (i.e. it is `TyInfer`).
2063 /// Go on without emitting any errors, and return the unresolved
2064 /// type. Useful for probing, e.g. in coercions.
2068 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2069 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2071 /// Note: this method does not modify the adjustments table. The caller is responsible for
2072 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2073 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2076 opt_expr: Option<&hir::Expr>,
2077 unresolved_type_action: UnresolvedTypeAction,
2078 mut lvalue_pref: LvaluePreference,
2080 -> (Ty<'tcx>, usize, Option<T>)
2081 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2083 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2088 let mut t = base_ty;
2089 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2090 let resolved_t = match unresolved_type_action {
2091 UnresolvedTypeAction::Error => {
2092 structurally_resolved_type(fcx, sp, t)
2094 UnresolvedTypeAction::Ignore => {
2095 // We can continue even when the type cannot be resolved
2096 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2097 // and `try_overloaded_deref` both simply return `None`
2098 // in such a case without producing spurious errors.
2099 fcx.resolve_type_vars_if_possible(t)
2102 if resolved_t.references_error() {
2103 return (resolved_t, autoderefs, None);
2106 match should_stop(resolved_t, autoderefs) {
2107 Some(x) => return (resolved_t, autoderefs, Some(x)),
2111 // Otherwise, deref if type is derefable:
2112 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2113 Some(mt) => Some(mt),
2116 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2118 // Super subtle: it might seem as though we should
2119 // pass `opt_expr` to `try_overloaded_deref`, so that
2120 // the (implicit) autoref of using an overloaded deref
2121 // would get added to the adjustment table. However we
2122 // do not do that, because it's kind of a
2123 // "meta-adjustment" -- instead, we just leave it
2124 // unrecorded and know that there "will be" an
2125 // autoref. regionck and other bits of the code base,
2126 // when they encounter an overloaded autoderef, have
2127 // to do some reconstructive surgery. This is a pretty
2128 // complex mess that is begging for a proper MIR.
2129 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2135 if mt.mutbl == hir::MutImmutable {
2136 lvalue_pref = NoPreference;
2139 None => return (resolved_t, autoderefs, None)
2143 // We've reached the recursion limit, error gracefully.
2144 span_err!(fcx.tcx().sess, sp, E0055,
2145 "reached the recursion limit while auto-dereferencing {:?}",
2147 (fcx.tcx().types.err, 0, None)
2150 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2152 method_call: Option<MethodCall>,
2153 base_expr: Option<&hir::Expr>,
2155 lvalue_pref: LvaluePreference)
2156 -> Option<ty::TypeAndMut<'tcx>>
2158 // Try DerefMut first, if preferred.
2159 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2160 (PreferMutLvalue, Some(trait_did)) => {
2161 method::lookup_in_trait(fcx, span, base_expr,
2162 token::intern("deref_mut"), trait_did,
2168 // Otherwise, fall back to Deref.
2169 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2170 (None, Some(trait_did)) => {
2171 method::lookup_in_trait(fcx, span, base_expr,
2172 token::intern("deref"), trait_did,
2175 (method, _) => method
2178 make_overloaded_lvalue_return_type(fcx, method_call, method)
2181 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2182 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2183 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2184 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2185 method_call: Option<MethodCall>,
2186 method: Option<MethodCallee<'tcx>>)
2187 -> Option<ty::TypeAndMut<'tcx>>
2191 // extract method return type, which will be &T;
2192 // all LB regions should have been instantiated during method lookup
2193 let ret_ty = method.ty.fn_ret();
2194 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2196 if let Some(method_call) = method_call {
2197 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2200 // method returns &T, but the type as visible to user is T, so deref
2201 ret_ty.builtin_deref(true, NoPreference)
2207 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2209 base_expr: &'tcx hir::Expr,
2212 lvalue_pref: LvaluePreference)
2213 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2215 // FIXME(#18741) -- this is almost but not quite the same as the
2216 // autoderef that normal method probing does. They could likely be
2219 let (ty, autoderefs, final_mt) = autoderef(fcx,
2223 UnresolvedTypeAction::Error,
2226 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2227 adj_ty, idx, false, lvalue_pref, idx_ty)
2230 if final_mt.is_some() {
2234 // After we have fully autoderef'd, if the resulting type is [T; n], then
2235 // do a final unsized coercion to yield [T].
2236 if let ty::TyArray(element_ty, _) = ty.sty {
2237 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2238 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2239 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2245 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2246 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2247 /// This loop implements one step in that search; the autoderef loop is implemented by
2248 /// `lookup_indexing`.
2249 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2250 method_call: MethodCall,
2252 base_expr: &'tcx hir::Expr,
2253 adjusted_ty: Ty<'tcx>,
2256 lvalue_pref: LvaluePreference,
2258 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2260 let tcx = fcx.tcx();
2261 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2262 autoderefs={}, unsize={}, index_ty={:?})",
2270 let input_ty = fcx.infcx().next_ty_var();
2272 // First, try built-in indexing.
2273 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2274 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2275 debug!("try_index_step: success, using built-in indexing");
2276 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2278 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2279 return Some((tcx.types.usize, ty));
2284 // Try `IndexMut` first, if preferred.
2285 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2286 (PreferMutLvalue, Some(trait_did)) => {
2287 method::lookup_in_trait_adjusted(fcx,
2290 token::intern("index_mut"),
2295 Some(vec![input_ty]))
2300 // Otherwise, fall back to `Index`.
2301 let method = match (method, tcx.lang_items.index_trait()) {
2302 (None, Some(trait_did)) => {
2303 method::lookup_in_trait_adjusted(fcx,
2306 token::intern("index"),
2311 Some(vec![input_ty]))
2313 (method, _) => method,
2316 // If some lookup succeeds, write callee into table and extract index/element
2317 // type from the method signature.
2318 // If some lookup succeeded, install method in table
2319 method.and_then(|method| {
2320 debug!("try_index_step: success, using overloaded indexing");
2321 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2322 map(|ret| (input_ty, ret.ty))
2326 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2328 method_fn_ty: Ty<'tcx>,
2329 callee_expr: &'tcx hir::Expr,
2330 args_no_rcvr: &'tcx [P<hir::Expr>],
2331 tuple_arguments: TupleArgumentsFlag,
2332 expected: Expectation<'tcx>)
2333 -> ty::FnOutput<'tcx> {
2334 if method_fn_ty.references_error() {
2335 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2337 let err_inputs = match tuple_arguments {
2338 DontTupleArguments => err_inputs,
2339 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2342 check_argument_types(fcx,
2349 ty::FnConverging(fcx.tcx().types.err)
2351 match method_fn_ty.sty {
2352 ty::TyBareFn(_, ref fty) => {
2353 // HACK(eddyb) ignore self in the definition (see above).
2354 let expected_arg_tys = expected_types_for_fn_args(fcx,
2358 &fty.sig.0.inputs[1..]);
2359 check_argument_types(fcx,
2361 &fty.sig.0.inputs[1..],
2362 &expected_arg_tys[..],
2369 fcx.tcx().sess.span_bug(callee_expr.span,
2370 "method without bare fn type");
2376 /// Generic function that factors out common logic from function calls, method calls and overloaded
2378 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2380 fn_inputs: &[Ty<'tcx>],
2381 expected_arg_tys: &[Ty<'tcx>],
2382 args: &'tcx [P<hir::Expr>],
2384 tuple_arguments: TupleArgumentsFlag) {
2385 let tcx = fcx.ccx.tcx;
2387 // Grab the argument types, supplying fresh type variables
2388 // if the wrong number of arguments were supplied
2389 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2395 // All the input types from the fn signature must outlive the call
2396 // so as to validate implied bounds.
2397 for &fn_input_ty in fn_inputs {
2398 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2401 let mut expected_arg_tys = expected_arg_tys;
2402 let expected_arg_count = fn_inputs.len();
2403 let formal_tys = if tuple_arguments == TupleArguments {
2404 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2405 match tuple_type.sty {
2406 ty::TyTuple(ref arg_types) => {
2407 if arg_types.len() != args.len() {
2408 span_err!(tcx.sess, sp, E0057,
2409 "this function takes {} parameter{} but {} parameter{} supplied",
2411 if arg_types.len() == 1 {""} else {"s"},
2413 if args.len() == 1 {" was"} else {"s were"});
2414 expected_arg_tys = &[];
2415 err_args(fcx.tcx(), args.len())
2417 expected_arg_tys = match expected_arg_tys.get(0) {
2418 Some(&ty) => match ty.sty {
2419 ty::TyTuple(ref tys) => &tys,
2424 (*arg_types).clone()
2428 span_err!(tcx.sess, sp, E0059,
2429 "cannot use call notation; the first type parameter \
2430 for the function trait is neither a tuple nor unit");
2431 expected_arg_tys = &[];
2432 err_args(fcx.tcx(), args.len())
2435 } else if expected_arg_count == supplied_arg_count {
2437 } else if variadic {
2438 if supplied_arg_count >= expected_arg_count {
2441 span_err!(tcx.sess, sp, E0060,
2442 "this function takes at least {} parameter{} \
2443 but {} parameter{} supplied",
2445 if expected_arg_count == 1 {""} else {"s"},
2447 if supplied_arg_count == 1 {" was"} else {"s were"});
2448 expected_arg_tys = &[];
2449 err_args(fcx.tcx(), supplied_arg_count)
2452 span_err!(tcx.sess, sp, E0061,
2453 "this function takes {} parameter{} but {} parameter{} supplied",
2455 if expected_arg_count == 1 {""} else {"s"},
2457 if supplied_arg_count == 1 {" was"} else {"s were"});
2458 expected_arg_tys = &[];
2459 err_args(fcx.tcx(), supplied_arg_count)
2462 debug!("check_argument_types: formal_tys={:?}",
2463 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2465 // Check the arguments.
2466 // We do this in a pretty awful way: first we typecheck any arguments
2467 // that are not anonymous functions, then we typecheck the anonymous
2468 // functions. This is so that we have more information about the types
2469 // of arguments when we typecheck the functions. This isn't really the
2470 // right way to do this.
2471 let xs = [false, true];
2472 let mut any_diverges = false; // has any of the arguments diverged?
2473 let mut warned = false; // have we already warned about unreachable code?
2474 for check_blocks in &xs {
2475 let check_blocks = *check_blocks;
2476 debug!("check_blocks={}", check_blocks);
2478 // More awful hacks: before we check argument types, try to do
2479 // an "opportunistic" vtable resolution of any trait bounds on
2480 // the call. This helps coercions.
2482 fcx.select_obligations_where_possible();
2485 // For variadic functions, we don't have a declared type for all of
2486 // the arguments hence we only do our usual type checking with
2487 // the arguments who's types we do know.
2488 let t = if variadic {
2490 } else if tuple_arguments == TupleArguments {
2495 for (i, arg) in args.iter().take(t).enumerate() {
2496 if any_diverges && !warned {
2500 .add_lint(lint::builtin::UNREACHABLE_CODE,
2503 "unreachable expression".to_string());
2506 let is_block = match arg.node {
2507 hir::ExprClosure(..) => true,
2511 if is_block == check_blocks {
2512 debug!("checking the argument");
2513 let formal_ty = formal_tys[i];
2515 // The special-cased logic below has three functions:
2516 // 1. Provide as good of an expected type as possible.
2517 let expected = expected_arg_tys.get(i).map(|&ty| {
2518 Expectation::rvalue_hint(fcx.tcx(), ty)
2521 check_expr_with_unifier(fcx,
2523 expected.unwrap_or(ExpectHasType(formal_ty)),
2525 // 2. Coerce to the most detailed type that could be coerced
2526 // to, which is `expected_ty` if `rvalue_hint` returns an
2527 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2528 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2529 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2531 // 3. Relate the expected type and the formal one,
2532 // if the expected type was used for the coercion.
2533 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2537 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2538 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2541 if any_diverges && !warned {
2542 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2546 .add_lint(lint::builtin::UNREACHABLE_CODE,
2549 "unreachable call".to_string());
2555 // We also need to make sure we at least write the ty of the other
2556 // arguments which we skipped above.
2558 for arg in args.iter().skip(expected_arg_count) {
2559 check_expr(fcx, &arg);
2561 // There are a few types which get autopromoted when passed via varargs
2562 // in C but we just error out instead and require explicit casts.
2563 let arg_ty = structurally_resolved_type(fcx, arg.span,
2566 ty::TyFloat(ast::FloatTy::F32) => {
2567 fcx.type_error_message(arg.span,
2569 format!("can't pass an {} to variadic \
2570 function, cast to c_double", t)
2573 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2574 fcx.type_error_message(arg.span, |t| {
2575 format!("can't pass {} to variadic \
2576 function, cast to c_int",
2580 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2581 fcx.type_error_message(arg.span, |t| {
2582 format!("can't pass {} to variadic \
2583 function, cast to c_uint",
2593 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2594 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2595 (0..len).map(|_| tcx.types.err).collect()
2598 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2599 call_expr: &hir::Expr,
2600 output: ty::FnOutput<'tcx>) {
2601 fcx.write_ty(call_expr.id, match output {
2602 ty::FnConverging(output_ty) => output_ty,
2603 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2607 // AST fragment checking
2608 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2610 expected: Expectation<'tcx>)
2613 let tcx = fcx.ccx.tcx;
2616 ast::LitKind::Str(..) => tcx.mk_static_str(),
2617 ast::LitKind::ByteStr(ref v) => {
2618 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2619 tcx.mk_array(tcx.types.u8, v.len()))
2621 ast::LitKind::Byte(_) => tcx.types.u8,
2622 ast::LitKind::Char(_) => tcx.types.char,
2623 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2624 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2625 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2626 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2628 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2629 ty::TyChar => Some(tcx.types.u8),
2630 ty::TyRawPtr(..) => Some(tcx.types.usize),
2631 ty::TyBareFn(..) => Some(tcx.types.usize),
2635 opt_ty.unwrap_or_else(
2636 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2638 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2639 ast::LitKind::FloatUnsuffixed(_) => {
2640 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2642 ty::TyFloat(_) => Some(ty),
2646 opt_ty.unwrap_or_else(
2647 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2649 ast::LitKind::Bool(_) => tcx.types.bool
2653 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2654 expr: &'tcx hir::Expr,
2655 expected: Ty<'tcx>) {
2656 check_expr_with_unifier(
2657 fcx, expr, ExpectHasType(expected), NoPreference,
2658 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2661 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2662 expr: &'tcx hir::Expr,
2663 expected: Ty<'tcx>) {
2664 check_expr_with_unifier(
2665 fcx, expr, ExpectHasType(expected), NoPreference,
2666 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2669 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2670 expr: &'tcx hir::Expr,
2671 expected: Ty<'tcx>) {
2672 check_expr_with_unifier(
2673 fcx, expr, ExpectHasType(expected), NoPreference,
2674 || demand::coerce(fcx, expr.span, expected, expr));
2677 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2678 expected: Ty<'tcx>) {
2679 check_expr_with_unifier(
2680 fcx, expr, ExpectHasType(expected), NoPreference,
2684 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2685 expr: &'tcx hir::Expr,
2686 expected: Expectation<'tcx>) {
2687 check_expr_with_unifier(
2688 fcx, expr, expected, NoPreference,
2692 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2693 expr: &'tcx hir::Expr,
2694 expected: Expectation<'tcx>,
2695 lvalue_pref: LvaluePreference)
2697 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2700 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2701 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2704 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2705 lvalue_pref: LvaluePreference) {
2706 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2709 // determine the `self` type, using fresh variables for all variables
2710 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2711 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2713 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2714 span: Span, // (potential) receiver for this impl
2716 -> TypeAndSubsts<'tcx> {
2717 let tcx = fcx.tcx();
2719 let ity = tcx.lookup_item_type(did);
2720 let (tps, rps, raw_ty) =
2721 (ity.generics.types.get_slice(subst::TypeSpace),
2722 ity.generics.regions.get_slice(subst::TypeSpace),
2725 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2727 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2728 let mut substs = subst::Substs::new(
2729 VecPerParamSpace::empty(),
2730 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2731 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2732 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2734 TypeAndSubsts { substs: substs, ty: substd_ty }
2737 /// Controls whether the arguments are tupled. This is used for the call
2740 /// Tupling means that all call-side arguments are packed into a tuple and
2741 /// passed as a single parameter. For example, if tupling is enabled, this
2744 /// fn f(x: (isize, isize))
2746 /// Can be called as:
2753 #[derive(Clone, Eq, PartialEq)]
2754 enum TupleArgumentsFlag {
2759 /// Unifies the return type with the expected type early, for more coercions
2760 /// and forward type information on the argument expressions.
2761 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2763 expected_ret: Expectation<'tcx>,
2764 formal_ret: ty::FnOutput<'tcx>,
2765 formal_args: &[Ty<'tcx>])
2767 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2768 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2769 fcx.infcx().commit_regions_if_ok(|| {
2770 // Attempt to apply a subtyping relationship between the formal
2771 // return type (likely containing type variables if the function
2772 // is polymorphic) and the expected return type.
2773 // No argument expectations are produced if unification fails.
2774 let origin = TypeOrigin::Misc(call_span);
2775 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2776 // FIXME(#15760) can't use try! here, FromError doesn't default
2777 // to identity so the resulting type is not constrained.
2778 if let Err(e) = ures {
2782 // Record all the argument types, with the substitutions
2783 // produced from the above subtyping unification.
2784 Ok(formal_args.iter().map(|ty| {
2785 fcx.infcx().resolve_type_vars_if_possible(ty)
2791 }).unwrap_or(vec![]);
2792 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2793 formal_args, formal_ret,
2794 expected_args, expected_ret);
2799 /// If an expression has any sub-expressions that result in a type error,
2800 /// inspecting that expression's type with `ty.references_error()` will return
2801 /// true. Likewise, if an expression is known to diverge, inspecting its
2802 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2803 /// strict, _|_ can appear in the type of an expression that does not,
2804 /// itself, diverge: for example, fn() -> _|_.)
2805 /// Note that inspecting a type's structure *directly* may expose the fact
2806 /// that there are actually multiple representations for `TyError`, so avoid
2807 /// that when err needs to be handled differently.
2808 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2809 expr: &'tcx hir::Expr,
2810 expected: Expectation<'tcx>,
2811 lvalue_pref: LvaluePreference,
2815 debug!(">> typechecking: expr={:?} expected={:?}",
2818 // Checks a method call.
2819 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2820 expr: &'tcx hir::Expr,
2821 method_name: Spanned<ast::Name>,
2822 args: &'tcx [P<hir::Expr>],
2824 expected: Expectation<'tcx>,
2825 lvalue_pref: LvaluePreference) {
2826 let rcvr = &args[0];
2827 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2829 // no need to check for bot/err -- callee does that
2830 let expr_t = structurally_resolved_type(fcx,
2832 fcx.expr_ty(&rcvr));
2834 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2835 let fn_ty = match method::lookup(fcx,
2843 let method_ty = method.ty;
2844 let method_call = MethodCall::expr(expr.id);
2845 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2849 if method_name.node != special_idents::invalid.name {
2850 method::report_error(fcx, method_name.span, expr_t,
2851 method_name.node, Some(rcvr), error);
2853 fcx.write_error(expr.id);
2858 // Call the generic checker.
2859 let ret_ty = check_method_argument_types(fcx,
2867 write_call(fcx, expr, ret_ty);
2870 // A generic function for checking the then and else in an if
2872 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2873 cond_expr: &'tcx hir::Expr,
2874 then_blk: &'tcx hir::Block,
2875 opt_else_expr: Option<&'tcx hir::Expr>,
2878 expected: Expectation<'tcx>) {
2879 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2881 let expected = expected.adjust_for_branches(fcx);
2882 check_block_with_expected(fcx, then_blk, expected);
2883 let then_ty = fcx.node_ty(then_blk.id);
2885 let branches_ty = match opt_else_expr {
2886 Some(ref else_expr) => {
2887 check_expr_with_expectation(fcx, &else_expr, expected);
2888 let else_ty = fcx.expr_ty(&else_expr);
2889 infer::common_supertype(fcx.infcx(),
2890 TypeOrigin::IfExpression(sp),
2896 infer::common_supertype(fcx.infcx(),
2897 TypeOrigin::IfExpressionWithNoElse(sp),
2904 let cond_ty = fcx.expr_ty(cond_expr);
2905 let if_ty = if cond_ty.references_error() {
2911 fcx.write_ty(id, if_ty);
2914 // Check field access expressions
2915 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2916 expr: &'tcx hir::Expr,
2917 lvalue_pref: LvaluePreference,
2918 base: &'tcx hir::Expr,
2919 field: &Spanned<ast::Name>) {
2920 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2921 let expr_t = structurally_resolved_type(fcx, expr.span,
2923 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2924 let (_, autoderefs, field_ty) = autoderef(fcx,
2928 UnresolvedTypeAction::Error,
2932 ty::TyStruct(base_def, substs) => {
2933 debug!("struct named {:?}", base_t);
2934 base_def.struct_variant()
2935 .find_field_named(field.node)
2936 .map(|f| fcx.field_ty(expr.span, f, substs))
2943 fcx.write_ty(expr.id, field_ty);
2944 fcx.write_autoderef_adjustment(base.id, autoderefs);
2950 if field.node == special_idents::invalid.name {
2951 fcx.write_error(expr.id);
2955 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2956 fcx.type_error_struct(field.span,
2958 format!("attempted to take value of method `{}` on type \
2959 `{}`", field.node, actual)
2962 .fileline_help(field.span,
2963 "maybe a `()` to call it is missing? \
2964 If not, try an anonymous function")
2967 let mut err = fcx.type_error_struct(
2970 format!("attempted access of field `{}` on \
2971 type `{}`, but no field with that \
2977 if let ty::TyStruct(def, _) = expr_t.sty {
2978 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2983 fcx.write_error(expr.id);
2986 // displays hints about the closest matches in field names
2987 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2988 variant: ty::VariantDef<'tcx>,
2989 field: &Spanned<ast::Name>,
2990 skip : Vec<InternedString>) {
2991 let name = field.node.as_str();
2992 let names = variant.fields
2994 .filter_map(|ref field| {
2995 // ignore already set fields and private fields from non-local crates
2996 if skip.iter().any(|x| *x == field.name.as_str()) ||
2997 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3004 // only find fits with at least one matching letter
3005 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3006 err.span_help(field.span,
3007 &format!("did you mean `{}`?", name));
3011 // Check tuple index expressions
3012 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3013 expr: &'tcx hir::Expr,
3014 lvalue_pref: LvaluePreference,
3015 base: &'tcx hir::Expr,
3016 idx: codemap::Spanned<usize>) {
3017 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3018 let expr_t = structurally_resolved_type(fcx, expr.span,
3020 let mut tuple_like = false;
3021 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3022 let (_, autoderefs, field_ty) = autoderef(fcx,
3026 UnresolvedTypeAction::Error,
3030 ty::TyStruct(base_def, substs) => {
3031 tuple_like = base_def.struct_variant().is_tuple_struct();
3033 debug!("tuple struct named {:?}", base_t);
3034 base_def.struct_variant()
3037 .map(|f| fcx.field_ty(expr.span, f, substs))
3042 ty::TyTuple(ref v) => {
3044 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3051 fcx.write_ty(expr.id, field_ty);
3052 fcx.write_autoderef_adjustment(base.id, autoderefs);
3057 fcx.type_error_message(
3061 format!("attempted out-of-bounds tuple index `{}` on \
3066 format!("attempted tuple index `{}` on type `{}`, but the \
3067 type was not a tuple or tuple struct",
3074 fcx.write_error(expr.id);
3077 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3079 variant: ty::VariantDef<'tcx>,
3081 skip_fields: &[hir::Field]) {
3082 let mut err = fcx.type_error_struct(
3084 |actual| if let ty::TyEnum(..) = ty.sty {
3085 format!("struct variant `{}::{}` has no field named `{}`",
3086 actual, variant.name.as_str(), field.name.node)
3088 format!("structure `{}` has no field named `{}`",
3089 actual, field.name.node)
3093 // prevent all specified fields from being suggested
3094 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3095 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3099 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3102 variant: ty::VariantDef<'tcx>,
3103 ast_fields: &'tcx [hir::Field],
3104 check_completeness: bool) {
3105 let tcx = fcx.ccx.tcx;
3106 let substs = match adt_ty.sty {
3107 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3108 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3111 let mut remaining_fields = FnvHashMap();
3112 for field in &variant.fields {
3113 remaining_fields.insert(field.name, field);
3116 let mut error_happened = false;
3118 // Typecheck each field.
3119 for field in ast_fields {
3120 let expected_field_type;
3122 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3123 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3125 error_happened = true;
3126 expected_field_type = tcx.types.err;
3127 if let Some(_) = variant.find_field_named(field.name.node) {
3128 span_err!(fcx.tcx().sess, field.name.span, E0062,
3129 "field `{}` specified more than once",
3132 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3136 // Make sure to give a type to the field even if there's
3137 // an error, so we can continue typechecking
3138 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3141 // Make sure the programmer specified all the fields.
3142 if check_completeness &&
3144 !remaining_fields.is_empty()
3146 span_err!(tcx.sess, span, E0063,
3147 "missing field{} {} in initializer of `{}`",
3148 if remaining_fields.len() == 1 {""} else {"s"},
3149 remaining_fields.keys()
3150 .map(|n| format!("`{}`", n))
3151 .collect::<Vec<_>>()
3158 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3160 fields: &'tcx [hir::Field],
3161 base_expr: &'tcx Option<P<hir::Expr>>) {
3162 // Make sure to still write the types
3163 // otherwise we might ICE
3164 fcx.write_error(id);
3165 for field in fields {
3166 check_expr(fcx, &field.expr);
3169 Some(ref base) => check_expr(fcx, &base),
3174 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3177 fields: &'tcx [hir::Field],
3178 base_expr: &'tcx Option<P<hir::Expr>>)
3180 let tcx = fcx.tcx();
3182 // Find the relevant variant
3183 let def = lookup_full_def(tcx, path.span, expr.id);
3184 if def == Def::Err {
3185 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3188 let variant = match fcx.def_struct_variant(def, path.span) {
3189 Some((_, variant)) => variant,
3191 span_err!(fcx.tcx().sess, path.span, E0071,
3192 "`{}` does not name a structure",
3193 pprust::path_to_string(path));
3194 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3199 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3200 fcx.write_ty(expr.id, expr_ty);
3202 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3203 base_expr.is_none());
3204 if let &Some(ref base_expr) = base_expr {
3205 check_expr_has_type(fcx, base_expr, expr_ty);
3207 ty::TyStruct(adt, substs) => {
3208 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3210 adt.struct_variant().fields.iter().map(|f| {
3211 fcx.normalize_associated_types_in(
3212 expr.span, &f.ty(tcx, substs)
3218 span_err!(tcx.sess, base_expr.span, E0436,
3219 "functional record update syntax requires a struct");
3225 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3227 let tcx = fcx.ccx.tcx;
3230 hir::ExprBox(ref subexpr) => {
3231 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3233 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3237 check_expr_with_expectation(fcx, subexpr, expected_inner);
3238 let referent_ty = fcx.expr_ty(&subexpr);
3239 fcx.write_ty(id, tcx.mk_box(referent_ty));
3242 hir::ExprLit(ref lit) => {
3243 let typ = check_lit(fcx, &lit, expected);
3244 fcx.write_ty(id, typ);
3246 hir::ExprBinary(op, ref lhs, ref rhs) => {
3247 op::check_binop(fcx, expr, op, lhs, rhs);
3249 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3250 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3252 hir::ExprUnary(unop, ref oprnd) => {
3253 let expected_inner = match unop {
3254 hir::UnNot | hir::UnNeg => {
3261 let lvalue_pref = match unop {
3262 hir::UnDeref => lvalue_pref,
3265 check_expr_with_expectation_and_lvalue_pref(
3266 fcx, &oprnd, expected_inner, lvalue_pref);
3267 let mut oprnd_t = fcx.expr_ty(&oprnd);
3269 if !oprnd_t.references_error() {
3272 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3273 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3275 None => match try_overloaded_deref(fcx, expr.span,
3276 Some(MethodCall::expr(expr.id)),
3277 Some(&oprnd), oprnd_t, lvalue_pref) {
3280 fcx.type_error_message(expr.span, |actual| {
3281 format!("type `{}` cannot be \
3282 dereferenced", actual)
3290 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3292 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3293 oprnd_t = op::check_user_unop(fcx, "!", "not",
3294 tcx.lang_items.not_trait(),
3295 expr, &oprnd, oprnd_t, unop);
3299 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3301 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3302 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3303 tcx.lang_items.neg_trait(),
3304 expr, &oprnd, oprnd_t, unop);
3309 fcx.write_ty(id, oprnd_t);
3311 hir::ExprAddrOf(mutbl, ref oprnd) => {
3312 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3314 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3315 if fcx.tcx().expr_is_lval(&oprnd) {
3316 // Lvalues may legitimately have unsized types.
3317 // For example, dereferences of a fat pointer and
3318 // the last field of a struct can be unsized.
3319 ExpectHasType(mt.ty)
3321 Expectation::rvalue_hint(tcx, mt.ty)
3327 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3328 check_expr_with_expectation_and_lvalue_pref(fcx,
3333 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3334 let oprnd_t = if tm.ty.references_error() {
3337 // Note: at this point, we cannot say what the best lifetime
3338 // is to use for resulting pointer. We want to use the
3339 // shortest lifetime possible so as to avoid spurious borrowck
3340 // errors. Moreover, the longest lifetime will depend on the
3341 // precise details of the value whose address is being taken
3342 // (and how long it is valid), which we don't know yet until type
3343 // inference is complete.
3345 // Therefore, here we simply generate a region variable. The
3346 // region inferencer will then select the ultimate value.
3347 // Finally, borrowck is charged with guaranteeing that the
3348 // value whose address was taken can actually be made to live
3349 // as long as it needs to live.
3350 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3351 tcx.mk_ref(tcx.mk_region(region), tm)
3353 fcx.write_ty(id, oprnd_t);
3355 hir::ExprPath(ref maybe_qself, ref path) => {
3356 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3357 fcx.to_ty(&qself.ty)
3360 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3362 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3363 // Create some fake resolution that can't possibly be a type.
3364 def::PathResolution {
3365 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3366 depth: path.segments.len()
3369 tcx.sess.span_bug(expr.span,
3370 &format!("unbound path {:?}", expr))
3373 if let Some((opt_ty, segments, def)) =
3374 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3375 expr.span, expr.id) {
3376 if def != Def::Err {
3377 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3380 instantiate_path(fcx,
3389 fcx.write_ty(id, fcx.tcx().types.err);
3393 // We always require that the type provided as the value for
3394 // a type parameter outlives the moment of instantiation.
3395 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3396 fcx.add_wf_bounds(&item_substs.substs, expr);
3399 hir::ExprInlineAsm(ref ia) => {
3400 for &(_, ref input) in &ia.inputs {
3401 check_expr(fcx, &input);
3403 for out in &ia.outputs {
3404 check_expr(fcx, &out.expr);
3408 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3409 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3410 hir::ExprRet(ref expr_opt) => {
3412 ty::FnConverging(result_type) => {
3415 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3416 result_type, fcx.tcx().mk_nil()) {
3417 span_err!(tcx.sess, expr.span, E0069,
3418 "`return;` in a function whose return type is \
3422 check_expr_coercable_to_type(fcx, &e, result_type);
3426 ty::FnDiverging => {
3427 if let Some(ref e) = *expr_opt {
3428 check_expr(fcx, &e);
3430 span_err!(tcx.sess, expr.span, E0166,
3431 "`return` in a function declared as diverging");
3434 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3436 hir::ExprAssign(ref lhs, ref rhs) => {
3437 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3439 let tcx = fcx.tcx();
3440 if !tcx.expr_is_lval(&lhs) {
3441 span_err!(tcx.sess, expr.span, E0070,
3442 "invalid left-hand side expression");
3445 let lhs_ty = fcx.expr_ty(&lhs);
3446 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3447 let rhs_ty = fcx.expr_ty(&rhs);
3449 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3451 if lhs_ty.references_error() || rhs_ty.references_error() {
3452 fcx.write_error(id);
3457 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3458 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3459 id, expr.span, expected);
3461 hir::ExprWhile(ref cond, ref body, _) => {
3462 check_expr_has_type(fcx, &cond, tcx.types.bool);
3463 check_block_no_value(fcx, &body);
3464 let cond_ty = fcx.expr_ty(&cond);
3465 let body_ty = fcx.node_ty(body.id);
3466 if cond_ty.references_error() || body_ty.references_error() {
3467 fcx.write_error(id);
3473 hir::ExprLoop(ref body, _) => {
3474 check_block_no_value(fcx, &body);
3475 if !may_break(tcx, expr.id, &body) {
3476 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3481 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3482 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3484 hir::ExprClosure(capture, ref decl, ref body) => {
3485 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3487 hir::ExprBlock(ref b) => {
3488 check_block_with_expected(fcx, &b, expected);
3489 fcx.write_ty(id, fcx.node_ty(b.id));
3491 hir::ExprCall(ref callee, ref args) => {
3492 callee::check_call(fcx, expr, &callee, &args[..], expected);
3494 // we must check that return type of called functions is WF:
3495 let ret_ty = fcx.expr_ty(expr);
3496 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3498 hir::ExprMethodCall(name, ref tps, ref args) => {
3499 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3500 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3501 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3503 fcx.write_error(id);
3506 hir::ExprCast(ref e, ref t) => {
3507 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3508 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3511 // Find the type of `e`. Supply hints based on the type we are casting to,
3513 let t_cast = fcx.to_ty(t);
3514 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3515 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3516 let t_expr = fcx.expr_ty(e);
3517 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3519 // Eagerly check for some obvious errors.
3520 if t_expr.references_error() || t_cast.references_error() {
3521 fcx.write_error(id);
3522 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3523 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3525 // Write a type for the whole expression, assuming everything is going
3527 fcx.write_ty(id, t_cast);
3529 // Defer other checks until we're done type checking.
3530 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3531 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3532 deferred_cast_checks.push(cast_check);
3535 hir::ExprType(ref e, ref t) => {
3536 let typ = fcx.to_ty(&t);
3537 check_expr_eq_type(fcx, &e, typ);
3538 fcx.write_ty(id, typ);
3540 hir::ExprVec(ref args) => {
3541 let uty = expected.to_option(fcx).and_then(|uty| {
3543 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3548 let typ = match uty {
3551 check_expr_coercable_to_type(fcx, &e, uty);
3556 let t: Ty = fcx.infcx().next_ty_var();
3558 check_expr_has_type(fcx, &e, t);
3563 let typ = tcx.mk_array(typ, args.len());
3564 fcx.write_ty(id, typ);
3566 hir::ExprRepeat(ref element, ref count_expr) => {
3567 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3568 let count = fcx.tcx().eval_repeat_count(&count_expr);
3570 let uty = match expected {
3571 ExpectHasType(uty) => {
3573 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3580 let (element_ty, t) = match uty {
3582 check_expr_coercable_to_type(fcx, &element, uty);
3586 let t: Ty = fcx.infcx().next_ty_var();
3587 check_expr_has_type(fcx, &element, t);
3588 (fcx.expr_ty(&element), t)
3593 // For [foo, ..n] where n > 1, `foo` must have
3595 fcx.require_type_meets(
3602 if element_ty.references_error() {
3603 fcx.write_error(id);
3605 let t = tcx.mk_array(t, count);
3606 fcx.write_ty(id, t);
3609 hir::ExprTup(ref elts) => {
3610 let flds = expected.only_has_type(fcx).and_then(|ty| {
3612 ty::TyTuple(ref flds) => Some(&flds[..]),
3616 let mut err_field = false;
3618 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3619 let t = match flds {
3620 Some(ref fs) if i < fs.len() => {
3622 check_expr_coercable_to_type(fcx, &e, ety);
3626 check_expr_with_expectation(fcx, &e, NoExpectation);
3630 err_field = err_field || t.references_error();
3634 fcx.write_error(id);
3636 let typ = tcx.mk_tup(elt_ts);
3637 fcx.write_ty(id, typ);
3640 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3641 check_expr_struct(fcx, expr, path, fields, base_expr);
3643 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3645 hir::ExprField(ref base, ref field) => {
3646 check_field(fcx, expr, lvalue_pref, &base, field);
3648 hir::ExprTupField(ref base, idx) => {
3649 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3651 hir::ExprIndex(ref base, ref idx) => {
3652 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3653 check_expr(fcx, &idx);
3655 let base_t = fcx.expr_ty(&base);
3656 let idx_t = fcx.expr_ty(&idx);
3658 if base_t.references_error() {
3659 fcx.write_ty(id, base_t);
3660 } else if idx_t.references_error() {
3661 fcx.write_ty(id, idx_t);
3663 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3664 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3665 Some((index_ty, element_ty)) => {
3666 let idx_expr_ty = fcx.expr_ty(idx);
3667 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3668 fcx.write_ty(id, element_ty);
3671 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3672 fcx.type_error_message(
3675 format!("cannot index a value of type `{}`",
3680 fcx.write_ty(id, fcx.tcx().types.err);
3685 hir::ExprRange(ref start, ref end) => {
3686 let t_start = start.as_ref().map(|e| {
3687 check_expr(fcx, &e);
3690 let t_end = end.as_ref().map(|e| {
3691 check_expr(fcx, &e);
3695 let idx_type = match (t_start, t_end) {
3696 (Some(ty), None) | (None, Some(ty)) => {
3699 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3700 t_end.references_error()) => {
3701 Some(fcx.tcx().types.err)
3703 (Some(t_start), Some(t_end)) => {
3704 Some(infer::common_supertype(fcx.infcx(),
3705 TypeOrigin::RangeExpression(expr.span),
3713 // Note that we don't check the type of start/end satisfy any
3714 // bounds because right now the range structs do not have any. If we add
3715 // some bounds, then we'll need to check `t_start` against them here.
3717 let range_type = match idx_type {
3718 Some(idx_type) if idx_type.references_error() => {
3722 // Find the did from the appropriate lang item.
3723 let did = match (start, end) {
3724 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3725 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3726 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3728 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3732 if let Some(did) = did {
3733 let def = tcx.lookup_adt_def(did);
3734 let predicates = tcx.lookup_predicates(did);
3735 let substs = Substs::new_type(vec![idx_type], vec![]);
3736 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3737 fcx.add_obligations_for_parameters(
3738 traits::ObligationCause::new(expr.span,
3740 traits::ItemObligation(did)),
3743 tcx.mk_struct(def, tcx.mk_substs(substs))
3745 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3750 // Neither start nor end => RangeFull
3751 if let Some(did) = tcx.lang_items.range_full_struct() {
3753 tcx.lookup_adt_def(did),
3754 tcx.mk_substs(Substs::empty())
3757 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3763 fcx.write_ty(id, range_type);
3768 debug!("type of expr({}) {} is...", expr.id,
3769 pprust::expr_to_string(expr));
3770 debug!("... {:?}, expected is {:?}",
3777 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3778 path_res: def::PathResolution,
3779 opt_self_ty: Option<Ty<'tcx>>,
3780 path: &'a hir::Path,
3782 node_id: ast::NodeId)
3783 -> Option<(Option<Ty<'tcx>>,
3784 &'a [hir::PathSegment],
3788 // If fully resolved already, we don't have to do anything.
3789 if path_res.depth == 0 {
3790 Some((opt_self_ty, &path.segments, path_res.base_def))
3792 let mut def = path_res.base_def;
3793 let ty_segments = path.segments.split_last().unwrap().1;
3794 let base_ty_end = path.segments.len() - path_res.depth;
3795 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3796 PathParamMode::Optional,
3799 &ty_segments[..base_ty_end],
3800 &ty_segments[base_ty_end..]);
3801 let item_segment = path.segments.last().unwrap();
3802 let item_name = item_segment.identifier.name;
3803 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3805 // Write back the new resolution.
3806 fcx.ccx.tcx.def_map.borrow_mut()
3807 .insert(node_id, def::PathResolution {
3811 Some((Some(ty), slice::ref_slice(item_segment), def))
3814 if item_name != special_idents::invalid.name {
3815 method::report_error(fcx, span, ty, item_name, None, error);
3817 fcx.write_error(node_id);
3824 impl<'tcx> Expectation<'tcx> {
3825 /// Provide an expectation for an rvalue expression given an *optional*
3826 /// hint, which is not required for type safety (the resulting type might
3827 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3828 /// is useful in determining the concrete type.
3830 /// The primary use case is where the expected type is a fat pointer,
3831 /// like `&[isize]`. For example, consider the following statement:
3833 /// let x: &[isize] = &[1, 2, 3];
3835 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3836 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3837 /// expectation `ExpectHasType([isize])`, that would be too strong --
3838 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3839 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3840 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3841 /// which still is useful, because it informs integer literals and the like.
3842 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3843 /// for examples of where this comes up,.
3844 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3845 match tcx.struct_tail(ty).sty {
3846 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3847 ExpectRvalueLikeUnsized(ty)
3849 _ => ExpectHasType(ty)
3853 // Resolves `expected` by a single level if it is a variable. If
3854 // there is no expected type or resolution is not possible (e.g.,
3855 // no constraints yet present), just returns `None`.
3856 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3861 ExpectCastableToType(t) => {
3862 ExpectCastableToType(
3863 fcx.infcx().resolve_type_vars_if_possible(&t))
3865 ExpectHasType(t) => {
3867 fcx.infcx().resolve_type_vars_if_possible(&t))
3869 ExpectRvalueLikeUnsized(t) => {
3870 ExpectRvalueLikeUnsized(
3871 fcx.infcx().resolve_type_vars_if_possible(&t))
3876 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3877 match self.resolve(fcx) {
3878 NoExpectation => None,
3879 ExpectCastableToType(ty) |
3881 ExpectRvalueLikeUnsized(ty) => Some(ty),
3885 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3886 match self.resolve(fcx) {
3887 ExpectHasType(ty) => Some(ty),
3893 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3894 local: &'tcx hir::Local,
3895 init: &'tcx hir::Expr)
3897 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3899 let local_ty = fcx.local_ty(init.span, local.id);
3900 if let Some(m) = ref_bindings {
3901 // Somewhat subtle: if we have a `ref` binding in the pattern,
3902 // we want to avoid introducing coercions for the RHS. This is
3903 // both because it helps preserve sanity and, in the case of
3904 // ref mut, for soundness (issue #23116). In particular, in
3905 // the latter case, we need to be clear that the type of the
3906 // referent for the reference that results is *equal to* the
3907 // type of the lvalue it is referencing, and not some
3908 // supertype thereof.
3909 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3910 let init_ty = fcx.expr_ty(init);
3911 demand::eqtype(fcx, init.span, init_ty, local_ty);
3913 check_expr_coercable_to_type(fcx, init, local_ty)
3917 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3918 let tcx = fcx.ccx.tcx;
3920 let t = fcx.local_ty(local.span, local.id);
3921 fcx.write_ty(local.id, t);
3923 if let Some(ref init) = local.init {
3924 check_decl_initializer(fcx, local, &init);
3925 let init_ty = fcx.expr_ty(&init);
3926 if init_ty.references_error() {
3927 fcx.write_ty(local.id, init_ty);
3931 let pcx = pat_ctxt {
3933 map: pat_id_map(&tcx.def_map, &local.pat),
3935 _match::check_pat(&pcx, &local.pat, t);
3936 let pat_ty = fcx.node_ty(local.pat.id);
3937 if pat_ty.references_error() {
3938 fcx.write_ty(local.id, pat_ty);
3942 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3944 let mut saw_bot = false;
3945 let mut saw_err = false;
3947 hir::StmtDecl(ref decl, id) => {
3950 hir::DeclLocal(ref l) => {
3951 check_decl_local(fcx, &l);
3952 let l_t = fcx.node_ty(l.id);
3953 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3954 saw_err = saw_err || l_t.references_error();
3956 hir::DeclItem(_) => {/* ignore for now */ }
3959 hir::StmtExpr(ref expr, id) => {
3961 // Check with expected type of ()
3962 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3963 let expr_ty = fcx.expr_ty(&expr);
3964 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3965 saw_err = saw_err || expr_ty.references_error();
3967 hir::StmtSemi(ref expr, id) => {
3969 check_expr(fcx, &expr);
3970 let expr_ty = fcx.expr_ty(&expr);
3971 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3972 saw_err |= expr_ty.references_error();
3976 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3979 fcx.write_error(node_id);
3982 fcx.write_nil(node_id)
3986 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3987 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3988 let blkty = fcx.node_ty(blk.id);
3989 if blkty.references_error() {
3990 fcx.write_error(blk.id);
3992 let nilty = fcx.tcx().mk_nil();
3993 demand::suptype(fcx, blk.span, nilty, blkty);
3997 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3998 blk: &'tcx hir::Block,
3999 expected: Expectation<'tcx>) {
4001 let mut fcx_ps = fcx.ps.borrow_mut();
4002 let unsafety_state = fcx_ps.recurse(blk);
4003 replace(&mut *fcx_ps, unsafety_state)
4006 let mut warned = false;
4007 let mut any_diverges = false;
4008 let mut any_err = false;
4009 for s in &blk.stmts {
4011 let s_id = ::rustc_front::util::stmt_id(s);
4012 let s_ty = fcx.node_ty(s_id);
4013 if any_diverges && !warned && match s.node {
4014 hir::StmtDecl(ref decl, _) => {
4016 hir::DeclLocal(_) => true,
4020 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4025 .add_lint(lint::builtin::UNREACHABLE_CODE,
4028 "unreachable statement".to_string());
4031 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4032 any_err = any_err || s_ty.references_error();
4035 None => if any_err {
4036 fcx.write_error(blk.id);
4037 } else if any_diverges {
4038 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4040 fcx.write_nil(blk.id);
4043 if any_diverges && !warned {
4047 .add_lint(lint::builtin::UNREACHABLE_CODE,
4050 "unreachable expression".to_string());
4052 let ety = match expected {
4053 ExpectHasType(ety) => {
4054 check_expr_coercable_to_type(fcx, &e, ety);
4058 check_expr_with_expectation(fcx, &e, expected);
4064 fcx.write_error(blk.id);
4065 } else if any_diverges {
4066 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4068 fcx.write_ty(blk.id, ety);
4073 *fcx.ps.borrow_mut() = prev;
4076 /// Checks a constant appearing in a type. At the moment this is just the
4077 /// length expression in a fixed-length vector, but someday it might be
4078 /// extended to type-level numeric literals.
4079 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4080 expr: &'tcx hir::Expr,
4081 expected_type: Ty<'tcx>) {
4082 let tables = RefCell::new(ty::Tables::empty());
4083 let inh = static_inherited_fields(ccx, &tables);
4084 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4085 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4088 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4092 let tables = RefCell::new(ty::Tables::empty());
4093 let inh = static_inherited_fields(ccx, &tables);
4094 let rty = ccx.tcx.node_id_to_type(id);
4095 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4096 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4097 check_const_with_ty(&fcx, sp, e, declty);
4100 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4104 // Gather locals in statics (because of block expressions).
4105 // This is technically unnecessary because locals in static items are forbidden,
4106 // but prevents type checking from blowing up before const checking can properly
4108 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4110 check_expr_with_hint(fcx, e, declty);
4111 demand::coerce(fcx, e.span, declty, e);
4113 fcx.select_all_obligations_and_apply_defaults();
4114 upvar::closure_analyze_const(&fcx, e);
4115 fcx.select_obligations_where_possible();
4117 fcx.select_all_obligations_or_error();
4119 regionck::regionck_expr(fcx, e);
4120 writeback::resolve_type_vars_in_expr(fcx, e);
4123 /// Checks whether a type can be represented in memory. In particular, it
4124 /// identifies types that contain themselves without indirection through a
4125 /// pointer, which would mean their size is unbounded.
4126 pub fn check_representable(tcx: &ty::ctxt,
4128 item_id: ast::NodeId,
4129 _designation: &str) -> bool {
4130 let rty = tcx.node_id_to_type(item_id);
4132 // Check that it is possible to represent this type. This call identifies
4133 // (1) types that contain themselves and (2) types that contain a different
4134 // recursive type. It is only necessary to throw an error on those that
4135 // contain themselves. For case 2, there must be an inner type that will be
4136 // caught by case 1.
4137 match rty.is_representable(tcx, sp) {
4138 Representability::SelfRecursive => {
4139 let item_def_id = tcx.map.local_def_id(item_id);
4140 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4143 Representability::Representable | Representability::ContainsRecursive => (),
4148 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4149 let t = tcx.node_id_to_type(id);
4151 ty::TyStruct(def, substs) => {
4152 let fields = &def.struct_variant().fields;
4153 if fields.is_empty() {
4154 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4157 let e = fields[0].ty(tcx, substs);
4158 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4159 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4163 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4164 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4166 span_err!(tcx.sess, sp, E0077,
4167 "SIMD vector element type should be machine type");
4176 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4178 vs: &'tcx [hir::Variant],
4180 // disr_in_range should be removed once we have forced type hints for consts
4181 fn disr_in_range(ccx: &CrateCtxt,
4183 disr: ty::Disr) -> bool {
4184 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4186 ast::UintTy::U8 => disr as u8 as Disr == disr,
4187 ast::UintTy::U16 => disr as u16 as Disr == disr,
4188 ast::UintTy::U32 => disr as u32 as Disr == disr,
4189 ast::UintTy::U64 => disr as u64 as Disr == disr,
4190 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4193 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4195 ast::IntTy::I8 => disr as i8 as Disr == disr,
4196 ast::IntTy::I16 => disr as i16 as Disr == disr,
4197 ast::IntTy::I32 => disr as i32 as Disr == disr,
4198 ast::IntTy::I64 => disr as i64 as Disr == disr,
4199 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4203 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4204 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4208 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4209 vs: &'tcx [hir::Variant],
4211 hint: attr::ReprAttr) {
4212 #![allow(trivial_numeric_casts)]
4214 let rty = ccx.tcx.node_id_to_type(id);
4215 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4217 let tables = RefCell::new(ty::Tables::empty());
4218 let inh = static_inherited_fields(ccx, &tables);
4219 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4221 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4223 if let Some(ref e) = v.node.disr_expr {
4224 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4228 let def_id = ccx.tcx.map.local_def_id(id);
4230 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4231 for (v, variant) in vs.iter().zip(variants.iter()) {
4232 let current_disr_val = variant.disr_val;
4234 // Check for duplicate discriminant values
4235 match disr_vals.iter().position(|&x| x == current_disr_val) {
4237 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4238 "discriminant value `{}` already exists", disr_vals[i]);
4239 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4240 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4241 "conflicting discriminant here");
4246 // Check for unrepresentable discriminant values
4248 attr::ReprAny | attr::ReprExtern => {
4249 disr_vals.push(current_disr_val);
4251 attr::ReprInt(sp, ity) => {
4252 if !disr_in_range(ccx, ity, current_disr_val) {
4253 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4254 "discriminant value outside specified type");
4255 span_note!(&mut err, sp,
4256 "discriminant type specified here");
4260 // Error reported elsewhere.
4261 attr::ReprSimd | attr::ReprPacked => {}
4266 let def_id = ccx.tcx.map.local_def_id(id);
4267 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4269 if hint != attr::ReprAny && vs.is_empty() {
4270 span_err!(ccx.tcx.sess, sp, E0084,
4271 "unsupported representation for zero-variant enum");
4274 do_check(ccx, vs, id, hint);
4276 check_representable(ccx.tcx, sp, id, "enum");
4279 // Returns the type parameter count and the type for the given definition.
4280 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4283 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4285 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4286 let typ = fcx.local_ty(sp, nid);
4287 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4288 ty::GenericPredicates::empty())
4290 Def::Fn(id) | Def::Method(id) |
4291 Def::Static(id, _) | Def::Variant(_, id) |
4292 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4293 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4298 Def::AssociatedTy(..) |
4302 Def::ForeignMod(..) |
4306 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4311 // Instantiates the given path, which must refer to an item with the given
4312 // number of type parameters and type.
4313 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4314 segments: &[hir::PathSegment],
4315 type_scheme: TypeScheme<'tcx>,
4316 type_predicates: &ty::GenericPredicates<'tcx>,
4317 opt_self_ty: Option<Ty<'tcx>>,
4320 node_id: ast::NodeId) {
4321 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4327 // We need to extract the type parameters supplied by the user in
4328 // the path `path`. Due to the current setup, this is a bit of a
4329 // tricky-process; the problem is that resolve only tells us the
4330 // end-point of the path resolution, and not the intermediate steps.
4331 // Luckily, we can (at least for now) deduce the intermediate steps
4332 // just from the end-point.
4334 // There are basically four cases to consider:
4336 // 1. Reference to a *type*, such as a struct or enum:
4338 // mod a { struct Foo<T> { ... } }
4340 // Because we don't allow types to be declared within one
4341 // another, a path that leads to a type will always look like
4342 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4343 // that only the final segment can have type parameters, and
4344 // they are located in the TypeSpace.
4346 // *Note:* Generally speaking, references to types don't
4347 // actually pass through this function, but rather the
4348 // `ast_ty_to_ty` function in `astconv`. However, in the case
4349 // of struct patterns (and maybe literals) we do invoke
4350 // `instantiate_path` to get the general type of an instance of
4351 // a struct. (In these cases, there are actually no type
4352 // parameters permitted at present, but perhaps we will allow
4353 // them in the future.)
4355 // 1b. Reference to an enum variant or tuple-like struct:
4357 // struct foo<T>(...)
4358 // enum E<T> { foo(...) }
4360 // In these cases, the parameters are declared in the type
4363 // 2. Reference to a *fn item*:
4367 // In this case, the path will again always have the form
4368 // `a::b::foo::<T>` where only the final segment should have
4369 // type parameters. However, in this case, those parameters are
4370 // declared on a value, and hence are in the `FnSpace`.
4372 // 3. Reference to a *method*:
4374 // impl<A> SomeStruct<A> {
4378 // Here we can have a path like
4379 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4380 // may appear in two places. The penultimate segment,
4381 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4382 // final segment, `foo::<B>` contains parameters in fn space.
4384 // 4. Reference to an *associated const*:
4386 // impl<A> AnotherStruct<A> {
4387 // const FOO: B = BAR;
4390 // The path in this case will look like
4391 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4392 // only will have parameters in TypeSpace.
4394 // The first step then is to categorize the segments appropriately.
4396 assert!(!segments.is_empty());
4398 let mut ufcs_associated = None;
4399 let mut segment_spaces: Vec<_>;
4401 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4407 Def::AssociatedTy(..) |
4410 Def::TyParam(..) => {
4411 // Everything but the final segment should have no
4412 // parameters at all.
4413 segment_spaces = vec![None; segments.len() - 1];
4414 segment_spaces.push(Some(subst::TypeSpace));
4417 // Case 2. Reference to a top-level value.
4420 Def::Static(..) => {
4421 segment_spaces = vec![None; segments.len() - 1];
4422 segment_spaces.push(Some(subst::FnSpace));
4425 // Case 3. Reference to a method.
4426 Def::Method(def_id) => {
4427 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4429 ty::TraitContainer(trait_did) => {
4430 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4432 ty::ImplContainer(_) => {}
4435 if segments.len() >= 2 {
4436 segment_spaces = vec![None; segments.len() - 2];
4437 segment_spaces.push(Some(subst::TypeSpace));
4438 segment_spaces.push(Some(subst::FnSpace));
4440 // `<T>::method` will end up here, and so can `T::method`.
4441 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4442 segment_spaces = vec![Some(subst::FnSpace)];
4443 ufcs_associated = Some((container, self_ty));
4447 Def::AssociatedConst(def_id) => {
4448 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4450 ty::TraitContainer(trait_did) => {
4451 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4453 ty::ImplContainer(_) => {}
4456 if segments.len() >= 2 {
4457 segment_spaces = vec![None; segments.len() - 2];
4458 segment_spaces.push(Some(subst::TypeSpace));
4459 segment_spaces.push(None);
4461 // `<T>::CONST` will end up here, and so can `T::CONST`.
4462 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4463 segment_spaces = vec![None];
4464 ufcs_associated = Some((container, self_ty));
4468 // Other cases. Various nonsense that really shouldn't show up
4469 // here. If they do, an error will have been reported
4470 // elsewhere. (I hope)
4472 Def::ForeignMod(..) |
4477 segment_spaces = vec![None; segments.len()];
4480 assert_eq!(segment_spaces.len(), segments.len());
4482 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4483 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4484 // type parameters are not mandatory.
4485 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4487 debug!("segment_spaces={:?}", segment_spaces);
4489 // Next, examine the definition, and determine how many type
4490 // parameters we expect from each space.
4491 let type_defs = &type_scheme.generics.types;
4492 let region_defs = &type_scheme.generics.regions;
4494 // Now that we have categorized what space the parameters for each
4495 // segment belong to, let's sort out the parameters that the user
4496 // provided (if any) into their appropriate spaces. We'll also report
4497 // errors if type parameters are provided in an inappropriate place.
4498 let mut substs = Substs::empty();
4499 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4502 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4506 push_explicit_parameters_from_segment_to_substs(fcx,
4516 if let Some(self_ty) = opt_self_ty {
4517 if type_defs.len(subst::SelfSpace) == 1 {
4518 substs.types.push(subst::SelfSpace, self_ty);
4522 // Now we have to compare the types that the user *actually*
4523 // provided against the types that were *expected*. If the user
4524 // did not provide any types, then we want to substitute inference
4525 // variables. If the user provided some types, we may still need
4526 // to add defaults. If the user provided *too many* types, that's
4528 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4529 adjust_type_parameters(fcx, span, space, type_defs,
4530 require_type_space, &mut substs);
4531 assert_eq!(substs.types.len(space), type_defs.len(space));
4533 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4534 assert_eq!(substs.regions().len(space), region_defs.len(space));
4537 // The things we are substituting into the type should not contain
4538 // escaping late-bound regions, and nor should the base type scheme.
4539 assert!(!substs.has_regions_escaping_depth(0));
4540 assert!(!type_scheme.has_escaping_regions());
4542 // Add all the obligations that are required, substituting and
4543 // normalized appropriately.
4544 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4545 fcx.add_obligations_for_parameters(
4546 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4549 // Substitute the values for the type parameters into the type of
4550 // the referenced item.
4551 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4554 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4555 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4556 // is inherent, there is no `Self` parameter, instead, the impl needs
4557 // type parameters, which we can infer by unifying the provided `Self`
4558 // with the substituted impl type.
4559 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4560 assert_eq!(substs.types.len(subst::TypeSpace),
4561 impl_scheme.generics.types.len(subst::TypeSpace));
4562 assert_eq!(substs.regions().len(subst::TypeSpace),
4563 impl_scheme.generics.regions.len(subst::TypeSpace));
4565 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4566 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4567 fcx.tcx().sess.span_bug(span,
4569 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4575 debug!("instantiate_path: type of {:?} is {:?}",
4578 fcx.write_ty(node_id, ty_substituted);
4579 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4582 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4583 /// parameters are provided, then reports an error and clears the output vector.
4585 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4586 /// use inference variables. This seems less likely to lead to derived errors.
4588 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4589 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4590 /// here because we can easily use the precise span of the N+1'th parameter.
4591 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4592 fcx: &FnCtxt<'a, 'tcx>,
4593 space: subst::ParamSpace,
4595 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4596 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4597 segment: &hir::PathSegment,
4598 substs: &mut Substs<'tcx>)
4600 match segment.parameters {
4601 hir::AngleBracketedParameters(ref data) => {
4602 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4603 fcx, space, type_defs, region_defs, data, substs);
4606 hir::ParenthesizedParameters(ref data) => {
4607 span_err!(fcx.tcx().sess, span, E0238,
4608 "parenthesized parameters may only be used with a trait");
4609 push_explicit_parenthesized_parameters_from_segment_to_substs(
4610 fcx, space, span, type_defs, data, substs);
4615 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4616 fcx: &FnCtxt<'a, 'tcx>,
4617 space: subst::ParamSpace,
4618 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4619 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4620 data: &hir::AngleBracketedParameterData,
4621 substs: &mut Substs<'tcx>)
4624 let type_count = type_defs.len(space);
4625 assert_eq!(substs.types.len(space), 0);
4626 for (i, typ) in data.types.iter().enumerate() {
4627 let t = fcx.to_ty(&typ);
4629 substs.types.push(space, t);
4630 } else if i == type_count {
4631 span_err!(fcx.tcx().sess, typ.span, E0087,
4632 "too many type parameters provided: \
4633 expected at most {} parameter{}, \
4634 found {} parameter{}",
4636 if type_count == 1 {""} else {"s"},
4638 if data.types.len() == 1 {""} else {"s"});
4639 substs.types.truncate(space, 0);
4645 if !data.bindings.is_empty() {
4646 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4647 "unexpected binding of associated item in expression path \
4648 (only allowed in type paths)");
4652 let region_count = region_defs.len(space);
4653 assert_eq!(substs.regions().len(space), 0);
4654 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4655 let r = ast_region_to_region(fcx.tcx(), lifetime);
4656 if i < region_count {
4657 substs.mut_regions().push(space, r);
4658 } else if i == region_count {
4659 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4660 "too many lifetime parameters provided: \
4661 expected {} parameter{}, found {} parameter{}",
4663 if region_count == 1 {""} else {"s"},
4664 data.lifetimes.len(),
4665 if data.lifetimes.len() == 1 {""} else {"s"});
4666 substs.mut_regions().truncate(space, 0);
4674 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4675 /// but intended for `Foo(A,B) -> C` form. This expands to
4676 /// roughly the same thing as `Foo<(A,B),C>`. One important
4677 /// difference has to do with the treatment of anonymous
4678 /// regions, which are translated into bound regions (NYI).
4679 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4680 fcx: &FnCtxt<'a, 'tcx>,
4681 space: subst::ParamSpace,
4683 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4684 data: &hir::ParenthesizedParameterData,
4685 substs: &mut Substs<'tcx>)
4687 let type_count = type_defs.len(space);
4689 span_err!(fcx.tcx().sess, span, E0167,
4690 "parenthesized form always supplies 2 type parameters, \
4691 but only {} parameter(s) were expected",
4695 let input_tys: Vec<Ty> =
4696 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4698 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4700 if type_count >= 1 {
4701 substs.types.push(space, tuple_ty);
4704 let output_ty: Option<Ty> =
4705 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4708 output_ty.unwrap_or(fcx.tcx().mk_nil());
4710 if type_count >= 2 {
4711 substs.types.push(space, output_ty);
4715 fn adjust_type_parameters<'a, 'tcx>(
4716 fcx: &FnCtxt<'a, 'tcx>,
4719 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4720 require_type_space: bool,
4721 substs: &mut Substs<'tcx>)
4723 let provided_len = substs.types.len(space);
4724 let desired = defs.get_slice(space);
4725 let required_len = desired.iter()
4726 .take_while(|d| d.default.is_none())
4729 debug!("adjust_type_parameters(space={:?}, \
4738 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4739 assert!(provided_len <= desired.len());
4741 // Nothing specified at all: supply inference variables for
4743 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4744 substs.types.replace(space, Vec::new());
4745 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4749 // Too few parameters specified: report an error and use Err
4751 if provided_len < required_len {
4753 if desired.len() != required_len { "at least " } else { "" };
4754 span_err!(fcx.tcx().sess, span, E0089,
4755 "too few type parameters provided: expected {}{} parameter{}, \
4756 found {} parameter{}",
4757 qualifier, required_len,
4758 if required_len == 1 {""} else {"s"},
4760 if provided_len == 1 {""} else {"s"});
4761 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4765 // Otherwise, add in any optional parameters that the user
4766 // omitted. The case of *too many* parameters is handled
4768 // push_explicit_parameters_from_segment_to_substs(). Note
4769 // that the *default* type are expressed in terms of all prior
4770 // parameters, so we have to substitute as we go with the
4771 // partial substitution that we have built up.
4772 for i in provided_len..desired.len() {
4773 let default = desired[i].default.unwrap();
4774 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4775 substs.types.push(space, default);
4777 assert_eq!(substs.types.len(space), desired.len());
4779 debug!("Final substs: {:?}", substs);
4782 fn adjust_region_parameters(
4786 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4787 substs: &mut Substs)
4789 let provided_len = substs.mut_regions().len(space);
4790 let desired = defs.get_slice(space);
4792 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4793 assert!(provided_len <= desired.len());
4795 // If nothing was provided, just use inference variables.
4796 if provided_len == 0 {
4797 substs.mut_regions().replace(
4799 fcx.infcx().region_vars_for_defs(span, desired));
4803 // If just the right number were provided, everybody is happy.
4804 if provided_len == desired.len() {
4808 // Otherwise, too few were provided. Report an error and then
4809 // use inference variables.
4810 span_err!(fcx.tcx().sess, span, E0090,
4811 "too few lifetime parameters provided: expected {} parameter{}, \
4812 found {} parameter{}",
4814 if desired.len() == 1 {""} else {"s"},
4816 if provided_len == 1 {""} else {"s"});
4818 substs.mut_regions().replace(
4820 fcx.infcx().region_vars_for_defs(span, desired));
4824 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4828 where F: Fn() -> Ty<'tcx>
4830 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4833 let alternative = f();
4836 if alternative.is_ty_var() || alternative.references_error() {
4837 fcx.type_error_message(sp, |_actual| {
4838 "the type of this value must be known in this context".to_string()
4840 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4841 ty = fcx.tcx().types.err;
4843 demand::suptype(fcx, sp, alternative, ty);
4851 // Resolves `typ` by a single level if `typ` is a type variable. If no
4852 // resolution is possible, then an error is reported.
4853 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4858 structurally_resolve_type_or_else(fcx, sp, ty, || {
4863 // Returns true if b contains a break that can exit from b
4864 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4865 // First: is there an unlabeled break immediately
4867 (loop_query(&b, |e| {
4869 hir::ExprBreak(None) => true,
4873 // Second: is there a labeled break with label
4874 // <id> nested anywhere inside the loop?
4875 (block_query(b, |e| {
4876 if let hir::ExprBreak(Some(_)) = e.node {
4877 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4884 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4885 tps: &[hir::TyParam],
4887 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4890 // make a vector of booleans initially false, set to true when used
4891 if tps.is_empty() { return; }
4892 let mut tps_used = vec![false; tps.len()];
4894 for leaf_ty in ty.walk() {
4895 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4896 debug!("Found use of ty param num {}", idx);
4897 tps_used[idx as usize] = true;
4901 for (i, b) in tps_used.iter().enumerate() {
4903 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4904 "type parameter `{}` is unused",