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 Some((adt, variant))
1450 pub fn write_nil(&self, node_id: ast::NodeId) {
1451 self.write_ty(node_id, self.tcx().mk_nil());
1453 pub fn write_error(&self, node_id: ast::NodeId) {
1454 self.write_ty(node_id, self.tcx().types.err);
1457 pub fn require_type_meets(&self,
1460 code: traits::ObligationCauseCode<'tcx>,
1461 bound: ty::BuiltinBound)
1463 self.register_builtin_bound(
1466 traits::ObligationCause::new(span, self.body_id, code));
1469 pub fn require_type_is_sized(&self,
1472 code: traits::ObligationCauseCode<'tcx>)
1474 self.require_type_meets(ty, span, code, ty::BoundSized);
1477 pub fn require_expr_have_sized_type(&self,
1479 code: traits::ObligationCauseCode<'tcx>)
1481 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1484 pub fn type_is_known_to_be_sized(&self,
1489 traits::type_known_to_meet_builtin_bound(self.infcx(),
1495 pub fn register_builtin_bound(&self,
1497 builtin_bound: ty::BuiltinBound,
1498 cause: traits::ObligationCause<'tcx>)
1500 self.inh.fulfillment_cx.borrow_mut()
1501 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1504 pub fn register_predicate(&self,
1505 obligation: traits::PredicateObligation<'tcx>)
1507 debug!("register_predicate({:?})",
1509 self.inh.fulfillment_cx
1511 .register_predicate_obligation(self.infcx(), obligation);
1514 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1515 let t = ast_ty_to_ty(self, self, ast_t);
1516 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1520 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1521 match self.inh.tables.borrow().node_types.get(&ex.id) {
1524 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1530 /// Apply `adjustment` to the type of `expr`
1531 pub fn adjust_expr_ty(&self,
1533 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1536 let raw_ty = self.expr_ty(expr);
1537 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1538 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1539 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1540 self.inh.tables.borrow().method_map.get(&method_call)
1541 .map(|method| resolve_ty(method.ty))
1545 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1546 match self.inh.tables.borrow().node_types.get(&id) {
1548 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1550 self.tcx().sess.bug(
1551 &format!("no type for node {}: {} in fcx {}",
1552 id, self.tcx().map.node_to_string(id),
1558 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1559 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1560 // it changes when we upgrade the snapshot compiler
1561 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1562 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1566 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1569 pub fn opt_node_ty_substs<F>(&self,
1572 F: FnOnce(&ty::ItemSubsts<'tcx>),
1574 match self.inh.tables.borrow().item_substs.get(&id) {
1580 pub fn mk_subty(&self,
1581 a_is_expected: bool,
1585 -> Result<(), TypeError<'tcx>> {
1586 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1589 pub fn mk_eqty(&self,
1590 a_is_expected: bool,
1594 -> Result<(), TypeError<'tcx>> {
1595 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1598 pub fn mk_subr(&self,
1599 origin: infer::SubregionOrigin<'tcx>,
1602 infer::mk_subr(self.infcx(), origin, sub, sup)
1605 pub fn type_error_message<M>(&self,
1608 actual_ty: Ty<'tcx>,
1609 err: Option<&TypeError<'tcx>>)
1610 where M: FnOnce(String) -> String,
1612 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1615 pub fn type_error_struct<M>(&self,
1618 actual_ty: Ty<'tcx>,
1619 err: Option<&TypeError<'tcx>>)
1620 -> DiagnosticBuilder<'tcx>
1621 where M: FnOnce(String) -> String,
1623 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1626 pub fn report_mismatched_types(&self,
1630 err: &TypeError<'tcx>) {
1631 self.infcx().report_mismatched_types(sp, e, a, err)
1634 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1635 /// outlive the region `r`.
1636 pub fn register_region_obligation(&self,
1639 cause: traits::ObligationCause<'tcx>)
1641 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1642 fulfillment_cx.register_region_obligation(ty, region, cause);
1645 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1646 /// outlive the region `r`.
1647 pub fn register_wf_obligation(&self,
1650 code: traits::ObligationCauseCode<'tcx>)
1652 // WF obligations never themselves fail, so no real need to give a detailed cause:
1653 let cause = traits::ObligationCause::new(span, self.body_id, code);
1654 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1657 pub fn register_old_wf_obligation(&self,
1660 code: traits::ObligationCauseCode<'tcx>)
1662 // Registers an "old-style" WF obligation that uses the
1663 // implicator code. This is basically a buggy version of
1664 // `register_wf_obligation` that is being kept around
1665 // temporarily just to help with phasing in the newer rules.
1667 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1668 let cause = traits::ObligationCause::new(span, self.body_id, code);
1669 self.register_region_obligation(ty, ty::ReEmpty, cause);
1672 /// Registers obligations that all types appearing in `substs` are well-formed.
1673 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1675 for &ty in &substs.types {
1676 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1680 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1681 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1682 /// trait/region obligations.
1684 /// For example, if there is a function:
1687 /// fn foo<'a,T:'a>(...)
1690 /// and a reference:
1696 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1697 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1698 pub fn add_obligations_for_parameters(&self,
1699 cause: traits::ObligationCause<'tcx>,
1700 predicates: &ty::InstantiatedPredicates<'tcx>)
1702 assert!(!predicates.has_escaping_regions());
1704 debug!("add_obligations_for_parameters(predicates={:?})",
1707 for obligation in traits::predicates_for_generics(cause, predicates) {
1708 self.register_predicate(obligation);
1712 // FIXME(arielb1): use this instead of field.ty everywhere
1713 pub fn field_ty(&self,
1715 field: ty::FieldDef<'tcx>,
1716 substs: &Substs<'tcx>)
1719 self.normalize_associated_types_in(span,
1720 &field.ty(self.tcx(), substs))
1723 // Only for fields! Returns <none> for methods>
1724 // Indifferent to privacy flags
1725 fn check_casts(&self) {
1726 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1727 for cast in deferred_cast_checks.drain(..) {
1732 /// Apply "fallbacks" to some types
1733 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1734 fn default_type_parameters(&self) {
1735 use middle::ty::error::UnconstrainedNumeric::Neither;
1736 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1737 for ty in &self.infcx().unsolved_variables() {
1738 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1739 if self.infcx().type_var_diverges(resolved) {
1740 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1742 match self.infcx().type_is_unconstrained_numeric(resolved) {
1743 UnconstrainedInt => {
1744 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1746 UnconstrainedFloat => {
1747 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1755 fn select_all_obligations_and_apply_defaults(&self) {
1756 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1757 self.new_select_all_obligations_and_apply_defaults();
1759 self.old_select_all_obligations_and_apply_defaults();
1763 // Implements old type inference fallback algorithm
1764 fn old_select_all_obligations_and_apply_defaults(&self) {
1765 self.select_obligations_where_possible();
1766 self.default_type_parameters();
1767 self.select_obligations_where_possible();
1770 fn new_select_all_obligations_and_apply_defaults(&self) {
1771 use middle::ty::error::UnconstrainedNumeric::Neither;
1772 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1774 // For the time being this errs on the side of being memory wasteful but provides better
1776 // let type_variables = self.infcx().type_variables.clone();
1778 // There is a possibility that this algorithm will have to run an arbitrary number of times
1779 // to terminate so we bound it by the compiler's recursion limit.
1780 for _ in 0..self.tcx().sess.recursion_limit.get() {
1781 // First we try to solve all obligations, it is possible that the last iteration
1782 // has made it possible to make more progress.
1783 self.select_obligations_where_possible();
1785 let mut conflicts = Vec::new();
1787 // Collect all unsolved type, integral and floating point variables.
1788 let unsolved_variables = self.inh.infcx.unsolved_variables();
1790 // We must collect the defaults *before* we do any unification. Because we have
1791 // directly attached defaults to the type variables any unification that occurs
1792 // will erase defaults causing conflicting defaults to be completely ignored.
1793 let default_map: FnvHashMap<_, _> =
1796 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1799 let mut unbound_tyvars = HashSet::new();
1801 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1803 // We loop over the unsolved variables, resolving them and if they are
1804 // and unconstrainted numeric type we add them to the set of unbound
1805 // variables. We do this so we only apply literal fallback to type
1806 // variables without defaults.
1807 for ty in &unsolved_variables {
1808 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1809 if self.infcx().type_var_diverges(resolved) {
1810 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1812 match self.infcx().type_is_unconstrained_numeric(resolved) {
1813 UnconstrainedInt | UnconstrainedFloat => {
1814 unbound_tyvars.insert(resolved);
1821 // We now remove any numeric types that also have defaults, and instead insert
1822 // the type variable with a defined fallback.
1823 for ty in &unsolved_variables {
1824 if let Some(_default) = default_map.get(ty) {
1825 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1827 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1830 match resolved.sty {
1831 ty::TyInfer(ty::TyVar(_)) => {
1832 unbound_tyvars.insert(ty);
1835 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1836 unbound_tyvars.insert(ty);
1837 if unbound_tyvars.contains(resolved) {
1838 unbound_tyvars.remove(resolved);
1847 // If there are no more fallbacks to apply at this point we have applied all possible
1848 // defaults and type inference will proceed as normal.
1849 if unbound_tyvars.is_empty() {
1853 // Finally we go through each of the unbound type variables and unify them with
1854 // the proper fallback, reporting a conflicting default error if any of the
1855 // unifications fail. We know it must be a conflicting default because the
1856 // variable would only be in `unbound_tyvars` and have a concrete value if
1857 // it had been solved by previously applying a default.
1859 // We wrap this in a transaction for error reporting, if we detect a conflict
1860 // we will rollback the inference context to its prior state so we can probe
1861 // for conflicts and correctly report them.
1864 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1865 for ty in &unbound_tyvars {
1866 if self.infcx().type_var_diverges(ty) {
1867 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1869 match self.infcx().type_is_unconstrained_numeric(ty) {
1870 UnconstrainedInt => {
1871 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1873 UnconstrainedFloat => {
1874 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1877 if let Some(default) = default_map.get(ty) {
1878 let default = default.clone();
1879 match infer::mk_eqty(self.infcx(), false,
1880 TypeOrigin::Misc(default.origin_span),
1884 conflicts.push((*ty, default));
1893 // If there are conflicts we rollback, otherwise commit
1894 if conflicts.len() > 0 {
1901 if conflicts.len() > 0 {
1902 // Loop through each conflicting default, figuring out the default that caused
1903 // a unification failure and then report an error for each.
1904 for (conflict, default) in conflicts {
1905 let conflicting_default =
1906 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1907 .unwrap_or(type_variable::Default {
1908 ty: self.infcx().next_ty_var(),
1909 origin_span: codemap::DUMMY_SP,
1910 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1913 // This is to ensure that we elimnate any non-determinism from the error
1914 // reporting by fixing an order, it doesn't matter what order we choose
1915 // just that it is consistent.
1916 let (first_default, second_default) =
1917 if default.def_id < conflicting_default.def_id {
1918 (default, conflicting_default)
1920 (conflicting_default, default)
1924 self.infcx().report_conflicting_default_types(
1925 first_default.origin_span,
1932 self.select_obligations_where_possible();
1935 // For use in error handling related to default type parameter fallback. We explicitly
1936 // apply the default that caused conflict first to a local version of the type variable
1937 // table then apply defaults until we find a conflict. That default must be the one
1938 // that caused conflict earlier.
1939 fn find_conflicting_default(&self,
1940 unbound_vars: &HashSet<Ty<'tcx>>,
1941 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1943 -> Option<type_variable::Default<'tcx>> {
1944 use middle::ty::error::UnconstrainedNumeric::Neither;
1945 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1947 // Ensure that we apply the conflicting default first
1948 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1949 unbound_tyvars.push(conflict);
1950 unbound_tyvars.extend(unbound_vars.iter());
1952 let mut result = None;
1953 // We run the same code as above applying defaults in order, this time when
1954 // we find the conflict we just return it for error reporting above.
1956 // We also run this inside snapshot that never commits so we can do error
1957 // reporting for more then one conflict.
1958 for ty in &unbound_tyvars {
1959 if self.infcx().type_var_diverges(ty) {
1960 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1962 match self.infcx().type_is_unconstrained_numeric(ty) {
1963 UnconstrainedInt => {
1964 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1966 UnconstrainedFloat => {
1967 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1970 if let Some(default) = default_map.get(ty) {
1971 let default = default.clone();
1972 match infer::mk_eqty(self.infcx(), false,
1973 TypeOrigin::Misc(default.origin_span),
1977 result = Some(default);
1989 fn select_all_obligations_or_error(&self) {
1990 debug!("select_all_obligations_or_error");
1992 // upvar inference should have ensured that all deferred call
1993 // resolutions are handled by now.
1994 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1996 self.select_all_obligations_and_apply_defaults();
1998 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1999 match fulfillment_cx.select_all_or_error(self.infcx()) {
2001 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2005 /// Select as many obligations as we can at present.
2006 fn select_obligations_where_possible(&self) {
2008 self.inh.fulfillment_cx
2010 .select_where_possible(self.infcx())
2013 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2018 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2019 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2020 Some(self.base_object_lifetime_default(span))
2023 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2024 // RFC #599 specifies that object lifetime defaults take
2025 // precedence over other defaults. But within a fn body we
2026 // don't have a *default* region, rather we use inference to
2027 // find the *correct* region, which is strictly more general
2028 // (and anyway, within a fn body the right region may not even
2029 // be something the user can write explicitly, since it might
2030 // be some expression).
2031 self.infcx().next_region_var(infer::MiscVariable(span))
2034 fn anon_regions(&self, span: Span, count: usize)
2035 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2036 Ok((0..count).map(|_| {
2037 self.infcx().next_region_var(infer::MiscVariable(span))
2042 /// Whether `autoderef` requires types to resolve.
2043 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2044 pub enum UnresolvedTypeAction {
2045 /// Produce an error and return `TyError` whenever a type cannot
2046 /// be resolved (i.e. it is `TyInfer`).
2048 /// Go on without emitting any errors, and return the unresolved
2049 /// type. Useful for probing, e.g. in coercions.
2053 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2054 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2056 /// Note: this method does not modify the adjustments table. The caller is responsible for
2057 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2058 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2061 opt_expr: Option<&hir::Expr>,
2062 unresolved_type_action: UnresolvedTypeAction,
2063 mut lvalue_pref: LvaluePreference,
2065 -> (Ty<'tcx>, usize, Option<T>)
2066 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2068 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2073 let mut t = base_ty;
2074 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2075 let resolved_t = match unresolved_type_action {
2076 UnresolvedTypeAction::Error => {
2077 structurally_resolved_type(fcx, sp, t)
2079 UnresolvedTypeAction::Ignore => {
2080 // We can continue even when the type cannot be resolved
2081 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2082 // and `try_overloaded_deref` both simply return `None`
2083 // in such a case without producing spurious errors.
2084 fcx.resolve_type_vars_if_possible(t)
2087 if resolved_t.references_error() {
2088 return (resolved_t, autoderefs, None);
2091 match should_stop(resolved_t, autoderefs) {
2092 Some(x) => return (resolved_t, autoderefs, Some(x)),
2096 // Otherwise, deref if type is derefable:
2097 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2098 Some(mt) => Some(mt),
2101 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2103 // Super subtle: it might seem as though we should
2104 // pass `opt_expr` to `try_overloaded_deref`, so that
2105 // the (implicit) autoref of using an overloaded deref
2106 // would get added to the adjustment table. However we
2107 // do not do that, because it's kind of a
2108 // "meta-adjustment" -- instead, we just leave it
2109 // unrecorded and know that there "will be" an
2110 // autoref. regionck and other bits of the code base,
2111 // when they encounter an overloaded autoderef, have
2112 // to do some reconstructive surgery. This is a pretty
2113 // complex mess that is begging for a proper MIR.
2114 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2120 if mt.mutbl == hir::MutImmutable {
2121 lvalue_pref = NoPreference;
2124 None => return (resolved_t, autoderefs, None)
2128 // We've reached the recursion limit, error gracefully.
2129 span_err!(fcx.tcx().sess, sp, E0055,
2130 "reached the recursion limit while auto-dereferencing {:?}",
2132 (fcx.tcx().types.err, 0, None)
2135 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2137 method_call: Option<MethodCall>,
2138 base_expr: Option<&hir::Expr>,
2140 lvalue_pref: LvaluePreference)
2141 -> Option<ty::TypeAndMut<'tcx>>
2143 // Try DerefMut first, if preferred.
2144 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2145 (PreferMutLvalue, Some(trait_did)) => {
2146 method::lookup_in_trait(fcx, span, base_expr,
2147 token::intern("deref_mut"), trait_did,
2153 // Otherwise, fall back to Deref.
2154 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2155 (None, Some(trait_did)) => {
2156 method::lookup_in_trait(fcx, span, base_expr,
2157 token::intern("deref"), trait_did,
2160 (method, _) => method
2163 make_overloaded_lvalue_return_type(fcx, method_call, method)
2166 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2167 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2168 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2169 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2170 method_call: Option<MethodCall>,
2171 method: Option<MethodCallee<'tcx>>)
2172 -> Option<ty::TypeAndMut<'tcx>>
2176 // extract method return type, which will be &T;
2177 // all LB regions should have been instantiated during method lookup
2178 let ret_ty = method.ty.fn_ret();
2179 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2181 if let Some(method_call) = method_call {
2182 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2185 // method returns &T, but the type as visible to user is T, so deref
2186 ret_ty.builtin_deref(true, NoPreference)
2192 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2194 base_expr: &'tcx hir::Expr,
2197 lvalue_pref: LvaluePreference)
2198 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2200 // FIXME(#18741) -- this is almost but not quite the same as the
2201 // autoderef that normal method probing does. They could likely be
2204 let (ty, autoderefs, final_mt) = autoderef(fcx,
2208 UnresolvedTypeAction::Error,
2211 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2212 adj_ty, idx, false, lvalue_pref, idx_ty)
2215 if final_mt.is_some() {
2219 // After we have fully autoderef'd, if the resulting type is [T; n], then
2220 // do a final unsized coercion to yield [T].
2221 if let ty::TyArray(element_ty, _) = ty.sty {
2222 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2223 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2224 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2230 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2231 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2232 /// This loop implements one step in that search; the autoderef loop is implemented by
2233 /// `lookup_indexing`.
2234 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2235 method_call: MethodCall,
2237 base_expr: &'tcx hir::Expr,
2238 adjusted_ty: Ty<'tcx>,
2241 lvalue_pref: LvaluePreference,
2243 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2245 let tcx = fcx.tcx();
2246 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2247 autoderefs={}, unsize={}, index_ty={:?})",
2255 let input_ty = fcx.infcx().next_ty_var();
2257 // First, try built-in indexing.
2258 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2259 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2260 debug!("try_index_step: success, using built-in indexing");
2261 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2263 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2264 return Some((tcx.types.usize, ty));
2269 // Try `IndexMut` first, if preferred.
2270 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2271 (PreferMutLvalue, Some(trait_did)) => {
2272 method::lookup_in_trait_adjusted(fcx,
2275 token::intern("index_mut"),
2280 Some(vec![input_ty]))
2285 // Otherwise, fall back to `Index`.
2286 let method = match (method, tcx.lang_items.index_trait()) {
2287 (None, Some(trait_did)) => {
2288 method::lookup_in_trait_adjusted(fcx,
2291 token::intern("index"),
2296 Some(vec![input_ty]))
2298 (method, _) => method,
2301 // If some lookup succeeds, write callee into table and extract index/element
2302 // type from the method signature.
2303 // If some lookup succeeded, install method in table
2304 method.and_then(|method| {
2305 debug!("try_index_step: success, using overloaded indexing");
2306 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2307 map(|ret| (input_ty, ret.ty))
2311 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2313 method_fn_ty: Ty<'tcx>,
2314 callee_expr: &'tcx hir::Expr,
2315 args_no_rcvr: &'tcx [P<hir::Expr>],
2316 tuple_arguments: TupleArgumentsFlag,
2317 expected: Expectation<'tcx>)
2318 -> ty::FnOutput<'tcx> {
2319 if method_fn_ty.references_error() {
2320 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2322 let err_inputs = match tuple_arguments {
2323 DontTupleArguments => err_inputs,
2324 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2327 check_argument_types(fcx,
2334 ty::FnConverging(fcx.tcx().types.err)
2336 match method_fn_ty.sty {
2337 ty::TyBareFn(_, ref fty) => {
2338 // HACK(eddyb) ignore self in the definition (see above).
2339 let expected_arg_tys = expected_types_for_fn_args(fcx,
2343 &fty.sig.0.inputs[1..]);
2344 check_argument_types(fcx,
2346 &fty.sig.0.inputs[1..],
2347 &expected_arg_tys[..],
2354 fcx.tcx().sess.span_bug(callee_expr.span,
2355 "method without bare fn type");
2361 /// Generic function that factors out common logic from function calls, method calls and overloaded
2363 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2365 fn_inputs: &[Ty<'tcx>],
2366 expected_arg_tys: &[Ty<'tcx>],
2367 args: &'tcx [P<hir::Expr>],
2369 tuple_arguments: TupleArgumentsFlag) {
2370 let tcx = fcx.ccx.tcx;
2372 // Grab the argument types, supplying fresh type variables
2373 // if the wrong number of arguments were supplied
2374 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2380 // All the input types from the fn signature must outlive the call
2381 // so as to validate implied bounds.
2382 for &fn_input_ty in fn_inputs {
2383 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2386 let mut expected_arg_tys = expected_arg_tys;
2387 let expected_arg_count = fn_inputs.len();
2388 let formal_tys = if tuple_arguments == TupleArguments {
2389 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2390 match tuple_type.sty {
2391 ty::TyTuple(ref arg_types) => {
2392 if arg_types.len() != args.len() {
2393 span_err!(tcx.sess, sp, E0057,
2394 "this function takes {} parameter{} but {} parameter{} supplied",
2396 if arg_types.len() == 1 {""} else {"s"},
2398 if args.len() == 1 {" was"} else {"s were"});
2399 expected_arg_tys = &[];
2400 err_args(fcx.tcx(), args.len())
2402 expected_arg_tys = match expected_arg_tys.get(0) {
2403 Some(&ty) => match ty.sty {
2404 ty::TyTuple(ref tys) => &tys,
2409 (*arg_types).clone()
2413 span_err!(tcx.sess, sp, E0059,
2414 "cannot use call notation; the first type parameter \
2415 for the function trait is neither a tuple nor unit");
2416 expected_arg_tys = &[];
2417 err_args(fcx.tcx(), args.len())
2420 } else if expected_arg_count == supplied_arg_count {
2422 } else if variadic {
2423 if supplied_arg_count >= expected_arg_count {
2426 span_err!(tcx.sess, sp, E0060,
2427 "this function takes at least {} parameter{} \
2428 but {} parameter{} supplied",
2430 if expected_arg_count == 1 {""} else {"s"},
2432 if supplied_arg_count == 1 {" was"} else {"s were"});
2433 expected_arg_tys = &[];
2434 err_args(fcx.tcx(), supplied_arg_count)
2437 span_err!(tcx.sess, sp, E0061,
2438 "this function takes {} parameter{} but {} parameter{} supplied",
2440 if expected_arg_count == 1 {""} else {"s"},
2442 if supplied_arg_count == 1 {" was"} else {"s were"});
2443 expected_arg_tys = &[];
2444 err_args(fcx.tcx(), supplied_arg_count)
2447 debug!("check_argument_types: formal_tys={:?}",
2448 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2450 // Check the arguments.
2451 // We do this in a pretty awful way: first we typecheck any arguments
2452 // that are not anonymous functions, then we typecheck the anonymous
2453 // functions. This is so that we have more information about the types
2454 // of arguments when we typecheck the functions. This isn't really the
2455 // right way to do this.
2456 let xs = [false, true];
2457 let mut any_diverges = false; // has any of the arguments diverged?
2458 let mut warned = false; // have we already warned about unreachable code?
2459 for check_blocks in &xs {
2460 let check_blocks = *check_blocks;
2461 debug!("check_blocks={}", check_blocks);
2463 // More awful hacks: before we check argument types, try to do
2464 // an "opportunistic" vtable resolution of any trait bounds on
2465 // the call. This helps coercions.
2467 fcx.select_obligations_where_possible();
2470 // For variadic functions, we don't have a declared type for all of
2471 // the arguments hence we only do our usual type checking with
2472 // the arguments who's types we do know.
2473 let t = if variadic {
2475 } else if tuple_arguments == TupleArguments {
2480 for (i, arg) in args.iter().take(t).enumerate() {
2481 if any_diverges && !warned {
2485 .add_lint(lint::builtin::UNREACHABLE_CODE,
2488 "unreachable expression".to_string());
2491 let is_block = match arg.node {
2492 hir::ExprClosure(..) => true,
2496 if is_block == check_blocks {
2497 debug!("checking the argument");
2498 let formal_ty = formal_tys[i];
2500 // The special-cased logic below has three functions:
2501 // 1. Provide as good of an expected type as possible.
2502 let expected = expected_arg_tys.get(i).map(|&ty| {
2503 Expectation::rvalue_hint(fcx.tcx(), ty)
2506 check_expr_with_unifier(fcx,
2508 expected.unwrap_or(ExpectHasType(formal_ty)),
2510 // 2. Coerce to the most detailed type that could be coerced
2511 // to, which is `expected_ty` if `rvalue_hint` returns an
2512 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2513 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2514 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2516 // 3. Relate the expected type and the formal one,
2517 // if the expected type was used for the coercion.
2518 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2522 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2523 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2526 if any_diverges && !warned {
2527 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2531 .add_lint(lint::builtin::UNREACHABLE_CODE,
2534 "unreachable call".to_string());
2540 // We also need to make sure we at least write the ty of the other
2541 // arguments which we skipped above.
2543 for arg in args.iter().skip(expected_arg_count) {
2544 check_expr(fcx, &arg);
2546 // There are a few types which get autopromoted when passed via varargs
2547 // in C but we just error out instead and require explicit casts.
2548 let arg_ty = structurally_resolved_type(fcx, arg.span,
2551 ty::TyFloat(ast::FloatTy::F32) => {
2552 fcx.type_error_message(arg.span,
2554 format!("can't pass an {} to variadic \
2555 function, cast to c_double", t)
2558 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2559 fcx.type_error_message(arg.span, |t| {
2560 format!("can't pass {} to variadic \
2561 function, cast to c_int",
2565 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2566 fcx.type_error_message(arg.span, |t| {
2567 format!("can't pass {} to variadic \
2568 function, cast to c_uint",
2578 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2579 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2580 (0..len).map(|_| tcx.types.err).collect()
2583 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2584 call_expr: &hir::Expr,
2585 output: ty::FnOutput<'tcx>) {
2586 fcx.write_ty(call_expr.id, match output {
2587 ty::FnConverging(output_ty) => output_ty,
2588 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2592 // AST fragment checking
2593 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2595 expected: Expectation<'tcx>)
2598 let tcx = fcx.ccx.tcx;
2601 ast::LitKind::Str(..) => tcx.mk_static_str(),
2602 ast::LitKind::ByteStr(ref v) => {
2603 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2604 tcx.mk_array(tcx.types.u8, v.len()))
2606 ast::LitKind::Byte(_) => tcx.types.u8,
2607 ast::LitKind::Char(_) => tcx.types.char,
2608 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2609 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2610 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2611 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2613 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2614 ty::TyChar => Some(tcx.types.u8),
2615 ty::TyRawPtr(..) => Some(tcx.types.usize),
2616 ty::TyBareFn(..) => Some(tcx.types.usize),
2620 opt_ty.unwrap_or_else(
2621 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2623 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2624 ast::LitKind::FloatUnsuffixed(_) => {
2625 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2627 ty::TyFloat(_) => Some(ty),
2631 opt_ty.unwrap_or_else(
2632 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2634 ast::LitKind::Bool(_) => tcx.types.bool
2638 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2639 expr: &'tcx hir::Expr,
2640 expected: Ty<'tcx>) {
2641 check_expr_with_unifier(
2642 fcx, expr, ExpectHasType(expected), NoPreference,
2643 || demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2646 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2647 expr: &'tcx hir::Expr,
2648 expected: Ty<'tcx>) {
2649 check_expr_with_unifier(
2650 fcx, expr, ExpectHasType(expected), NoPreference,
2651 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2654 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2655 expr: &'tcx hir::Expr,
2656 expected: Ty<'tcx>) {
2657 check_expr_with_unifier(
2658 fcx, expr, ExpectHasType(expected), NoPreference,
2659 || demand::coerce(fcx, expr.span, expected, expr));
2662 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2663 expected: Ty<'tcx>) {
2664 check_expr_with_unifier(
2665 fcx, expr, ExpectHasType(expected), NoPreference,
2669 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2670 expr: &'tcx hir::Expr,
2671 expected: Expectation<'tcx>) {
2672 check_expr_with_unifier(
2673 fcx, expr, expected, NoPreference,
2677 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2678 expr: &'tcx hir::Expr,
2679 expected: Expectation<'tcx>,
2680 lvalue_pref: LvaluePreference)
2682 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2685 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2686 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2689 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2690 lvalue_pref: LvaluePreference) {
2691 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2694 // determine the `self` type, using fresh variables for all variables
2695 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2696 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2698 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2699 span: Span, // (potential) receiver for this impl
2701 -> TypeAndSubsts<'tcx> {
2702 let tcx = fcx.tcx();
2704 let ity = tcx.lookup_item_type(did);
2705 let (tps, rps, raw_ty) =
2706 (ity.generics.types.get_slice(subst::TypeSpace),
2707 ity.generics.regions.get_slice(subst::TypeSpace),
2710 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2712 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2713 let mut substs = subst::Substs::new(
2714 VecPerParamSpace::empty(),
2715 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2716 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2717 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2719 TypeAndSubsts { substs: substs, ty: substd_ty }
2722 /// Controls whether the arguments are tupled. This is used for the call
2725 /// Tupling means that all call-side arguments are packed into a tuple and
2726 /// passed as a single parameter. For example, if tupling is enabled, this
2729 /// fn f(x: (isize, isize))
2731 /// Can be called as:
2738 #[derive(Clone, Eq, PartialEq)]
2739 enum TupleArgumentsFlag {
2744 /// Unifies the return type with the expected type early, for more coercions
2745 /// and forward type information on the argument expressions.
2746 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2748 expected_ret: Expectation<'tcx>,
2749 formal_ret: ty::FnOutput<'tcx>,
2750 formal_args: &[Ty<'tcx>])
2752 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2753 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2754 fcx.infcx().commit_regions_if_ok(|| {
2755 // Attempt to apply a subtyping relationship between the formal
2756 // return type (likely containing type variables if the function
2757 // is polymorphic) and the expected return type.
2758 // No argument expectations are produced if unification fails.
2759 let origin = TypeOrigin::Misc(call_span);
2760 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2761 // FIXME(#15760) can't use try! here, FromError doesn't default
2762 // to identity so the resulting type is not constrained.
2763 if let Err(e) = ures {
2767 // Record all the argument types, with the substitutions
2768 // produced from the above subtyping unification.
2769 Ok(formal_args.iter().map(|ty| {
2770 fcx.infcx().resolve_type_vars_if_possible(ty)
2776 }).unwrap_or(vec![]);
2777 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2778 formal_args, formal_ret,
2779 expected_args, expected_ret);
2784 /// If an expression has any sub-expressions that result in a type error,
2785 /// inspecting that expression's type with `ty.references_error()` will return
2786 /// true. Likewise, if an expression is known to diverge, inspecting its
2787 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2788 /// strict, _|_ can appear in the type of an expression that does not,
2789 /// itself, diverge: for example, fn() -> _|_.)
2790 /// Note that inspecting a type's structure *directly* may expose the fact
2791 /// that there are actually multiple representations for `TyError`, so avoid
2792 /// that when err needs to be handled differently.
2793 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2794 expr: &'tcx hir::Expr,
2795 expected: Expectation<'tcx>,
2796 lvalue_pref: LvaluePreference,
2800 debug!(">> typechecking: expr={:?} expected={:?}",
2803 // Checks a method call.
2804 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2805 expr: &'tcx hir::Expr,
2806 method_name: Spanned<ast::Name>,
2807 args: &'tcx [P<hir::Expr>],
2809 expected: Expectation<'tcx>,
2810 lvalue_pref: LvaluePreference) {
2811 let rcvr = &args[0];
2812 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2814 // no need to check for bot/err -- callee does that
2815 let expr_t = structurally_resolved_type(fcx,
2817 fcx.expr_ty(&rcvr));
2819 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2820 let fn_ty = match method::lookup(fcx,
2828 let method_ty = method.ty;
2829 let method_call = MethodCall::expr(expr.id);
2830 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2834 if method_name.node != special_idents::invalid.name {
2835 method::report_error(fcx, method_name.span, expr_t,
2836 method_name.node, Some(rcvr), error);
2838 fcx.write_error(expr.id);
2843 // Call the generic checker.
2844 let ret_ty = check_method_argument_types(fcx,
2852 write_call(fcx, expr, ret_ty);
2855 // A generic function for checking the then and else in an if
2857 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2858 cond_expr: &'tcx hir::Expr,
2859 then_blk: &'tcx hir::Block,
2860 opt_else_expr: Option<&'tcx hir::Expr>,
2863 expected: Expectation<'tcx>) {
2864 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2866 let expected = expected.adjust_for_branches(fcx);
2867 check_block_with_expected(fcx, then_blk, expected);
2868 let then_ty = fcx.node_ty(then_blk.id);
2870 let branches_ty = match opt_else_expr {
2871 Some(ref else_expr) => {
2872 check_expr_with_expectation(fcx, &else_expr, expected);
2873 let else_ty = fcx.expr_ty(&else_expr);
2874 infer::common_supertype(fcx.infcx(),
2875 TypeOrigin::IfExpression(sp),
2881 infer::common_supertype(fcx.infcx(),
2882 TypeOrigin::IfExpressionWithNoElse(sp),
2889 let cond_ty = fcx.expr_ty(cond_expr);
2890 let if_ty = if cond_ty.references_error() {
2896 fcx.write_ty(id, if_ty);
2899 // Check field access expressions
2900 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2901 expr: &'tcx hir::Expr,
2902 lvalue_pref: LvaluePreference,
2903 base: &'tcx hir::Expr,
2904 field: &Spanned<ast::Name>) {
2905 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2906 let expr_t = structurally_resolved_type(fcx, expr.span,
2908 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2909 let (_, autoderefs, field_ty) = autoderef(fcx,
2913 UnresolvedTypeAction::Error,
2917 ty::TyStruct(base_def, substs) => {
2918 debug!("struct named {:?}", base_t);
2919 base_def.struct_variant()
2920 .find_field_named(field.node)
2921 .map(|f| fcx.field_ty(expr.span, f, substs))
2928 fcx.write_ty(expr.id, field_ty);
2929 fcx.write_autoderef_adjustment(base.id, autoderefs);
2935 if field.node == special_idents::invalid.name {
2936 fcx.write_error(expr.id);
2940 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2941 fcx.type_error_struct(field.span,
2943 format!("attempted to take value of method `{}` on type \
2944 `{}`", field.node, actual)
2947 .fileline_help(field.span,
2948 "maybe a `()` to call it is missing? \
2949 If not, try an anonymous function")
2952 let mut err = fcx.type_error_struct(
2955 format!("attempted access of field `{}` on \
2956 type `{}`, but no field with that \
2962 if let ty::TyStruct(def, _) = expr_t.sty {
2963 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2968 fcx.write_error(expr.id);
2971 // displays hints about the closest matches in field names
2972 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2973 variant: ty::VariantDef<'tcx>,
2974 field: &Spanned<ast::Name>,
2975 skip : Vec<InternedString>) {
2976 let name = field.node.as_str();
2977 let names = variant.fields
2979 .filter_map(|ref field| {
2980 // ignore already set fields and private fields from non-local crates
2981 if skip.iter().any(|x| *x == field.name.as_str()) ||
2982 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2989 // only find fits with at least one matching letter
2990 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2991 err.span_help(field.span,
2992 &format!("did you mean `{}`?", name));
2996 // Check tuple index expressions
2997 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2998 expr: &'tcx hir::Expr,
2999 lvalue_pref: LvaluePreference,
3000 base: &'tcx hir::Expr,
3001 idx: codemap::Spanned<usize>) {
3002 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3003 let expr_t = structurally_resolved_type(fcx, expr.span,
3005 let mut tuple_like = false;
3006 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3007 let (_, autoderefs, field_ty) = autoderef(fcx,
3011 UnresolvedTypeAction::Error,
3015 ty::TyStruct(base_def, substs) => {
3016 tuple_like = base_def.struct_variant().is_tuple_struct();
3018 debug!("tuple struct named {:?}", base_t);
3019 base_def.struct_variant()
3022 .map(|f| fcx.field_ty(expr.span, f, substs))
3027 ty::TyTuple(ref v) => {
3029 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3036 fcx.write_ty(expr.id, field_ty);
3037 fcx.write_autoderef_adjustment(base.id, autoderefs);
3042 fcx.type_error_message(
3046 format!("attempted out-of-bounds tuple index `{}` on \
3051 format!("attempted tuple index `{}` on type `{}`, but the \
3052 type was not a tuple or tuple struct",
3059 fcx.write_error(expr.id);
3062 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3064 variant: ty::VariantDef<'tcx>,
3066 skip_fields: &[hir::Field]) {
3067 let mut err = fcx.type_error_struct(
3069 |actual| if let ty::TyEnum(..) = ty.sty {
3070 format!("struct variant `{}::{}` has no field named `{}`",
3071 actual, variant.name.as_str(), field.name.node)
3073 format!("structure `{}` has no field named `{}`",
3074 actual, field.name.node)
3078 // prevent all specified fields from being suggested
3079 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3080 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3084 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3087 variant: ty::VariantDef<'tcx>,
3088 ast_fields: &'tcx [hir::Field],
3089 check_completeness: bool) {
3090 let tcx = fcx.ccx.tcx;
3091 let substs = match adt_ty.sty {
3092 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3093 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3096 let mut remaining_fields = FnvHashMap();
3097 for field in &variant.fields {
3098 remaining_fields.insert(field.name, field);
3101 let mut error_happened = false;
3103 // Typecheck each field.
3104 for field in ast_fields {
3105 let expected_field_type;
3107 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3108 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3110 error_happened = true;
3111 expected_field_type = tcx.types.err;
3112 if let Some(_) = variant.find_field_named(field.name.node) {
3113 span_err!(fcx.tcx().sess, field.name.span, E0062,
3114 "field `{}` specified more than once",
3117 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3121 // Make sure to give a type to the field even if there's
3122 // an error, so we can continue typechecking
3123 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3126 // Make sure the programmer specified all the fields.
3127 if check_completeness &&
3129 !remaining_fields.is_empty()
3131 span_err!(tcx.sess, span, E0063,
3132 "missing field{} {} in initializer of `{}`",
3133 if remaining_fields.len() == 1 {""} else {"s"},
3134 remaining_fields.keys()
3135 .map(|n| format!("`{}`", n))
3136 .collect::<Vec<_>>()
3143 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3145 fields: &'tcx [hir::Field],
3146 base_expr: &'tcx Option<P<hir::Expr>>) {
3147 // Make sure to still write the types
3148 // otherwise we might ICE
3149 fcx.write_error(id);
3150 for field in fields {
3151 check_expr(fcx, &field.expr);
3154 Some(ref base) => check_expr(fcx, &base),
3159 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3162 fields: &'tcx [hir::Field],
3163 base_expr: &'tcx Option<P<hir::Expr>>)
3165 let tcx = fcx.tcx();
3167 // Find the relevant variant
3168 let def = lookup_full_def(tcx, path.span, expr.id);
3169 if def == Def::Err {
3170 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3173 let variant = match fcx.def_struct_variant(def, path.span) {
3174 Some((_, variant)) => variant,
3176 span_err!(fcx.tcx().sess, path.span, E0071,
3177 "`{}` does not name a structure",
3178 pprust::path_to_string(path));
3179 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3184 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3185 fcx.write_ty(expr.id, expr_ty);
3187 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3188 base_expr.is_none());
3189 if let &Some(ref base_expr) = base_expr {
3190 check_expr_has_type(fcx, base_expr, expr_ty);
3192 ty::TyStruct(adt, substs) => {
3193 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3195 adt.struct_variant().fields.iter().map(|f| {
3196 fcx.normalize_associated_types_in(
3197 expr.span, &f.ty(tcx, substs)
3203 span_err!(tcx.sess, base_expr.span, E0436,
3204 "functional record update syntax requires a struct");
3210 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3212 let tcx = fcx.ccx.tcx;
3215 hir::ExprBox(ref subexpr) => {
3216 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3218 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3222 check_expr_with_expectation(fcx, subexpr, expected_inner);
3223 let referent_ty = fcx.expr_ty(&subexpr);
3224 fcx.write_ty(id, tcx.mk_box(referent_ty));
3227 hir::ExprLit(ref lit) => {
3228 let typ = check_lit(fcx, &lit, expected);
3229 fcx.write_ty(id, typ);
3231 hir::ExprBinary(op, ref lhs, ref rhs) => {
3232 op::check_binop(fcx, expr, op, lhs, rhs);
3234 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3235 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3237 hir::ExprUnary(unop, ref oprnd) => {
3238 let expected_inner = match unop {
3239 hir::UnNot | hir::UnNeg => {
3246 let lvalue_pref = match unop {
3247 hir::UnDeref => lvalue_pref,
3250 check_expr_with_expectation_and_lvalue_pref(
3251 fcx, &oprnd, expected_inner, lvalue_pref);
3252 let mut oprnd_t = fcx.expr_ty(&oprnd);
3254 if !oprnd_t.references_error() {
3257 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3258 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3260 None => match try_overloaded_deref(fcx, expr.span,
3261 Some(MethodCall::expr(expr.id)),
3262 Some(&oprnd), oprnd_t, lvalue_pref) {
3265 fcx.type_error_message(expr.span, |actual| {
3266 format!("type `{}` cannot be \
3267 dereferenced", actual)
3275 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3277 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3278 oprnd_t = op::check_user_unop(fcx, "!", "not",
3279 tcx.lang_items.not_trait(),
3280 expr, &oprnd, oprnd_t, unop);
3284 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3286 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3287 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3288 tcx.lang_items.neg_trait(),
3289 expr, &oprnd, oprnd_t, unop);
3294 fcx.write_ty(id, oprnd_t);
3296 hir::ExprAddrOf(mutbl, ref oprnd) => {
3297 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3299 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3300 if fcx.tcx().expr_is_lval(&oprnd) {
3301 // Lvalues may legitimately have unsized types.
3302 // For example, dereferences of a fat pointer and
3303 // the last field of a struct can be unsized.
3304 ExpectHasType(mt.ty)
3306 Expectation::rvalue_hint(tcx, mt.ty)
3312 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3313 check_expr_with_expectation_and_lvalue_pref(fcx,
3318 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3319 let oprnd_t = if tm.ty.references_error() {
3322 // Note: at this point, we cannot say what the best lifetime
3323 // is to use for resulting pointer. We want to use the
3324 // shortest lifetime possible so as to avoid spurious borrowck
3325 // errors. Moreover, the longest lifetime will depend on the
3326 // precise details of the value whose address is being taken
3327 // (and how long it is valid), which we don't know yet until type
3328 // inference is complete.
3330 // Therefore, here we simply generate a region variable. The
3331 // region inferencer will then select the ultimate value.
3332 // Finally, borrowck is charged with guaranteeing that the
3333 // value whose address was taken can actually be made to live
3334 // as long as it needs to live.
3335 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3336 tcx.mk_ref(tcx.mk_region(region), tm)
3338 fcx.write_ty(id, oprnd_t);
3340 hir::ExprPath(ref maybe_qself, ref path) => {
3341 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3342 fcx.to_ty(&qself.ty)
3345 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3347 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3348 // Create some fake resolution that can't possibly be a type.
3349 def::PathResolution {
3350 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3351 last_private: LastMod(AllPublic),
3352 depth: path.segments.len()
3355 tcx.sess.span_bug(expr.span,
3356 &format!("unbound path {:?}", expr))
3359 if let Some((opt_ty, segments, def)) =
3360 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3361 expr.span, expr.id) {
3362 if def != Def::Err {
3363 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3366 instantiate_path(fcx,
3375 fcx.write_ty(id, fcx.tcx().types.err);
3379 // We always require that the type provided as the value for
3380 // a type parameter outlives the moment of instantiation.
3381 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3382 fcx.add_wf_bounds(&item_substs.substs, expr);
3385 hir::ExprInlineAsm(ref ia) => {
3386 for &(_, ref input) in &ia.inputs {
3387 check_expr(fcx, &input);
3389 for out in &ia.outputs {
3390 check_expr(fcx, &out.expr);
3394 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3395 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3396 hir::ExprRet(ref expr_opt) => {
3398 ty::FnConverging(result_type) => {
3401 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3402 result_type, fcx.tcx().mk_nil()) {
3403 span_err!(tcx.sess, expr.span, E0069,
3404 "`return;` in a function whose return type is \
3408 check_expr_coercable_to_type(fcx, &e, result_type);
3412 ty::FnDiverging => {
3413 if let Some(ref e) = *expr_opt {
3414 check_expr(fcx, &e);
3416 span_err!(tcx.sess, expr.span, E0166,
3417 "`return` in a function declared as diverging");
3420 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3422 hir::ExprAssign(ref lhs, ref rhs) => {
3423 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3425 let tcx = fcx.tcx();
3426 if !tcx.expr_is_lval(&lhs) {
3427 span_err!(tcx.sess, expr.span, E0070,
3428 "invalid left-hand side expression");
3431 let lhs_ty = fcx.expr_ty(&lhs);
3432 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3433 let rhs_ty = fcx.expr_ty(&rhs);
3435 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3437 if lhs_ty.references_error() || rhs_ty.references_error() {
3438 fcx.write_error(id);
3443 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3444 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3445 id, expr.span, expected);
3447 hir::ExprWhile(ref cond, ref body, _) => {
3448 check_expr_has_type(fcx, &cond, tcx.types.bool);
3449 check_block_no_value(fcx, &body);
3450 let cond_ty = fcx.expr_ty(&cond);
3451 let body_ty = fcx.node_ty(body.id);
3452 if cond_ty.references_error() || body_ty.references_error() {
3453 fcx.write_error(id);
3459 hir::ExprLoop(ref body, _) => {
3460 check_block_no_value(fcx, &body);
3461 if !may_break(tcx, expr.id, &body) {
3462 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3467 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3468 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3470 hir::ExprClosure(capture, ref decl, ref body) => {
3471 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3473 hir::ExprBlock(ref b) => {
3474 check_block_with_expected(fcx, &b, expected);
3475 fcx.write_ty(id, fcx.node_ty(b.id));
3477 hir::ExprCall(ref callee, ref args) => {
3478 callee::check_call(fcx, expr, &callee, &args[..], expected);
3480 // we must check that return type of called functions is WF:
3481 let ret_ty = fcx.expr_ty(expr);
3482 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3484 hir::ExprMethodCall(name, ref tps, ref args) => {
3485 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3486 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3487 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3489 fcx.write_error(id);
3492 hir::ExprCast(ref e, ref t) => {
3493 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3494 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3497 // Find the type of `e`. Supply hints based on the type we are casting to,
3499 let t_cast = fcx.to_ty(t);
3500 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3501 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3502 let t_expr = fcx.expr_ty(e);
3503 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3505 // Eagerly check for some obvious errors.
3506 if t_expr.references_error() || t_cast.references_error() {
3507 fcx.write_error(id);
3508 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3509 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3511 // Write a type for the whole expression, assuming everything is going
3513 fcx.write_ty(id, t_cast);
3515 // Defer other checks until we're done type checking.
3516 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3517 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3518 deferred_cast_checks.push(cast_check);
3521 hir::ExprType(ref e, ref t) => {
3522 let typ = fcx.to_ty(&t);
3523 check_expr_eq_type(fcx, &e, typ);
3524 fcx.write_ty(id, typ);
3526 hir::ExprVec(ref args) => {
3527 let uty = expected.to_option(fcx).and_then(|uty| {
3529 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3534 let typ = match uty {
3537 check_expr_coercable_to_type(fcx, &e, uty);
3542 let t: Ty = fcx.infcx().next_ty_var();
3544 check_expr_has_type(fcx, &e, t);
3549 let typ = tcx.mk_array(typ, args.len());
3550 fcx.write_ty(id, typ);
3552 hir::ExprRepeat(ref element, ref count_expr) => {
3553 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3554 let count = fcx.tcx().eval_repeat_count(&count_expr);
3556 let uty = match expected {
3557 ExpectHasType(uty) => {
3559 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3566 let (element_ty, t) = match uty {
3568 check_expr_coercable_to_type(fcx, &element, uty);
3572 let t: Ty = fcx.infcx().next_ty_var();
3573 check_expr_has_type(fcx, &element, t);
3574 (fcx.expr_ty(&element), t)
3579 // For [foo, ..n] where n > 1, `foo` must have
3581 fcx.require_type_meets(
3588 if element_ty.references_error() {
3589 fcx.write_error(id);
3591 let t = tcx.mk_array(t, count);
3592 fcx.write_ty(id, t);
3595 hir::ExprTup(ref elts) => {
3596 let flds = expected.only_has_type(fcx).and_then(|ty| {
3598 ty::TyTuple(ref flds) => Some(&flds[..]),
3602 let mut err_field = false;
3604 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3605 let t = match flds {
3606 Some(ref fs) if i < fs.len() => {
3608 check_expr_coercable_to_type(fcx, &e, ety);
3612 check_expr_with_expectation(fcx, &e, NoExpectation);
3616 err_field = err_field || t.references_error();
3620 fcx.write_error(id);
3622 let typ = tcx.mk_tup(elt_ts);
3623 fcx.write_ty(id, typ);
3626 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3627 check_expr_struct(fcx, expr, path, fields, base_expr);
3629 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3631 hir::ExprField(ref base, ref field) => {
3632 check_field(fcx, expr, lvalue_pref, &base, field);
3634 hir::ExprTupField(ref base, idx) => {
3635 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3637 hir::ExprIndex(ref base, ref idx) => {
3638 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3639 check_expr(fcx, &idx);
3641 let base_t = fcx.expr_ty(&base);
3642 let idx_t = fcx.expr_ty(&idx);
3644 if base_t.references_error() {
3645 fcx.write_ty(id, base_t);
3646 } else if idx_t.references_error() {
3647 fcx.write_ty(id, idx_t);
3649 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3650 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3651 Some((index_ty, element_ty)) => {
3652 let idx_expr_ty = fcx.expr_ty(idx);
3653 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3654 fcx.write_ty(id, element_ty);
3657 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3658 fcx.type_error_message(
3661 format!("cannot index a value of type `{}`",
3666 fcx.write_ty(id, fcx.tcx().types.err);
3671 hir::ExprRange(ref start, ref end) => {
3672 let t_start = start.as_ref().map(|e| {
3673 check_expr(fcx, &e);
3676 let t_end = end.as_ref().map(|e| {
3677 check_expr(fcx, &e);
3681 let idx_type = match (t_start, t_end) {
3682 (Some(ty), None) | (None, Some(ty)) => {
3685 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3686 t_end.references_error()) => {
3687 Some(fcx.tcx().types.err)
3689 (Some(t_start), Some(t_end)) => {
3690 Some(infer::common_supertype(fcx.infcx(),
3691 TypeOrigin::RangeExpression(expr.span),
3699 // Note that we don't check the type of start/end satisfy any
3700 // bounds because right now the range structs do not have any. If we add
3701 // some bounds, then we'll need to check `t_start` against them here.
3703 let range_type = match idx_type {
3704 Some(idx_type) if idx_type.references_error() => {
3708 // Find the did from the appropriate lang item.
3709 let did = match (start, end) {
3710 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3711 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3712 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3714 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3718 if let Some(did) = did {
3719 let def = tcx.lookup_adt_def(did);
3720 let predicates = tcx.lookup_predicates(did);
3721 let substs = Substs::new_type(vec![idx_type], vec![]);
3722 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3723 fcx.add_obligations_for_parameters(
3724 traits::ObligationCause::new(expr.span,
3726 traits::ItemObligation(did)),
3729 tcx.mk_struct(def, tcx.mk_substs(substs))
3731 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3736 // Neither start nor end => RangeFull
3737 if let Some(did) = tcx.lang_items.range_full_struct() {
3739 tcx.lookup_adt_def(did),
3740 tcx.mk_substs(Substs::empty())
3743 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3749 fcx.write_ty(id, range_type);
3754 debug!("type of expr({}) {} is...", expr.id,
3755 pprust::expr_to_string(expr));
3756 debug!("... {:?}, expected is {:?}",
3763 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3764 path_res: def::PathResolution,
3765 opt_self_ty: Option<Ty<'tcx>>,
3766 path: &'a hir::Path,
3768 node_id: ast::NodeId)
3769 -> Option<(Option<Ty<'tcx>>,
3770 &'a [hir::PathSegment],
3774 // If fully resolved already, we don't have to do anything.
3775 if path_res.depth == 0 {
3776 Some((opt_self_ty, &path.segments, path_res.base_def))
3778 let mut def = path_res.base_def;
3779 let ty_segments = path.segments.split_last().unwrap().1;
3780 let base_ty_end = path.segments.len() - path_res.depth;
3781 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3782 PathParamMode::Optional,
3785 &ty_segments[..base_ty_end],
3786 &ty_segments[base_ty_end..]);
3787 let item_segment = path.segments.last().unwrap();
3788 let item_name = item_segment.identifier.name;
3789 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3791 // Write back the new resolution.
3792 fcx.ccx.tcx.def_map.borrow_mut()
3793 .insert(node_id, def::PathResolution {
3795 last_private: path_res.last_private.or(lp),
3798 Some((Some(ty), slice::ref_slice(item_segment), def))
3801 if item_name != special_idents::invalid.name {
3802 method::report_error(fcx, span, ty, item_name, None, error);
3804 fcx.write_error(node_id);
3811 impl<'tcx> Expectation<'tcx> {
3812 /// Provide an expectation for an rvalue expression given an *optional*
3813 /// hint, which is not required for type safety (the resulting type might
3814 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3815 /// is useful in determining the concrete type.
3817 /// The primary use case is where the expected type is a fat pointer,
3818 /// like `&[isize]`. For example, consider the following statement:
3820 /// let x: &[isize] = &[1, 2, 3];
3822 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3823 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3824 /// expectation `ExpectHasType([isize])`, that would be too strong --
3825 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3826 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3827 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3828 /// which still is useful, because it informs integer literals and the like.
3829 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3830 /// for examples of where this comes up,.
3831 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3832 match tcx.struct_tail(ty).sty {
3833 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3834 ExpectRvalueLikeUnsized(ty)
3836 _ => ExpectHasType(ty)
3840 // Resolves `expected` by a single level if it is a variable. If
3841 // there is no expected type or resolution is not possible (e.g.,
3842 // no constraints yet present), just returns `None`.
3843 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3848 ExpectCastableToType(t) => {
3849 ExpectCastableToType(
3850 fcx.infcx().resolve_type_vars_if_possible(&t))
3852 ExpectHasType(t) => {
3854 fcx.infcx().resolve_type_vars_if_possible(&t))
3856 ExpectRvalueLikeUnsized(t) => {
3857 ExpectRvalueLikeUnsized(
3858 fcx.infcx().resolve_type_vars_if_possible(&t))
3863 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3864 match self.resolve(fcx) {
3865 NoExpectation => None,
3866 ExpectCastableToType(ty) |
3868 ExpectRvalueLikeUnsized(ty) => Some(ty),
3872 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3873 match self.resolve(fcx) {
3874 ExpectHasType(ty) => Some(ty),
3880 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3881 local: &'tcx hir::Local,
3882 init: &'tcx hir::Expr)
3884 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3886 let local_ty = fcx.local_ty(init.span, local.id);
3887 if let Some(m) = ref_bindings {
3888 // Somewhat subtle: if we have a `ref` binding in the pattern,
3889 // we want to avoid introducing coercions for the RHS. This is
3890 // both because it helps preserve sanity and, in the case of
3891 // ref mut, for soundness (issue #23116). In particular, in
3892 // the latter case, we need to be clear that the type of the
3893 // referent for the reference that results is *equal to* the
3894 // type of the lvalue it is referencing, and not some
3895 // supertype thereof.
3896 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3897 let init_ty = fcx.expr_ty(init);
3898 demand::eqtype(fcx, init.span, init_ty, local_ty);
3900 check_expr_coercable_to_type(fcx, init, local_ty)
3904 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3905 let tcx = fcx.ccx.tcx;
3907 let t = fcx.local_ty(local.span, local.id);
3908 fcx.write_ty(local.id, t);
3910 if let Some(ref init) = local.init {
3911 check_decl_initializer(fcx, local, &init);
3912 let init_ty = fcx.expr_ty(&init);
3913 if init_ty.references_error() {
3914 fcx.write_ty(local.id, init_ty);
3918 let pcx = pat_ctxt {
3920 map: pat_id_map(&tcx.def_map, &local.pat),
3922 _match::check_pat(&pcx, &local.pat, t);
3923 let pat_ty = fcx.node_ty(local.pat.id);
3924 if pat_ty.references_error() {
3925 fcx.write_ty(local.id, pat_ty);
3929 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3931 let mut saw_bot = false;
3932 let mut saw_err = false;
3934 hir::StmtDecl(ref decl, id) => {
3937 hir::DeclLocal(ref l) => {
3938 check_decl_local(fcx, &l);
3939 let l_t = fcx.node_ty(l.id);
3940 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3941 saw_err = saw_err || l_t.references_error();
3943 hir::DeclItem(_) => {/* ignore for now */ }
3946 hir::StmtExpr(ref expr, id) => {
3948 // Check with expected type of ()
3949 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3950 let expr_ty = fcx.expr_ty(&expr);
3951 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3952 saw_err = saw_err || expr_ty.references_error();
3954 hir::StmtSemi(ref expr, id) => {
3956 check_expr(fcx, &expr);
3957 let expr_ty = fcx.expr_ty(&expr);
3958 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3959 saw_err |= expr_ty.references_error();
3963 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3966 fcx.write_error(node_id);
3969 fcx.write_nil(node_id)
3973 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3974 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3975 let blkty = fcx.node_ty(blk.id);
3976 if blkty.references_error() {
3977 fcx.write_error(blk.id);
3979 let nilty = fcx.tcx().mk_nil();
3980 demand::suptype(fcx, blk.span, nilty, blkty);
3984 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3985 blk: &'tcx hir::Block,
3986 expected: Expectation<'tcx>) {
3988 let mut fcx_ps = fcx.ps.borrow_mut();
3989 let unsafety_state = fcx_ps.recurse(blk);
3990 replace(&mut *fcx_ps, unsafety_state)
3993 let mut warned = false;
3994 let mut any_diverges = false;
3995 let mut any_err = false;
3996 for s in &blk.stmts {
3998 let s_id = ::rustc_front::util::stmt_id(s);
3999 let s_ty = fcx.node_ty(s_id);
4000 if any_diverges && !warned && match s.node {
4001 hir::StmtDecl(ref decl, _) => {
4003 hir::DeclLocal(_) => true,
4007 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4012 .add_lint(lint::builtin::UNREACHABLE_CODE,
4015 "unreachable statement".to_string());
4018 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4019 any_err = any_err || s_ty.references_error();
4022 None => if any_err {
4023 fcx.write_error(blk.id);
4024 } else if any_diverges {
4025 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4027 fcx.write_nil(blk.id);
4030 if any_diverges && !warned {
4034 .add_lint(lint::builtin::UNREACHABLE_CODE,
4037 "unreachable expression".to_string());
4039 let ety = match expected {
4040 ExpectHasType(ety) => {
4041 check_expr_coercable_to_type(fcx, &e, ety);
4045 check_expr_with_expectation(fcx, &e, expected);
4051 fcx.write_error(blk.id);
4052 } else if any_diverges {
4053 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4055 fcx.write_ty(blk.id, ety);
4060 *fcx.ps.borrow_mut() = prev;
4063 /// Checks a constant appearing in a type. At the moment this is just the
4064 /// length expression in a fixed-length vector, but someday it might be
4065 /// extended to type-level numeric literals.
4066 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4067 expr: &'tcx hir::Expr,
4068 expected_type: Ty<'tcx>) {
4069 let tables = RefCell::new(ty::Tables::empty());
4070 let inh = static_inherited_fields(ccx, &tables);
4071 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4072 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4075 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4079 let tables = RefCell::new(ty::Tables::empty());
4080 let inh = static_inherited_fields(ccx, &tables);
4081 let rty = ccx.tcx.node_id_to_type(id);
4082 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4083 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4084 check_const_with_ty(&fcx, sp, e, declty);
4087 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4091 // Gather locals in statics (because of block expressions).
4092 // This is technically unnecessary because locals in static items are forbidden,
4093 // but prevents type checking from blowing up before const checking can properly
4095 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4097 check_expr_with_hint(fcx, e, declty);
4098 demand::coerce(fcx, e.span, declty, e);
4100 fcx.select_all_obligations_and_apply_defaults();
4101 upvar::closure_analyze_const(&fcx, e);
4102 fcx.select_obligations_where_possible();
4104 fcx.select_all_obligations_or_error();
4106 regionck::regionck_expr(fcx, e);
4107 writeback::resolve_type_vars_in_expr(fcx, e);
4110 /// Checks whether a type can be represented in memory. In particular, it
4111 /// identifies types that contain themselves without indirection through a
4112 /// pointer, which would mean their size is unbounded.
4113 pub fn check_representable(tcx: &ty::ctxt,
4115 item_id: ast::NodeId,
4116 _designation: &str) -> bool {
4117 let rty = tcx.node_id_to_type(item_id);
4119 // Check that it is possible to represent this type. This call identifies
4120 // (1) types that contain themselves and (2) types that contain a different
4121 // recursive type. It is only necessary to throw an error on those that
4122 // contain themselves. For case 2, there must be an inner type that will be
4123 // caught by case 1.
4124 match rty.is_representable(tcx, sp) {
4125 Representability::SelfRecursive => {
4126 let item_def_id = tcx.map.local_def_id(item_id);
4127 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4130 Representability::Representable | Representability::ContainsRecursive => (),
4135 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4136 let t = tcx.node_id_to_type(id);
4138 ty::TyStruct(def, substs) => {
4139 let fields = &def.struct_variant().fields;
4140 if fields.is_empty() {
4141 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4144 let e = fields[0].ty(tcx, substs);
4145 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4146 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4150 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4151 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4153 span_err!(tcx.sess, sp, E0077,
4154 "SIMD vector element type should be machine type");
4163 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4165 vs: &'tcx [hir::Variant],
4167 // disr_in_range should be removed once we have forced type hints for consts
4168 fn disr_in_range(ccx: &CrateCtxt,
4170 disr: ty::Disr) -> bool {
4171 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4173 ast::UintTy::U8 => disr as u8 as Disr == disr,
4174 ast::UintTy::U16 => disr as u16 as Disr == disr,
4175 ast::UintTy::U32 => disr as u32 as Disr == disr,
4176 ast::UintTy::U64 => disr as u64 as Disr == disr,
4177 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4180 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4182 ast::IntTy::I8 => disr as i8 as Disr == disr,
4183 ast::IntTy::I16 => disr as i16 as Disr == disr,
4184 ast::IntTy::I32 => disr as i32 as Disr == disr,
4185 ast::IntTy::I64 => disr as i64 as Disr == disr,
4186 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4190 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4191 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4195 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4196 vs: &'tcx [hir::Variant],
4198 hint: attr::ReprAttr) {
4199 #![allow(trivial_numeric_casts)]
4201 let rty = ccx.tcx.node_id_to_type(id);
4202 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4204 let tables = RefCell::new(ty::Tables::empty());
4205 let inh = static_inherited_fields(ccx, &tables);
4206 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4208 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4210 if let Some(ref e) = v.node.disr_expr {
4211 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4215 let def_id = ccx.tcx.map.local_def_id(id);
4217 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4218 for (v, variant) in vs.iter().zip(variants.iter()) {
4219 let current_disr_val = variant.disr_val;
4221 // Check for duplicate discriminant values
4222 match disr_vals.iter().position(|&x| x == current_disr_val) {
4224 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4225 "discriminant value `{}` already exists", disr_vals[i]);
4226 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4227 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4228 "conflicting discriminant here");
4233 // Check for unrepresentable discriminant values
4235 attr::ReprAny | attr::ReprExtern => {
4236 disr_vals.push(current_disr_val);
4238 attr::ReprInt(sp, ity) => {
4239 if !disr_in_range(ccx, ity, current_disr_val) {
4240 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4241 "discriminant value outside specified type");
4242 span_note!(&mut err, sp,
4243 "discriminant type specified here");
4247 // Error reported elsewhere.
4248 attr::ReprSimd | attr::ReprPacked => {}
4253 let def_id = ccx.tcx.map.local_def_id(id);
4254 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4256 if hint != attr::ReprAny && vs.is_empty() {
4257 span_err!(ccx.tcx.sess, sp, E0084,
4258 "unsupported representation for zero-variant enum");
4261 do_check(ccx, vs, id, hint);
4263 check_representable(ccx.tcx, sp, id, "enum");
4266 // Returns the type parameter count and the type for the given definition.
4267 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4270 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4272 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4273 let typ = fcx.local_ty(sp, nid);
4274 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4275 ty::GenericPredicates::empty())
4277 Def::Fn(id) | Def::Method(id) |
4278 Def::Static(id, _) | Def::Variant(_, id) |
4279 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4280 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4285 Def::AssociatedTy(..) |
4289 Def::ForeignMod(..) |
4293 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4298 // Instantiates the given path, which must refer to an item with the given
4299 // number of type parameters and type.
4300 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4301 segments: &[hir::PathSegment],
4302 type_scheme: TypeScheme<'tcx>,
4303 type_predicates: &ty::GenericPredicates<'tcx>,
4304 opt_self_ty: Option<Ty<'tcx>>,
4307 node_id: ast::NodeId) {
4308 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4314 // We need to extract the type parameters supplied by the user in
4315 // the path `path`. Due to the current setup, this is a bit of a
4316 // tricky-process; the problem is that resolve only tells us the
4317 // end-point of the path resolution, and not the intermediate steps.
4318 // Luckily, we can (at least for now) deduce the intermediate steps
4319 // just from the end-point.
4321 // There are basically four cases to consider:
4323 // 1. Reference to a *type*, such as a struct or enum:
4325 // mod a { struct Foo<T> { ... } }
4327 // Because we don't allow types to be declared within one
4328 // another, a path that leads to a type will always look like
4329 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4330 // that only the final segment can have type parameters, and
4331 // they are located in the TypeSpace.
4333 // *Note:* Generally speaking, references to types don't
4334 // actually pass through this function, but rather the
4335 // `ast_ty_to_ty` function in `astconv`. However, in the case
4336 // of struct patterns (and maybe literals) we do invoke
4337 // `instantiate_path` to get the general type of an instance of
4338 // a struct. (In these cases, there are actually no type
4339 // parameters permitted at present, but perhaps we will allow
4340 // them in the future.)
4342 // 1b. Reference to an enum variant or tuple-like struct:
4344 // struct foo<T>(...)
4345 // enum E<T> { foo(...) }
4347 // In these cases, the parameters are declared in the type
4350 // 2. Reference to a *fn item*:
4354 // In this case, the path will again always have the form
4355 // `a::b::foo::<T>` where only the final segment should have
4356 // type parameters. However, in this case, those parameters are
4357 // declared on a value, and hence are in the `FnSpace`.
4359 // 3. Reference to a *method*:
4361 // impl<A> SomeStruct<A> {
4365 // Here we can have a path like
4366 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4367 // may appear in two places. The penultimate segment,
4368 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4369 // final segment, `foo::<B>` contains parameters in fn space.
4371 // 4. Reference to an *associated const*:
4373 // impl<A> AnotherStruct<A> {
4374 // const FOO: B = BAR;
4377 // The path in this case will look like
4378 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4379 // only will have parameters in TypeSpace.
4381 // The first step then is to categorize the segments appropriately.
4383 assert!(!segments.is_empty());
4385 let mut ufcs_associated = None;
4386 let mut segment_spaces: Vec<_>;
4388 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4394 Def::AssociatedTy(..) |
4397 Def::TyParam(..) => {
4398 // Everything but the final segment should have no
4399 // parameters at all.
4400 segment_spaces = vec![None; segments.len() - 1];
4401 segment_spaces.push(Some(subst::TypeSpace));
4404 // Case 2. Reference to a top-level value.
4407 Def::Static(..) => {
4408 segment_spaces = vec![None; segments.len() - 1];
4409 segment_spaces.push(Some(subst::FnSpace));
4412 // Case 3. Reference to a method.
4413 Def::Method(def_id) => {
4414 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4416 ty::TraitContainer(trait_did) => {
4417 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4419 ty::ImplContainer(_) => {}
4422 if segments.len() >= 2 {
4423 segment_spaces = vec![None; segments.len() - 2];
4424 segment_spaces.push(Some(subst::TypeSpace));
4425 segment_spaces.push(Some(subst::FnSpace));
4427 // `<T>::method` will end up here, and so can `T::method`.
4428 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4429 segment_spaces = vec![Some(subst::FnSpace)];
4430 ufcs_associated = Some((container, self_ty));
4434 Def::AssociatedConst(def_id) => {
4435 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4437 ty::TraitContainer(trait_did) => {
4438 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4440 ty::ImplContainer(_) => {}
4443 if segments.len() >= 2 {
4444 segment_spaces = vec![None; segments.len() - 2];
4445 segment_spaces.push(Some(subst::TypeSpace));
4446 segment_spaces.push(None);
4448 // `<T>::CONST` will end up here, and so can `T::CONST`.
4449 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4450 segment_spaces = vec![None];
4451 ufcs_associated = Some((container, self_ty));
4455 // Other cases. Various nonsense that really shouldn't show up
4456 // here. If they do, an error will have been reported
4457 // elsewhere. (I hope)
4459 Def::ForeignMod(..) |
4464 segment_spaces = vec![None; segments.len()];
4467 assert_eq!(segment_spaces.len(), segments.len());
4469 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4470 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4471 // type parameters are not mandatory.
4472 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4474 debug!("segment_spaces={:?}", segment_spaces);
4476 // Next, examine the definition, and determine how many type
4477 // parameters we expect from each space.
4478 let type_defs = &type_scheme.generics.types;
4479 let region_defs = &type_scheme.generics.regions;
4481 // Now that we have categorized what space the parameters for each
4482 // segment belong to, let's sort out the parameters that the user
4483 // provided (if any) into their appropriate spaces. We'll also report
4484 // errors if type parameters are provided in an inappropriate place.
4485 let mut substs = Substs::empty();
4486 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4489 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4493 push_explicit_parameters_from_segment_to_substs(fcx,
4503 if let Some(self_ty) = opt_self_ty {
4504 if type_defs.len(subst::SelfSpace) == 1 {
4505 substs.types.push(subst::SelfSpace, self_ty);
4509 // Now we have to compare the types that the user *actually*
4510 // provided against the types that were *expected*. If the user
4511 // did not provide any types, then we want to substitute inference
4512 // variables. If the user provided some types, we may still need
4513 // to add defaults. If the user provided *too many* types, that's
4515 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4516 adjust_type_parameters(fcx, span, space, type_defs,
4517 require_type_space, &mut substs);
4518 assert_eq!(substs.types.len(space), type_defs.len(space));
4520 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4521 assert_eq!(substs.regions().len(space), region_defs.len(space));
4524 // The things we are substituting into the type should not contain
4525 // escaping late-bound regions, and nor should the base type scheme.
4526 assert!(!substs.has_regions_escaping_depth(0));
4527 assert!(!type_scheme.has_escaping_regions());
4529 // Add all the obligations that are required, substituting and
4530 // normalized appropriately.
4531 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4532 fcx.add_obligations_for_parameters(
4533 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4536 // Substitute the values for the type parameters into the type of
4537 // the referenced item.
4538 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4541 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4542 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4543 // is inherent, there is no `Self` parameter, instead, the impl needs
4544 // type parameters, which we can infer by unifying the provided `Self`
4545 // with the substituted impl type.
4546 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4547 assert_eq!(substs.types.len(subst::TypeSpace),
4548 impl_scheme.generics.types.len(subst::TypeSpace));
4549 assert_eq!(substs.regions().len(subst::TypeSpace),
4550 impl_scheme.generics.regions.len(subst::TypeSpace));
4552 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4553 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4554 fcx.tcx().sess.span_bug(span,
4556 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4562 debug!("instantiate_path: type of {:?} is {:?}",
4565 fcx.write_ty(node_id, ty_substituted);
4566 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4569 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4570 /// parameters are provided, then reports an error and clears the output vector.
4572 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4573 /// use inference variables. This seems less likely to lead to derived errors.
4575 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4576 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4577 /// here because we can easily use the precise span of the N+1'th parameter.
4578 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4579 fcx: &FnCtxt<'a, 'tcx>,
4580 space: subst::ParamSpace,
4582 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4583 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4584 segment: &hir::PathSegment,
4585 substs: &mut Substs<'tcx>)
4587 match segment.parameters {
4588 hir::AngleBracketedParameters(ref data) => {
4589 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4590 fcx, space, type_defs, region_defs, data, substs);
4593 hir::ParenthesizedParameters(ref data) => {
4594 span_err!(fcx.tcx().sess, span, E0238,
4595 "parenthesized parameters may only be used with a trait");
4596 push_explicit_parenthesized_parameters_from_segment_to_substs(
4597 fcx, space, span, type_defs, data, substs);
4602 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4603 fcx: &FnCtxt<'a, 'tcx>,
4604 space: subst::ParamSpace,
4605 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4606 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4607 data: &hir::AngleBracketedParameterData,
4608 substs: &mut Substs<'tcx>)
4611 let type_count = type_defs.len(space);
4612 assert_eq!(substs.types.len(space), 0);
4613 for (i, typ) in data.types.iter().enumerate() {
4614 let t = fcx.to_ty(&typ);
4616 substs.types.push(space, t);
4617 } else if i == type_count {
4618 span_err!(fcx.tcx().sess, typ.span, E0087,
4619 "too many type parameters provided: \
4620 expected at most {} parameter{}, \
4621 found {} parameter{}",
4623 if type_count == 1 {""} else {"s"},
4625 if data.types.len() == 1 {""} else {"s"});
4626 substs.types.truncate(space, 0);
4632 if !data.bindings.is_empty() {
4633 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4634 "unexpected binding of associated item in expression path \
4635 (only allowed in type paths)");
4639 let region_count = region_defs.len(space);
4640 assert_eq!(substs.regions().len(space), 0);
4641 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4642 let r = ast_region_to_region(fcx.tcx(), lifetime);
4643 if i < region_count {
4644 substs.mut_regions().push(space, r);
4645 } else if i == region_count {
4646 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4647 "too many lifetime parameters provided: \
4648 expected {} parameter{}, found {} parameter{}",
4650 if region_count == 1 {""} else {"s"},
4651 data.lifetimes.len(),
4652 if data.lifetimes.len() == 1 {""} else {"s"});
4653 substs.mut_regions().truncate(space, 0);
4661 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4662 /// but intended for `Foo(A,B) -> C` form. This expands to
4663 /// roughly the same thing as `Foo<(A,B),C>`. One important
4664 /// difference has to do with the treatment of anonymous
4665 /// regions, which are translated into bound regions (NYI).
4666 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4667 fcx: &FnCtxt<'a, 'tcx>,
4668 space: subst::ParamSpace,
4670 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4671 data: &hir::ParenthesizedParameterData,
4672 substs: &mut Substs<'tcx>)
4674 let type_count = type_defs.len(space);
4676 span_err!(fcx.tcx().sess, span, E0167,
4677 "parenthesized form always supplies 2 type parameters, \
4678 but only {} parameter(s) were expected",
4682 let input_tys: Vec<Ty> =
4683 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4685 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4687 if type_count >= 1 {
4688 substs.types.push(space, tuple_ty);
4691 let output_ty: Option<Ty> =
4692 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4695 output_ty.unwrap_or(fcx.tcx().mk_nil());
4697 if type_count >= 2 {
4698 substs.types.push(space, output_ty);
4702 fn adjust_type_parameters<'a, 'tcx>(
4703 fcx: &FnCtxt<'a, 'tcx>,
4706 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4707 require_type_space: bool,
4708 substs: &mut Substs<'tcx>)
4710 let provided_len = substs.types.len(space);
4711 let desired = defs.get_slice(space);
4712 let required_len = desired.iter()
4713 .take_while(|d| d.default.is_none())
4716 debug!("adjust_type_parameters(space={:?}, \
4725 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4726 assert!(provided_len <= desired.len());
4728 // Nothing specified at all: supply inference variables for
4730 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4731 substs.types.replace(space, Vec::new());
4732 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4736 // Too few parameters specified: report an error and use Err
4738 if provided_len < required_len {
4740 if desired.len() != required_len { "at least " } else { "" };
4741 span_err!(fcx.tcx().sess, span, E0089,
4742 "too few type parameters provided: expected {}{} parameter{}, \
4743 found {} parameter{}",
4744 qualifier, required_len,
4745 if required_len == 1 {""} else {"s"},
4747 if provided_len == 1 {""} else {"s"});
4748 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4752 // Otherwise, add in any optional parameters that the user
4753 // omitted. The case of *too many* parameters is handled
4755 // push_explicit_parameters_from_segment_to_substs(). Note
4756 // that the *default* type are expressed in terms of all prior
4757 // parameters, so we have to substitute as we go with the
4758 // partial substitution that we have built up.
4759 for i in provided_len..desired.len() {
4760 let default = desired[i].default.unwrap();
4761 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4762 substs.types.push(space, default);
4764 assert_eq!(substs.types.len(space), desired.len());
4766 debug!("Final substs: {:?}", substs);
4769 fn adjust_region_parameters(
4773 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4774 substs: &mut Substs)
4776 let provided_len = substs.mut_regions().len(space);
4777 let desired = defs.get_slice(space);
4779 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4780 assert!(provided_len <= desired.len());
4782 // If nothing was provided, just use inference variables.
4783 if provided_len == 0 {
4784 substs.mut_regions().replace(
4786 fcx.infcx().region_vars_for_defs(span, desired));
4790 // If just the right number were provided, everybody is happy.
4791 if provided_len == desired.len() {
4795 // Otherwise, too few were provided. Report an error and then
4796 // use inference variables.
4797 span_err!(fcx.tcx().sess, span, E0090,
4798 "too few lifetime parameters provided: expected {} parameter{}, \
4799 found {} parameter{}",
4801 if desired.len() == 1 {""} else {"s"},
4803 if provided_len == 1 {""} else {"s"});
4805 substs.mut_regions().replace(
4807 fcx.infcx().region_vars_for_defs(span, desired));
4811 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4815 where F: Fn() -> Ty<'tcx>
4817 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4820 let alternative = f();
4823 if alternative.is_ty_var() || alternative.references_error() {
4824 fcx.type_error_message(sp, |_actual| {
4825 "the type of this value must be known in this context".to_string()
4827 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4828 ty = fcx.tcx().types.err;
4830 demand::suptype(fcx, sp, alternative, ty);
4838 // Resolves `typ` by a single level if `typ` is a type variable. If no
4839 // resolution is possible, then an error is reported.
4840 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4845 structurally_resolve_type_or_else(fcx, sp, ty, || {
4850 // Returns true if b contains a break that can exit from b
4851 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4852 // First: is there an unlabeled break immediately
4854 (loop_query(&b, |e| {
4856 hir::ExprBreak(None) => true,
4860 // Second: is there a labeled break with label
4861 // <id> nested anywhere inside the loop?
4862 (block_query(b, |e| {
4863 if let hir::ExprBreak(Some(_)) = e.node {
4864 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4871 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4872 tps: &[hir::TyParam],
4874 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4877 // make a vector of booleans initially false, set to true when used
4878 if tps.is_empty() { return; }
4879 let mut tps_used = vec![false; tps.len()];
4881 for leaf_ty in ty.walk() {
4882 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4883 debug!("Found use of ty param num {}", idx);
4884 tps_used[idx as usize] = true;
4888 for (i, b) in tps_used.iter().enumerate() {
4890 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4891 "type parameter `{}` is unused",