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, TypeTrace, type_variable};
93 use middle::pat_util::{self, pat_id_map};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{GenericPredicates, TypeScheme};
97 use middle::ty::{ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, ToPolyTraitRef, Ty, TyCtxt};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::relate::TypeRelation;
105 use middle::ty::util::{Representability, IntTypeExt};
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 TyCtxt<'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::TyFnDef(_, _, 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 let impl_def_id = ccx.tcx.map.local_def_id(it.id);
676 match ccx.tcx.impl_trait_ref(impl_def_id) {
677 Some(impl_trait_ref) => {
678 check_impl_items_against_trait(ccx,
687 hir::ItemTrait(_, ref generics, _, _) => {
688 check_trait_on_unimplemented(ccx, generics, it);
690 hir::ItemStruct(..) => {
691 check_struct(ccx, it.id, it.span);
693 hir::ItemTy(_, ref generics) => {
694 let pty_ty = ccx.tcx.node_id_to_type(it.id);
695 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
697 hir::ItemForeignMod(ref m) => {
698 if m.abi == Abi::RustIntrinsic {
699 for item in &m.items {
700 intrinsic::check_intrinsic_type(ccx, item);
702 } else if m.abi == Abi::PlatformIntrinsic {
703 for item in &m.items {
704 intrinsic::check_platform_intrinsic_type(ccx, item);
707 for item in &m.items {
708 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
709 if !pty.generics.types.is_empty() {
710 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
711 "foreign items may not have type parameters");
712 span_help!(&mut err, item.span,
713 "consider using specialization instead of \
718 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
719 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
724 _ => {/* nothing to do */ }
728 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
729 debug!("check_item_body(it.id={}, it.name={})",
731 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
732 let _indenter = indenter();
734 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
735 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
736 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
737 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
739 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
740 debug!("ItemImpl {} with id {}", it.name, it.id);
742 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
744 for impl_item in impl_items {
745 match impl_item.node {
746 hir::ImplItemKind::Const(_, ref expr) => {
747 check_const(ccx, impl_item.span, &expr, impl_item.id)
749 hir::ImplItemKind::Method(ref sig, ref body) => {
750 check_method_body(ccx, &impl_pty.generics, sig, body,
751 impl_item.id, impl_item.span);
753 hir::ImplItemKind::Type(_) => {
754 // Nothing to do here.
759 hir::ItemTrait(_, _, _, ref trait_items) => {
760 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
761 for trait_item in trait_items {
762 match trait_item.node {
763 hir::ConstTraitItem(_, Some(ref expr)) => {
764 check_const(ccx, trait_item.span, &expr, trait_item.id)
766 hir::MethodTraitItem(ref sig, Some(ref body)) => {
767 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
769 check_method_body(ccx, &trait_def.generics, sig, body,
770 trait_item.id, trait_item.span);
772 hir::MethodTraitItem(ref sig, None) => {
773 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
775 hir::ConstTraitItem(_, None) |
776 hir::TypeTraitItem(..) => {
782 _ => {/* nothing to do */ }
786 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
788 constness: hir::Constness)
791 hir::Constness::NotConst => {
794 hir::Constness::Const => {
795 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
800 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
801 generics: &hir::Generics,
803 if let Some(ref attr) = item.attrs.iter().find(|a| {
804 a.check_name("rustc_on_unimplemented")
806 if let Some(ref istring) = attr.value_str() {
807 let parser = Parser::new(&istring);
808 let types = &generics.ty_params;
809 for token in parser {
811 Piece::String(_) => (), // Normal string, no need to check it
812 Piece::NextArgument(a) => match a.position {
813 // `{Self}` is allowed
814 Position::ArgumentNamed(s) if s == "Self" => (),
815 // So is `{A}` if A is a type parameter
816 Position::ArgumentNamed(s) => match types.iter().find(|t| {
821 span_err!(ccx.tcx.sess, attr.span, E0230,
822 "there is no type parameter \
827 // `{:1}` and `{}` are not to be used
828 Position::ArgumentIs(_) | Position::ArgumentNext => {
829 span_err!(ccx.tcx.sess, attr.span, E0231,
830 "only named substitution \
831 parameters are allowed");
837 span_err!(ccx.tcx.sess, attr.span, E0232,
838 "this attribute must have a value, \
839 eg `#[rustc_on_unimplemented = \"foo\"]`")
844 /// Type checks a method body.
848 /// * `item_generics`: generics defined on the impl/trait that contains
850 /// * `self_bound`: bound for the `Self` type parameter, if any
851 /// * `method`: the method definition
852 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
853 item_generics: &ty::Generics<'tcx>,
854 sig: &'tcx hir::MethodSig,
855 body: &'tcx hir::Block,
856 id: ast::NodeId, span: Span) {
857 debug!("check_method_body(item_generics={:?}, id={})",
859 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
861 let fty = ccx.tcx.node_id_to_type(id);
862 debug!("check_method_body: fty={:?}", fty);
864 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
867 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
870 impl_trait_ref: &ty::TraitRef<'tcx>,
871 impl_items: &[hir::ImplItem]) {
872 // Locate trait methods
874 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
875 let mut overridden_associated_type = None;
877 // Check existing impl methods to see if they are both present in trait
878 // and compatible with trait signature
879 for impl_item in impl_items {
880 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
881 let ty_trait_item = trait_items.iter()
882 .find(|ac| ac.name() == ty_impl_item.name());
884 if let Some(ty_trait_item) = ty_trait_item {
885 match impl_item.node {
886 hir::ImplItemKind::Const(..) => {
887 let impl_const = match ty_impl_item {
888 ty::ConstTraitItem(ref cti) => cti,
889 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
892 // Find associated const definition.
893 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
894 compare_const_impl(ccx.tcx,
900 span_err!(tcx.sess, impl_item.span, E0323,
901 "item `{}` is an associated const, \
902 which doesn't match its trait `{:?}`",
907 hir::ImplItemKind::Method(ref sig, ref body) => {
908 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
910 let impl_method = match ty_impl_item {
911 ty::MethodTraitItem(ref mti) => mti,
912 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
915 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
916 compare_impl_method(ccx.tcx,
923 span_err!(tcx.sess, impl_item.span, E0324,
924 "item `{}` is an associated method, \
925 which doesn't match its trait `{:?}`",
930 hir::ImplItemKind::Type(_) => {
931 let impl_type = match ty_impl_item {
932 ty::TypeTraitItem(ref tti) => tti,
933 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
936 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
937 if let Some(_) = at.ty {
938 overridden_associated_type = Some(impl_item);
941 span_err!(tcx.sess, impl_item.span, E0325,
942 "item `{}` is an associated type, \
943 which doesn't match its trait `{:?}`",
952 // Check for missing items from trait
953 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
954 let mut missing_items = Vec::new();
955 let mut invalidated_items = Vec::new();
956 let associated_type_overridden = overridden_associated_type.is_some();
957 for trait_item in trait_items.iter() {
959 ty::ConstTraitItem(ref associated_const) => {
960 let is_implemented = impl_items.iter().any(|ii| {
962 hir::ImplItemKind::Const(..) => {
963 ii.name == associated_const.name
968 let is_provided = associated_const.has_value;
972 missing_items.push(associated_const.name);
973 } else if associated_type_overridden {
974 invalidated_items.push(associated_const.name);
978 ty::MethodTraitItem(ref trait_method) => {
979 let search_result = traits::get_impl_item_or_default(tcx, impl_id, |cand| {
980 if let &ty::MethodTraitItem(ref meth) = cand {
981 if meth.name == trait_method.name {
988 if let Some((_, source)) = search_result {
989 if source.is_from_trait() {
991 provided_methods.iter().any(|m| m.name == trait_method.name);
993 missing_items.push(trait_method.name);
994 } else if associated_type_overridden {
995 invalidated_items.push(trait_method.name);
999 missing_items.push(trait_method.name);
1002 ty::TypeTraitItem(ref associated_type) => {
1003 let is_implemented = impl_items.iter().any(|ii| {
1005 hir::ImplItemKind::Type(_) => {
1006 ii.name == associated_type.name
1011 let is_provided = associated_type.ty.is_some();
1012 if !is_implemented {
1014 missing_items.push(associated_type.name);
1015 } else if associated_type_overridden {
1016 invalidated_items.push(associated_type.name);
1023 if !missing_items.is_empty() {
1024 span_err!(tcx.sess, impl_span, E0046,
1025 "not all trait items implemented, missing: `{}`",
1026 missing_items.iter()
1027 .map(|name| name.to_string())
1028 .collect::<Vec<_>>().join("`, `"))
1031 if !invalidated_items.is_empty() {
1032 let invalidator = overridden_associated_type.unwrap();
1033 span_err!(tcx.sess, invalidator.span, E0399,
1034 "the following trait items need to be reimplemented \
1035 as `{}` was overridden: `{}`",
1037 invalidated_items.iter()
1038 .map(|name| name.to_string())
1039 .collect::<Vec<_>>().join("`, `"))
1043 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1050 if t_cast.references_error() || t_expr.references_error() {
1053 let tstr = fcx.infcx().ty_to_string(t_cast);
1054 let mut err = fcx.type_error_struct(span, |actual| {
1055 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1058 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1059 let mtstr = match mt {
1060 hir::MutMutable => "mut ",
1061 hir::MutImmutable => ""
1063 if t_cast.is_trait() {
1064 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1066 err.span_suggestion(t_span,
1067 "try casting to a reference instead:",
1068 format!("&{}{}", mtstr, s));
1071 span_help!(err, t_span,
1072 "did you mean `&{}{}`?", mtstr, tstr),
1075 span_help!(err, span,
1076 "consider using an implicit coercion to `&{}{}` instead",
1081 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1083 err.span_suggestion(t_span,
1084 "try casting to a `Box` instead:",
1085 format!("Box<{}>", s));
1088 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1092 span_help!(err, e_span,
1093 "consider using a box or reference as appropriate");
1097 fcx.write_error(id);
1101 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1102 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1104 fn get_item_type_scheme(&self, _: Span, id: DefId)
1105 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1107 Ok(self.tcx().lookup_item_type(id))
1110 fn get_trait_def(&self, _: Span, id: DefId)
1111 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1113 Ok(self.tcx().lookup_trait_def(id))
1116 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1117 // all super predicates are ensured during collect pass
1121 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1122 Some(&self.inh.infcx.parameter_environment.free_substs)
1125 fn get_type_parameter_bounds(&self,
1127 node_id: ast::NodeId)
1128 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1130 let def = self.tcx().type_parameter_def(node_id);
1131 let r = self.inh.infcx.parameter_environment
1134 .filter_map(|predicate| {
1136 ty::Predicate::Trait(ref data) => {
1137 if data.0.self_ty().is_param(def.space, def.index) {
1138 Some(data.to_poly_trait_ref())
1152 fn trait_defines_associated_type_named(&self,
1153 trait_def_id: DefId,
1154 assoc_name: ast::Name)
1157 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1158 trait_def.associated_type_names.contains(&assoc_name)
1162 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1163 substs: Option<&mut subst::Substs<'tcx>>,
1164 space: Option<subst::ParamSpace>,
1165 span: Span) -> Ty<'tcx> {
1166 // Grab the default doing subsitution
1167 let default = ty_param_def.and_then(|def| {
1168 def.default.map(|ty| type_variable::Default {
1169 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1171 def_id: def.default_def_id
1175 let ty_var = self.infcx().next_ty_var_with_default(default);
1177 // Finally we add the type variable to the substs
1180 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1184 fn projected_ty_from_poly_trait_ref(&self,
1186 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1187 item_name: ast::Name)
1190 let (trait_ref, _) =
1191 self.infcx().replace_late_bound_regions_with_fresh_var(
1193 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1196 self.normalize_associated_type(span, trait_ref, item_name)
1199 fn projected_ty(&self,
1201 trait_ref: ty::TraitRef<'tcx>,
1202 item_name: ast::Name)
1205 self.normalize_associated_type(span, trait_ref, item_name)
1209 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1210 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1212 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1216 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1217 &self.inh.infcx.parameter_environment
1220 pub fn sess(&self) -> &Session {
1224 pub fn err_count_since_creation(&self) -> usize {
1225 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1228 /// Resolves type variables in `ty` if possible. Unlike the infcx
1229 /// version, this version will also select obligations if it seems
1230 /// useful, in an effort to get more type information.
1231 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1232 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1234 // No TyInfer()? Nothing needs doing.
1235 if !ty.has_infer_types() {
1236 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1240 // If `ty` is a type variable, see whether we already know what it is.
1241 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1242 if !ty.has_infer_types() {
1243 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1247 // If not, try resolving pending obligations as much as
1248 // possible. This can help substantially when there are
1249 // indirect dependencies that don't seem worth tracking
1251 self.select_obligations_where_possible();
1252 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1254 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1258 fn record_deferred_call_resolution(&self,
1259 closure_def_id: DefId,
1260 r: DeferredCallResolutionHandler<'tcx>) {
1261 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1262 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1265 fn remove_deferred_call_resolutions(&self,
1266 closure_def_id: DefId)
1267 -> Vec<DeferredCallResolutionHandler<'tcx>>
1269 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1270 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1273 pub fn tag(&self) -> String {
1274 let self_ptr: *const FnCtxt = self;
1275 format!("{:?}", self_ptr)
1278 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1279 match self.inh.locals.borrow().get(&nid) {
1282 span_err!(self.tcx().sess, span, E0513,
1283 "no type for local variable {}",
1285 self.tcx().types.err
1291 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1292 debug!("write_ty({}, {:?}) in fcx {}",
1293 node_id, ty, self.tag());
1294 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1297 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1298 if !substs.substs.is_noop() {
1299 debug!("write_substs({}, {:?}) in fcx {}",
1304 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1308 pub fn write_autoderef_adjustment(&self,
1309 node_id: ast::NodeId,
1311 self.write_adjustment(
1313 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1321 pub fn write_adjustment(&self,
1322 node_id: ast::NodeId,
1323 adj: adjustment::AutoAdjustment<'tcx>) {
1324 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1326 if adj.is_identity() {
1330 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1333 /// Basically whenever we are converting from a type scheme into
1334 /// the fn body space, we always want to normalize associated
1335 /// types as well. This function combines the two.
1336 fn instantiate_type_scheme<T>(&self,
1338 substs: &Substs<'tcx>,
1341 where T : TypeFoldable<'tcx>
1343 let value = value.subst(self.tcx(), substs);
1344 let result = self.normalize_associated_types_in(span, &value);
1345 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1352 /// As `instantiate_type_scheme`, but for the bounds found in a
1353 /// generic type scheme.
1354 fn instantiate_bounds(&self,
1356 substs: &Substs<'tcx>,
1357 bounds: &ty::GenericPredicates<'tcx>)
1358 -> ty::InstantiatedPredicates<'tcx>
1360 ty::InstantiatedPredicates {
1361 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1366 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1367 where T : TypeFoldable<'tcx>
1369 self.inh.normalize_associated_types_in(span, self.body_id, value)
1372 fn normalize_associated_type(&self,
1374 trait_ref: ty::TraitRef<'tcx>,
1375 item_name: ast::Name)
1378 let cause = traits::ObligationCause::new(span,
1380 traits::ObligationCauseCode::MiscObligation);
1384 .normalize_projection_type(self.infcx(),
1386 trait_ref: trait_ref,
1387 item_name: item_name,
1392 /// Instantiates the type in `did` with the generics in `path` and returns
1393 /// it (registering the necessary trait obligations along the way).
1395 /// Note that this function is only intended to be used with type-paths,
1396 /// not with value-paths.
1397 pub fn instantiate_type(&self,
1402 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1404 self.tcx().lookup_item_type(did);
1405 let type_predicates =
1406 self.tcx().lookup_predicates(did);
1407 let substs = astconv::ast_path_substs_for_ty(self, self,
1409 PathParamMode::Optional,
1410 &type_scheme.generics,
1411 path.segments.last().unwrap());
1412 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1414 self.instantiate_bounds(path.span, &substs, &type_predicates);
1415 self.add_obligations_for_parameters(
1416 traits::ObligationCause::new(
1419 traits::ItemObligation(did)),
1422 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1425 /// Return the dict-like variant corresponding to a given `Def`.
1426 pub fn def_struct_variant(&self,
1429 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1431 let (adt, variant) = match def {
1432 Def::Variant(enum_id, variant_id) => {
1433 let adt = self.tcx().lookup_adt_def(enum_id);
1434 (adt, adt.variant_with_id(variant_id))
1436 Def::Struct(did) | Def::TyAlias(did) => {
1437 let typ = self.tcx().lookup_item_type(did);
1438 if let ty::TyStruct(adt, _) = typ.ty.sty {
1439 (adt, adt.struct_variant())
1447 let var_kind = variant.kind();
1448 if var_kind == ty::VariantKind::Struct {
1449 Some((adt, variant))
1450 } else if var_kind == ty::VariantKind::Unit {
1451 Some((adt, variant))
1457 pub fn write_nil(&self, node_id: ast::NodeId) {
1458 self.write_ty(node_id, self.tcx().mk_nil());
1460 pub fn write_error(&self, node_id: ast::NodeId) {
1461 self.write_ty(node_id, self.tcx().types.err);
1464 pub fn require_type_meets(&self,
1467 code: traits::ObligationCauseCode<'tcx>,
1468 bound: ty::BuiltinBound)
1470 self.register_builtin_bound(
1473 traits::ObligationCause::new(span, self.body_id, code));
1476 pub fn require_type_is_sized(&self,
1479 code: traits::ObligationCauseCode<'tcx>)
1481 self.require_type_meets(ty, span, code, ty::BoundSized);
1484 pub fn require_expr_have_sized_type(&self,
1486 code: traits::ObligationCauseCode<'tcx>)
1488 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1491 pub fn type_is_known_to_be_sized(&self,
1496 traits::type_known_to_meet_builtin_bound(self.infcx(),
1502 pub fn register_builtin_bound(&self,
1504 builtin_bound: ty::BuiltinBound,
1505 cause: traits::ObligationCause<'tcx>)
1507 self.inh.fulfillment_cx.borrow_mut()
1508 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1511 pub fn register_predicate(&self,
1512 obligation: traits::PredicateObligation<'tcx>)
1514 debug!("register_predicate({:?})",
1516 self.inh.fulfillment_cx
1518 .register_predicate_obligation(self.infcx(), obligation);
1521 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1522 let t = ast_ty_to_ty(self, self, ast_t);
1523 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1527 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1528 match self.inh.tables.borrow().node_types.get(&ex.id) {
1531 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1537 /// Apply `adjustment` to the type of `expr`
1538 pub fn adjust_expr_ty(&self,
1540 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1543 let raw_ty = self.expr_ty(expr);
1544 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1545 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1546 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1547 self.inh.tables.borrow().method_map.get(&method_call)
1548 .map(|method| resolve_ty(method.ty))
1552 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1553 match self.inh.tables.borrow().node_types.get(&id) {
1555 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1557 self.tcx().sess.bug(
1558 &format!("no type for node {}: {} in fcx {}",
1559 id, self.tcx().map.node_to_string(id),
1565 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1566 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1567 // it changes when we upgrade the snapshot compiler
1568 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1569 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1573 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1576 pub fn opt_node_ty_substs<F>(&self,
1579 F: FnOnce(&ty::ItemSubsts<'tcx>),
1581 match self.inh.tables.borrow().item_substs.get(&id) {
1587 pub fn mk_subty(&self,
1588 a_is_expected: bool,
1592 -> Result<(), TypeError<'tcx>> {
1593 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1596 pub fn mk_eqty(&self,
1597 a_is_expected: bool,
1601 -> Result<(), TypeError<'tcx>> {
1602 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1605 pub fn mk_subr(&self,
1606 origin: infer::SubregionOrigin<'tcx>,
1609 infer::mk_subr(self.infcx(), origin, sub, sup)
1612 pub fn type_error_message<M>(&self,
1615 actual_ty: Ty<'tcx>,
1616 err: Option<&TypeError<'tcx>>)
1617 where M: FnOnce(String) -> String,
1619 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1622 pub fn type_error_struct<M>(&self,
1625 actual_ty: Ty<'tcx>,
1626 err: Option<&TypeError<'tcx>>)
1627 -> DiagnosticBuilder<'tcx>
1628 where M: FnOnce(String) -> String,
1630 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1633 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1634 /// outlive the region `r`.
1635 pub fn register_region_obligation(&self,
1638 cause: traits::ObligationCause<'tcx>)
1640 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1641 fulfillment_cx.register_region_obligation(ty, region, cause);
1644 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1645 /// outlive the region `r`.
1646 pub fn register_wf_obligation(&self,
1649 code: traits::ObligationCauseCode<'tcx>)
1651 // WF obligations never themselves fail, so no real need to give a detailed cause:
1652 let cause = traits::ObligationCause::new(span, self.body_id, code);
1653 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1656 pub fn register_old_wf_obligation(&self,
1659 code: traits::ObligationCauseCode<'tcx>)
1661 // Registers an "old-style" WF obligation that uses the
1662 // implicator code. This is basically a buggy version of
1663 // `register_wf_obligation` that is being kept around
1664 // temporarily just to help with phasing in the newer rules.
1666 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1667 let cause = traits::ObligationCause::new(span, self.body_id, code);
1668 self.register_region_obligation(ty, ty::ReEmpty, cause);
1671 /// Registers obligations that all types appearing in `substs` are well-formed.
1672 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1674 for &ty in &substs.types {
1675 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1679 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1680 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1681 /// trait/region obligations.
1683 /// For example, if there is a function:
1686 /// fn foo<'a,T:'a>(...)
1689 /// and a reference:
1695 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1696 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1697 pub fn add_obligations_for_parameters(&self,
1698 cause: traits::ObligationCause<'tcx>,
1699 predicates: &ty::InstantiatedPredicates<'tcx>)
1701 assert!(!predicates.has_escaping_regions());
1703 debug!("add_obligations_for_parameters(predicates={:?})",
1706 for obligation in traits::predicates_for_generics(cause, predicates) {
1707 self.register_predicate(obligation);
1711 // FIXME(arielb1): use this instead of field.ty everywhere
1712 // Only for fields! Returns <none> for methods>
1713 // Indifferent to privacy flags
1714 pub fn field_ty(&self,
1716 field: ty::FieldDef<'tcx>,
1717 substs: &Substs<'tcx>)
1720 self.normalize_associated_types_in(span,
1721 &field.ty(self.tcx(), substs))
1724 fn check_casts(&self) {
1725 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1726 for cast in deferred_cast_checks.drain(..) {
1731 /// Apply "fallbacks" to some types
1732 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1733 fn default_type_parameters(&self) {
1734 use middle::ty::error::UnconstrainedNumeric::Neither;
1735 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1736 for ty in &self.infcx().unsolved_variables() {
1737 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1738 if self.infcx().type_var_diverges(resolved) {
1739 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1741 match self.infcx().type_is_unconstrained_numeric(resolved) {
1742 UnconstrainedInt => {
1743 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1745 UnconstrainedFloat => {
1746 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1754 fn select_all_obligations_and_apply_defaults(&self) {
1755 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1756 self.new_select_all_obligations_and_apply_defaults();
1758 self.old_select_all_obligations_and_apply_defaults();
1762 // Implements old type inference fallback algorithm
1763 fn old_select_all_obligations_and_apply_defaults(&self) {
1764 self.select_obligations_where_possible();
1765 self.default_type_parameters();
1766 self.select_obligations_where_possible();
1769 fn new_select_all_obligations_and_apply_defaults(&self) {
1770 use middle::ty::error::UnconstrainedNumeric::Neither;
1771 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1773 // For the time being this errs on the side of being memory wasteful but provides better
1775 // let type_variables = self.infcx().type_variables.clone();
1777 // There is a possibility that this algorithm will have to run an arbitrary number of times
1778 // to terminate so we bound it by the compiler's recursion limit.
1779 for _ in 0..self.tcx().sess.recursion_limit.get() {
1780 // First we try to solve all obligations, it is possible that the last iteration
1781 // has made it possible to make more progress.
1782 self.select_obligations_where_possible();
1784 let mut conflicts = Vec::new();
1786 // Collect all unsolved type, integral and floating point variables.
1787 let unsolved_variables = self.inh.infcx.unsolved_variables();
1789 // We must collect the defaults *before* we do any unification. Because we have
1790 // directly attached defaults to the type variables any unification that occurs
1791 // will erase defaults causing conflicting defaults to be completely ignored.
1792 let default_map: FnvHashMap<_, _> =
1795 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1798 let mut unbound_tyvars = HashSet::new();
1800 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1802 // We loop over the unsolved variables, resolving them and if they are
1803 // and unconstrainted numeric type we add them to the set of unbound
1804 // variables. We do this so we only apply literal fallback to type
1805 // variables without defaults.
1806 for ty in &unsolved_variables {
1807 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1808 if self.infcx().type_var_diverges(resolved) {
1809 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1811 match self.infcx().type_is_unconstrained_numeric(resolved) {
1812 UnconstrainedInt | UnconstrainedFloat => {
1813 unbound_tyvars.insert(resolved);
1820 // We now remove any numeric types that also have defaults, and instead insert
1821 // the type variable with a defined fallback.
1822 for ty in &unsolved_variables {
1823 if let Some(_default) = default_map.get(ty) {
1824 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1826 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1829 match resolved.sty {
1830 ty::TyInfer(ty::TyVar(_)) => {
1831 unbound_tyvars.insert(ty);
1834 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1835 unbound_tyvars.insert(ty);
1836 if unbound_tyvars.contains(resolved) {
1837 unbound_tyvars.remove(resolved);
1846 // If there are no more fallbacks to apply at this point we have applied all possible
1847 // defaults and type inference will proceed as normal.
1848 if unbound_tyvars.is_empty() {
1852 // Finally we go through each of the unbound type variables and unify them with
1853 // the proper fallback, reporting a conflicting default error if any of the
1854 // unifications fail. We know it must be a conflicting default because the
1855 // variable would only be in `unbound_tyvars` and have a concrete value if
1856 // it had been solved by previously applying a default.
1858 // We wrap this in a transaction for error reporting, if we detect a conflict
1859 // we will rollback the inference context to its prior state so we can probe
1860 // for conflicts and correctly report them.
1863 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1864 for ty in &unbound_tyvars {
1865 if self.infcx().type_var_diverges(ty) {
1866 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1868 match self.infcx().type_is_unconstrained_numeric(ty) {
1869 UnconstrainedInt => {
1870 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1872 UnconstrainedFloat => {
1873 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1876 if let Some(default) = default_map.get(ty) {
1877 let default = default.clone();
1878 match infer::mk_eqty(self.infcx(), false,
1879 TypeOrigin::Misc(default.origin_span),
1883 conflicts.push((*ty, default));
1892 // If there are conflicts we rollback, otherwise commit
1893 if conflicts.len() > 0 {
1900 if conflicts.len() > 0 {
1901 // Loop through each conflicting default, figuring out the default that caused
1902 // a unification failure and then report an error for each.
1903 for (conflict, default) in conflicts {
1904 let conflicting_default =
1905 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1906 .unwrap_or(type_variable::Default {
1907 ty: self.infcx().next_ty_var(),
1908 origin_span: codemap::DUMMY_SP,
1909 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1912 // This is to ensure that we elimnate any non-determinism from the error
1913 // reporting by fixing an order, it doesn't matter what order we choose
1914 // just that it is consistent.
1915 let (first_default, second_default) =
1916 if default.def_id < conflicting_default.def_id {
1917 (default, conflicting_default)
1919 (conflicting_default, default)
1923 self.infcx().report_conflicting_default_types(
1924 first_default.origin_span,
1931 self.select_obligations_where_possible();
1934 // For use in error handling related to default type parameter fallback. We explicitly
1935 // apply the default that caused conflict first to a local version of the type variable
1936 // table then apply defaults until we find a conflict. That default must be the one
1937 // that caused conflict earlier.
1938 fn find_conflicting_default(&self,
1939 unbound_vars: &HashSet<Ty<'tcx>>,
1940 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1942 -> Option<type_variable::Default<'tcx>> {
1943 use middle::ty::error::UnconstrainedNumeric::Neither;
1944 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1946 // Ensure that we apply the conflicting default first
1947 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1948 unbound_tyvars.push(conflict);
1949 unbound_tyvars.extend(unbound_vars.iter());
1951 let mut result = None;
1952 // We run the same code as above applying defaults in order, this time when
1953 // we find the conflict we just return it for error reporting above.
1955 // We also run this inside snapshot that never commits so we can do error
1956 // reporting for more then one conflict.
1957 for ty in &unbound_tyvars {
1958 if self.infcx().type_var_diverges(ty) {
1959 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1961 match self.infcx().type_is_unconstrained_numeric(ty) {
1962 UnconstrainedInt => {
1963 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1965 UnconstrainedFloat => {
1966 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1969 if let Some(default) = default_map.get(ty) {
1970 let default = default.clone();
1971 match infer::mk_eqty(self.infcx(), false,
1972 TypeOrigin::Misc(default.origin_span),
1976 result = Some(default);
1988 fn select_all_obligations_or_error(&self) {
1989 debug!("select_all_obligations_or_error");
1991 // upvar inference should have ensured that all deferred call
1992 // resolutions are handled by now.
1993 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1995 self.select_all_obligations_and_apply_defaults();
1997 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1998 match fulfillment_cx.select_all_or_error(self.infcx()) {
2000 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2004 /// Select as many obligations as we can at present.
2005 fn select_obligations_where_possible(&self) {
2007 self.inh.fulfillment_cx
2009 .select_where_possible(self.infcx())
2012 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2016 fn private_item_is_visible(&self, def_id: DefId) -> bool {
2017 match self.tcx().map.as_local_node_id(def_id) {
2018 Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2019 None => false, // Private items from other crates are never visible
2024 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2025 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2026 Some(self.base_object_lifetime_default(span))
2029 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2030 // RFC #599 specifies that object lifetime defaults take
2031 // precedence over other defaults. But within a fn body we
2032 // don't have a *default* region, rather we use inference to
2033 // find the *correct* region, which is strictly more general
2034 // (and anyway, within a fn body the right region may not even
2035 // be something the user can write explicitly, since it might
2036 // be some expression).
2037 self.infcx().next_region_var(infer::MiscVariable(span))
2040 fn anon_regions(&self, span: Span, count: usize)
2041 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2042 Ok((0..count).map(|_| {
2043 self.infcx().next_region_var(infer::MiscVariable(span))
2048 /// Whether `autoderef` requires types to resolve.
2049 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2050 pub enum UnresolvedTypeAction {
2051 /// Produce an error and return `TyError` whenever a type cannot
2052 /// be resolved (i.e. it is `TyInfer`).
2054 /// Go on without emitting any errors, and return the unresolved
2055 /// type. Useful for probing, e.g. in coercions.
2059 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2060 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2062 /// Note: this method does not modify the adjustments table. The caller is responsible for
2063 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2064 pub fn autoderef<'a, 'b, 'tcx, E, I, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2068 unresolved_type_action: UnresolvedTypeAction,
2069 mut lvalue_pref: LvaluePreference,
2071 -> (Ty<'tcx>, usize, Option<T>)
2072 // FIXME(eddyb) use copyable iterators when that becomes ergonomic.
2074 I: IntoIterator<Item=&'b hir::Expr>,
2075 F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2077 debug!("autoderef(base_ty={:?}, lvalue_pref={:?})",
2078 base_ty, lvalue_pref);
2080 let mut t = base_ty;
2081 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2082 let resolved_t = match unresolved_type_action {
2083 UnresolvedTypeAction::Error => {
2084 structurally_resolved_type(fcx, sp, t)
2086 UnresolvedTypeAction::Ignore => {
2087 // We can continue even when the type cannot be resolved
2088 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2089 // and `try_overloaded_deref` both simply return `None`
2090 // in such a case without producing spurious errors.
2091 fcx.infcx().resolve_type_vars_if_possible(&t)
2094 if resolved_t.references_error() {
2095 return (resolved_t, autoderefs, None);
2098 match should_stop(resolved_t, autoderefs) {
2099 Some(x) => return (resolved_t, autoderefs, Some(x)),
2103 // Otherwise, deref if type is derefable:
2105 // Super subtle: it might seem as though we should
2106 // pass `opt_expr` to `try_overloaded_deref`, so that
2107 // the (implicit) autoref of using an overloaded deref
2108 // would get added to the adjustment table. However we
2109 // do not do that, because it's kind of a
2110 // "meta-adjustment" -- instead, we just leave it
2111 // unrecorded and know that there "will be" an
2112 // autoref. regionck and other bits of the code base,
2113 // when they encounter an overloaded autoderef, have
2114 // to do some reconstructive surgery. This is a pretty
2115 // complex mess that is begging for a proper MIR.
2116 let mt = if let Some(mt) = resolved_t.builtin_deref(false, lvalue_pref) {
2118 } else if let Some(method) = try_overloaded_deref(fcx, sp, None,
2119 resolved_t, lvalue_pref) {
2120 for expr in maybe_exprs() {
2121 let method_call = MethodCall::autoderef(expr.id, autoderefs as u32);
2122 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2124 make_overloaded_lvalue_return_type(fcx.tcx(), method)
2126 return (resolved_t, autoderefs, None);
2130 if mt.mutbl == hir::MutImmutable {
2131 lvalue_pref = NoPreference;
2135 // We've reached the recursion limit, error gracefully.
2136 span_err!(fcx.tcx().sess, sp, E0055,
2137 "reached the recursion limit while auto-dereferencing {:?}",
2139 (fcx.tcx().types.err, 0, None)
2142 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2144 base_expr: Option<&hir::Expr>,
2146 lvalue_pref: LvaluePreference)
2147 -> Option<MethodCallee<'tcx>>
2149 // Try DerefMut first, if preferred.
2150 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2151 (PreferMutLvalue, Some(trait_did)) => {
2152 method::lookup_in_trait(fcx, span, base_expr,
2153 token::intern("deref_mut"), trait_did,
2159 // Otherwise, fall back to Deref.
2160 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2161 (None, Some(trait_did)) => {
2162 method::lookup_in_trait(fcx, span, base_expr,
2163 token::intern("deref"), trait_did,
2166 (method, _) => method
2172 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2173 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2174 /// type by one layer to yield `T`.
2175 fn make_overloaded_lvalue_return_type<'tcx>(tcx: &TyCtxt<'tcx>,
2176 method: MethodCallee<'tcx>)
2177 -> ty::TypeAndMut<'tcx>
2179 // extract method return type, which will be &T;
2180 // all LB regions should have been instantiated during method lookup
2181 let ret_ty = method.ty.fn_ret();
2182 let ret_ty = tcx.no_late_bound_regions(&ret_ty).unwrap().unwrap();
2184 // method returns &T, but the type as visible to user is T, so deref
2185 ret_ty.builtin_deref(true, NoPreference).unwrap()
2188 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2190 base_expr: &'tcx hir::Expr,
2193 lvalue_pref: LvaluePreference)
2194 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2196 // FIXME(#18741) -- this is almost but not quite the same as the
2197 // autoderef that normal method probing does. They could likely be
2200 let (ty, autoderefs, final_mt) = autoderef(fcx,
2204 UnresolvedTypeAction::Error,
2207 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2208 adj_ty, idx, false, lvalue_pref, idx_ty)
2211 if final_mt.is_some() {
2215 // After we have fully autoderef'd, if the resulting type is [T; n], then
2216 // do a final unsized coercion to yield [T].
2217 if let ty::TyArray(element_ty, _) = ty.sty {
2218 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2219 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2220 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2226 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2227 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2228 /// This loop implements one step in that search; the autoderef loop is implemented by
2229 /// `lookup_indexing`.
2230 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2231 method_call: MethodCall,
2233 base_expr: &'tcx hir::Expr,
2234 adjusted_ty: Ty<'tcx>,
2237 lvalue_pref: LvaluePreference,
2239 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2241 let tcx = fcx.tcx();
2242 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2243 autoderefs={}, unsize={}, index_ty={:?})",
2251 let input_ty = fcx.infcx().next_ty_var();
2253 // First, try built-in indexing.
2254 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2255 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2256 debug!("try_index_step: success, using built-in indexing");
2257 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2259 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2260 return Some((tcx.types.usize, ty));
2265 // Try `IndexMut` first, if preferred.
2266 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2267 (PreferMutLvalue, Some(trait_did)) => {
2268 method::lookup_in_trait_adjusted(fcx,
2271 token::intern("index_mut"),
2276 Some(vec![input_ty]))
2281 // Otherwise, fall back to `Index`.
2282 let method = match (method, tcx.lang_items.index_trait()) {
2283 (None, Some(trait_did)) => {
2284 method::lookup_in_trait_adjusted(fcx,
2287 token::intern("index"),
2292 Some(vec![input_ty]))
2294 (method, _) => method,
2297 // If some lookup succeeds, write callee into table and extract index/element
2298 // type from the method signature.
2299 // If some lookup succeeded, install method in table
2300 method.map(|method| {
2301 debug!("try_index_step: success, using overloaded indexing");
2302 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2303 (input_ty, make_overloaded_lvalue_return_type(fcx.tcx(), method).ty)
2307 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2309 method_fn_ty: Ty<'tcx>,
2310 callee_expr: &'tcx hir::Expr,
2311 args_no_rcvr: &'tcx [P<hir::Expr>],
2312 tuple_arguments: TupleArgumentsFlag,
2313 expected: Expectation<'tcx>)
2314 -> ty::FnOutput<'tcx> {
2315 if method_fn_ty.references_error() {
2316 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2318 let err_inputs = match tuple_arguments {
2319 DontTupleArguments => err_inputs,
2320 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2323 check_argument_types(fcx,
2330 ty::FnConverging(fcx.tcx().types.err)
2332 match method_fn_ty.sty {
2333 ty::TyFnDef(_, _, ref fty) => {
2334 // HACK(eddyb) ignore self in the definition (see above).
2335 let expected_arg_tys = expected_types_for_fn_args(fcx,
2339 &fty.sig.0.inputs[1..]);
2340 check_argument_types(fcx,
2342 &fty.sig.0.inputs[1..],
2343 &expected_arg_tys[..],
2350 fcx.tcx().sess.span_bug(callee_expr.span,
2351 "method without bare fn type");
2357 /// Generic function that factors out common logic from function calls, method calls and overloaded
2359 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2361 fn_inputs: &[Ty<'tcx>],
2362 expected_arg_tys: &[Ty<'tcx>],
2363 args: &'tcx [P<hir::Expr>],
2365 tuple_arguments: TupleArgumentsFlag) {
2366 let tcx = fcx.ccx.tcx;
2368 // Grab the argument types, supplying fresh type variables
2369 // if the wrong number of arguments were supplied
2370 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2376 // All the input types from the fn signature must outlive the call
2377 // so as to validate implied bounds.
2378 for &fn_input_ty in fn_inputs {
2379 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2382 let mut expected_arg_tys = expected_arg_tys;
2383 let expected_arg_count = fn_inputs.len();
2384 let formal_tys = if tuple_arguments == TupleArguments {
2385 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2386 match tuple_type.sty {
2387 ty::TyTuple(ref arg_types) => {
2388 if arg_types.len() != args.len() {
2389 span_err!(tcx.sess, sp, E0057,
2390 "this function takes {} parameter{} but {} parameter{} supplied",
2392 if arg_types.len() == 1 {""} else {"s"},
2394 if args.len() == 1 {" was"} else {"s were"});
2395 expected_arg_tys = &[];
2396 err_args(fcx.tcx(), args.len())
2398 expected_arg_tys = match expected_arg_tys.get(0) {
2399 Some(&ty) => match ty.sty {
2400 ty::TyTuple(ref tys) => &tys,
2405 (*arg_types).clone()
2409 span_err!(tcx.sess, sp, E0059,
2410 "cannot use call notation; the first type parameter \
2411 for the function trait is neither a tuple nor unit");
2412 expected_arg_tys = &[];
2413 err_args(fcx.tcx(), args.len())
2416 } else if expected_arg_count == supplied_arg_count {
2418 } else if variadic {
2419 if supplied_arg_count >= expected_arg_count {
2422 span_err!(tcx.sess, sp, E0060,
2423 "this function takes at least {} parameter{} \
2424 but {} parameter{} supplied",
2426 if expected_arg_count == 1 {""} else {"s"},
2428 if supplied_arg_count == 1 {" was"} else {"s were"});
2429 expected_arg_tys = &[];
2430 err_args(fcx.tcx(), supplied_arg_count)
2433 span_err!(tcx.sess, sp, E0061,
2434 "this function takes {} parameter{} but {} parameter{} supplied",
2436 if expected_arg_count == 1 {""} else {"s"},
2438 if supplied_arg_count == 1 {" was"} else {"s were"});
2439 expected_arg_tys = &[];
2440 err_args(fcx.tcx(), supplied_arg_count)
2443 debug!("check_argument_types: formal_tys={:?}",
2444 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2446 // Check the arguments.
2447 // We do this in a pretty awful way: first we typecheck any arguments
2448 // that are not anonymous functions, then we typecheck the anonymous
2449 // functions. This is so that we have more information about the types
2450 // of arguments when we typecheck the functions. This isn't really the
2451 // right way to do this.
2452 let xs = [false, true];
2453 let mut any_diverges = false; // has any of the arguments diverged?
2454 let mut warned = false; // have we already warned about unreachable code?
2455 for check_blocks in &xs {
2456 let check_blocks = *check_blocks;
2457 debug!("check_blocks={}", check_blocks);
2459 // More awful hacks: before we check argument types, try to do
2460 // an "opportunistic" vtable resolution of any trait bounds on
2461 // the call. This helps coercions.
2463 fcx.select_obligations_where_possible();
2466 // For variadic functions, we don't have a declared type for all of
2467 // the arguments hence we only do our usual type checking with
2468 // the arguments who's types we do know.
2469 let t = if variadic {
2471 } else if tuple_arguments == TupleArguments {
2476 for (i, arg) in args.iter().take(t).enumerate() {
2477 if any_diverges && !warned {
2481 .add_lint(lint::builtin::UNREACHABLE_CODE,
2484 "unreachable expression".to_string());
2487 let is_block = match arg.node {
2488 hir::ExprClosure(..) => true,
2492 if is_block == check_blocks {
2493 debug!("checking the argument");
2494 let formal_ty = formal_tys[i];
2496 // The special-cased logic below has three functions:
2497 // 1. Provide as good of an expected type as possible.
2498 let expected = expected_arg_tys.get(i).map(|&ty| {
2499 Expectation::rvalue_hint(fcx.tcx(), ty)
2502 check_expr_with_expectation(fcx, &arg,
2503 expected.unwrap_or(ExpectHasType(formal_ty)));
2504 // 2. Coerce to the most detailed type that could be coerced
2505 // to, which is `expected_ty` if `rvalue_hint` returns an
2506 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2507 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2508 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2510 // 3. Relate the expected type and the formal one,
2511 // if the expected type was used for the coercion.
2512 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2515 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2516 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2519 if any_diverges && !warned {
2520 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2524 .add_lint(lint::builtin::UNREACHABLE_CODE,
2527 "unreachable call".to_string());
2533 // We also need to make sure we at least write the ty of the other
2534 // arguments which we skipped above.
2536 for arg in args.iter().skip(expected_arg_count) {
2537 check_expr(fcx, &arg);
2539 // There are a few types which get autopromoted when passed via varargs
2540 // in C but we just error out instead and require explicit casts.
2541 let arg_ty = structurally_resolved_type(fcx, arg.span,
2544 ty::TyFloat(ast::FloatTy::F32) => {
2545 fcx.type_error_message(arg.span,
2547 format!("can't pass an {} to variadic \
2548 function, cast to c_double", t)
2551 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2552 fcx.type_error_message(arg.span, |t| {
2553 format!("can't pass {} to variadic \
2554 function, cast to c_int",
2558 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2559 fcx.type_error_message(arg.span, |t| {
2560 format!("can't pass {} to variadic \
2561 function, cast to c_uint",
2571 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2572 fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2573 (0..len).map(|_| tcx.types.err).collect()
2576 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2577 call_expr: &hir::Expr,
2578 output: ty::FnOutput<'tcx>) {
2579 fcx.write_ty(call_expr.id, match output {
2580 ty::FnConverging(output_ty) => output_ty,
2581 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2585 // AST fragment checking
2586 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2588 expected: Expectation<'tcx>)
2591 let tcx = fcx.ccx.tcx;
2594 ast::LitKind::Str(..) => tcx.mk_static_str(),
2595 ast::LitKind::ByteStr(ref v) => {
2596 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2597 tcx.mk_array(tcx.types.u8, v.len()))
2599 ast::LitKind::Byte(_) => tcx.types.u8,
2600 ast::LitKind::Char(_) => tcx.types.char,
2601 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2602 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2603 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2604 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2606 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2607 ty::TyChar => Some(tcx.types.u8),
2608 ty::TyRawPtr(..) => Some(tcx.types.usize),
2609 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2613 opt_ty.unwrap_or_else(
2614 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2616 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2617 ast::LitKind::FloatUnsuffixed(_) => {
2618 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2620 ty::TyFloat(_) => Some(ty),
2624 opt_ty.unwrap_or_else(
2625 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2627 ast::LitKind::Bool(_) => tcx.types.bool
2631 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2632 expr: &'tcx hir::Expr,
2633 expected: Ty<'tcx>) {
2634 check_expr_with_hint(fcx, expr, expected);
2635 demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr));
2638 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2639 expr: &'tcx hir::Expr,
2640 expected: Ty<'tcx>) {
2641 check_expr_with_hint(fcx, expr, expected);
2642 demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr));
2645 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2646 expr: &'tcx hir::Expr,
2647 expected: Ty<'tcx>) {
2648 check_expr_with_hint(fcx, expr, expected);
2649 demand::coerce(fcx, expr.span, expected, expr);
2652 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2653 expected: Ty<'tcx>) {
2654 check_expr_with_expectation(fcx, expr, ExpectHasType(expected))
2657 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2658 expr: &'tcx hir::Expr,
2659 expected: Expectation<'tcx>) {
2660 check_expr_with_expectation_and_lvalue_pref(fcx, expr, expected, NoPreference)
2663 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2664 check_expr_with_expectation(fcx, expr, NoExpectation)
2667 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2668 lvalue_pref: LvaluePreference) {
2669 check_expr_with_expectation_and_lvalue_pref(fcx, expr, NoExpectation, lvalue_pref)
2672 // determine the `self` type, using fresh variables for all variables
2673 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2674 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2676 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2677 span: Span, // (potential) receiver for this impl
2679 -> TypeAndSubsts<'tcx> {
2680 let tcx = fcx.tcx();
2682 let ity = tcx.lookup_item_type(did);
2683 let (tps, rps, raw_ty) =
2684 (ity.generics.types.get_slice(subst::TypeSpace),
2685 ity.generics.regions.get_slice(subst::TypeSpace),
2688 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2690 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2691 let mut substs = subst::Substs::new(
2692 VecPerParamSpace::empty(),
2693 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2694 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2695 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2697 TypeAndSubsts { substs: substs, ty: substd_ty }
2700 /// Controls whether the arguments are tupled. This is used for the call
2703 /// Tupling means that all call-side arguments are packed into a tuple and
2704 /// passed as a single parameter. For example, if tupling is enabled, this
2707 /// fn f(x: (isize, isize))
2709 /// Can be called as:
2716 #[derive(Clone, Eq, PartialEq)]
2717 enum TupleArgumentsFlag {
2722 /// Unifies the return type with the expected type early, for more coercions
2723 /// and forward type information on the argument expressions.
2724 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2726 expected_ret: Expectation<'tcx>,
2727 formal_ret: ty::FnOutput<'tcx>,
2728 formal_args: &[Ty<'tcx>])
2730 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2731 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2732 fcx.infcx().commit_regions_if_ok(|| {
2733 // Attempt to apply a subtyping relationship between the formal
2734 // return type (likely containing type variables if the function
2735 // is polymorphic) and the expected return type.
2736 // No argument expectations are produced if unification fails.
2737 let origin = TypeOrigin::Misc(call_span);
2738 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2739 // FIXME(#15760) can't use try! here, FromError doesn't default
2740 // to identity so the resulting type is not constrained.
2741 if let Err(e) = ures {
2745 // Record all the argument types, with the substitutions
2746 // produced from the above subtyping unification.
2747 Ok(formal_args.iter().map(|ty| {
2748 fcx.infcx().resolve_type_vars_if_possible(ty)
2754 }).unwrap_or(vec![]);
2755 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2756 formal_args, formal_ret,
2757 expected_args, expected_ret);
2762 /// If an expression has any sub-expressions that result in a type error,
2763 /// inspecting that expression's type with `ty.references_error()` will return
2764 /// true. Likewise, if an expression is known to diverge, inspecting its
2765 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2766 /// strict, _|_ can appear in the type of an expression that does not,
2767 /// itself, diverge: for example, fn() -> _|_.)
2768 /// Note that inspecting a type's structure *directly* may expose the fact
2769 /// that there are actually multiple representations for `TyError`, so avoid
2770 /// that when err needs to be handled differently.
2771 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2772 expr: &'tcx hir::Expr,
2773 expected: Expectation<'tcx>,
2774 lvalue_pref: LvaluePreference) {
2775 debug!(">> typechecking: expr={:?} expected={:?}",
2778 // Checks a method call.
2779 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2780 expr: &'tcx hir::Expr,
2781 method_name: Spanned<ast::Name>,
2782 args: &'tcx [P<hir::Expr>],
2784 expected: Expectation<'tcx>,
2785 lvalue_pref: LvaluePreference) {
2786 let rcvr = &args[0];
2787 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2789 // no need to check for bot/err -- callee does that
2790 let expr_t = structurally_resolved_type(fcx,
2792 fcx.expr_ty(&rcvr));
2794 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2795 let fn_ty = match method::lookup(fcx,
2803 let method_ty = method.ty;
2804 let method_call = MethodCall::expr(expr.id);
2805 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2809 if method_name.node != special_idents::invalid.name {
2810 method::report_error(fcx, method_name.span, expr_t,
2811 method_name.node, Some(rcvr), error);
2813 fcx.write_error(expr.id);
2818 // Call the generic checker.
2819 let ret_ty = check_method_argument_types(fcx,
2827 write_call(fcx, expr, ret_ty);
2830 // A generic function for checking the then and else in an if
2832 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2833 cond_expr: &'tcx hir::Expr,
2834 then_blk: &'tcx hir::Block,
2835 opt_else_expr: Option<&'tcx hir::Expr>,
2838 expected: Expectation<'tcx>) {
2839 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2841 let expected = expected.adjust_for_branches(fcx);
2842 check_block_with_expected(fcx, then_blk, expected);
2843 let then_ty = fcx.node_ty(then_blk.id);
2845 let unit = fcx.tcx().mk_nil();
2846 let (origin, expected, found, result) =
2847 if let Some(else_expr) = opt_else_expr {
2848 check_expr_with_expectation(fcx, else_expr, expected);
2849 let else_ty = fcx.expr_ty(else_expr);
2850 let origin = TypeOrigin::IfExpression(sp);
2852 // Only try to coerce-unify if we have a then expression
2853 // to assign coercions to, otherwise it's () or diverging.
2854 let result = if let Some(ref then) = then_blk.expr {
2855 let res = coercion::try_find_lub(fcx, origin, || Some(&**then),
2856 then_ty, else_expr);
2858 // In case we did perform an adjustment, we have to update
2859 // the type of the block, because old trans still uses it.
2860 let adj = fcx.inh.tables.borrow().adjustments.get(&then.id).cloned();
2861 if res.is_ok() && adj.is_some() {
2862 fcx.write_ty(then_blk.id, fcx.adjust_expr_ty(then, adj.as_ref()));
2867 fcx.infcx().commit_if_ok(|_| {
2868 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2869 fcx.infcx().lub(true, trace).relate(&then_ty, &else_ty)
2872 (origin, then_ty, else_ty, result)
2874 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2875 (origin, unit, then_ty,
2876 fcx.infcx().eq_types(true, origin, unit, then_ty).map(|_| unit))
2879 let if_ty = match result {
2881 if fcx.expr_ty(cond_expr).references_error() {
2888 fcx.infcx().report_mismatched_types(origin, expected, found, e);
2893 fcx.write_ty(id, if_ty);
2896 // Check field access expressions
2897 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2898 expr: &'tcx hir::Expr,
2899 lvalue_pref: LvaluePreference,
2900 base: &'tcx hir::Expr,
2901 field: &Spanned<ast::Name>) {
2902 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2903 let expr_t = structurally_resolved_type(fcx, expr.span,
2905 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2906 let (_, autoderefs, field_ty) = autoderef(fcx,
2910 UnresolvedTypeAction::Error,
2914 ty::TyStruct(base_def, substs) => {
2915 debug!("struct named {:?}", base_t);
2916 base_def.struct_variant()
2917 .find_field_named(field.node)
2918 .map(|f| fcx.field_ty(expr.span, f, substs))
2925 fcx.write_ty(expr.id, field_ty);
2926 fcx.write_autoderef_adjustment(base.id, autoderefs);
2932 if field.node == special_idents::invalid.name {
2933 fcx.write_error(expr.id);
2937 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2938 fcx.type_error_struct(field.span,
2940 format!("attempted to take value of method `{}` on type \
2941 `{}`", field.node, actual)
2944 .fileline_help(field.span,
2945 "maybe a `()` to call it is missing? \
2946 If not, try an anonymous function")
2949 let mut err = fcx.type_error_struct(
2952 format!("attempted access of field `{}` on \
2953 type `{}`, but no field with that \
2959 if let ty::TyStruct(def, _) = expr_t.sty {
2960 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2965 fcx.write_error(expr.id);
2968 // displays hints about the closest matches in field names
2969 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2970 variant: ty::VariantDef<'tcx>,
2971 field: &Spanned<ast::Name>,
2972 skip : Vec<InternedString>) {
2973 let name = field.node.as_str();
2974 let names = variant.fields
2976 .filter_map(|ref field| {
2977 // ignore already set fields and private fields from non-local crates
2978 if skip.iter().any(|x| *x == field.name.as_str()) ||
2979 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2986 // only find fits with at least one matching letter
2987 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2988 err.span_help(field.span,
2989 &format!("did you mean `{}`?", name));
2993 // Check tuple index expressions
2994 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2995 expr: &'tcx hir::Expr,
2996 lvalue_pref: LvaluePreference,
2997 base: &'tcx hir::Expr,
2998 idx: codemap::Spanned<usize>) {
2999 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3000 let expr_t = structurally_resolved_type(fcx, expr.span,
3002 let mut tuple_like = false;
3003 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3004 let (_, autoderefs, field_ty) = autoderef(fcx,
3008 UnresolvedTypeAction::Error,
3012 ty::TyStruct(base_def, substs) => {
3013 tuple_like = base_def.struct_variant().is_tuple_struct();
3015 debug!("tuple struct named {:?}", base_t);
3016 base_def.struct_variant()
3019 .map(|f| fcx.field_ty(expr.span, f, substs))
3024 ty::TyTuple(ref v) => {
3026 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3033 fcx.write_ty(expr.id, field_ty);
3034 fcx.write_autoderef_adjustment(base.id, autoderefs);
3039 fcx.type_error_message(
3043 format!("attempted out-of-bounds tuple index `{}` on \
3048 format!("attempted tuple index `{}` on type `{}`, but the \
3049 type was not a tuple or tuple struct",
3056 fcx.write_error(expr.id);
3059 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3061 variant: ty::VariantDef<'tcx>,
3063 skip_fields: &[hir::Field]) {
3064 let mut err = fcx.type_error_struct(
3066 |actual| if let ty::TyEnum(..) = ty.sty {
3067 format!("struct variant `{}::{}` has no field named `{}`",
3068 actual, variant.name.as_str(), field.name.node)
3070 format!("structure `{}` has no field named `{}`",
3071 actual, field.name.node)
3075 // prevent all specified fields from being suggested
3076 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3077 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3081 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3084 variant: ty::VariantDef<'tcx>,
3085 ast_fields: &'tcx [hir::Field],
3086 check_completeness: bool) {
3087 let tcx = fcx.ccx.tcx;
3088 let substs = match adt_ty.sty {
3089 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3090 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3093 let mut remaining_fields = FnvHashMap();
3094 for field in &variant.fields {
3095 remaining_fields.insert(field.name, field);
3098 let mut error_happened = false;
3100 // Typecheck each field.
3101 for field in ast_fields {
3102 let expected_field_type;
3104 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3105 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3107 error_happened = true;
3108 expected_field_type = tcx.types.err;
3109 if let Some(_) = variant.find_field_named(field.name.node) {
3110 span_err!(fcx.tcx().sess, field.name.span, E0062,
3111 "field `{}` specified more than once",
3114 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3118 // Make sure to give a type to the field even if there's
3119 // an error, so we can continue typechecking
3120 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3123 // Make sure the programmer specified all the fields.
3124 if check_completeness &&
3126 !remaining_fields.is_empty()
3128 span_err!(tcx.sess, span, E0063,
3129 "missing field{} {} in initializer of `{}`",
3130 if remaining_fields.len() == 1 {""} else {"s"},
3131 remaining_fields.keys()
3132 .map(|n| format!("`{}`", n))
3133 .collect::<Vec<_>>()
3140 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3142 fields: &'tcx [hir::Field],
3143 base_expr: &'tcx Option<P<hir::Expr>>) {
3144 // Make sure to still write the types
3145 // otherwise we might ICE
3146 fcx.write_error(id);
3147 for field in fields {
3148 check_expr(fcx, &field.expr);
3151 Some(ref base) => check_expr(fcx, &base),
3156 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3159 fields: &'tcx [hir::Field],
3160 base_expr: &'tcx Option<P<hir::Expr>>)
3162 let tcx = fcx.tcx();
3164 // Find the relevant variant
3165 let def = lookup_full_def(tcx, path.span, expr.id);
3166 if def == Def::Err {
3167 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3170 let variant = match fcx.def_struct_variant(def, path.span) {
3171 Some((_, variant)) => variant,
3173 span_err!(fcx.tcx().sess, path.span, E0071,
3174 "`{}` does not name a structure",
3175 pprust::path_to_string(path));
3176 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3181 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3182 fcx.write_ty(expr.id, expr_ty);
3184 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3185 base_expr.is_none());
3186 if let &Some(ref base_expr) = base_expr {
3187 check_expr_has_type(fcx, base_expr, expr_ty);
3189 ty::TyStruct(adt, substs) => {
3190 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3192 adt.struct_variant().fields.iter().map(|f| {
3193 fcx.normalize_associated_types_in(
3194 expr.span, &f.ty(tcx, substs)
3200 span_err!(tcx.sess, base_expr.span, E0436,
3201 "functional record update syntax requires a struct");
3207 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3209 let tcx = fcx.ccx.tcx;
3212 hir::ExprBox(ref subexpr) => {
3213 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3215 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3219 check_expr_with_expectation(fcx, subexpr, expected_inner);
3220 let referent_ty = fcx.expr_ty(&subexpr);
3221 fcx.write_ty(id, tcx.mk_box(referent_ty));
3224 hir::ExprLit(ref lit) => {
3225 let typ = check_lit(fcx, &lit, expected);
3226 fcx.write_ty(id, typ);
3228 hir::ExprBinary(op, ref lhs, ref rhs) => {
3229 op::check_binop(fcx, expr, op, lhs, rhs);
3231 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3232 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3234 hir::ExprUnary(unop, ref oprnd) => {
3235 let expected_inner = match unop {
3236 hir::UnNot | hir::UnNeg => {
3243 let lvalue_pref = match unop {
3244 hir::UnDeref => lvalue_pref,
3247 check_expr_with_expectation_and_lvalue_pref(
3248 fcx, &oprnd, expected_inner, lvalue_pref);
3249 let mut oprnd_t = fcx.expr_ty(&oprnd);
3251 if !oprnd_t.references_error() {
3254 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3256 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3258 } else if let Some(method) = try_overloaded_deref(
3259 fcx, expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3260 oprnd_t = make_overloaded_lvalue_return_type(tcx, method).ty;
3261 fcx.inh.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3264 fcx.type_error_message(expr.span, |actual| {
3265 format!("type `{}` cannot be \
3266 dereferenced", actual)
3268 oprnd_t = tcx.types.err;
3272 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3274 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3275 oprnd_t = op::check_user_unop(fcx, "!", "not",
3276 tcx.lang_items.not_trait(),
3277 expr, &oprnd, oprnd_t, unop);
3281 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3283 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3284 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3285 tcx.lang_items.neg_trait(),
3286 expr, &oprnd, oprnd_t, unop);
3291 fcx.write_ty(id, oprnd_t);
3293 hir::ExprAddrOf(mutbl, ref oprnd) => {
3294 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3296 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3297 if fcx.tcx().expr_is_lval(&oprnd) {
3298 // Lvalues may legitimately have unsized types.
3299 // For example, dereferences of a fat pointer and
3300 // the last field of a struct can be unsized.
3301 ExpectHasType(mt.ty)
3303 Expectation::rvalue_hint(tcx, mt.ty)
3309 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3310 check_expr_with_expectation_and_lvalue_pref(fcx,
3315 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3316 let oprnd_t = if tm.ty.references_error() {
3319 // Note: at this point, we cannot say what the best lifetime
3320 // is to use for resulting pointer. We want to use the
3321 // shortest lifetime possible so as to avoid spurious borrowck
3322 // errors. Moreover, the longest lifetime will depend on the
3323 // precise details of the value whose address is being taken
3324 // (and how long it is valid), which we don't know yet until type
3325 // inference is complete.
3327 // Therefore, here we simply generate a region variable. The
3328 // region inferencer will then select the ultimate value.
3329 // Finally, borrowck is charged with guaranteeing that the
3330 // value whose address was taken can actually be made to live
3331 // as long as it needs to live.
3332 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3333 tcx.mk_ref(tcx.mk_region(region), tm)
3335 fcx.write_ty(id, oprnd_t);
3337 hir::ExprPath(ref maybe_qself, ref path) => {
3338 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3339 fcx.to_ty(&qself.ty)
3342 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3344 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3345 // Create some fake resolution that can't possibly be a type.
3346 def::PathResolution {
3347 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3348 depth: path.segments.len()
3351 tcx.sess.span_bug(expr.span,
3352 &format!("unbound path {:?}", expr))
3355 if let Some((opt_ty, segments, def)) =
3356 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3357 expr.span, expr.id) {
3358 if def != Def::Err {
3359 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3362 instantiate_path(fcx,
3371 fcx.write_ty(id, fcx.tcx().types.err);
3375 // We always require that the type provided as the value for
3376 // a type parameter outlives the moment of instantiation.
3377 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3378 fcx.add_wf_bounds(&item_substs.substs, expr);
3381 hir::ExprInlineAsm(ref ia) => {
3382 for &(_, ref input) in &ia.inputs {
3383 check_expr(fcx, &input);
3385 for out in &ia.outputs {
3386 check_expr(fcx, &out.expr);
3390 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3391 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3392 hir::ExprRet(ref expr_opt) => {
3394 ty::FnConverging(result_type) => {
3397 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3398 result_type, fcx.tcx().mk_nil()) {
3399 span_err!(tcx.sess, expr.span, E0069,
3400 "`return;` in a function whose return type is \
3404 check_expr_coercable_to_type(fcx, &e, result_type);
3408 ty::FnDiverging => {
3409 if let Some(ref e) = *expr_opt {
3410 check_expr(fcx, &e);
3412 span_err!(tcx.sess, expr.span, E0166,
3413 "`return` in a function declared as diverging");
3416 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3418 hir::ExprAssign(ref lhs, ref rhs) => {
3419 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3421 let tcx = fcx.tcx();
3422 if !tcx.expr_is_lval(&lhs) {
3423 span_err!(tcx.sess, expr.span, E0070,
3424 "invalid left-hand side expression");
3427 let lhs_ty = fcx.expr_ty(&lhs);
3428 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3429 let rhs_ty = fcx.expr_ty(&rhs);
3431 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3433 if lhs_ty.references_error() || rhs_ty.references_error() {
3434 fcx.write_error(id);
3439 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3440 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3441 id, expr.span, expected);
3443 hir::ExprWhile(ref cond, ref body, _) => {
3444 check_expr_has_type(fcx, &cond, tcx.types.bool);
3445 check_block_no_value(fcx, &body);
3446 let cond_ty = fcx.expr_ty(&cond);
3447 let body_ty = fcx.node_ty(body.id);
3448 if cond_ty.references_error() || body_ty.references_error() {
3449 fcx.write_error(id);
3455 hir::ExprLoop(ref body, _) => {
3456 check_block_no_value(fcx, &body);
3457 if !may_break(tcx, expr.id, &body) {
3458 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3463 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3464 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3466 hir::ExprClosure(capture, ref decl, ref body) => {
3467 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3469 hir::ExprBlock(ref b) => {
3470 check_block_with_expected(fcx, &b, expected);
3471 fcx.write_ty(id, fcx.node_ty(b.id));
3473 hir::ExprCall(ref callee, ref args) => {
3474 callee::check_call(fcx, expr, &callee, &args[..], expected);
3476 // we must check that return type of called functions is WF:
3477 let ret_ty = fcx.expr_ty(expr);
3478 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3480 hir::ExprMethodCall(name, ref tps, ref args) => {
3481 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3482 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3483 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3485 fcx.write_error(id);
3488 hir::ExprCast(ref e, ref t) => {
3489 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3490 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3493 // Find the type of `e`. Supply hints based on the type we are casting to,
3495 let t_cast = fcx.to_ty(t);
3496 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3497 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3498 let t_expr = fcx.expr_ty(e);
3499 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3501 // Eagerly check for some obvious errors.
3502 if t_expr.references_error() || t_cast.references_error() {
3503 fcx.write_error(id);
3504 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3505 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3507 // Write a type for the whole expression, assuming everything is going
3509 fcx.write_ty(id, t_cast);
3511 // Defer other checks until we're done type checking.
3512 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3513 let cast_check = cast::CastCheck::new(e, t_expr, t_cast, expr.span);
3514 deferred_cast_checks.push(cast_check);
3517 hir::ExprType(ref e, ref t) => {
3518 let typ = fcx.to_ty(&t);
3519 check_expr_eq_type(fcx, &e, typ);
3520 fcx.write_ty(id, typ);
3522 hir::ExprVec(ref args) => {
3523 let uty = expected.to_option(fcx).and_then(|uty| {
3525 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3530 let mut unified = fcx.infcx().next_ty_var();
3531 let coerce_to = uty.unwrap_or(unified);
3533 for (i, e) in args.iter().enumerate() {
3534 check_expr_with_hint(fcx, e, coerce_to);
3535 let e_ty = fcx.expr_ty(e);
3536 let origin = TypeOrigin::Misc(e.span);
3538 // Special-case the first element, as it has no "previous expressions".
3539 let result = if i == 0 {
3540 coercion::try(fcx, e, coerce_to)
3542 let prev_elems = || args[..i].iter().map(|e| &**e);
3543 coercion::try_find_lub(fcx, origin, prev_elems, unified, e)
3547 Ok(ty) => unified = ty,
3549 fcx.infcx().report_mismatched_types(origin, unified, e_ty, e);
3553 fcx.write_ty(id, tcx.mk_array(unified, args.len()));
3555 hir::ExprRepeat(ref element, ref count_expr) => {
3556 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3557 let count = fcx.tcx().eval_repeat_count(&count_expr);
3559 let uty = match expected {
3560 ExpectHasType(uty) => {
3562 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3569 let (element_ty, t) = match uty {
3571 check_expr_coercable_to_type(fcx, &element, uty);
3575 let t: Ty = fcx.infcx().next_ty_var();
3576 check_expr_has_type(fcx, &element, t);
3577 (fcx.expr_ty(&element), t)
3582 // For [foo, ..n] where n > 1, `foo` must have
3584 fcx.require_type_meets(
3591 if element_ty.references_error() {
3592 fcx.write_error(id);
3594 let t = tcx.mk_array(t, count);
3595 fcx.write_ty(id, t);
3598 hir::ExprTup(ref elts) => {
3599 let flds = expected.only_has_type(fcx).and_then(|ty| {
3601 ty::TyTuple(ref flds) => Some(&flds[..]),
3605 let mut err_field = false;
3607 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3608 let t = match flds {
3609 Some(ref fs) if i < fs.len() => {
3611 check_expr_coercable_to_type(fcx, &e, ety);
3615 check_expr_with_expectation(fcx, &e, NoExpectation);
3619 err_field = err_field || t.references_error();
3623 fcx.write_error(id);
3625 let typ = tcx.mk_tup(elt_ts);
3626 fcx.write_ty(id, typ);
3629 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3630 check_expr_struct(fcx, expr, path, fields, base_expr);
3632 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3634 hir::ExprField(ref base, ref field) => {
3635 check_field(fcx, expr, lvalue_pref, &base, field);
3637 hir::ExprTupField(ref base, idx) => {
3638 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3640 hir::ExprIndex(ref base, ref idx) => {
3641 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3642 check_expr(fcx, &idx);
3644 let base_t = fcx.expr_ty(&base);
3645 let idx_t = fcx.expr_ty(&idx);
3647 if base_t.references_error() {
3648 fcx.write_ty(id, base_t);
3649 } else if idx_t.references_error() {
3650 fcx.write_ty(id, idx_t);
3652 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3653 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3654 Some((index_ty, element_ty)) => {
3655 let idx_expr_ty = fcx.expr_ty(idx);
3656 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3657 fcx.write_ty(id, element_ty);
3660 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3661 fcx.type_error_message(
3664 format!("cannot index a value of type `{}`",
3669 fcx.write_ty(id, fcx.tcx().types.err);
3676 debug!("type of expr({}) {} is...", expr.id,
3677 pprust::expr_to_string(expr));
3678 debug!("... {:?}, expected is {:?}",
3683 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3684 path_res: def::PathResolution,
3685 opt_self_ty: Option<Ty<'tcx>>,
3686 path: &'a hir::Path,
3688 node_id: ast::NodeId)
3689 -> Option<(Option<Ty<'tcx>>,
3690 &'a [hir::PathSegment],
3694 // If fully resolved already, we don't have to do anything.
3695 if path_res.depth == 0 {
3696 Some((opt_self_ty, &path.segments, path_res.base_def))
3698 let mut def = path_res.base_def;
3699 let ty_segments = path.segments.split_last().unwrap().1;
3700 let base_ty_end = path.segments.len() - path_res.depth;
3701 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3702 PathParamMode::Optional,
3705 &ty_segments[..base_ty_end],
3706 &ty_segments[base_ty_end..]);
3707 let item_segment = path.segments.last().unwrap();
3708 let item_name = item_segment.identifier.name;
3709 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3711 // Write back the new resolution.
3712 fcx.ccx.tcx.def_map.borrow_mut()
3713 .insert(node_id, def::PathResolution {
3717 Some((Some(ty), slice::ref_slice(item_segment), def))
3720 if item_name != special_idents::invalid.name {
3721 method::report_error(fcx, span, ty, item_name, None, error);
3723 fcx.write_error(node_id);
3730 impl<'tcx> Expectation<'tcx> {
3731 /// Provide an expectation for an rvalue expression given an *optional*
3732 /// hint, which is not required for type safety (the resulting type might
3733 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3734 /// is useful in determining the concrete type.
3736 /// The primary use case is where the expected type is a fat pointer,
3737 /// like `&[isize]`. For example, consider the following statement:
3739 /// let x: &[isize] = &[1, 2, 3];
3741 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3742 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3743 /// expectation `ExpectHasType([isize])`, that would be too strong --
3744 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3745 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3746 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3747 /// which still is useful, because it informs integer literals and the like.
3748 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3749 /// for examples of where this comes up,.
3750 fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3751 match tcx.struct_tail(ty).sty {
3752 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3753 ExpectRvalueLikeUnsized(ty)
3755 _ => ExpectHasType(ty)
3759 // Resolves `expected` by a single level if it is a variable. If
3760 // there is no expected type or resolution is not possible (e.g.,
3761 // no constraints yet present), just returns `None`.
3762 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3767 ExpectCastableToType(t) => {
3768 ExpectCastableToType(
3769 fcx.infcx().resolve_type_vars_if_possible(&t))
3771 ExpectHasType(t) => {
3773 fcx.infcx().resolve_type_vars_if_possible(&t))
3775 ExpectRvalueLikeUnsized(t) => {
3776 ExpectRvalueLikeUnsized(
3777 fcx.infcx().resolve_type_vars_if_possible(&t))
3782 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3783 match self.resolve(fcx) {
3784 NoExpectation => None,
3785 ExpectCastableToType(ty) |
3787 ExpectRvalueLikeUnsized(ty) => Some(ty),
3791 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3792 match self.resolve(fcx) {
3793 ExpectHasType(ty) => Some(ty),
3799 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3800 local: &'tcx hir::Local,
3801 init: &'tcx hir::Expr)
3803 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3805 let local_ty = fcx.local_ty(init.span, local.id);
3806 if let Some(m) = ref_bindings {
3807 // Somewhat subtle: if we have a `ref` binding in the pattern,
3808 // we want to avoid introducing coercions for the RHS. This is
3809 // both because it helps preserve sanity and, in the case of
3810 // ref mut, for soundness (issue #23116). In particular, in
3811 // the latter case, we need to be clear that the type of the
3812 // referent for the reference that results is *equal to* the
3813 // type of the lvalue it is referencing, and not some
3814 // supertype thereof.
3815 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3816 let init_ty = fcx.expr_ty(init);
3817 demand::eqtype(fcx, init.span, init_ty, local_ty);
3819 check_expr_coercable_to_type(fcx, init, local_ty)
3823 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3824 let tcx = fcx.ccx.tcx;
3826 let t = fcx.local_ty(local.span, local.id);
3827 fcx.write_ty(local.id, t);
3829 if let Some(ref init) = local.init {
3830 check_decl_initializer(fcx, local, &init);
3831 let init_ty = fcx.expr_ty(&init);
3832 if init_ty.references_error() {
3833 fcx.write_ty(local.id, init_ty);
3837 let pcx = pat_ctxt {
3839 map: pat_id_map(&tcx.def_map, &local.pat),
3841 _match::check_pat(&pcx, &local.pat, t);
3842 let pat_ty = fcx.node_ty(local.pat.id);
3843 if pat_ty.references_error() {
3844 fcx.write_ty(local.id, pat_ty);
3848 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3850 let mut saw_bot = false;
3851 let mut saw_err = false;
3853 hir::StmtDecl(ref decl, id) => {
3856 hir::DeclLocal(ref l) => {
3857 check_decl_local(fcx, &l);
3858 let l_t = fcx.node_ty(l.id);
3859 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3860 saw_err = saw_err || l_t.references_error();
3862 hir::DeclItem(_) => {/* ignore for now */ }
3865 hir::StmtExpr(ref expr, id) => {
3867 // Check with expected type of ()
3868 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3869 let expr_ty = fcx.expr_ty(&expr);
3870 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3871 saw_err = saw_err || expr_ty.references_error();
3873 hir::StmtSemi(ref expr, id) => {
3875 check_expr(fcx, &expr);
3876 let expr_ty = fcx.expr_ty(&expr);
3877 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3878 saw_err |= expr_ty.references_error();
3882 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3885 fcx.write_error(node_id);
3888 fcx.write_nil(node_id)
3892 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3893 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3894 let blkty = fcx.node_ty(blk.id);
3895 if blkty.references_error() {
3896 fcx.write_error(blk.id);
3898 let nilty = fcx.tcx().mk_nil();
3899 demand::suptype(fcx, blk.span, nilty, blkty);
3903 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3904 blk: &'tcx hir::Block,
3905 expected: Expectation<'tcx>) {
3907 let mut fcx_ps = fcx.ps.borrow_mut();
3908 let unsafety_state = fcx_ps.recurse(blk);
3909 replace(&mut *fcx_ps, unsafety_state)
3912 let mut warned = false;
3913 let mut any_diverges = false;
3914 let mut any_err = false;
3915 for s in &blk.stmts {
3917 let s_id = ::rustc_front::util::stmt_id(s);
3918 let s_ty = fcx.node_ty(s_id);
3919 if any_diverges && !warned && match s.node {
3920 hir::StmtDecl(ref decl, _) => {
3922 hir::DeclLocal(_) => true,
3926 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3931 .add_lint(lint::builtin::UNREACHABLE_CODE,
3934 "unreachable statement".to_string());
3937 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3938 any_err = any_err || s_ty.references_error();
3941 None => if any_err {
3942 fcx.write_error(blk.id);
3943 } else if any_diverges {
3944 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3946 fcx.write_nil(blk.id);
3949 if any_diverges && !warned {
3953 .add_lint(lint::builtin::UNREACHABLE_CODE,
3956 "unreachable expression".to_string());
3958 let ety = match expected {
3959 ExpectHasType(ety) => {
3960 check_expr_coercable_to_type(fcx, &e, ety);
3964 check_expr_with_expectation(fcx, &e, expected);
3970 fcx.write_error(blk.id);
3971 } else if any_diverges {
3972 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3974 fcx.write_ty(blk.id, ety);
3979 *fcx.ps.borrow_mut() = prev;
3982 /// Checks a constant appearing in a type. At the moment this is just the
3983 /// length expression in a fixed-length vector, but someday it might be
3984 /// extended to type-level numeric literals.
3985 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3986 expr: &'tcx hir::Expr,
3987 expected_type: Ty<'tcx>) {
3988 let tables = RefCell::new(ty::Tables::empty());
3989 let inh = static_inherited_fields(ccx, &tables);
3990 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3991 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3994 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3998 let tables = RefCell::new(ty::Tables::empty());
3999 let inh = static_inherited_fields(ccx, &tables);
4000 let rty = ccx.tcx.node_id_to_type(id);
4001 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4002 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4003 check_const_with_ty(&fcx, sp, e, declty);
4006 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4010 // Gather locals in statics (because of block expressions).
4011 // This is technically unnecessary because locals in static items are forbidden,
4012 // but prevents type checking from blowing up before const checking can properly
4014 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4016 check_expr_with_hint(fcx, e, declty);
4017 demand::coerce(fcx, e.span, declty, e);
4019 fcx.select_all_obligations_and_apply_defaults();
4020 upvar::closure_analyze_const(&fcx, e);
4021 fcx.select_obligations_where_possible();
4023 fcx.select_all_obligations_or_error();
4025 regionck::regionck_expr(fcx, e);
4026 writeback::resolve_type_vars_in_expr(fcx, e);
4029 /// Checks whether a type can be represented in memory. In particular, it
4030 /// identifies types that contain themselves without indirection through a
4031 /// pointer, which would mean their size is unbounded.
4032 pub fn check_representable(tcx: &TyCtxt,
4034 item_id: ast::NodeId,
4035 _designation: &str) -> bool {
4036 let rty = tcx.node_id_to_type(item_id);
4038 // Check that it is possible to represent this type. This call identifies
4039 // (1) types that contain themselves and (2) types that contain a different
4040 // recursive type. It is only necessary to throw an error on those that
4041 // contain themselves. For case 2, there must be an inner type that will be
4042 // caught by case 1.
4043 match rty.is_representable(tcx, sp) {
4044 Representability::SelfRecursive => {
4045 let item_def_id = tcx.map.local_def_id(item_id);
4046 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4049 Representability::Representable | Representability::ContainsRecursive => (),
4054 pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
4055 let t = tcx.node_id_to_type(id);
4057 ty::TyStruct(def, substs) => {
4058 let fields = &def.struct_variant().fields;
4059 if fields.is_empty() {
4060 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4063 let e = fields[0].ty(tcx, substs);
4064 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4065 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4069 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4070 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4072 span_err!(tcx.sess, sp, E0077,
4073 "SIMD vector element type should be machine type");
4082 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4084 vs: &'tcx [hir::Variant],
4086 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4087 vs: &'tcx [hir::Variant],
4089 hint: attr::ReprAttr) {
4090 #![allow(trivial_numeric_casts)]
4092 let rty = ccx.tcx.node_id_to_type(id);
4093 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4095 let tables = RefCell::new(ty::Tables::empty());
4096 let inh = static_inherited_fields(ccx, &tables);
4097 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4099 let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(&ccx.tcx);
4101 if let Some(ref e) = v.node.disr_expr {
4102 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4106 let def_id = ccx.tcx.map.local_def_id(id);
4108 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4109 for (v, variant) in vs.iter().zip(variants.iter()) {
4110 let current_disr_val = variant.disr_val;
4112 // Check for duplicate discriminant values
4113 match disr_vals.iter().position(|&x| x == current_disr_val) {
4115 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4116 "discriminant value `{}` already exists", disr_vals[i]);
4117 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4118 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4119 "conflicting discriminant here");
4124 disr_vals.push(current_disr_val);
4128 let def_id = ccx.tcx.map.local_def_id(id);
4129 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4131 if hint != attr::ReprAny && vs.is_empty() {
4132 span_err!(ccx.tcx.sess, sp, E0084,
4133 "unsupported representation for zero-variant enum");
4136 do_check(ccx, vs, id, hint);
4138 check_representable(ccx.tcx, sp, id, "enum");
4141 // Returns the type parameter count and the type for the given definition.
4142 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4145 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4147 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4148 let typ = fcx.local_ty(sp, nid);
4149 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4150 ty::GenericPredicates::empty())
4152 Def::Fn(id) | Def::Method(id) |
4153 Def::Static(id, _) | Def::Variant(_, id) |
4154 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4155 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4160 Def::AssociatedTy(..) |
4164 Def::ForeignMod(..) |
4168 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4173 // Instantiates the given path, which must refer to an item with the given
4174 // number of type parameters and type.
4175 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4176 segments: &[hir::PathSegment],
4177 type_scheme: TypeScheme<'tcx>,
4178 type_predicates: &ty::GenericPredicates<'tcx>,
4179 opt_self_ty: Option<Ty<'tcx>>,
4182 node_id: ast::NodeId) {
4183 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4189 // We need to extract the type parameters supplied by the user in
4190 // the path `path`. Due to the current setup, this is a bit of a
4191 // tricky-process; the problem is that resolve only tells us the
4192 // end-point of the path resolution, and not the intermediate steps.
4193 // Luckily, we can (at least for now) deduce the intermediate steps
4194 // just from the end-point.
4196 // There are basically four cases to consider:
4198 // 1. Reference to a *type*, such as a struct or enum:
4200 // mod a { struct Foo<T> { ... } }
4202 // Because we don't allow types to be declared within one
4203 // another, a path that leads to a type will always look like
4204 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4205 // that only the final segment can have type parameters, and
4206 // they are located in the TypeSpace.
4208 // *Note:* Generally speaking, references to types don't
4209 // actually pass through this function, but rather the
4210 // `ast_ty_to_ty` function in `astconv`. However, in the case
4211 // of struct patterns (and maybe literals) we do invoke
4212 // `instantiate_path` to get the general type of an instance of
4213 // a struct. (In these cases, there are actually no type
4214 // parameters permitted at present, but perhaps we will allow
4215 // them in the future.)
4217 // 1b. Reference to an enum variant or tuple-like struct:
4219 // struct foo<T>(...)
4220 // enum E<T> { foo(...) }
4222 // In these cases, the parameters are declared in the type
4225 // 2. Reference to a *fn item*:
4229 // In this case, the path will again always have the form
4230 // `a::b::foo::<T>` where only the final segment should have
4231 // type parameters. However, in this case, those parameters are
4232 // declared on a value, and hence are in the `FnSpace`.
4234 // 3. Reference to a *method*:
4236 // impl<A> SomeStruct<A> {
4240 // Here we can have a path like
4241 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4242 // may appear in two places. The penultimate segment,
4243 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4244 // final segment, `foo::<B>` contains parameters in fn space.
4246 // 4. Reference to an *associated const*:
4248 // impl<A> AnotherStruct<A> {
4249 // const FOO: B = BAR;
4252 // The path in this case will look like
4253 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4254 // only will have parameters in TypeSpace.
4256 // The first step then is to categorize the segments appropriately.
4258 assert!(!segments.is_empty());
4260 let mut ufcs_associated = None;
4261 let mut segment_spaces: Vec<_>;
4263 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4269 Def::AssociatedTy(..) |
4272 Def::TyParam(..) => {
4273 // Everything but the final segment should have no
4274 // parameters at all.
4275 segment_spaces = vec![None; segments.len() - 1];
4276 segment_spaces.push(Some(subst::TypeSpace));
4279 // Case 2. Reference to a top-level value.
4282 Def::Static(..) => {
4283 segment_spaces = vec![None; segments.len() - 1];
4284 segment_spaces.push(Some(subst::FnSpace));
4287 // Case 3. Reference to a method.
4288 Def::Method(def_id) => {
4289 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4291 ty::TraitContainer(trait_did) => {
4292 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4294 ty::ImplContainer(_) => {}
4297 if segments.len() >= 2 {
4298 segment_spaces = vec![None; segments.len() - 2];
4299 segment_spaces.push(Some(subst::TypeSpace));
4300 segment_spaces.push(Some(subst::FnSpace));
4302 // `<T>::method` will end up here, and so can `T::method`.
4303 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4304 segment_spaces = vec![Some(subst::FnSpace)];
4305 ufcs_associated = Some((container, self_ty));
4309 Def::AssociatedConst(def_id) => {
4310 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4312 ty::TraitContainer(trait_did) => {
4313 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4315 ty::ImplContainer(_) => {}
4318 if segments.len() >= 2 {
4319 segment_spaces = vec![None; segments.len() - 2];
4320 segment_spaces.push(Some(subst::TypeSpace));
4321 segment_spaces.push(None);
4323 // `<T>::CONST` will end up here, and so can `T::CONST`.
4324 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4325 segment_spaces = vec![None];
4326 ufcs_associated = Some((container, self_ty));
4330 // Other cases. Various nonsense that really shouldn't show up
4331 // here. If they do, an error will have been reported
4332 // elsewhere. (I hope)
4334 Def::ForeignMod(..) |
4339 segment_spaces = vec![None; segments.len()];
4342 assert_eq!(segment_spaces.len(), segments.len());
4344 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4345 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4346 // type parameters are not mandatory.
4347 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4349 debug!("segment_spaces={:?}", segment_spaces);
4351 // Next, examine the definition, and determine how many type
4352 // parameters we expect from each space.
4353 let type_defs = &type_scheme.generics.types;
4354 let region_defs = &type_scheme.generics.regions;
4356 // Now that we have categorized what space the parameters for each
4357 // segment belong to, let's sort out the parameters that the user
4358 // provided (if any) into their appropriate spaces. We'll also report
4359 // errors if type parameters are provided in an inappropriate place.
4360 let mut substs = Substs::empty();
4361 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4364 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4368 push_explicit_parameters_from_segment_to_substs(fcx,
4378 if let Some(self_ty) = opt_self_ty {
4379 if type_defs.len(subst::SelfSpace) == 1 {
4380 substs.types.push(subst::SelfSpace, self_ty);
4384 // Now we have to compare the types that the user *actually*
4385 // provided against the types that were *expected*. If the user
4386 // did not provide any types, then we want to substitute inference
4387 // variables. If the user provided some types, we may still need
4388 // to add defaults. If the user provided *too many* types, that's
4390 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4391 adjust_type_parameters(fcx, span, space, type_defs,
4392 require_type_space, &mut substs);
4393 assert_eq!(substs.types.len(space), type_defs.len(space));
4395 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4396 assert_eq!(substs.regions().len(space), region_defs.len(space));
4399 // The things we are substituting into the type should not contain
4400 // escaping late-bound regions, and nor should the base type scheme.
4401 assert!(!substs.has_regions_escaping_depth(0));
4402 assert!(!type_scheme.has_escaping_regions());
4404 // Add all the obligations that are required, substituting and
4405 // normalized appropriately.
4406 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4407 fcx.add_obligations_for_parameters(
4408 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4411 // Substitute the values for the type parameters into the type of
4412 // the referenced item.
4413 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4416 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4417 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4418 // is inherent, there is no `Self` parameter, instead, the impl needs
4419 // type parameters, which we can infer by unifying the provided `Self`
4420 // with the substituted impl type.
4421 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4422 assert_eq!(substs.types.len(subst::TypeSpace),
4423 impl_scheme.generics.types.len(subst::TypeSpace));
4424 assert_eq!(substs.regions().len(subst::TypeSpace),
4425 impl_scheme.generics.regions.len(subst::TypeSpace));
4427 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4428 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4429 fcx.tcx().sess.span_bug(span,
4431 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4437 debug!("instantiate_path: type of {:?} is {:?}",
4440 fcx.write_ty(node_id, ty_substituted);
4441 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4444 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4445 /// parameters are provided, then reports an error and clears the output vector.
4447 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4448 /// use inference variables. This seems less likely to lead to derived errors.
4450 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4451 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4452 /// here because we can easily use the precise span of the N+1'th parameter.
4453 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4454 fcx: &FnCtxt<'a, 'tcx>,
4455 space: subst::ParamSpace,
4457 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4458 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4459 segment: &hir::PathSegment,
4460 substs: &mut Substs<'tcx>)
4462 match segment.parameters {
4463 hir::AngleBracketedParameters(ref data) => {
4464 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4465 fcx, space, type_defs, region_defs, data, substs);
4468 hir::ParenthesizedParameters(ref data) => {
4469 span_err!(fcx.tcx().sess, span, E0238,
4470 "parenthesized parameters may only be used with a trait");
4471 push_explicit_parenthesized_parameters_from_segment_to_substs(
4472 fcx, space, span, type_defs, data, substs);
4477 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4478 fcx: &FnCtxt<'a, 'tcx>,
4479 space: subst::ParamSpace,
4480 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4481 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4482 data: &hir::AngleBracketedParameterData,
4483 substs: &mut Substs<'tcx>)
4486 let type_count = type_defs.len(space);
4487 assert_eq!(substs.types.len(space), 0);
4488 for (i, typ) in data.types.iter().enumerate() {
4489 let t = fcx.to_ty(&typ);
4491 substs.types.push(space, t);
4492 } else if i == type_count {
4493 span_err!(fcx.tcx().sess, typ.span, E0087,
4494 "too many type parameters provided: \
4495 expected at most {} parameter{}, \
4496 found {} parameter{}",
4498 if type_count == 1 {""} else {"s"},
4500 if data.types.len() == 1 {""} else {"s"});
4501 substs.types.truncate(space, 0);
4507 if !data.bindings.is_empty() {
4508 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4509 "unexpected binding of associated item in expression path \
4510 (only allowed in type paths)");
4514 let region_count = region_defs.len(space);
4515 assert_eq!(substs.regions().len(space), 0);
4516 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4517 let r = ast_region_to_region(fcx.tcx(), lifetime);
4518 if i < region_count {
4519 substs.mut_regions().push(space, r);
4520 } else if i == region_count {
4521 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4522 "too many lifetime parameters provided: \
4523 expected {} parameter{}, found {} parameter{}",
4525 if region_count == 1 {""} else {"s"},
4526 data.lifetimes.len(),
4527 if data.lifetimes.len() == 1 {""} else {"s"});
4528 substs.mut_regions().truncate(space, 0);
4536 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4537 /// but intended for `Foo(A,B) -> C` form. This expands to
4538 /// roughly the same thing as `Foo<(A,B),C>`. One important
4539 /// difference has to do with the treatment of anonymous
4540 /// regions, which are translated into bound regions (NYI).
4541 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4542 fcx: &FnCtxt<'a, 'tcx>,
4543 space: subst::ParamSpace,
4545 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4546 data: &hir::ParenthesizedParameterData,
4547 substs: &mut Substs<'tcx>)
4549 let type_count = type_defs.len(space);
4551 span_err!(fcx.tcx().sess, span, E0167,
4552 "parenthesized form always supplies 2 type parameters, \
4553 but only {} parameter(s) were expected",
4557 let input_tys: Vec<Ty> =
4558 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4560 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4562 if type_count >= 1 {
4563 substs.types.push(space, tuple_ty);
4566 let output_ty: Option<Ty> =
4567 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4570 output_ty.unwrap_or(fcx.tcx().mk_nil());
4572 if type_count >= 2 {
4573 substs.types.push(space, output_ty);
4577 fn adjust_type_parameters<'a, 'tcx>(
4578 fcx: &FnCtxt<'a, 'tcx>,
4581 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4582 require_type_space: bool,
4583 substs: &mut Substs<'tcx>)
4585 let provided_len = substs.types.len(space);
4586 let desired = defs.get_slice(space);
4587 let required_len = desired.iter()
4588 .take_while(|d| d.default.is_none())
4591 debug!("adjust_type_parameters(space={:?}, \
4600 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4601 assert!(provided_len <= desired.len());
4603 // Nothing specified at all: supply inference variables for
4605 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4606 substs.types.replace(space, Vec::new());
4607 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4611 // Too few parameters specified: report an error and use Err
4613 if provided_len < required_len {
4615 if desired.len() != required_len { "at least " } else { "" };
4616 span_err!(fcx.tcx().sess, span, E0089,
4617 "too few type parameters provided: expected {}{} parameter{}, \
4618 found {} parameter{}",
4619 qualifier, required_len,
4620 if required_len == 1 {""} else {"s"},
4622 if provided_len == 1 {""} else {"s"});
4623 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4627 // Otherwise, add in any optional parameters that the user
4628 // omitted. The case of *too many* parameters is handled
4630 // push_explicit_parameters_from_segment_to_substs(). Note
4631 // that the *default* type are expressed in terms of all prior
4632 // parameters, so we have to substitute as we go with the
4633 // partial substitution that we have built up.
4634 for i in provided_len..desired.len() {
4635 let default = desired[i].default.unwrap();
4636 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4637 substs.types.push(space, default);
4639 assert_eq!(substs.types.len(space), desired.len());
4641 debug!("Final substs: {:?}", substs);
4644 fn adjust_region_parameters(
4648 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4649 substs: &mut Substs)
4651 let provided_len = substs.mut_regions().len(space);
4652 let desired = defs.get_slice(space);
4654 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4655 assert!(provided_len <= desired.len());
4657 // If nothing was provided, just use inference variables.
4658 if provided_len == 0 {
4659 substs.mut_regions().replace(
4661 fcx.infcx().region_vars_for_defs(span, desired));
4665 // If just the right number were provided, everybody is happy.
4666 if provided_len == desired.len() {
4670 // Otherwise, too few were provided. Report an error and then
4671 // use inference variables.
4672 span_err!(fcx.tcx().sess, span, E0090,
4673 "too few lifetime parameters provided: expected {} parameter{}, \
4674 found {} parameter{}",
4676 if desired.len() == 1 {""} else {"s"},
4678 if provided_len == 1 {""} else {"s"});
4680 substs.mut_regions().replace(
4682 fcx.infcx().region_vars_for_defs(span, desired));
4686 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4690 where F: Fn() -> Ty<'tcx>
4692 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4695 let alternative = f();
4698 if alternative.is_ty_var() || alternative.references_error() {
4699 fcx.type_error_message(sp, |_actual| {
4700 "the type of this value must be known in this context".to_string()
4702 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4703 ty = fcx.tcx().types.err;
4705 demand::suptype(fcx, sp, alternative, ty);
4713 // Resolves `typ` by a single level if `typ` is a type variable. If no
4714 // resolution is possible, then an error is reported.
4715 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4720 structurally_resolve_type_or_else(fcx, sp, ty, || {
4725 // Returns true if b contains a break that can exit from b
4726 pub fn may_break(cx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4727 // First: is there an unlabeled break immediately
4729 (loop_query(&b, |e| {
4731 hir::ExprBreak(None) => true,
4735 // Second: is there a labeled break with label
4736 // <id> nested anywhere inside the loop?
4737 (block_query(b, |e| {
4738 if let hir::ExprBreak(Some(_)) = e.node {
4739 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4746 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4747 tps: &[hir::TyParam],
4749 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4752 // make a vector of booleans initially false, set to true when used
4753 if tps.is_empty() { return; }
4754 let mut tps_used = vec![false; tps.len()];
4756 for leaf_ty in ty.walk() {
4757 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4758 debug!("Found use of ty param num {}", idx);
4759 tps_used[idx as usize] = true;
4763 for (i, b) in tps_used.iter().enumerate() {
4765 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4766 "type parameter `{}` is unused",