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