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::privacy::{AllPublic, LastMod};
95 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
96 use middle::traits::{self, report_fulfillment_errors};
97 use middle::ty::{GenericPredicates, TypeScheme};
98 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
99 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
100 use middle::ty::{self, ToPolyTraitRef, Ty};
101 use middle::ty::{MethodCall, MethodCallee};
102 use middle::ty::adjustment;
103 use middle::ty::error::TypeError;
104 use middle::ty::fold::{TypeFolder, TypeFoldable};
105 use middle::ty::util::Representability;
106 use require_c_abi_if_variadic;
107 use rscope::{ElisionFailureInfo, RegionScope};
108 use session::{Session, CompileResult};
109 use {CrateCtxt, lookup_full_def};
112 use util::common::{block_query, ErrorReported, indenter, loop_query};
113 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
115 use std::cell::{Cell, Ref, RefCell};
116 use std::collections::{HashSet};
117 use std::mem::replace;
118 use syntax::abi::Abi;
121 use syntax::attr::AttrMetaMethods;
122 use syntax::codemap::{self, Span, Spanned};
123 use syntax::errors::DiagnosticBuilder;
124 use syntax::parse::token::{self, InternedString, special_idents};
126 use syntax::util::lev_distance::find_best_match_for_name;
128 use rustc_front::intravisit::{self, Visitor};
129 use rustc_front::hir;
130 use rustc_front::hir::{Visibility, PatKind};
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
151 /// closures defined within the function. For example:
154 /// bar(move|| { ... })
157 /// Here, the function `foo()` and the closure passed to
158 /// `bar()` will each have their own `FnCtxt`, but they will
159 /// share the inherited fields.
160 pub struct Inherited<'a, 'tcx: 'a> {
161 infcx: infer::InferCtxt<'a, 'tcx>,
162 locals: RefCell<NodeMap<Ty<'tcx>>>,
164 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
166 tables: &'a RefCell<ty::Tables<'tcx>>,
168 // When we process a call like `c()` where `c` is a closure type,
169 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
170 // `FnOnce` closure. In that case, we defer full resolution of the
171 // call until upvar inference can kick in and make the
172 // decision. We keep these deferred resolutions grouped by the
173 // def-id of the closure, so that once we decide, we can easily go
174 // back and process them.
175 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
177 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
180 trait DeferredCallResolution<'tcx> {
181 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
184 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
186 /// When type-checking an expression, we propagate downward
187 /// whatever type hint we are able in the form of an `Expectation`.
188 #[derive(Copy, Clone, Debug)]
189 pub enum Expectation<'tcx> {
190 /// We know nothing about what type this expression should have.
193 /// This expression should have the type given (or some subtype)
194 ExpectHasType(Ty<'tcx>),
196 /// This expression will be cast to the `Ty`
197 ExpectCastableToType(Ty<'tcx>),
199 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
200 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
201 ExpectRvalueLikeUnsized(Ty<'tcx>),
204 impl<'tcx> Expectation<'tcx> {
205 // Disregard "castable to" expectations because they
206 // can lead us astray. Consider for example `if cond
207 // {22} else {c} as u8` -- if we propagate the
208 // "castable to u8" constraint to 22, it will pick the
209 // type 22u8, which is overly constrained (c might not
210 // be a u8). In effect, the problem is that the
211 // "castable to" expectation is not the tightest thing
212 // we can say, so we want to drop it in this case.
213 // The tightest thing we can say is "must unify with
214 // else branch". Note that in the case of a "has type"
215 // constraint, this limitation does not hold.
217 // If the expected type is just a type variable, then don't use
218 // an expected type. Otherwise, we might write parts of the type
219 // when checking the 'then' block which are incompatible with the
221 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
223 ExpectHasType(ety) => {
224 let ety = fcx.infcx().shallow_resolve(ety);
225 if !ety.is_ty_var() {
231 ExpectRvalueLikeUnsized(ety) => {
232 ExpectRvalueLikeUnsized(ety)
239 #[derive(Copy, Clone)]
240 pub struct UnsafetyState {
241 pub def: ast::NodeId,
242 pub unsafety: hir::Unsafety,
243 pub unsafe_push_count: u32,
248 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
249 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
252 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
253 match self.unsafety {
254 // If this unsafe, then if the outer function was already marked as
255 // unsafe we shouldn't attribute the unsafe'ness to the block. This
256 // way the block can be warned about instead of ignoring this
257 // extraneous block (functions are never warned about).
258 hir::Unsafety::Unsafe if self.from_fn => *self,
261 let (unsafety, def, count) = match blk.rules {
262 hir::PushUnsafeBlock(..) =>
263 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
264 hir::PopUnsafeBlock(..) =>
265 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
266 hir::UnsafeBlock(..) =>
267 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
268 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
269 (unsafety, self.def, self.unsafe_push_count),
271 UnsafetyState{ def: def,
273 unsafe_push_count: count,
281 pub struct FnCtxt<'a, 'tcx: 'a> {
282 body_id: ast::NodeId,
284 // This flag is set to true if, during the writeback phase, we encounter
285 // a type error in this function.
286 writeback_errors: Cell<bool>,
288 // Number of errors that had been reported when we started
289 // checking this function. On exit, if we find that *more* errors
290 // have been reported, we will skip regionck and other work that
291 // expects the types within the function to be consistent.
292 err_count_on_creation: usize,
294 ret_ty: ty::FnOutput<'tcx>,
296 ps: RefCell<UnsafetyState>,
298 inh: &'a Inherited<'a, 'tcx>,
300 ccx: &'a CrateCtxt<'a, 'tcx>,
303 impl<'a, 'tcx> Inherited<'a, 'tcx> {
304 fn new(tcx: &'a ty::ctxt<'tcx>,
305 tables: &'a RefCell<ty::Tables<'tcx>>,
306 param_env: ty::ParameterEnvironment<'a, 'tcx>)
307 -> Inherited<'a, 'tcx> {
310 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
311 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
312 locals: RefCell::new(NodeMap()),
314 deferred_call_resolutions: RefCell::new(DefIdMap()),
315 deferred_cast_checks: RefCell::new(Vec::new()),
319 fn normalize_associated_types_in<T>(&self,
321 body_id: ast::NodeId,
324 where T : TypeFoldable<'tcx>
326 assoc::normalize_associated_types_in(&self.infcx,
327 &mut self.fulfillment_cx.borrow_mut(),
335 // Used by check_const and check_enum_variants
336 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
337 inh: &'a Inherited<'a, 'tcx>,
338 rty: ty::FnOutput<'tcx>,
339 body_id: ast::NodeId)
340 -> FnCtxt<'a, 'tcx> {
343 writeback_errors: Cell::new(false),
344 err_count_on_creation: ccx.tcx.sess.err_count(),
346 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
352 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
353 tables: &'a RefCell<ty::Tables<'tcx>>)
354 -> Inherited<'a, 'tcx> {
355 // It's kind of a kludge to manufacture a fake function context
356 // and statement context, but we might as well do write the code only once
357 let param_env = ccx.tcx.empty_parameter_environment();
358 Inherited::new(ccx.tcx, &tables, param_env)
361 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
362 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
364 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
365 fn visit_item(&mut self, i: &'tcx hir::Item) {
366 check_item_type(self.ccx, i);
367 intravisit::walk_item(self, i);
370 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
372 hir::TyFixedLengthVec(_, ref expr) => {
373 check_const_in_type(self.ccx, &expr, self.ccx.tcx.types.usize);
378 intravisit::walk_ty(self, t);
382 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
383 fn visit_item(&mut self, i: &'tcx hir::Item) {
384 check_item_body(self.ccx, i);
388 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
389 ccx.tcx.sess.track_errors(|| {
390 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
391 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
395 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
396 ccx.tcx.sess.track_errors(|| {
397 let mut visit = CheckItemTypesVisitor { ccx: ccx };
398 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
402 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
403 ccx.tcx.sess.track_errors(|| {
404 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
405 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
409 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
410 ccx.tcx.sess.track_errors(|| {
411 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
412 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
413 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
415 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
416 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
417 if drop_impl_did.is_local() {
418 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
421 assert!(ccx.tcx.sess.has_errors());
429 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
430 decl: &'tcx hir::FnDecl,
431 body: &'tcx hir::Block,
435 param_env: ty::ParameterEnvironment<'a, 'tcx>)
438 ty::TyBareFn(_, ref fn_ty) => {
439 let tables = RefCell::new(ty::Tables::empty());
440 let inh = Inherited::new(ccx.tcx, &tables, param_env);
442 // Compute the fty from point of view of inside fn.
443 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
445 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
447 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
449 inh.normalize_associated_types_in(body.span,
453 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
454 decl, fn_id, body, &inh);
456 fcx.select_all_obligations_and_apply_defaults();
457 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
458 fcx.select_obligations_where_possible();
460 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
462 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
463 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
465 _ => ccx.tcx.sess.impossible_case(body.span,
466 "check_bare_fn: function type expected")
470 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
471 fcx: &'a FnCtxt<'a, 'tcx>
474 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
475 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
478 // infer the variable's type
479 let var_ty = self.fcx.infcx().next_ty_var();
480 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
484 // take type that the user specified
485 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
492 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
493 // Add explicitly-declared locals.
494 fn visit_local(&mut self, local: &'tcx hir::Local) {
495 let o_ty = match local.ty {
496 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
499 self.assign(local.span, local.id, o_ty);
500 debug!("Local variable {:?} is assigned type {}",
502 self.fcx.infcx().ty_to_string(
503 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
504 intravisit::walk_local(self, local);
507 // Add pattern bindings.
508 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
509 if let PatKind::Ident(_, ref path1, _) = p.node {
510 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
511 let var_ty = self.assign(p.span, p.id, None);
513 self.fcx.require_type_is_sized(var_ty, p.span,
514 traits::VariableType(p.id));
516 debug!("Pattern binding {} is assigned to {} with type {:?}",
518 self.fcx.infcx().ty_to_string(
519 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
523 intravisit::walk_pat(self, p);
526 fn visit_block(&mut self, b: &'tcx hir::Block) {
527 // non-obvious: the `blk` variable maps to region lb, so
528 // we have to keep this up-to-date. This
529 // is... unfortunate. It'd be nice to not need this.
530 intravisit::walk_block(self, b);
533 // Since an expr occurs as part of the type fixed size arrays we
534 // need to record the type for that node
535 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
537 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
539 check_expr_with_hint(self.fcx, &count_expr, self.fcx.tcx().types.usize);
541 hir::TyBareFn(ref function_declaration) => {
542 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
543 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
545 _ => intravisit::walk_ty(self, t)
549 // Don't descend into the bodies of nested closures
550 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
551 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
554 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
555 /// body and returns the function context used for that purpose, since in the case of a fn item
556 /// there is still a bit more to do.
559 /// * inherited: other fields inherited from the enclosing fn (if any)
560 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
561 unsafety: hir::Unsafety,
562 unsafety_id: ast::NodeId,
563 fn_sig: &ty::FnSig<'tcx>,
564 decl: &'tcx hir::FnDecl,
566 body: &'tcx hir::Block,
567 inherited: &'a Inherited<'a, 'tcx>)
571 let err_count_on_creation = tcx.sess.err_count();
573 let arg_tys = &fn_sig.inputs;
574 let ret_ty = fn_sig.output;
576 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
581 // Create the function context. This is either derived from scratch or,
582 // in the case of function expressions, based on the outer context.
585 writeback_errors: Cell::new(false),
586 err_count_on_creation: err_count_on_creation,
588 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
593 if let ty::FnConverging(ret_ty) = ret_ty {
594 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
597 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
599 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
602 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
604 // Add formal parameters.
605 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
606 // The type of the argument must be well-formed.
608 // NB -- this is now checked in wfcheck, but that
609 // currently only results in warnings, so we issue an
610 // old-style WF obligation here so that we still get the
611 // errors that we used to get.
612 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
614 // Create type variables for each argument.
615 pat_util::pat_bindings(
618 |_bm, pat_id, sp, _path| {
619 let var_ty = visit.assign(sp, pat_id, None);
620 fcx.require_type_is_sized(var_ty, sp,
621 traits::VariableType(pat_id));
624 // Check the pattern.
627 map: pat_id_map(&tcx.def_map, &input.pat),
629 _match::check_pat(&pcx, &input.pat, *arg_ty);
632 visit.visit_block(body);
635 check_block_with_expected(&fcx, body, match ret_ty {
636 ty::FnConverging(result_type) => ExpectHasType(result_type),
637 ty::FnDiverging => NoExpectation
640 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
641 fcx.write_ty(input.id, arg);
647 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
650 check_representable(tcx, span, id, "struct");
652 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
653 check_simd(tcx, span, id);
657 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
658 debug!("check_item_type(it.id={}, it.name={})",
660 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
661 let _indenter = indenter();
663 // Consts can play a role in type-checking, so they are included here.
664 hir::ItemStatic(_, _, ref e) |
665 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &e, it.id),
666 hir::ItemEnum(ref enum_definition, _) => {
667 check_enum_variants(ccx,
669 &enum_definition.variants,
672 hir::ItemFn(..) => {} // entirely within check_item_body
673 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
674 debug!("ItemImpl {} with id {}", it.name, it.id);
675 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
676 Some(impl_trait_ref) => {
677 check_impl_items_against_trait(ccx,
685 hir::ItemTrait(_, ref generics, _, _) => {
686 check_trait_on_unimplemented(ccx, generics, it);
688 hir::ItemStruct(..) => {
689 check_struct(ccx, it.id, it.span);
691 hir::ItemTy(_, ref generics) => {
692 let pty_ty = ccx.tcx.node_id_to_type(it.id);
693 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
695 hir::ItemForeignMod(ref m) => {
696 if m.abi == Abi::RustIntrinsic {
697 for item in &m.items {
698 intrinsic::check_intrinsic_type(ccx, item);
700 } else if m.abi == Abi::PlatformIntrinsic {
701 for item in &m.items {
702 intrinsic::check_platform_intrinsic_type(ccx, item);
705 for item in &m.items {
706 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
707 if !pty.generics.types.is_empty() {
708 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
709 "foreign items may not have type parameters");
710 span_help!(&mut err, item.span,
711 "consider using specialization instead of \
716 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
717 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
722 _ => {/* nothing to do */ }
726 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
727 debug!("check_item_body(it.id={}, it.name={})",
729 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
730 let _indenter = indenter();
732 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
733 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
734 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
735 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
737 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
738 debug!("ItemImpl {} with id {}", it.name, it.id);
740 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
742 for impl_item in impl_items {
743 match impl_item.node {
744 hir::ImplItemKind::Const(_, ref expr) => {
745 check_const(ccx, impl_item.span, &expr, impl_item.id)
747 hir::ImplItemKind::Method(ref sig, ref body) => {
748 check_method_body(ccx, &impl_pty.generics, sig, body,
749 impl_item.id, impl_item.span);
751 hir::ImplItemKind::Type(_) => {
752 // Nothing to do here.
757 hir::ItemTrait(_, _, _, ref trait_items) => {
758 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
759 for trait_item in trait_items {
760 match trait_item.node {
761 hir::ConstTraitItem(_, Some(ref expr)) => {
762 check_const(ccx, trait_item.span, &expr, trait_item.id)
764 hir::MethodTraitItem(ref sig, Some(ref body)) => {
765 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
767 check_method_body(ccx, &trait_def.generics, sig, body,
768 trait_item.id, trait_item.span);
770 hir::MethodTraitItem(ref sig, None) => {
771 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
773 hir::ConstTraitItem(_, None) |
774 hir::TypeTraitItem(..) => {
780 _ => {/* nothing to do */ }
784 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
786 constness: hir::Constness)
789 hir::Constness::NotConst => {
792 hir::Constness::Const => {
793 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
798 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
799 generics: &hir::Generics,
801 if let Some(ref attr) = item.attrs.iter().find(|a| {
802 a.check_name("rustc_on_unimplemented")
804 if let Some(ref istring) = attr.value_str() {
805 let parser = Parser::new(&istring);
806 let types = &generics.ty_params;
807 for token in parser {
809 Piece::String(_) => (), // Normal string, no need to check it
810 Piece::NextArgument(a) => match a.position {
811 // `{Self}` is allowed
812 Position::ArgumentNamed(s) if s == "Self" => (),
813 // So is `{A}` if A is a type parameter
814 Position::ArgumentNamed(s) => match types.iter().find(|t| {
819 span_err!(ccx.tcx.sess, attr.span, E0230,
820 "there is no type parameter \
825 // `{:1}` and `{}` are not to be used
826 Position::ArgumentIs(_) | Position::ArgumentNext => {
827 span_err!(ccx.tcx.sess, attr.span, E0231,
828 "only named substitution \
829 parameters are allowed");
835 span_err!(ccx.tcx.sess, attr.span, E0232,
836 "this attribute must have a value, \
837 eg `#[rustc_on_unimplemented = \"foo\"]`")
842 /// Type checks a method body.
846 /// * `item_generics`: generics defined on the impl/trait that contains
848 /// * `self_bound`: bound for the `Self` type parameter, if any
849 /// * `method`: the method definition
850 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
851 item_generics: &ty::Generics<'tcx>,
852 sig: &'tcx hir::MethodSig,
853 body: &'tcx hir::Block,
854 id: ast::NodeId, span: Span) {
855 debug!("check_method_body(item_generics={:?}, id={})",
857 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
859 let fty = ccx.tcx.node_id_to_type(id);
860 debug!("check_method_body: fty={:?}", fty);
862 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
865 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
867 impl_trait_ref: &ty::TraitRef<'tcx>,
868 impl_items: &[hir::ImplItem]) {
869 // Locate trait methods
871 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
872 let mut overridden_associated_type = None;
874 // Check existing impl methods to see if they are both present in trait
875 // and compatible with trait signature
876 for impl_item in impl_items {
877 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
878 let ty_trait_item = trait_items.iter()
879 .find(|ac| ac.name() == ty_impl_item.name());
881 if let Some(ty_trait_item) = ty_trait_item {
882 match impl_item.node {
883 hir::ImplItemKind::Const(..) => {
884 let impl_const = match ty_impl_item {
885 ty::ConstTraitItem(ref cti) => cti,
886 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
889 // Find associated const definition.
890 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
891 compare_const_impl(ccx.tcx,
897 span_err!(tcx.sess, impl_item.span, E0323,
898 "item `{}` is an associated const, \
899 which doesn't match its trait `{:?}`",
904 hir::ImplItemKind::Method(ref sig, ref body) => {
905 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
907 let impl_method = match ty_impl_item {
908 ty::MethodTraitItem(ref mti) => mti,
909 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
912 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
913 compare_impl_method(ccx.tcx,
920 span_err!(tcx.sess, impl_item.span, E0324,
921 "item `{}` is an associated method, \
922 which doesn't match its trait `{:?}`",
927 hir::ImplItemKind::Type(_) => {
928 let impl_type = match ty_impl_item {
929 ty::TypeTraitItem(ref tti) => tti,
930 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
933 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
934 if let Some(_) = at.ty {
935 overridden_associated_type = Some(impl_item);
938 span_err!(tcx.sess, impl_item.span, E0325,
939 "item `{}` is an associated type, \
940 which doesn't match its trait `{:?}`",
949 // Check for missing items from trait
950 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
951 let mut missing_items = Vec::new();
952 let mut invalidated_items = Vec::new();
953 let associated_type_overridden = overridden_associated_type.is_some();
954 for trait_item in trait_items.iter() {
956 ty::ConstTraitItem(ref associated_const) => {
957 let is_implemented = impl_items.iter().any(|ii| {
959 hir::ImplItemKind::Const(..) => {
960 ii.name == associated_const.name
965 let is_provided = associated_const.has_value;
969 missing_items.push(associated_const.name);
970 } else if associated_type_overridden {
971 invalidated_items.push(associated_const.name);
975 ty::MethodTraitItem(ref trait_method) => {
977 impl_items.iter().any(|ii| {
979 hir::ImplItemKind::Method(..) => {
980 ii.name == trait_method.name
986 provided_methods.iter().any(|m| m.name == trait_method.name);
989 missing_items.push(trait_method.name);
990 } else if associated_type_overridden {
991 invalidated_items.push(trait_method.name);
995 ty::TypeTraitItem(ref associated_type) => {
996 let is_implemented = impl_items.iter().any(|ii| {
998 hir::ImplItemKind::Type(_) => {
999 ii.name == associated_type.name
1004 let is_provided = associated_type.ty.is_some();
1005 if !is_implemented {
1007 missing_items.push(associated_type.name);
1008 } else if associated_type_overridden {
1009 invalidated_items.push(associated_type.name);
1016 if !missing_items.is_empty() {
1017 span_err!(tcx.sess, impl_span, E0046,
1018 "not all trait items implemented, missing: `{}`",
1019 missing_items.iter()
1020 .map(|name| name.to_string())
1021 .collect::<Vec<_>>().join("`, `"))
1024 if !invalidated_items.is_empty() {
1025 let invalidator = overridden_associated_type.unwrap();
1026 span_err!(tcx.sess, invalidator.span, E0399,
1027 "the following trait items need to be reimplemented \
1028 as `{}` was overridden: `{}`",
1030 invalidated_items.iter()
1031 .map(|name| name.to_string())
1032 .collect::<Vec<_>>().join("`, `"))
1036 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1043 if t_cast.references_error() || t_expr.references_error() {
1046 let tstr = fcx.infcx().ty_to_string(t_cast);
1047 let mut err = fcx.type_error_struct(span, |actual| {
1048 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1051 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1052 let mtstr = match mt {
1053 hir::MutMutable => "mut ",
1054 hir::MutImmutable => ""
1056 if t_cast.is_trait() {
1057 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1059 err.span_suggestion(t_span,
1060 "try casting to a reference instead:",
1061 format!("&{}{}", mtstr, s));
1064 span_help!(err, t_span,
1065 "did you mean `&{}{}`?", mtstr, tstr),
1068 span_help!(err, span,
1069 "consider using an implicit coercion to `&{}{}` instead",
1074 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1076 err.span_suggestion(t_span,
1077 "try casting to a `Box` instead:",
1078 format!("Box<{}>", s));
1081 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1085 span_help!(err, e_span,
1086 "consider using a box or reference as appropriate");
1090 fcx.write_error(id);
1094 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1095 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1097 fn get_item_type_scheme(&self, _: Span, id: DefId)
1098 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1100 Ok(self.tcx().lookup_item_type(id))
1103 fn get_trait_def(&self, _: Span, id: DefId)
1104 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1106 Ok(self.tcx().lookup_trait_def(id))
1109 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1110 // all super predicates are ensured during collect pass
1114 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1115 Some(&self.inh.infcx.parameter_environment.free_substs)
1118 fn get_type_parameter_bounds(&self,
1120 node_id: ast::NodeId)
1121 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1123 let def = self.tcx().type_parameter_def(node_id);
1124 let r = self.inh.infcx.parameter_environment
1127 .filter_map(|predicate| {
1129 ty::Predicate::Trait(ref data) => {
1130 if data.0.self_ty().is_param(def.space, def.index) {
1131 Some(data.to_poly_trait_ref())
1145 fn trait_defines_associated_type_named(&self,
1146 trait_def_id: DefId,
1147 assoc_name: ast::Name)
1150 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1151 trait_def.associated_type_names.contains(&assoc_name)
1155 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1156 substs: Option<&mut subst::Substs<'tcx>>,
1157 space: Option<subst::ParamSpace>,
1158 span: Span) -> Ty<'tcx> {
1159 // Grab the default doing subsitution
1160 let default = ty_param_def.and_then(|def| {
1161 def.default.map(|ty| type_variable::Default {
1162 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1164 def_id: def.default_def_id
1168 let ty_var = self.infcx().next_ty_var_with_default(default);
1170 // Finally we add the type variable to the substs
1173 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1177 fn projected_ty_from_poly_trait_ref(&self,
1179 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1180 item_name: ast::Name)
1183 let (trait_ref, _) =
1184 self.infcx().replace_late_bound_regions_with_fresh_var(
1186 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1189 self.normalize_associated_type(span, trait_ref, item_name)
1192 fn projected_ty(&self,
1194 trait_ref: ty::TraitRef<'tcx>,
1195 item_name: ast::Name)
1198 self.normalize_associated_type(span, trait_ref, item_name)
1202 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1203 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1205 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1209 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1210 &self.inh.infcx.parameter_environment
1213 pub fn sess(&self) -> &Session {
1217 pub fn err_count_since_creation(&self) -> usize {
1218 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1221 /// Resolves type variables in `ty` if possible. Unlike the infcx
1222 /// version, this version will also select obligations if it seems
1223 /// useful, in an effort to get more type information.
1224 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1225 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1227 // No TyInfer()? Nothing needs doing.
1228 if !ty.has_infer_types() {
1229 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1233 // If `ty` is a type variable, see whether we already know what it is.
1234 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1235 if !ty.has_infer_types() {
1236 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1240 // If not, try resolving pending obligations as much as
1241 // possible. This can help substantially when there are
1242 // indirect dependencies that don't seem worth tracking
1244 self.select_obligations_where_possible();
1245 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1247 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1251 fn record_deferred_call_resolution(&self,
1252 closure_def_id: DefId,
1253 r: DeferredCallResolutionHandler<'tcx>) {
1254 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1255 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1258 fn remove_deferred_call_resolutions(&self,
1259 closure_def_id: DefId)
1260 -> Vec<DeferredCallResolutionHandler<'tcx>>
1262 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1263 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1266 pub fn tag(&self) -> String {
1267 let self_ptr: *const FnCtxt = self;
1268 format!("{:?}", self_ptr)
1271 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1272 match self.inh.locals.borrow().get(&nid) {
1275 span_err!(self.tcx().sess, span, E0513,
1276 "no type for local variable {}",
1278 self.tcx().types.err
1284 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1285 debug!("write_ty({}, {:?}) in fcx {}",
1286 node_id, ty, self.tag());
1287 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1290 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1291 if !substs.substs.is_noop() {
1292 debug!("write_substs({}, {:?}) in fcx {}",
1297 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1301 pub fn write_autoderef_adjustment(&self,
1302 node_id: ast::NodeId,
1304 self.write_adjustment(
1306 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1314 pub fn write_adjustment(&self,
1315 node_id: ast::NodeId,
1316 adj: adjustment::AutoAdjustment<'tcx>) {
1317 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1319 if adj.is_identity() {
1323 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1326 /// Basically whenever we are converting from a type scheme into
1327 /// the fn body space, we always want to normalize associated
1328 /// types as well. This function combines the two.
1329 fn instantiate_type_scheme<T>(&self,
1331 substs: &Substs<'tcx>,
1334 where T : TypeFoldable<'tcx>
1336 let value = value.subst(self.tcx(), substs);
1337 let result = self.normalize_associated_types_in(span, &value);
1338 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1345 /// As `instantiate_type_scheme`, but for the bounds found in a
1346 /// generic type scheme.
1347 fn instantiate_bounds(&self,
1349 substs: &Substs<'tcx>,
1350 bounds: &ty::GenericPredicates<'tcx>)
1351 -> ty::InstantiatedPredicates<'tcx>
1353 ty::InstantiatedPredicates {
1354 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1359 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1360 where T : TypeFoldable<'tcx>
1362 self.inh.normalize_associated_types_in(span, self.body_id, value)
1365 fn normalize_associated_type(&self,
1367 trait_ref: ty::TraitRef<'tcx>,
1368 item_name: ast::Name)
1371 let cause = traits::ObligationCause::new(span,
1373 traits::ObligationCauseCode::MiscObligation);
1377 .normalize_projection_type(self.infcx(),
1379 trait_ref: trait_ref,
1380 item_name: item_name,
1385 /// Instantiates the type in `did` with the generics in `path` and returns
1386 /// it (registering the necessary trait obligations along the way).
1388 /// Note that this function is only intended to be used with type-paths,
1389 /// not with value-paths.
1390 pub fn instantiate_type(&self,
1395 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1397 self.tcx().lookup_item_type(did);
1398 let type_predicates =
1399 self.tcx().lookup_predicates(did);
1400 let substs = astconv::ast_path_substs_for_ty(self, self,
1402 PathParamMode::Optional,
1403 &type_scheme.generics,
1404 path.segments.last().unwrap());
1405 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1407 self.instantiate_bounds(path.span, &substs, &type_predicates);
1408 self.add_obligations_for_parameters(
1409 traits::ObligationCause::new(
1412 traits::ItemObligation(did)),
1415 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1418 /// Return the dict-like variant corresponding to a given `Def`.
1419 pub fn def_struct_variant(&self,
1422 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1424 let (adt, variant) = match def {
1425 Def::Variant(enum_id, variant_id) => {
1426 let adt = self.tcx().lookup_adt_def(enum_id);
1427 (adt, adt.variant_with_id(variant_id))
1429 Def::Struct(did) | Def::TyAlias(did) => {
1430 let typ = self.tcx().lookup_item_type(did);
1431 if let ty::TyStruct(adt, _) = typ.ty.sty {
1432 (adt, adt.struct_variant())
1440 let var_kind = variant.kind();
1441 if var_kind == ty::VariantKind::Struct {
1442 Some((adt, variant))
1443 } else if var_kind == ty::VariantKind::Unit {
1444 if !self.tcx().sess.features.borrow().braced_empty_structs {
1445 let mut err = self.tcx().sess.struct_span_err(span,
1446 "empty structs and enum variants \
1447 with braces are unstable");
1448 fileline_help!(&mut err, span, "add #![feature(braced_empty_structs)] to \
1449 the crate features to enable");
1453 Some((adt, variant))
1459 pub fn write_nil(&self, node_id: ast::NodeId) {
1460 self.write_ty(node_id, self.tcx().mk_nil());
1462 pub fn write_error(&self, node_id: ast::NodeId) {
1463 self.write_ty(node_id, self.tcx().types.err);
1466 pub fn require_type_meets(&self,
1469 code: traits::ObligationCauseCode<'tcx>,
1470 bound: ty::BuiltinBound)
1472 self.register_builtin_bound(
1475 traits::ObligationCause::new(span, self.body_id, code));
1478 pub fn require_type_is_sized(&self,
1481 code: traits::ObligationCauseCode<'tcx>)
1483 self.require_type_meets(ty, span, code, ty::BoundSized);
1486 pub fn require_expr_have_sized_type(&self,
1488 code: traits::ObligationCauseCode<'tcx>)
1490 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1493 pub fn type_is_known_to_be_sized(&self,
1498 traits::type_known_to_meet_builtin_bound(self.infcx(),
1504 pub fn register_builtin_bound(&self,
1506 builtin_bound: ty::BuiltinBound,
1507 cause: traits::ObligationCause<'tcx>)
1509 self.inh.fulfillment_cx.borrow_mut()
1510 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1513 pub fn register_predicate(&self,
1514 obligation: traits::PredicateObligation<'tcx>)
1516 debug!("register_predicate({:?})",
1518 self.inh.fulfillment_cx
1520 .register_predicate_obligation(self.infcx(), obligation);
1523 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1524 let t = ast_ty_to_ty(self, self, ast_t);
1525 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1529 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1530 match self.inh.tables.borrow().node_types.get(&ex.id) {
1533 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1539 /// Apply `adjustment` to the type of `expr`
1540 pub fn adjust_expr_ty(&self,
1542 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1545 let raw_ty = self.expr_ty(expr);
1546 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1547 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1548 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1549 self.inh.tables.borrow().method_map.get(&method_call)
1550 .map(|method| resolve_ty(method.ty))
1554 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1555 match self.inh.tables.borrow().node_types.get(&id) {
1557 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1559 self.tcx().sess.bug(
1560 &format!("no type for node {}: {} in fcx {}",
1561 id, self.tcx().map.node_to_string(id),
1567 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1568 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1569 // it changes when we upgrade the snapshot compiler
1570 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1571 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1575 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1578 pub fn opt_node_ty_substs<F>(&self,
1581 F: FnOnce(&ty::ItemSubsts<'tcx>),
1583 match self.inh.tables.borrow().item_substs.get(&id) {
1589 pub fn mk_subty(&self,
1590 a_is_expected: bool,
1594 -> Result<(), TypeError<'tcx>> {
1595 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1598 pub fn mk_eqty(&self,
1599 a_is_expected: bool,
1603 -> Result<(), TypeError<'tcx>> {
1604 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1607 pub fn mk_subr(&self,
1608 origin: infer::SubregionOrigin<'tcx>,
1611 infer::mk_subr(self.infcx(), origin, sub, sup)
1614 pub fn type_error_message<M>(&self,
1617 actual_ty: Ty<'tcx>,
1618 err: Option<&TypeError<'tcx>>)
1619 where M: FnOnce(String) -> String,
1621 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1624 pub fn type_error_struct<M>(&self,
1627 actual_ty: Ty<'tcx>,
1628 err: Option<&TypeError<'tcx>>)
1629 -> DiagnosticBuilder<'tcx>
1630 where M: FnOnce(String) -> String,
1632 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1635 pub fn report_mismatched_types(&self,
1639 err: &TypeError<'tcx>) {
1640 self.infcx().report_mismatched_types(sp, e, a, err)
1643 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1644 /// outlive the region `r`.
1645 pub fn register_region_obligation(&self,
1648 cause: traits::ObligationCause<'tcx>)
1650 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1651 fulfillment_cx.register_region_obligation(ty, region, cause);
1654 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1655 /// outlive the region `r`.
1656 pub fn register_wf_obligation(&self,
1659 code: traits::ObligationCauseCode<'tcx>)
1661 // WF obligations never themselves fail, so no real need to give a detailed cause:
1662 let cause = traits::ObligationCause::new(span, self.body_id, code);
1663 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1666 pub fn register_old_wf_obligation(&self,
1669 code: traits::ObligationCauseCode<'tcx>)
1671 // Registers an "old-style" WF obligation that uses the
1672 // implicator code. This is basically a buggy version of
1673 // `register_wf_obligation` that is being kept around
1674 // temporarily just to help with phasing in the newer rules.
1676 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1677 let cause = traits::ObligationCause::new(span, self.body_id, code);
1678 self.register_region_obligation(ty, ty::ReEmpty, cause);
1681 /// Registers obligations that all types appearing in `substs` are well-formed.
1682 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1684 for &ty in &substs.types {
1685 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1689 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1690 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1691 /// trait/region obligations.
1693 /// For example, if there is a function:
1696 /// fn foo<'a,T:'a>(...)
1699 /// and a reference:
1705 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1706 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1707 pub fn add_obligations_for_parameters(&self,
1708 cause: traits::ObligationCause<'tcx>,
1709 predicates: &ty::InstantiatedPredicates<'tcx>)
1711 assert!(!predicates.has_escaping_regions());
1713 debug!("add_obligations_for_parameters(predicates={:?})",
1716 for obligation in traits::predicates_for_generics(cause, predicates) {
1717 self.register_predicate(obligation);
1721 // FIXME(arielb1): use this instead of field.ty everywhere
1722 pub fn field_ty(&self,
1724 field: ty::FieldDef<'tcx>,
1725 substs: &Substs<'tcx>)
1728 self.normalize_associated_types_in(span,
1729 &field.ty(self.tcx(), substs))
1732 // Only for fields! Returns <none> for methods>
1733 // Indifferent to privacy flags
1734 fn check_casts(&self) {
1735 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1736 for cast in deferred_cast_checks.drain(..) {
1741 /// Apply "fallbacks" to some types
1742 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1743 fn default_type_parameters(&self) {
1744 use middle::ty::error::UnconstrainedNumeric::Neither;
1745 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1746 for ty in &self.infcx().unsolved_variables() {
1747 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1748 if self.infcx().type_var_diverges(resolved) {
1749 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1751 match self.infcx().type_is_unconstrained_numeric(resolved) {
1752 UnconstrainedInt => {
1753 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1755 UnconstrainedFloat => {
1756 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1764 fn select_all_obligations_and_apply_defaults(&self) {
1765 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1766 self.new_select_all_obligations_and_apply_defaults();
1768 self.old_select_all_obligations_and_apply_defaults();
1772 // Implements old type inference fallback algorithm
1773 fn old_select_all_obligations_and_apply_defaults(&self) {
1774 self.select_obligations_where_possible();
1775 self.default_type_parameters();
1776 self.select_obligations_where_possible();
1779 fn new_select_all_obligations_and_apply_defaults(&self) {
1780 use middle::ty::error::UnconstrainedNumeric::Neither;
1781 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1783 // For the time being this errs on the side of being memory wasteful but provides better
1785 // let type_variables = self.infcx().type_variables.clone();
1787 // There is a possibility that this algorithm will have to run an arbitrary number of times
1788 // to terminate so we bound it by the compiler's recursion limit.
1789 for _ in 0..self.tcx().sess.recursion_limit.get() {
1790 // First we try to solve all obligations, it is possible that the last iteration
1791 // has made it possible to make more progress.
1792 self.select_obligations_where_possible();
1794 let mut conflicts = Vec::new();
1796 // Collect all unsolved type, integral and floating point variables.
1797 let unsolved_variables = self.inh.infcx.unsolved_variables();
1799 // We must collect the defaults *before* we do any unification. Because we have
1800 // directly attached defaults to the type variables any unification that occurs
1801 // will erase defaults causing conflicting defaults to be completely ignored.
1802 let default_map: FnvHashMap<_, _> =
1805 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1808 let mut unbound_tyvars = HashSet::new();
1810 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1812 // We loop over the unsolved variables, resolving them and if they are
1813 // and unconstrainted numeric type we add them to the set of unbound
1814 // variables. We do this so we only apply literal fallback to type
1815 // variables without defaults.
1816 for ty in &unsolved_variables {
1817 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1818 if self.infcx().type_var_diverges(resolved) {
1819 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1821 match self.infcx().type_is_unconstrained_numeric(resolved) {
1822 UnconstrainedInt | UnconstrainedFloat => {
1823 unbound_tyvars.insert(resolved);
1830 // We now remove any numeric types that also have defaults, and instead insert
1831 // the type variable with a defined fallback.
1832 for ty in &unsolved_variables {
1833 if let Some(_default) = default_map.get(ty) {
1834 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1836 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1839 match resolved.sty {
1840 ty::TyInfer(ty::TyVar(_)) => {
1841 unbound_tyvars.insert(ty);
1844 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1845 unbound_tyvars.insert(ty);
1846 if unbound_tyvars.contains(resolved) {
1847 unbound_tyvars.remove(resolved);
1856 // If there are no more fallbacks to apply at this point we have applied all possible
1857 // defaults and type inference will proceed as normal.
1858 if unbound_tyvars.is_empty() {
1862 // Finally we go through each of the unbound type variables and unify them with
1863 // the proper fallback, reporting a conflicting default error if any of the
1864 // unifications fail. We know it must be a conflicting default because the
1865 // variable would only be in `unbound_tyvars` and have a concrete value if
1866 // it had been solved by previously applying a default.
1868 // We wrap this in a transaction for error reporting, if we detect a conflict
1869 // we will rollback the inference context to its prior state so we can probe
1870 // for conflicts and correctly report them.
1873 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1874 for ty in &unbound_tyvars {
1875 if self.infcx().type_var_diverges(ty) {
1876 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1878 match self.infcx().type_is_unconstrained_numeric(ty) {
1879 UnconstrainedInt => {
1880 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1882 UnconstrainedFloat => {
1883 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1886 if let Some(default) = default_map.get(ty) {
1887 let default = default.clone();
1888 match infer::mk_eqty(self.infcx(), false,
1889 TypeOrigin::Misc(default.origin_span),
1893 conflicts.push((*ty, default));
1902 // If there are conflicts we rollback, otherwise commit
1903 if conflicts.len() > 0 {
1910 if conflicts.len() > 0 {
1911 // Loop through each conflicting default, figuring out the default that caused
1912 // a unification failure and then report an error for each.
1913 for (conflict, default) in conflicts {
1914 let conflicting_default =
1915 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1916 .unwrap_or(type_variable::Default {
1917 ty: self.infcx().next_ty_var(),
1918 origin_span: codemap::DUMMY_SP,
1919 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1922 // This is to ensure that we elimnate any non-determinism from the error
1923 // reporting by fixing an order, it doesn't matter what order we choose
1924 // just that it is consistent.
1925 let (first_default, second_default) =
1926 if default.def_id < conflicting_default.def_id {
1927 (default, conflicting_default)
1929 (conflicting_default, default)
1933 self.infcx().report_conflicting_default_types(
1934 first_default.origin_span,
1941 self.select_obligations_where_possible();
1944 // For use in error handling related to default type parameter fallback. We explicitly
1945 // apply the default that caused conflict first to a local version of the type variable
1946 // table then apply defaults until we find a conflict. That default must be the one
1947 // that caused conflict earlier.
1948 fn find_conflicting_default(&self,
1949 unbound_vars: &HashSet<Ty<'tcx>>,
1950 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1952 -> Option<type_variable::Default<'tcx>> {
1953 use middle::ty::error::UnconstrainedNumeric::Neither;
1954 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1956 // Ensure that we apply the conflicting default first
1957 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1958 unbound_tyvars.push(conflict);
1959 unbound_tyvars.extend(unbound_vars.iter());
1961 let mut result = None;
1962 // We run the same code as above applying defaults in order, this time when
1963 // we find the conflict we just return it for error reporting above.
1965 // We also run this inside snapshot that never commits so we can do error
1966 // reporting for more then one conflict.
1967 for ty in &unbound_tyvars {
1968 if self.infcx().type_var_diverges(ty) {
1969 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1971 match self.infcx().type_is_unconstrained_numeric(ty) {
1972 UnconstrainedInt => {
1973 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1975 UnconstrainedFloat => {
1976 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1979 if let Some(default) = default_map.get(ty) {
1980 let default = default.clone();
1981 match infer::mk_eqty(self.infcx(), false,
1982 TypeOrigin::Misc(default.origin_span),
1986 result = Some(default);
1998 fn select_all_obligations_or_error(&self) {
1999 debug!("select_all_obligations_or_error");
2001 // upvar inference should have ensured that all deferred call
2002 // resolutions are handled by now.
2003 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2005 self.select_all_obligations_and_apply_defaults();
2007 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
2008 match fulfillment_cx.select_all_or_error(self.infcx()) {
2010 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2014 /// Select as many obligations as we can at present.
2015 fn select_obligations_where_possible(&self) {
2017 self.inh.fulfillment_cx
2019 .select_where_possible(self.infcx())
2022 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2027 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2028 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2029 Some(self.base_object_lifetime_default(span))
2032 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2033 // RFC #599 specifies that object lifetime defaults take
2034 // precedence over other defaults. But within a fn body we
2035 // don't have a *default* region, rather we use inference to
2036 // find the *correct* region, which is strictly more general
2037 // (and anyway, within a fn body the right region may not even
2038 // be something the user can write explicitly, since it might
2039 // be some expression).
2040 self.infcx().next_region_var(infer::MiscVariable(span))
2043 fn anon_regions(&self, span: Span, count: usize)
2044 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2045 Ok((0..count).map(|_| {
2046 self.infcx().next_region_var(infer::MiscVariable(span))
2051 /// Whether `autoderef` requires types to resolve.
2052 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2053 pub enum UnresolvedTypeAction {
2054 /// Produce an error and return `TyError` whenever a type cannot
2055 /// be resolved (i.e. it is `TyInfer`).
2057 /// Go on without emitting any errors, and return the unresolved
2058 /// type. Useful for probing, e.g. in coercions.
2062 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2063 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2065 /// Note: this method does not modify the adjustments table. The caller is responsible for
2066 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2067 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2070 opt_expr: Option<&hir::Expr>,
2071 unresolved_type_action: UnresolvedTypeAction,
2072 mut lvalue_pref: LvaluePreference,
2074 -> (Ty<'tcx>, usize, Option<T>)
2075 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2077 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2082 let mut t = base_ty;
2083 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2084 let resolved_t = match unresolved_type_action {
2085 UnresolvedTypeAction::Error => {
2086 structurally_resolved_type(fcx, sp, t)
2088 UnresolvedTypeAction::Ignore => {
2089 // We can continue even when the type cannot be resolved
2090 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2091 // and `try_overloaded_deref` both simply return `None`
2092 // in such a case without producing spurious errors.
2093 fcx.resolve_type_vars_if_possible(t)
2096 if resolved_t.references_error() {
2097 return (resolved_t, autoderefs, None);
2100 match should_stop(resolved_t, autoderefs) {
2101 Some(x) => return (resolved_t, autoderefs, Some(x)),
2105 // Otherwise, deref if type is derefable:
2106 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2107 Some(mt) => Some(mt),
2110 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2112 // Super subtle: it might seem as though we should
2113 // pass `opt_expr` to `try_overloaded_deref`, so that
2114 // the (implicit) autoref of using an overloaded deref
2115 // would get added to the adjustment table. However we
2116 // do not do that, because it's kind of a
2117 // "meta-adjustment" -- instead, we just leave it
2118 // unrecorded and know that there "will be" an
2119 // autoref. regionck and other bits of the code base,
2120 // when they encounter an overloaded autoderef, have
2121 // to do some reconstructive surgery. This is a pretty
2122 // complex mess that is begging for a proper MIR.
2123 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2129 if mt.mutbl == hir::MutImmutable {
2130 lvalue_pref = NoPreference;
2133 None => return (resolved_t, autoderefs, None)
2137 // We've reached the recursion limit, error gracefully.
2138 span_err!(fcx.tcx().sess, sp, E0055,
2139 "reached the recursion limit while auto-dereferencing {:?}",
2141 (fcx.tcx().types.err, 0, None)
2144 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2146 method_call: Option<MethodCall>,
2147 base_expr: Option<&hir::Expr>,
2149 lvalue_pref: LvaluePreference)
2150 -> Option<ty::TypeAndMut<'tcx>>
2152 // Try DerefMut first, if preferred.
2153 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2154 (PreferMutLvalue, Some(trait_did)) => {
2155 method::lookup_in_trait(fcx, span, base_expr,
2156 token::intern("deref_mut"), trait_did,
2162 // Otherwise, fall back to Deref.
2163 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2164 (None, Some(trait_did)) => {
2165 method::lookup_in_trait(fcx, span, base_expr,
2166 token::intern("deref"), trait_did,
2169 (method, _) => method
2172 make_overloaded_lvalue_return_type(fcx, method_call, method)
2175 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2176 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2177 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2178 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2179 method_call: Option<MethodCall>,
2180 method: Option<MethodCallee<'tcx>>)
2181 -> Option<ty::TypeAndMut<'tcx>>
2185 // extract method return type, which will be &T;
2186 // all LB regions should have been instantiated during method lookup
2187 let ret_ty = method.ty.fn_ret();
2188 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2190 if let Some(method_call) = method_call {
2191 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2194 // method returns &T, but the type as visible to user is T, so deref
2195 ret_ty.builtin_deref(true, NoPreference)
2201 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2203 base_expr: &'tcx hir::Expr,
2206 lvalue_pref: LvaluePreference)
2207 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2209 // FIXME(#18741) -- this is almost but not quite the same as the
2210 // autoderef that normal method probing does. They could likely be
2213 let (ty, autoderefs, final_mt) = autoderef(fcx,
2217 UnresolvedTypeAction::Error,
2220 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2221 adj_ty, idx, false, lvalue_pref, idx_ty)
2224 if final_mt.is_some() {
2228 // After we have fully autoderef'd, if the resulting type is [T; n], then
2229 // do a final unsized coercion to yield [T].
2230 if let ty::TyArray(element_ty, _) = ty.sty {
2231 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2232 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2233 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2239 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2240 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2241 /// This loop implements one step in that search; the autoderef loop is implemented by
2242 /// `lookup_indexing`.
2243 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2244 method_call: MethodCall,
2246 base_expr: &'tcx hir::Expr,
2247 adjusted_ty: Ty<'tcx>,
2250 lvalue_pref: LvaluePreference,
2252 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2254 let tcx = fcx.tcx();
2255 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2256 autoderefs={}, unsize={}, index_ty={:?})",
2264 let input_ty = fcx.infcx().next_ty_var();
2266 // First, try built-in indexing.
2267 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2268 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2269 debug!("try_index_step: success, using built-in indexing");
2270 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2272 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2273 return Some((tcx.types.usize, ty));
2278 // Try `IndexMut` first, if preferred.
2279 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2280 (PreferMutLvalue, Some(trait_did)) => {
2281 method::lookup_in_trait_adjusted(fcx,
2284 token::intern("index_mut"),
2289 Some(vec![input_ty]))
2294 // Otherwise, fall back to `Index`.
2295 let method = match (method, tcx.lang_items.index_trait()) {
2296 (None, Some(trait_did)) => {
2297 method::lookup_in_trait_adjusted(fcx,
2300 token::intern("index"),
2305 Some(vec![input_ty]))
2307 (method, _) => method,
2310 // If some lookup succeeds, write callee into table and extract index/element
2311 // type from the method signature.
2312 // If some lookup succeeded, install method in table
2313 method.and_then(|method| {
2314 debug!("try_index_step: success, using overloaded indexing");
2315 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2316 map(|ret| (input_ty, ret.ty))
2320 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2322 method_fn_ty: Ty<'tcx>,
2323 callee_expr: &'tcx hir::Expr,
2324 args_no_rcvr: &'tcx [P<hir::Expr>],
2325 tuple_arguments: TupleArgumentsFlag,
2326 expected: Expectation<'tcx>)
2327 -> ty::FnOutput<'tcx> {
2328 if method_fn_ty.references_error() {
2329 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2331 let err_inputs = match tuple_arguments {
2332 DontTupleArguments => err_inputs,
2333 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2336 check_argument_types(fcx,
2343 ty::FnConverging(fcx.tcx().types.err)
2345 match method_fn_ty.sty {
2346 ty::TyBareFn(_, ref fty) => {
2347 // HACK(eddyb) ignore self in the definition (see above).
2348 let expected_arg_tys = expected_types_for_fn_args(fcx,
2352 &fty.sig.0.inputs[1..]);
2353 check_argument_types(fcx,
2355 &fty.sig.0.inputs[1..],
2356 &expected_arg_tys[..],
2363 fcx.tcx().sess.span_bug(callee_expr.span,
2364 "method without bare fn type");
2370 /// Generic function that factors out common logic from function calls, method calls and overloaded
2372 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2374 fn_inputs: &[Ty<'tcx>],
2375 expected_arg_tys: &[Ty<'tcx>],
2376 args: &'tcx [P<hir::Expr>],
2378 tuple_arguments: TupleArgumentsFlag) {
2379 let tcx = fcx.ccx.tcx;
2381 // Grab the argument types, supplying fresh type variables
2382 // if the wrong number of arguments were supplied
2383 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2389 // All the input types from the fn signature must outlive the call
2390 // so as to validate implied bounds.
2391 for &fn_input_ty in fn_inputs {
2392 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2395 let mut expected_arg_tys = expected_arg_tys;
2396 let expected_arg_count = fn_inputs.len();
2397 let formal_tys = if tuple_arguments == TupleArguments {
2398 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2399 match tuple_type.sty {
2400 ty::TyTuple(ref arg_types) => {
2401 if arg_types.len() != args.len() {
2402 span_err!(tcx.sess, sp, E0057,
2403 "this function takes {} parameter{} but {} parameter{} supplied",
2405 if arg_types.len() == 1 {""} else {"s"},
2407 if args.len() == 1 {" was"} else {"s were"});
2408 expected_arg_tys = &[];
2409 err_args(fcx.tcx(), args.len())
2411 expected_arg_tys = match expected_arg_tys.get(0) {
2412 Some(&ty) => match ty.sty {
2413 ty::TyTuple(ref tys) => &tys,
2418 (*arg_types).clone()
2422 span_err!(tcx.sess, sp, E0059,
2423 "cannot use call notation; the first type parameter \
2424 for the function trait is neither a tuple nor unit");
2425 expected_arg_tys = &[];
2426 err_args(fcx.tcx(), args.len())
2429 } else if expected_arg_count == supplied_arg_count {
2431 } else if variadic {
2432 if supplied_arg_count >= expected_arg_count {
2435 span_err!(tcx.sess, sp, E0060,
2436 "this function takes at least {} parameter{} \
2437 but {} parameter{} supplied",
2439 if expected_arg_count == 1 {""} else {"s"},
2441 if supplied_arg_count == 1 {" was"} else {"s were"});
2442 expected_arg_tys = &[];
2443 err_args(fcx.tcx(), supplied_arg_count)
2446 span_err!(tcx.sess, sp, E0061,
2447 "this function takes {} parameter{} but {} parameter{} supplied",
2449 if expected_arg_count == 1 {""} else {"s"},
2451 if supplied_arg_count == 1 {" was"} else {"s were"});
2452 expected_arg_tys = &[];
2453 err_args(fcx.tcx(), supplied_arg_count)
2456 debug!("check_argument_types: formal_tys={:?}",
2457 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2459 // Check the arguments.
2460 // We do this in a pretty awful way: first we typecheck any arguments
2461 // that are not anonymous functions, then we typecheck the anonymous
2462 // functions. This is so that we have more information about the types
2463 // of arguments when we typecheck the functions. This isn't really the
2464 // right way to do this.
2465 let xs = [false, true];
2466 let mut any_diverges = false; // has any of the arguments diverged?
2467 let mut warned = false; // have we already warned about unreachable code?
2468 for check_blocks in &xs {
2469 let check_blocks = *check_blocks;
2470 debug!("check_blocks={}", check_blocks);
2472 // More awful hacks: before we check argument types, try to do
2473 // an "opportunistic" vtable resolution of any trait bounds on
2474 // the call. This helps coercions.
2476 fcx.select_obligations_where_possible();
2479 // For variadic functions, we don't have a declared type for all of
2480 // the arguments hence we only do our usual type checking with
2481 // the arguments who's types we do know.
2482 let t = if variadic {
2484 } else if tuple_arguments == TupleArguments {
2489 for (i, arg) in args.iter().take(t).enumerate() {
2490 if any_diverges && !warned {
2494 .add_lint(lint::builtin::UNREACHABLE_CODE,
2497 "unreachable expression".to_string());
2500 let is_block = match arg.node {
2501 hir::ExprClosure(..) => true,
2505 if is_block == check_blocks {
2506 debug!("checking the argument");
2507 let formal_ty = formal_tys[i];
2509 // The special-cased logic below has three functions:
2510 // 1. Provide as good of an expected type as possible.
2511 let expected = expected_arg_tys.get(i).map(|&ty| {
2512 Expectation::rvalue_hint(fcx.tcx(), ty)
2515 check_expr_with_unifier(fcx,
2517 expected.unwrap_or(ExpectHasType(formal_ty)),
2519 // 2. Coerce to the most detailed type that could be coerced
2520 // to, which is `expected_ty` if `rvalue_hint` returns an
2521 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2522 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2523 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2525 // 3. Relate the expected type and the formal one,
2526 // if the expected type was used for the coercion.
2527 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2531 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2532 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2535 if any_diverges && !warned {
2536 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2540 .add_lint(lint::builtin::UNREACHABLE_CODE,
2543 "unreachable call".to_string());
2549 // We also need to make sure we at least write the ty of the other
2550 // arguments which we skipped above.
2552 for arg in args.iter().skip(expected_arg_count) {
2553 check_expr(fcx, &arg);
2555 // There are a few types which get autopromoted when passed via varargs
2556 // in C but we just error out instead and require explicit casts.
2557 let arg_ty = structurally_resolved_type(fcx, arg.span,
2560 ty::TyFloat(ast::FloatTy::F32) => {
2561 fcx.type_error_message(arg.span,
2563 format!("can't pass an {} to variadic \
2564 function, cast to c_double", t)
2567 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2568 fcx.type_error_message(arg.span, |t| {
2569 format!("can't pass {} to variadic \
2570 function, cast to c_int",
2574 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2575 fcx.type_error_message(arg.span, |t| {
2576 format!("can't pass {} to variadic \
2577 function, cast to c_uint",
2587 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2588 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2589 (0..len).map(|_| tcx.types.err).collect()
2592 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2593 call_expr: &hir::Expr,
2594 output: ty::FnOutput<'tcx>) {
2595 fcx.write_ty(call_expr.id, match output {
2596 ty::FnConverging(output_ty) => output_ty,
2597 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2601 // AST fragment checking
2602 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2604 expected: Expectation<'tcx>)
2607 let tcx = fcx.ccx.tcx;
2610 ast::LitKind::Str(..) => tcx.mk_static_str(),
2611 ast::LitKind::ByteStr(ref v) => {
2612 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2613 tcx.mk_array(tcx.types.u8, v.len()))
2615 ast::LitKind::Byte(_) => tcx.types.u8,
2616 ast::LitKind::Char(_) => tcx.types.char,
2617 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2618 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2619 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2620 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2622 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2623 ty::TyChar => Some(tcx.types.u8),
2624 ty::TyRawPtr(..) => Some(tcx.types.usize),
2625 ty::TyBareFn(..) => Some(tcx.types.usize),
2629 opt_ty.unwrap_or_else(
2630 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2632 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2633 ast::LitKind::FloatUnsuffixed(_) => {
2634 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2636 ty::TyFloat(_) => Some(ty),
2640 opt_ty.unwrap_or_else(
2641 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2643 ast::LitKind::Bool(_) => tcx.types.bool
2647 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2648 expr: &'tcx hir::Expr,
2649 expected: Ty<'tcx>) {
2650 check_expr_with_unifier(
2651 fcx, expr, ExpectHasType(expected), NoPreference,
2652 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2655 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2656 expr: &'tcx hir::Expr,
2657 expected: Ty<'tcx>) {
2658 check_expr_with_unifier(
2659 fcx, expr, ExpectHasType(expected), NoPreference,
2660 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2663 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2664 expr: &'tcx hir::Expr,
2665 expected: Ty<'tcx>) {
2666 check_expr_with_unifier(
2667 fcx, expr, ExpectHasType(expected), NoPreference,
2668 || demand::coerce(fcx, expr.span, expected, expr));
2671 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2672 expected: Ty<'tcx>) {
2673 check_expr_with_unifier(
2674 fcx, expr, ExpectHasType(expected), NoPreference,
2678 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2679 expr: &'tcx hir::Expr,
2680 expected: Expectation<'tcx>) {
2681 check_expr_with_unifier(
2682 fcx, expr, expected, NoPreference,
2686 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2687 expr: &'tcx hir::Expr,
2688 expected: Expectation<'tcx>,
2689 lvalue_pref: LvaluePreference)
2691 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2694 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2695 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2698 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2699 lvalue_pref: LvaluePreference) {
2700 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2703 // determine the `self` type, using fresh variables for all variables
2704 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2705 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2707 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2708 span: Span, // (potential) receiver for this impl
2710 -> TypeAndSubsts<'tcx> {
2711 let tcx = fcx.tcx();
2713 let ity = tcx.lookup_item_type(did);
2714 let (tps, rps, raw_ty) =
2715 (ity.generics.types.get_slice(subst::TypeSpace),
2716 ity.generics.regions.get_slice(subst::TypeSpace),
2719 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2721 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2722 let mut substs = subst::Substs::new(
2723 VecPerParamSpace::empty(),
2724 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2725 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2726 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2728 TypeAndSubsts { substs: substs, ty: substd_ty }
2731 /// Controls whether the arguments are tupled. This is used for the call
2734 /// Tupling means that all call-side arguments are packed into a tuple and
2735 /// passed as a single parameter. For example, if tupling is enabled, this
2738 /// fn f(x: (isize, isize))
2740 /// Can be called as:
2747 #[derive(Clone, Eq, PartialEq)]
2748 enum TupleArgumentsFlag {
2753 /// Unifies the return type with the expected type early, for more coercions
2754 /// and forward type information on the argument expressions.
2755 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2757 expected_ret: Expectation<'tcx>,
2758 formal_ret: ty::FnOutput<'tcx>,
2759 formal_args: &[Ty<'tcx>])
2761 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2762 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2763 fcx.infcx().commit_regions_if_ok(|| {
2764 // Attempt to apply a subtyping relationship between the formal
2765 // return type (likely containing type variables if the function
2766 // is polymorphic) and the expected return type.
2767 // No argument expectations are produced if unification fails.
2768 let origin = TypeOrigin::Misc(call_span);
2769 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2770 // FIXME(#15760) can't use try! here, FromError doesn't default
2771 // to identity so the resulting type is not constrained.
2772 if let Err(e) = ures {
2776 // Record all the argument types, with the substitutions
2777 // produced from the above subtyping unification.
2778 Ok(formal_args.iter().map(|ty| {
2779 fcx.infcx().resolve_type_vars_if_possible(ty)
2785 }).unwrap_or(vec![]);
2786 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2787 formal_args, formal_ret,
2788 expected_args, expected_ret);
2793 /// If an expression has any sub-expressions that result in a type error,
2794 /// inspecting that expression's type with `ty.references_error()` will return
2795 /// true. Likewise, if an expression is known to diverge, inspecting its
2796 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2797 /// strict, _|_ can appear in the type of an expression that does not,
2798 /// itself, diverge: for example, fn() -> _|_.)
2799 /// Note that inspecting a type's structure *directly* may expose the fact
2800 /// that there are actually multiple representations for `TyError`, so avoid
2801 /// that when err needs to be handled differently.
2802 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2803 expr: &'tcx hir::Expr,
2804 expected: Expectation<'tcx>,
2805 lvalue_pref: LvaluePreference,
2809 debug!(">> typechecking: expr={:?} expected={:?}",
2812 // Checks a method call.
2813 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2814 expr: &'tcx hir::Expr,
2815 method_name: Spanned<ast::Name>,
2816 args: &'tcx [P<hir::Expr>],
2818 expected: Expectation<'tcx>,
2819 lvalue_pref: LvaluePreference) {
2820 let rcvr = &args[0];
2821 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2823 // no need to check for bot/err -- callee does that
2824 let expr_t = structurally_resolved_type(fcx,
2826 fcx.expr_ty(&rcvr));
2828 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2829 let fn_ty = match method::lookup(fcx,
2837 let method_ty = method.ty;
2838 let method_call = MethodCall::expr(expr.id);
2839 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2843 if method_name.node != special_idents::invalid.name {
2844 method::report_error(fcx, method_name.span, expr_t,
2845 method_name.node, Some(rcvr), error);
2847 fcx.write_error(expr.id);
2852 // Call the generic checker.
2853 let ret_ty = check_method_argument_types(fcx,
2861 write_call(fcx, expr, ret_ty);
2864 // A generic function for checking the then and else in an if
2866 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2867 cond_expr: &'tcx hir::Expr,
2868 then_blk: &'tcx hir::Block,
2869 opt_else_expr: Option<&'tcx hir::Expr>,
2872 expected: Expectation<'tcx>) {
2873 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2875 let expected = expected.adjust_for_branches(fcx);
2876 check_block_with_expected(fcx, then_blk, expected);
2877 let then_ty = fcx.node_ty(then_blk.id);
2879 let branches_ty = match opt_else_expr {
2880 Some(ref else_expr) => {
2881 check_expr_with_expectation(fcx, &else_expr, expected);
2882 let else_ty = fcx.expr_ty(&else_expr);
2883 infer::common_supertype(fcx.infcx(),
2884 TypeOrigin::IfExpression(sp),
2890 infer::common_supertype(fcx.infcx(),
2891 TypeOrigin::IfExpressionWithNoElse(sp),
2898 let cond_ty = fcx.expr_ty(cond_expr);
2899 let if_ty = if cond_ty.references_error() {
2905 fcx.write_ty(id, if_ty);
2908 // Check field access expressions
2909 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2910 expr: &'tcx hir::Expr,
2911 lvalue_pref: LvaluePreference,
2912 base: &'tcx hir::Expr,
2913 field: &Spanned<ast::Name>) {
2914 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2915 let expr_t = structurally_resolved_type(fcx, expr.span,
2917 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2918 let (_, autoderefs, field_ty) = autoderef(fcx,
2922 UnresolvedTypeAction::Error,
2926 ty::TyStruct(base_def, substs) => {
2927 debug!("struct named {:?}", base_t);
2928 base_def.struct_variant()
2929 .find_field_named(field.node)
2930 .map(|f| fcx.field_ty(expr.span, f, substs))
2937 fcx.write_ty(expr.id, field_ty);
2938 fcx.write_autoderef_adjustment(base.id, autoderefs);
2944 if field.node == special_idents::invalid.name {
2945 fcx.write_error(expr.id);
2949 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2950 fcx.type_error_struct(field.span,
2952 format!("attempted to take value of method `{}` on type \
2953 `{}`", field.node, actual)
2956 .fileline_help(field.span,
2957 "maybe a `()` to call it is missing? \
2958 If not, try an anonymous function")
2961 let mut err = fcx.type_error_struct(
2964 format!("attempted access of field `{}` on \
2965 type `{}`, but no field with that \
2971 if let ty::TyStruct(def, _) = expr_t.sty {
2972 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2977 fcx.write_error(expr.id);
2980 // displays hints about the closest matches in field names
2981 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2982 variant: ty::VariantDef<'tcx>,
2983 field: &Spanned<ast::Name>,
2984 skip : Vec<InternedString>) {
2985 let name = field.node.as_str();
2986 let names = variant.fields
2988 .filter_map(|ref field| {
2989 // ignore already set fields and private fields from non-local crates
2990 if skip.iter().any(|x| *x == field.name.as_str()) ||
2991 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2998 // only find fits with at least one matching letter
2999 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3000 err.span_help(field.span,
3001 &format!("did you mean `{}`?", name));
3005 // Check tuple index expressions
3006 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3007 expr: &'tcx hir::Expr,
3008 lvalue_pref: LvaluePreference,
3009 base: &'tcx hir::Expr,
3010 idx: codemap::Spanned<usize>) {
3011 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3012 let expr_t = structurally_resolved_type(fcx, expr.span,
3014 let mut tuple_like = false;
3015 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3016 let (_, autoderefs, field_ty) = autoderef(fcx,
3020 UnresolvedTypeAction::Error,
3024 ty::TyStruct(base_def, substs) => {
3025 tuple_like = base_def.struct_variant().is_tuple_struct();
3027 debug!("tuple struct named {:?}", base_t);
3028 base_def.struct_variant()
3031 .map(|f| fcx.field_ty(expr.span, f, substs))
3036 ty::TyTuple(ref v) => {
3038 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3045 fcx.write_ty(expr.id, field_ty);
3046 fcx.write_autoderef_adjustment(base.id, autoderefs);
3051 fcx.type_error_message(
3055 format!("attempted out-of-bounds tuple index `{}` on \
3060 format!("attempted tuple index `{}` on type `{}`, but the \
3061 type was not a tuple or tuple struct",
3068 fcx.write_error(expr.id);
3071 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3073 variant: ty::VariantDef<'tcx>,
3075 skip_fields: &[hir::Field]) {
3076 let mut err = fcx.type_error_struct(
3078 |actual| if let ty::TyEnum(..) = ty.sty {
3079 format!("struct variant `{}::{}` has no field named `{}`",
3080 actual, variant.name.as_str(), field.name.node)
3082 format!("structure `{}` has no field named `{}`",
3083 actual, field.name.node)
3087 // prevent all specified fields from being suggested
3088 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3089 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3093 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3096 variant: ty::VariantDef<'tcx>,
3097 ast_fields: &'tcx [hir::Field],
3098 check_completeness: bool) {
3099 let tcx = fcx.ccx.tcx;
3100 let substs = match adt_ty.sty {
3101 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3102 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3105 let mut remaining_fields = FnvHashMap();
3106 for field in &variant.fields {
3107 remaining_fields.insert(field.name, field);
3110 let mut error_happened = false;
3112 // Typecheck each field.
3113 for field in ast_fields {
3114 let expected_field_type;
3116 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3117 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3119 error_happened = true;
3120 expected_field_type = tcx.types.err;
3121 if let Some(_) = variant.find_field_named(field.name.node) {
3122 span_err!(fcx.tcx().sess, field.name.span, E0062,
3123 "field `{}` specified more than once",
3126 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3130 // Make sure to give a type to the field even if there's
3131 // an error, so we can continue typechecking
3132 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3135 // Make sure the programmer specified all the fields.
3136 if check_completeness &&
3138 !remaining_fields.is_empty()
3140 span_err!(tcx.sess, span, E0063,
3141 "missing field{} {} in initializer of `{}`",
3142 if remaining_fields.len() == 1 {""} else {"s"},
3143 remaining_fields.keys()
3144 .map(|n| format!("`{}`", n))
3145 .collect::<Vec<_>>()
3152 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3154 fields: &'tcx [hir::Field],
3155 base_expr: &'tcx Option<P<hir::Expr>>) {
3156 // Make sure to still write the types
3157 // otherwise we might ICE
3158 fcx.write_error(id);
3159 for field in fields {
3160 check_expr(fcx, &field.expr);
3163 Some(ref base) => check_expr(fcx, &base),
3168 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3171 fields: &'tcx [hir::Field],
3172 base_expr: &'tcx Option<P<hir::Expr>>)
3174 let tcx = fcx.tcx();
3176 // Find the relevant variant
3177 let def = lookup_full_def(tcx, path.span, expr.id);
3178 if def == Def::Err {
3179 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3182 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3183 Some((adt, variant)) => (adt, variant),
3185 span_err!(fcx.tcx().sess, path.span, E0071,
3186 "`{}` does not name a structure",
3187 pprust::path_to_string(path));
3188 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3193 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3194 fcx.write_ty(expr.id, expr_ty);
3196 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3197 base_expr.is_none());
3199 if let &Some(ref base_expr) = base_expr {
3200 check_expr_has_type(fcx, base_expr, expr_ty);
3201 if adt.adt_kind() == ty::AdtKind::Enum {
3202 span_err!(tcx.sess, base_expr.span, E0436,
3203 "functional record update syntax requires a struct");
3208 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3210 let tcx = fcx.ccx.tcx;
3213 hir::ExprBox(ref subexpr) => {
3214 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3216 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3220 check_expr_with_expectation(fcx, subexpr, expected_inner);
3221 let referent_ty = fcx.expr_ty(&subexpr);
3222 fcx.write_ty(id, tcx.mk_box(referent_ty));
3225 hir::ExprLit(ref lit) => {
3226 let typ = check_lit(fcx, &lit, expected);
3227 fcx.write_ty(id, typ);
3229 hir::ExprBinary(op, ref lhs, ref rhs) => {
3230 op::check_binop(fcx, expr, op, lhs, rhs);
3232 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3233 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3235 hir::ExprUnary(unop, ref oprnd) => {
3236 let expected_inner = match unop {
3237 hir::UnNot | hir::UnNeg => {
3244 let lvalue_pref = match unop {
3245 hir::UnDeref => lvalue_pref,
3248 check_expr_with_expectation_and_lvalue_pref(
3249 fcx, &oprnd, expected_inner, lvalue_pref);
3250 let mut oprnd_t = fcx.expr_ty(&oprnd);
3252 if !oprnd_t.references_error() {
3255 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3256 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3258 None => match try_overloaded_deref(fcx, expr.span,
3259 Some(MethodCall::expr(expr.id)),
3260 Some(&oprnd), oprnd_t, lvalue_pref) {
3263 fcx.type_error_message(expr.span, |actual| {
3264 format!("type `{}` cannot be \
3265 dereferenced", actual)
3273 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3275 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3276 oprnd_t = op::check_user_unop(fcx, "!", "not",
3277 tcx.lang_items.not_trait(),
3278 expr, &oprnd, oprnd_t, unop);
3282 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3284 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3285 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3286 tcx.lang_items.neg_trait(),
3287 expr, &oprnd, oprnd_t, unop);
3292 fcx.write_ty(id, oprnd_t);
3294 hir::ExprAddrOf(mutbl, ref oprnd) => {
3295 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3297 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3298 if fcx.tcx().expr_is_lval(&oprnd) {
3299 // Lvalues may legitimately have unsized types.
3300 // For example, dereferences of a fat pointer and
3301 // the last field of a struct can be unsized.
3302 ExpectHasType(mt.ty)
3304 Expectation::rvalue_hint(tcx, mt.ty)
3310 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3311 check_expr_with_expectation_and_lvalue_pref(fcx,
3316 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3317 let oprnd_t = if tm.ty.references_error() {
3320 // Note: at this point, we cannot say what the best lifetime
3321 // is to use for resulting pointer. We want to use the
3322 // shortest lifetime possible so as to avoid spurious borrowck
3323 // errors. Moreover, the longest lifetime will depend on the
3324 // precise details of the value whose address is being taken
3325 // (and how long it is valid), which we don't know yet until type
3326 // inference is complete.
3328 // Therefore, here we simply generate a region variable. The
3329 // region inferencer will then select the ultimate value.
3330 // Finally, borrowck is charged with guaranteeing that the
3331 // value whose address was taken can actually be made to live
3332 // as long as it needs to live.
3333 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3334 tcx.mk_ref(tcx.mk_region(region), tm)
3336 fcx.write_ty(id, oprnd_t);
3338 hir::ExprPath(ref maybe_qself, ref path) => {
3339 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3340 fcx.to_ty(&qself.ty)
3343 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3345 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3346 // Create some fake resolution that can't possibly be a type.
3347 def::PathResolution {
3348 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3349 last_private: LastMod(AllPublic),
3350 depth: path.segments.len()
3353 tcx.sess.span_bug(expr.span,
3354 &format!("unbound path {:?}", expr))
3357 if let Some((opt_ty, segments, def)) =
3358 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3359 expr.span, expr.id) {
3360 if def != Def::Err {
3361 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3364 instantiate_path(fcx,
3373 fcx.write_ty(id, fcx.tcx().types.err);
3377 // We always require that the type provided as the value for
3378 // a type parameter outlives the moment of instantiation.
3379 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3380 fcx.add_wf_bounds(&item_substs.substs, expr);
3383 hir::ExprInlineAsm(ref ia) => {
3384 for &(_, ref input) in &ia.inputs {
3385 check_expr(fcx, &input);
3387 for out in &ia.outputs {
3388 check_expr(fcx, &out.expr);
3392 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3393 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3394 hir::ExprRet(ref expr_opt) => {
3396 ty::FnConverging(result_type) => {
3399 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3400 result_type, fcx.tcx().mk_nil()) {
3401 span_err!(tcx.sess, expr.span, E0069,
3402 "`return;` in a function whose return type is \
3406 check_expr_coercable_to_type(fcx, &e, result_type);
3410 ty::FnDiverging => {
3411 if let Some(ref e) = *expr_opt {
3412 check_expr(fcx, &e);
3414 span_err!(tcx.sess, expr.span, E0166,
3415 "`return` in a function declared as diverging");
3418 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3420 hir::ExprAssign(ref lhs, ref rhs) => {
3421 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3423 let tcx = fcx.tcx();
3424 if !tcx.expr_is_lval(&lhs) {
3425 span_err!(tcx.sess, expr.span, E0070,
3426 "invalid left-hand side expression");
3429 let lhs_ty = fcx.expr_ty(&lhs);
3430 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3431 let rhs_ty = fcx.expr_ty(&rhs);
3433 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3435 if lhs_ty.references_error() || rhs_ty.references_error() {
3436 fcx.write_error(id);
3441 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3442 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3443 id, expr.span, expected);
3445 hir::ExprWhile(ref cond, ref body, _) => {
3446 check_expr_has_type(fcx, &cond, tcx.types.bool);
3447 check_block_no_value(fcx, &body);
3448 let cond_ty = fcx.expr_ty(&cond);
3449 let body_ty = fcx.node_ty(body.id);
3450 if cond_ty.references_error() || body_ty.references_error() {
3451 fcx.write_error(id);
3457 hir::ExprLoop(ref body, _) => {
3458 check_block_no_value(fcx, &body);
3459 if !may_break(tcx, expr.id, &body) {
3460 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3465 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3466 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3468 hir::ExprClosure(capture, ref decl, ref body) => {
3469 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3471 hir::ExprBlock(ref b) => {
3472 check_block_with_expected(fcx, &b, expected);
3473 fcx.write_ty(id, fcx.node_ty(b.id));
3475 hir::ExprCall(ref callee, ref args) => {
3476 callee::check_call(fcx, expr, &callee, &args[..], expected);
3478 // we must check that return type of called functions is WF:
3479 let ret_ty = fcx.expr_ty(expr);
3480 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3482 hir::ExprMethodCall(name, ref tps, ref args) => {
3483 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3484 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3485 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3487 fcx.write_error(id);
3490 hir::ExprCast(ref e, ref t) => {
3491 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3492 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3495 // Find the type of `e`. Supply hints based on the type we are casting to,
3497 let t_cast = fcx.to_ty(t);
3498 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3499 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3500 let t_expr = fcx.expr_ty(e);
3501 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3503 // Eagerly check for some obvious errors.
3504 if t_expr.references_error() || t_cast.references_error() {
3505 fcx.write_error(id);
3506 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3507 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3509 // Write a type for the whole expression, assuming everything is going
3511 fcx.write_ty(id, t_cast);
3513 // Defer other checks until we're done type checking.
3514 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3515 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3516 deferred_cast_checks.push(cast_check);
3519 hir::ExprType(ref e, ref t) => {
3520 let typ = fcx.to_ty(&t);
3521 check_expr_eq_type(fcx, &e, typ);
3522 fcx.write_ty(id, typ);
3524 hir::ExprVec(ref args) => {
3525 let uty = expected.to_option(fcx).and_then(|uty| {
3527 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3532 let typ = match uty {
3535 check_expr_coercable_to_type(fcx, &e, uty);
3540 let t: Ty = fcx.infcx().next_ty_var();
3542 check_expr_has_type(fcx, &e, t);
3547 let typ = tcx.mk_array(typ, args.len());
3548 fcx.write_ty(id, typ);
3550 hir::ExprRepeat(ref element, ref count_expr) => {
3551 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3552 let count = fcx.tcx().eval_repeat_count(&count_expr);
3554 let uty = match expected {
3555 ExpectHasType(uty) => {
3557 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3564 let (element_ty, t) = match uty {
3566 check_expr_coercable_to_type(fcx, &element, uty);
3570 let t: Ty = fcx.infcx().next_ty_var();
3571 check_expr_has_type(fcx, &element, t);
3572 (fcx.expr_ty(&element), t)
3577 // For [foo, ..n] where n > 1, `foo` must have
3579 fcx.require_type_meets(
3586 if element_ty.references_error() {
3587 fcx.write_error(id);
3589 let t = tcx.mk_array(t, count);
3590 fcx.write_ty(id, t);
3593 hir::ExprTup(ref elts) => {
3594 let flds = expected.only_has_type(fcx).and_then(|ty| {
3596 ty::TyTuple(ref flds) => Some(&flds[..]),
3600 let mut err_field = false;
3602 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3603 let t = match flds {
3604 Some(ref fs) if i < fs.len() => {
3606 check_expr_coercable_to_type(fcx, &e, ety);
3610 check_expr_with_expectation(fcx, &e, NoExpectation);
3614 err_field = err_field || t.references_error();
3618 fcx.write_error(id);
3620 let typ = tcx.mk_tup(elt_ts);
3621 fcx.write_ty(id, typ);
3624 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3625 check_expr_struct(fcx, expr, path, fields, base_expr);
3627 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3629 hir::ExprField(ref base, ref field) => {
3630 check_field(fcx, expr, lvalue_pref, &base, field);
3632 hir::ExprTupField(ref base, idx) => {
3633 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3635 hir::ExprIndex(ref base, ref idx) => {
3636 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3637 check_expr(fcx, &idx);
3639 let base_t = fcx.expr_ty(&base);
3640 let idx_t = fcx.expr_ty(&idx);
3642 if base_t.references_error() {
3643 fcx.write_ty(id, base_t);
3644 } else if idx_t.references_error() {
3645 fcx.write_ty(id, idx_t);
3647 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3648 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3649 Some((index_ty, element_ty)) => {
3650 let idx_expr_ty = fcx.expr_ty(idx);
3651 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3652 fcx.write_ty(id, element_ty);
3655 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3656 fcx.type_error_message(
3659 format!("cannot index a value of type `{}`",
3664 fcx.write_ty(id, fcx.tcx().types.err);
3669 hir::ExprRange(ref start, ref end) => {
3670 let t_start = start.as_ref().map(|e| {
3671 check_expr(fcx, &e);
3674 let t_end = end.as_ref().map(|e| {
3675 check_expr(fcx, &e);
3679 let idx_type = match (t_start, t_end) {
3680 (Some(ty), None) | (None, Some(ty)) => {
3683 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3684 t_end.references_error()) => {
3685 Some(fcx.tcx().types.err)
3687 (Some(t_start), Some(t_end)) => {
3688 Some(infer::common_supertype(fcx.infcx(),
3689 TypeOrigin::RangeExpression(expr.span),
3697 // Note that we don't check the type of start/end satisfy any
3698 // bounds because right now the range structs do not have any. If we add
3699 // some bounds, then we'll need to check `t_start` against them here.
3701 let range_type = match idx_type {
3702 Some(idx_type) if idx_type.references_error() => {
3706 // Find the did from the appropriate lang item.
3707 let did = match (start, end) {
3708 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3709 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3710 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3712 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3716 if let Some(did) = did {
3717 let def = tcx.lookup_adt_def(did);
3718 let predicates = tcx.lookup_predicates(did);
3719 let substs = Substs::new_type(vec![idx_type], vec![]);
3720 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3721 fcx.add_obligations_for_parameters(
3722 traits::ObligationCause::new(expr.span,
3724 traits::ItemObligation(did)),
3727 tcx.mk_struct(def, tcx.mk_substs(substs))
3729 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3734 // Neither start nor end => RangeFull
3735 if let Some(did) = tcx.lang_items.range_full_struct() {
3737 tcx.lookup_adt_def(did),
3738 tcx.mk_substs(Substs::empty())
3741 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3747 fcx.write_ty(id, range_type);
3752 debug!("type of expr({}) {} is...", expr.id,
3753 pprust::expr_to_string(expr));
3754 debug!("... {:?}, expected is {:?}",
3761 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3762 path_res: def::PathResolution,
3763 opt_self_ty: Option<Ty<'tcx>>,
3764 path: &'a hir::Path,
3766 node_id: ast::NodeId)
3767 -> Option<(Option<Ty<'tcx>>,
3768 &'a [hir::PathSegment],
3772 // If fully resolved already, we don't have to do anything.
3773 if path_res.depth == 0 {
3774 Some((opt_self_ty, &path.segments, path_res.base_def))
3776 let mut def = path_res.base_def;
3777 let ty_segments = path.segments.split_last().unwrap().1;
3778 let base_ty_end = path.segments.len() - path_res.depth;
3779 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3780 PathParamMode::Optional,
3783 &ty_segments[..base_ty_end],
3784 &ty_segments[base_ty_end..]);
3785 let item_segment = path.segments.last().unwrap();
3786 let item_name = item_segment.identifier.name;
3787 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3789 // Write back the new resolution.
3790 fcx.ccx.tcx.def_map.borrow_mut()
3791 .insert(node_id, def::PathResolution {
3793 last_private: path_res.last_private.or(lp),
3796 Some((Some(ty), slice::ref_slice(item_segment), def))
3799 if item_name != special_idents::invalid.name {
3800 method::report_error(fcx, span, ty, item_name, None, error);
3802 fcx.write_error(node_id);
3809 impl<'tcx> Expectation<'tcx> {
3810 /// Provide an expectation for an rvalue expression given an *optional*
3811 /// hint, which is not required for type safety (the resulting type might
3812 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3813 /// is useful in determining the concrete type.
3815 /// The primary use case is where the expected type is a fat pointer,
3816 /// like `&[isize]`. For example, consider the following statement:
3818 /// let x: &[isize] = &[1, 2, 3];
3820 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3821 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3822 /// expectation `ExpectHasType([isize])`, that would be too strong --
3823 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3824 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3825 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3826 /// which still is useful, because it informs integer literals and the like.
3827 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3828 /// for examples of where this comes up,.
3829 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3830 match tcx.struct_tail(ty).sty {
3831 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3832 ExpectRvalueLikeUnsized(ty)
3834 _ => ExpectHasType(ty)
3838 // Resolves `expected` by a single level if it is a variable. If
3839 // there is no expected type or resolution is not possible (e.g.,
3840 // no constraints yet present), just returns `None`.
3841 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3846 ExpectCastableToType(t) => {
3847 ExpectCastableToType(
3848 fcx.infcx().resolve_type_vars_if_possible(&t))
3850 ExpectHasType(t) => {
3852 fcx.infcx().resolve_type_vars_if_possible(&t))
3854 ExpectRvalueLikeUnsized(t) => {
3855 ExpectRvalueLikeUnsized(
3856 fcx.infcx().resolve_type_vars_if_possible(&t))
3861 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3862 match self.resolve(fcx) {
3863 NoExpectation => None,
3864 ExpectCastableToType(ty) |
3866 ExpectRvalueLikeUnsized(ty) => Some(ty),
3870 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3871 match self.resolve(fcx) {
3872 ExpectHasType(ty) => Some(ty),
3878 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3879 local: &'tcx hir::Local,
3880 init: &'tcx hir::Expr)
3882 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3884 let local_ty = fcx.local_ty(init.span, local.id);
3885 if let Some(m) = ref_bindings {
3886 // Somewhat subtle: if we have a `ref` binding in the pattern,
3887 // we want to avoid introducing coercions for the RHS. This is
3888 // both because it helps preserve sanity and, in the case of
3889 // ref mut, for soundness (issue #23116). In particular, in
3890 // the latter case, we need to be clear that the type of the
3891 // referent for the reference that results is *equal to* the
3892 // type of the lvalue it is referencing, and not some
3893 // supertype thereof.
3894 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3895 let init_ty = fcx.expr_ty(init);
3896 demand::eqtype(fcx, init.span, init_ty, local_ty);
3898 check_expr_coercable_to_type(fcx, init, local_ty)
3902 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3903 let tcx = fcx.ccx.tcx;
3905 let t = fcx.local_ty(local.span, local.id);
3906 fcx.write_ty(local.id, t);
3908 if let Some(ref init) = local.init {
3909 check_decl_initializer(fcx, local, &init);
3910 let init_ty = fcx.expr_ty(&init);
3911 if init_ty.references_error() {
3912 fcx.write_ty(local.id, init_ty);
3916 let pcx = pat_ctxt {
3918 map: pat_id_map(&tcx.def_map, &local.pat),
3920 _match::check_pat(&pcx, &local.pat, t);
3921 let pat_ty = fcx.node_ty(local.pat.id);
3922 if pat_ty.references_error() {
3923 fcx.write_ty(local.id, pat_ty);
3927 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3929 let mut saw_bot = false;
3930 let mut saw_err = false;
3932 hir::StmtDecl(ref decl, id) => {
3935 hir::DeclLocal(ref l) => {
3936 check_decl_local(fcx, &l);
3937 let l_t = fcx.node_ty(l.id);
3938 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3939 saw_err = saw_err || l_t.references_error();
3941 hir::DeclItem(_) => {/* ignore for now */ }
3944 hir::StmtExpr(ref expr, id) => {
3946 // Check with expected type of ()
3947 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3948 let expr_ty = fcx.expr_ty(&expr);
3949 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3950 saw_err = saw_err || expr_ty.references_error();
3952 hir::StmtSemi(ref expr, id) => {
3954 check_expr(fcx, &expr);
3955 let expr_ty = fcx.expr_ty(&expr);
3956 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3957 saw_err |= expr_ty.references_error();
3961 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3964 fcx.write_error(node_id);
3967 fcx.write_nil(node_id)
3971 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3972 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3973 let blkty = fcx.node_ty(blk.id);
3974 if blkty.references_error() {
3975 fcx.write_error(blk.id);
3977 let nilty = fcx.tcx().mk_nil();
3978 demand::suptype(fcx, blk.span, nilty, blkty);
3982 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3983 blk: &'tcx hir::Block,
3984 expected: Expectation<'tcx>) {
3986 let mut fcx_ps = fcx.ps.borrow_mut();
3987 let unsafety_state = fcx_ps.recurse(blk);
3988 replace(&mut *fcx_ps, unsafety_state)
3991 let mut warned = false;
3992 let mut any_diverges = false;
3993 let mut any_err = false;
3994 for s in &blk.stmts {
3996 let s_id = ::rustc_front::util::stmt_id(s);
3997 let s_ty = fcx.node_ty(s_id);
3998 if any_diverges && !warned && match s.node {
3999 hir::StmtDecl(ref decl, _) => {
4001 hir::DeclLocal(_) => true,
4005 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4010 .add_lint(lint::builtin::UNREACHABLE_CODE,
4013 "unreachable statement".to_string());
4016 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4017 any_err = any_err || s_ty.references_error();
4020 None => if any_err {
4021 fcx.write_error(blk.id);
4022 } else if any_diverges {
4023 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4025 fcx.write_nil(blk.id);
4028 if any_diverges && !warned {
4032 .add_lint(lint::builtin::UNREACHABLE_CODE,
4035 "unreachable expression".to_string());
4037 let ety = match expected {
4038 ExpectHasType(ety) => {
4039 check_expr_coercable_to_type(fcx, &e, ety);
4043 check_expr_with_expectation(fcx, &e, expected);
4049 fcx.write_error(blk.id);
4050 } else if any_diverges {
4051 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4053 fcx.write_ty(blk.id, ety);
4058 *fcx.ps.borrow_mut() = prev;
4061 /// Checks a constant appearing in a type. At the moment this is just the
4062 /// length expression in a fixed-length vector, but someday it might be
4063 /// extended to type-level numeric literals.
4064 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4065 expr: &'tcx hir::Expr,
4066 expected_type: Ty<'tcx>) {
4067 let tables = RefCell::new(ty::Tables::empty());
4068 let inh = static_inherited_fields(ccx, &tables);
4069 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4070 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4073 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4077 let tables = RefCell::new(ty::Tables::empty());
4078 let inh = static_inherited_fields(ccx, &tables);
4079 let rty = ccx.tcx.node_id_to_type(id);
4080 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4081 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4082 check_const_with_ty(&fcx, sp, e, declty);
4085 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4089 // Gather locals in statics (because of block expressions).
4090 // This is technically unnecessary because locals in static items are forbidden,
4091 // but prevents type checking from blowing up before const checking can properly
4093 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4095 check_expr_with_hint(fcx, e, declty);
4096 demand::coerce(fcx, e.span, declty, e);
4098 fcx.select_all_obligations_and_apply_defaults();
4099 upvar::closure_analyze_const(&fcx, e);
4100 fcx.select_obligations_where_possible();
4102 fcx.select_all_obligations_or_error();
4104 regionck::regionck_expr(fcx, e);
4105 writeback::resolve_type_vars_in_expr(fcx, e);
4108 /// Checks whether a type can be represented in memory. In particular, it
4109 /// identifies types that contain themselves without indirection through a
4110 /// pointer, which would mean their size is unbounded.
4111 pub fn check_representable(tcx: &ty::ctxt,
4113 item_id: ast::NodeId,
4114 _designation: &str) -> bool {
4115 let rty = tcx.node_id_to_type(item_id);
4117 // Check that it is possible to represent this type. This call identifies
4118 // (1) types that contain themselves and (2) types that contain a different
4119 // recursive type. It is only necessary to throw an error on those that
4120 // contain themselves. For case 2, there must be an inner type that will be
4121 // caught by case 1.
4122 match rty.is_representable(tcx, sp) {
4123 Representability::SelfRecursive => {
4124 let item_def_id = tcx.map.local_def_id(item_id);
4125 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4128 Representability::Representable | Representability::ContainsRecursive => (),
4133 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4134 let t = tcx.node_id_to_type(id);
4136 ty::TyStruct(def, substs) => {
4137 let fields = &def.struct_variant().fields;
4138 if fields.is_empty() {
4139 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4142 let e = fields[0].ty(tcx, substs);
4143 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4144 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4148 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4149 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4151 span_err!(tcx.sess, sp, E0077,
4152 "SIMD vector element type should be machine type");
4161 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4163 vs: &'tcx [hir::Variant],
4165 // disr_in_range should be removed once we have forced type hints for consts
4166 fn disr_in_range(ccx: &CrateCtxt,
4168 disr: ty::Disr) -> bool {
4169 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4171 ast::UintTy::U8 => disr as u8 as Disr == disr,
4172 ast::UintTy::U16 => disr as u16 as Disr == disr,
4173 ast::UintTy::U32 => disr as u32 as Disr == disr,
4174 ast::UintTy::U64 => disr as u64 as Disr == disr,
4175 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4178 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4180 ast::IntTy::I8 => disr as i8 as Disr == disr,
4181 ast::IntTy::I16 => disr as i16 as Disr == disr,
4182 ast::IntTy::I32 => disr as i32 as Disr == disr,
4183 ast::IntTy::I64 => disr as i64 as Disr == disr,
4184 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4188 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4189 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4193 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4194 vs: &'tcx [hir::Variant],
4196 hint: attr::ReprAttr) {
4197 #![allow(trivial_numeric_casts)]
4199 let rty = ccx.tcx.node_id_to_type(id);
4200 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4202 let tables = RefCell::new(ty::Tables::empty());
4203 let inh = static_inherited_fields(ccx, &tables);
4204 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4206 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4208 if let Some(ref e) = v.node.disr_expr {
4209 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4213 let def_id = ccx.tcx.map.local_def_id(id);
4215 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4216 for (v, variant) in vs.iter().zip(variants.iter()) {
4217 let current_disr_val = variant.disr_val;
4219 // Check for duplicate discriminant values
4220 match disr_vals.iter().position(|&x| x == current_disr_val) {
4222 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4223 "discriminant value `{}` already exists", disr_vals[i]);
4224 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4225 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4226 "conflicting discriminant here");
4231 // Check for unrepresentable discriminant values
4233 attr::ReprAny | attr::ReprExtern => {
4234 disr_vals.push(current_disr_val);
4236 attr::ReprInt(sp, ity) => {
4237 if !disr_in_range(ccx, ity, current_disr_val) {
4238 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4239 "discriminant value outside specified type");
4240 span_note!(&mut err, sp,
4241 "discriminant type specified here");
4245 // Error reported elsewhere.
4246 attr::ReprSimd | attr::ReprPacked => {}
4251 let def_id = ccx.tcx.map.local_def_id(id);
4252 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4254 if hint != attr::ReprAny && vs.is_empty() {
4255 span_err!(ccx.tcx.sess, sp, E0084,
4256 "unsupported representation for zero-variant enum");
4259 do_check(ccx, vs, id, hint);
4261 check_representable(ccx.tcx, sp, id, "enum");
4264 // Returns the type parameter count and the type for the given definition.
4265 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4268 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4270 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4271 let typ = fcx.local_ty(sp, nid);
4272 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4273 ty::GenericPredicates::empty())
4275 Def::Fn(id) | Def::Method(id) |
4276 Def::Static(id, _) | Def::Variant(_, id) |
4277 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4278 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4283 Def::AssociatedTy(..) |
4287 Def::ForeignMod(..) |
4291 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4296 // Instantiates the given path, which must refer to an item with the given
4297 // number of type parameters and type.
4298 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4299 segments: &[hir::PathSegment],
4300 type_scheme: TypeScheme<'tcx>,
4301 type_predicates: &ty::GenericPredicates<'tcx>,
4302 opt_self_ty: Option<Ty<'tcx>>,
4305 node_id: ast::NodeId) {
4306 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4312 // We need to extract the type parameters supplied by the user in
4313 // the path `path`. Due to the current setup, this is a bit of a
4314 // tricky-process; the problem is that resolve only tells us the
4315 // end-point of the path resolution, and not the intermediate steps.
4316 // Luckily, we can (at least for now) deduce the intermediate steps
4317 // just from the end-point.
4319 // There are basically four cases to consider:
4321 // 1. Reference to a *type*, such as a struct or enum:
4323 // mod a { struct Foo<T> { ... } }
4325 // Because we don't allow types to be declared within one
4326 // another, a path that leads to a type will always look like
4327 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4328 // that only the final segment can have type parameters, and
4329 // they are located in the TypeSpace.
4331 // *Note:* Generally speaking, references to types don't
4332 // actually pass through this function, but rather the
4333 // `ast_ty_to_ty` function in `astconv`. However, in the case
4334 // of struct patterns (and maybe literals) we do invoke
4335 // `instantiate_path` to get the general type of an instance of
4336 // a struct. (In these cases, there are actually no type
4337 // parameters permitted at present, but perhaps we will allow
4338 // them in the future.)
4340 // 1b. Reference to an enum variant or tuple-like struct:
4342 // struct foo<T>(...)
4343 // enum E<T> { foo(...) }
4345 // In these cases, the parameters are declared in the type
4348 // 2. Reference to a *fn item*:
4352 // In this case, the path will again always have the form
4353 // `a::b::foo::<T>` where only the final segment should have
4354 // type parameters. However, in this case, those parameters are
4355 // declared on a value, and hence are in the `FnSpace`.
4357 // 3. Reference to a *method*:
4359 // impl<A> SomeStruct<A> {
4363 // Here we can have a path like
4364 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4365 // may appear in two places. The penultimate segment,
4366 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4367 // final segment, `foo::<B>` contains parameters in fn space.
4369 // 4. Reference to an *associated const*:
4371 // impl<A> AnotherStruct<A> {
4372 // const FOO: B = BAR;
4375 // The path in this case will look like
4376 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4377 // only will have parameters in TypeSpace.
4379 // The first step then is to categorize the segments appropriately.
4381 assert!(!segments.is_empty());
4383 let mut ufcs_associated = None;
4384 let mut segment_spaces: Vec<_>;
4386 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4392 Def::AssociatedTy(..) |
4395 Def::TyParam(..) => {
4396 // Everything but the final segment should have no
4397 // parameters at all.
4398 segment_spaces = vec![None; segments.len() - 1];
4399 segment_spaces.push(Some(subst::TypeSpace));
4402 // Case 2. Reference to a top-level value.
4405 Def::Static(..) => {
4406 segment_spaces = vec![None; segments.len() - 1];
4407 segment_spaces.push(Some(subst::FnSpace));
4410 // Case 3. Reference to a method.
4411 Def::Method(def_id) => {
4412 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4414 ty::TraitContainer(trait_did) => {
4415 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4417 ty::ImplContainer(_) => {}
4420 if segments.len() >= 2 {
4421 segment_spaces = vec![None; segments.len() - 2];
4422 segment_spaces.push(Some(subst::TypeSpace));
4423 segment_spaces.push(Some(subst::FnSpace));
4425 // `<T>::method` will end up here, and so can `T::method`.
4426 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4427 segment_spaces = vec![Some(subst::FnSpace)];
4428 ufcs_associated = Some((container, self_ty));
4432 Def::AssociatedConst(def_id) => {
4433 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4435 ty::TraitContainer(trait_did) => {
4436 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4438 ty::ImplContainer(_) => {}
4441 if segments.len() >= 2 {
4442 segment_spaces = vec![None; segments.len() - 2];
4443 segment_spaces.push(Some(subst::TypeSpace));
4444 segment_spaces.push(None);
4446 // `<T>::CONST` will end up here, and so can `T::CONST`.
4447 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4448 segment_spaces = vec![None];
4449 ufcs_associated = Some((container, self_ty));
4453 // Other cases. Various nonsense that really shouldn't show up
4454 // here. If they do, an error will have been reported
4455 // elsewhere. (I hope)
4457 Def::ForeignMod(..) |
4462 segment_spaces = vec![None; segments.len()];
4465 assert_eq!(segment_spaces.len(), segments.len());
4467 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4468 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4469 // type parameters are not mandatory.
4470 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4472 debug!("segment_spaces={:?}", segment_spaces);
4474 // Next, examine the definition, and determine how many type
4475 // parameters we expect from each space.
4476 let type_defs = &type_scheme.generics.types;
4477 let region_defs = &type_scheme.generics.regions;
4479 // Now that we have categorized what space the parameters for each
4480 // segment belong to, let's sort out the parameters that the user
4481 // provided (if any) into their appropriate spaces. We'll also report
4482 // errors if type parameters are provided in an inappropriate place.
4483 let mut substs = Substs::empty();
4484 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4487 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4491 push_explicit_parameters_from_segment_to_substs(fcx,
4501 if let Some(self_ty) = opt_self_ty {
4502 if type_defs.len(subst::SelfSpace) == 1 {
4503 substs.types.push(subst::SelfSpace, self_ty);
4507 // Now we have to compare the types that the user *actually*
4508 // provided against the types that were *expected*. If the user
4509 // did not provide any types, then we want to substitute inference
4510 // variables. If the user provided some types, we may still need
4511 // to add defaults. If the user provided *too many* types, that's
4513 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4514 adjust_type_parameters(fcx, span, space, type_defs,
4515 require_type_space, &mut substs);
4516 assert_eq!(substs.types.len(space), type_defs.len(space));
4518 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4519 assert_eq!(substs.regions().len(space), region_defs.len(space));
4522 // The things we are substituting into the type should not contain
4523 // escaping late-bound regions, and nor should the base type scheme.
4524 assert!(!substs.has_regions_escaping_depth(0));
4525 assert!(!type_scheme.has_escaping_regions());
4527 // Add all the obligations that are required, substituting and
4528 // normalized appropriately.
4529 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4530 fcx.add_obligations_for_parameters(
4531 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4534 // Substitute the values for the type parameters into the type of
4535 // the referenced item.
4536 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4539 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4540 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4541 // is inherent, there is no `Self` parameter, instead, the impl needs
4542 // type parameters, which we can infer by unifying the provided `Self`
4543 // with the substituted impl type.
4544 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4545 assert_eq!(substs.types.len(subst::TypeSpace),
4546 impl_scheme.generics.types.len(subst::TypeSpace));
4547 assert_eq!(substs.regions().len(subst::TypeSpace),
4548 impl_scheme.generics.regions.len(subst::TypeSpace));
4550 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4551 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4552 fcx.tcx().sess.span_bug(span,
4554 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4560 debug!("instantiate_path: type of {:?} is {:?}",
4563 fcx.write_ty(node_id, ty_substituted);
4564 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4567 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4568 /// parameters are provided, then reports an error and clears the output vector.
4570 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4571 /// use inference variables. This seems less likely to lead to derived errors.
4573 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4574 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4575 /// here because we can easily use the precise span of the N+1'th parameter.
4576 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4577 fcx: &FnCtxt<'a, 'tcx>,
4578 space: subst::ParamSpace,
4580 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4581 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4582 segment: &hir::PathSegment,
4583 substs: &mut Substs<'tcx>)
4585 match segment.parameters {
4586 hir::AngleBracketedParameters(ref data) => {
4587 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4588 fcx, space, type_defs, region_defs, data, substs);
4591 hir::ParenthesizedParameters(ref data) => {
4592 span_err!(fcx.tcx().sess, span, E0238,
4593 "parenthesized parameters may only be used with a trait");
4594 push_explicit_parenthesized_parameters_from_segment_to_substs(
4595 fcx, space, span, type_defs, data, substs);
4600 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4601 fcx: &FnCtxt<'a, 'tcx>,
4602 space: subst::ParamSpace,
4603 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4604 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4605 data: &hir::AngleBracketedParameterData,
4606 substs: &mut Substs<'tcx>)
4609 let type_count = type_defs.len(space);
4610 assert_eq!(substs.types.len(space), 0);
4611 for (i, typ) in data.types.iter().enumerate() {
4612 let t = fcx.to_ty(&typ);
4614 substs.types.push(space, t);
4615 } else if i == type_count {
4616 span_err!(fcx.tcx().sess, typ.span, E0087,
4617 "too many type parameters provided: \
4618 expected at most {} parameter{}, \
4619 found {} parameter{}",
4621 if type_count == 1 {""} else {"s"},
4623 if data.types.len() == 1 {""} else {"s"});
4624 substs.types.truncate(space, 0);
4630 if !data.bindings.is_empty() {
4631 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4632 "unexpected binding of associated item in expression path \
4633 (only allowed in type paths)");
4637 let region_count = region_defs.len(space);
4638 assert_eq!(substs.regions().len(space), 0);
4639 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4640 let r = ast_region_to_region(fcx.tcx(), lifetime);
4641 if i < region_count {
4642 substs.mut_regions().push(space, r);
4643 } else if i == region_count {
4644 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4645 "too many lifetime parameters provided: \
4646 expected {} parameter{}, found {} parameter{}",
4648 if region_count == 1 {""} else {"s"},
4649 data.lifetimes.len(),
4650 if data.lifetimes.len() == 1 {""} else {"s"});
4651 substs.mut_regions().truncate(space, 0);
4659 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4660 /// but intended for `Foo(A,B) -> C` form. This expands to
4661 /// roughly the same thing as `Foo<(A,B),C>`. One important
4662 /// difference has to do with the treatment of anonymous
4663 /// regions, which are translated into bound regions (NYI).
4664 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4665 fcx: &FnCtxt<'a, 'tcx>,
4666 space: subst::ParamSpace,
4668 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4669 data: &hir::ParenthesizedParameterData,
4670 substs: &mut Substs<'tcx>)
4672 let type_count = type_defs.len(space);
4674 span_err!(fcx.tcx().sess, span, E0167,
4675 "parenthesized form always supplies 2 type parameters, \
4676 but only {} parameter(s) were expected",
4680 let input_tys: Vec<Ty> =
4681 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4683 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4685 if type_count >= 1 {
4686 substs.types.push(space, tuple_ty);
4689 let output_ty: Option<Ty> =
4690 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4693 output_ty.unwrap_or(fcx.tcx().mk_nil());
4695 if type_count >= 2 {
4696 substs.types.push(space, output_ty);
4700 fn adjust_type_parameters<'a, 'tcx>(
4701 fcx: &FnCtxt<'a, 'tcx>,
4704 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4705 require_type_space: bool,
4706 substs: &mut Substs<'tcx>)
4708 let provided_len = substs.types.len(space);
4709 let desired = defs.get_slice(space);
4710 let required_len = desired.iter()
4711 .take_while(|d| d.default.is_none())
4714 debug!("adjust_type_parameters(space={:?}, \
4723 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4724 assert!(provided_len <= desired.len());
4726 // Nothing specified at all: supply inference variables for
4728 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4729 substs.types.replace(space, Vec::new());
4730 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4734 // Too few parameters specified: report an error and use Err
4736 if provided_len < required_len {
4738 if desired.len() != required_len { "at least " } else { "" };
4739 span_err!(fcx.tcx().sess, span, E0089,
4740 "too few type parameters provided: expected {}{} parameter{}, \
4741 found {} parameter{}",
4742 qualifier, required_len,
4743 if required_len == 1 {""} else {"s"},
4745 if provided_len == 1 {""} else {"s"});
4746 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4750 // Otherwise, add in any optional parameters that the user
4751 // omitted. The case of *too many* parameters is handled
4753 // push_explicit_parameters_from_segment_to_substs(). Note
4754 // that the *default* type are expressed in terms of all prior
4755 // parameters, so we have to substitute as we go with the
4756 // partial substitution that we have built up.
4757 for i in provided_len..desired.len() {
4758 let default = desired[i].default.unwrap();
4759 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4760 substs.types.push(space, default);
4762 assert_eq!(substs.types.len(space), desired.len());
4764 debug!("Final substs: {:?}", substs);
4767 fn adjust_region_parameters(
4771 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4772 substs: &mut Substs)
4774 let provided_len = substs.mut_regions().len(space);
4775 let desired = defs.get_slice(space);
4777 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4778 assert!(provided_len <= desired.len());
4780 // If nothing was provided, just use inference variables.
4781 if provided_len == 0 {
4782 substs.mut_regions().replace(
4784 fcx.infcx().region_vars_for_defs(span, desired));
4788 // If just the right number were provided, everybody is happy.
4789 if provided_len == desired.len() {
4793 // Otherwise, too few were provided. Report an error and then
4794 // use inference variables.
4795 span_err!(fcx.tcx().sess, span, E0090,
4796 "too few lifetime parameters provided: expected {} parameter{}, \
4797 found {} parameter{}",
4799 if desired.len() == 1 {""} else {"s"},
4801 if provided_len == 1 {""} else {"s"});
4803 substs.mut_regions().replace(
4805 fcx.infcx().region_vars_for_defs(span, desired));
4809 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4813 where F: Fn() -> Ty<'tcx>
4815 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4818 let alternative = f();
4821 if alternative.is_ty_var() || alternative.references_error() {
4822 fcx.type_error_message(sp, |_actual| {
4823 "the type of this value must be known in this context".to_string()
4825 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4826 ty = fcx.tcx().types.err;
4828 demand::suptype(fcx, sp, alternative, ty);
4836 // Resolves `typ` by a single level if `typ` is a type variable. If no
4837 // resolution is possible, then an error is reported.
4838 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4843 structurally_resolve_type_or_else(fcx, sp, ty, || {
4848 // Returns true if b contains a break that can exit from b
4849 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4850 // First: is there an unlabeled break immediately
4852 (loop_query(&b, |e| {
4854 hir::ExprBreak(None) => true,
4858 // Second: is there a labeled break with label
4859 // <id> nested anywhere inside the loop?
4860 (block_query(b, |e| {
4861 if let hir::ExprBreak(Some(_)) = e.node {
4862 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4869 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4870 tps: &[hir::TyParam],
4872 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4875 // make a vector of booleans initially false, set to true when used
4876 if tps.is_empty() { return; }
4877 let mut tps_used = vec![false; tps.len()];
4879 for leaf_ty in ty.walk() {
4880 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4881 debug!("Found use of ty param num {}", idx);
4882 tps_used[idx as usize] = true;
4886 for (i, b) in tps_used.iter().enumerate() {
4888 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4889 "type parameter `{}` is unused",