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 `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 use self::coercion::CoerceMany;
81 pub use self::compare_method::{compare_impl_method, compare_const_impl};
82 use self::TupleArgumentsFlag::*;
85 use dep_graph::DepNode;
86 use fmt_macros::{Parser, Piece, Position};
87 use hir::def::{Def, CtorKind};
88 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
89 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin, TypeTrace};
90 use rustc::infer::type_variable::{self, TypeVariableOrigin};
91 use rustc::ty::subst::{Kind, Subst, Substs};
92 use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
93 use rustc::ty::{ParamTy, ParameterEnvironment};
94 use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
95 use rustc::ty::{self, Ty, TyCtxt, Visibility};
96 use rustc::ty::{MethodCall, MethodCallee};
97 use rustc::ty::adjustment;
98 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
99 use rustc::ty::maps::Providers;
100 use rustc::ty::util::{Representability, IntTypeExt};
101 use require_c_abi_if_variadic;
102 use session::{Session, CompileResult};
105 use util::common::{ErrorReported, indenter};
106 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap};
108 use std::cell::{Cell, RefCell};
110 use std::mem::replace;
111 use std::ops::{self, Deref};
112 use syntax::abi::Abi;
114 use syntax::codemap::{self, original_sp, Spanned};
115 use syntax::feature_gate::{GateIssue, emit_feature_err};
117 use syntax::symbol::{Symbol, InternedString, keywords};
118 use syntax::util::lev_distance::find_best_match_for_name;
119 use syntax_pos::{self, BytePos, Span, DUMMY_SP};
121 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
122 use rustc::hir::itemlikevisit::ItemLikeVisitor;
123 use rustc::hir::{self, PatKind};
124 use rustc::middle::lang_items;
125 use rustc_back::slice;
126 use rustc_const_eval::eval_length;
127 use rustc_const_math::ConstInt;
147 /// closures defined within the function. For example:
150 /// bar(move|| { ... })
153 /// Here, the function `foo()` and the closure passed to
154 /// `bar()` will each have their own `FnCtxt`, but they will
155 /// share the inherited fields.
156 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
157 infcx: InferCtxt<'a, 'gcx, 'tcx>,
159 locals: RefCell<NodeMap<Ty<'tcx>>>,
161 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
163 // When we process a call like `c()` where `c` is a closure type,
164 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
165 // `FnOnce` closure. In that case, we defer full resolution of the
166 // call until upvar inference can kick in and make the
167 // decision. We keep these deferred resolutions grouped by the
168 // def-id of the closure, so that once we decide, we can easily go
169 // back and process them.
170 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
172 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
174 // Anonymized types found in explicit return types and their
175 // associated fresh inference variable. Writeback resolves these
176 // variables to get the concrete type, which can be used to
177 // deanonymize TyAnon, after typeck is done with all functions.
178 anon_types: RefCell<NodeMap<Ty<'tcx>>>,
181 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
182 type Target = InferCtxt<'a, 'gcx, 'tcx>;
183 fn deref(&self) -> &Self::Target {
188 trait DeferredCallResolution<'gcx, 'tcx> {
189 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
192 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
194 /// When type-checking an expression, we propagate downward
195 /// whatever type hint we are able in the form of an `Expectation`.
196 #[derive(Copy, Clone, Debug)]
197 pub enum Expectation<'tcx> {
198 /// We know nothing about what type this expression should have.
201 /// This expression should have the type given (or some subtype)
202 ExpectHasType(Ty<'tcx>),
204 /// This expression will be cast to the `Ty`
205 ExpectCastableToType(Ty<'tcx>),
207 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
208 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
209 ExpectRvalueLikeUnsized(Ty<'tcx>),
212 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
213 // Disregard "castable to" expectations because they
214 // can lead us astray. Consider for example `if cond
215 // {22} else {c} as u8` -- if we propagate the
216 // "castable to u8" constraint to 22, it will pick the
217 // type 22u8, which is overly constrained (c might not
218 // be a u8). In effect, the problem is that the
219 // "castable to" expectation is not the tightest thing
220 // we can say, so we want to drop it in this case.
221 // The tightest thing we can say is "must unify with
222 // else branch". Note that in the case of a "has type"
223 // constraint, this limitation does not hold.
225 // If the expected type is just a type variable, then don't use
226 // an expected type. Otherwise, we might write parts of the type
227 // when checking the 'then' block which are incompatible with the
229 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
231 ExpectHasType(ety) => {
232 let ety = fcx.shallow_resolve(ety);
233 if !ety.is_ty_var() {
239 ExpectRvalueLikeUnsized(ety) => {
240 ExpectRvalueLikeUnsized(ety)
246 /// Provide an expectation for an rvalue expression given an *optional*
247 /// hint, which is not required for type safety (the resulting type might
248 /// be checked higher up, as is the case with `&expr` and `box expr`), but
249 /// is useful in determining the concrete type.
251 /// The primary use case is where the expected type is a fat pointer,
252 /// like `&[isize]`. For example, consider the following statement:
254 /// let x: &[isize] = &[1, 2, 3];
256 /// In this case, the expected type for the `&[1, 2, 3]` expression is
257 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
258 /// expectation `ExpectHasType([isize])`, that would be too strong --
259 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
260 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
261 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
262 /// which still is useful, because it informs integer literals and the like.
263 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
264 /// for examples of where this comes up,.
265 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
266 match fcx.tcx.struct_tail(ty).sty {
267 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
268 ExpectRvalueLikeUnsized(ty)
270 _ => ExpectHasType(ty)
274 // Resolves `expected` by a single level if it is a variable. If
275 // there is no expected type or resolution is not possible (e.g.,
276 // no constraints yet present), just returns `None`.
277 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
282 ExpectCastableToType(t) => {
283 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
285 ExpectHasType(t) => {
286 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
288 ExpectRvalueLikeUnsized(t) => {
289 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
294 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
295 match self.resolve(fcx) {
296 NoExpectation => None,
297 ExpectCastableToType(ty) |
299 ExpectRvalueLikeUnsized(ty) => Some(ty),
303 /// It sometimes happens that we want to turn an expectation into
304 /// a **hard constraint** (i.e., something that must be satisfied
305 /// for the program to type-check). `only_has_type` will return
306 /// such a constraint, if it exists.
307 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
308 match self.resolve(fcx) {
309 ExpectHasType(ty) => Some(ty),
314 /// Like `only_has_type`, but instead of returning `None` if no
315 /// hard constraint exists, creates a fresh type variable.
316 fn only_has_type_or_fresh_var(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
317 self.only_has_type(fcx)
318 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
322 #[derive(Copy, Clone)]
323 pub struct UnsafetyState {
324 pub def: ast::NodeId,
325 pub unsafety: hir::Unsafety,
326 pub unsafe_push_count: u32,
331 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
332 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
335 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
336 match self.unsafety {
337 // If this unsafe, then if the outer function was already marked as
338 // unsafe we shouldn't attribute the unsafe'ness to the block. This
339 // way the block can be warned about instead of ignoring this
340 // extraneous block (functions are never warned about).
341 hir::Unsafety::Unsafe if self.from_fn => *self,
344 let (unsafety, def, count) = match blk.rules {
345 hir::PushUnsafeBlock(..) =>
346 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
347 hir::PopUnsafeBlock(..) =>
348 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
349 hir::UnsafeBlock(..) =>
350 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
352 (unsafety, self.def, self.unsafe_push_count),
354 UnsafetyState{ def: def,
356 unsafe_push_count: count,
363 /// Whether a node ever exits normally or not.
364 /// Tracked semi-automatically (through type variables
365 /// marked as diverging), with some manual adjustments
366 /// for control-flow primitives (approximating a CFG).
367 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
369 /// Potentially unknown, some cases converge,
370 /// others require a CFG to determine them.
373 /// Definitely known to diverge and therefore
374 /// not reach the next sibling or its parent.
377 /// Same as `Always` but with a reachability
378 /// warning already emitted
382 // Convenience impls for combinig `Diverges`.
384 impl ops::BitAnd for Diverges {
386 fn bitand(self, other: Self) -> Self {
387 cmp::min(self, other)
391 impl ops::BitOr for Diverges {
393 fn bitor(self, other: Self) -> Self {
394 cmp::max(self, other)
398 impl ops::BitAndAssign for Diverges {
399 fn bitand_assign(&mut self, other: Self) {
400 *self = *self & other;
404 impl ops::BitOrAssign for Diverges {
405 fn bitor_assign(&mut self, other: Self) {
406 *self = *self | other;
411 fn always(self) -> bool {
412 self >= Diverges::Always
417 pub struct BreakableCtxt<'gcx, 'tcx> {
420 break_exprs: Vec<&'gcx hir::Expr>,
425 pub struct EnclosingBreakables<'gcx, 'tcx> {
426 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
427 by_id: NodeMap<usize>,
430 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
431 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
432 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
433 bug!("could not find enclosing breakable with id {}", target_id);
440 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
441 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
443 body_id: ast::NodeId,
445 // Number of errors that had been reported when we started
446 // checking this function. On exit, if we find that *more* errors
447 // have been reported, we will skip regionck and other work that
448 // expects the types within the function to be consistent.
449 err_count_on_creation: usize,
451 ret_ty: Option<Ty<'tcx>>,
453 ps: RefCell<UnsafetyState>,
455 /// Whether the last checked node can ever exit.
456 diverges: Cell<Diverges>,
458 /// Whether any child nodes have any type errors.
459 has_errors: Cell<bool>,
461 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
463 inh: &'a Inherited<'a, 'gcx, 'tcx>,
466 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
467 type Target = Inherited<'a, 'gcx, 'tcx>;
468 fn deref(&self) -> &Self::Target {
473 /// Helper type of a temporary returned by Inherited::build(...).
474 /// Necessary because we can't write the following bound:
475 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
476 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
477 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
480 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
481 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId)
482 -> InheritedBuilder<'a, 'gcx, 'tcx> {
483 let tables = ty::TypeckTables::empty();
484 let param_env = ParameterEnvironment::for_item(tcx, id);
486 infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing)
491 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
492 fn enter<F, R>(&'tcx mut self, f: F) -> R
493 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
495 self.infcx.enter(|infcx| f(Inherited::new(infcx)))
499 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
500 pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
503 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
504 locals: RefCell::new(NodeMap()),
505 deferred_call_resolutions: RefCell::new(DefIdMap()),
506 deferred_cast_checks: RefCell::new(Vec::new()),
507 anon_types: RefCell::new(NodeMap()),
511 fn normalize_associated_types_in<T>(&self,
513 body_id: ast::NodeId,
516 where T : TypeFoldable<'tcx>
518 assoc::normalize_associated_types_in(self,
519 &mut self.fulfillment_cx.borrow_mut(),
527 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
529 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
530 fn visit_item(&mut self, i: &'tcx hir::Item) {
531 check_item_type(self.tcx, i);
533 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
534 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
537 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
538 tcx.sess.track_errors(|| {
539 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
540 tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor());
544 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
545 tcx.sess.track_errors(|| {
546 tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType,
547 &mut CheckItemTypesVisitor { tcx });
551 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
552 ty::queries::typeck_item_bodies::get(tcx, DUMMY_SP, LOCAL_CRATE)
555 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
556 debug_assert!(crate_num == LOCAL_CRATE);
557 tcx.sess.track_errors(|| {
558 tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
559 tcx.item_tables(body_owner_def_id);
564 pub fn provide(providers: &mut Providers) {
565 *providers = Providers {
575 fn closure_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
577 -> ty::PolyFnSig<'tcx> {
578 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
579 tcx.item_tables(def_id).closure_tys[&node_id]
582 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
585 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
586 tcx.item_tables(def_id).closure_kinds[&node_id]
589 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
591 -> Option<ty::Destructor> {
592 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
595 fn typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
597 -> &'tcx ty::TypeckTables<'tcx> {
598 // Closures' tables come from their outermost function,
599 // as they are part of the same "inference environment".
600 let outer_def_id = tcx.closure_base_def_id(def_id);
601 if outer_def_id != def_id {
602 return tcx.item_tables(outer_def_id);
605 let id = tcx.hir.as_local_node_id(def_id).unwrap();
606 let span = tcx.hir.span(id);
607 let unsupported = || {
608 span_bug!(span, "can't type-check body of {:?}", def_id);
611 // Figure out what primary body this item has.
612 let mut fn_decl = None;
613 let body_id = match tcx.hir.get(id) {
614 hir::map::NodeItem(item) => {
616 hir::ItemConst(_, body) |
617 hir::ItemStatic(_, _, body) => body,
618 hir::ItemFn(ref decl, .., body) => {
619 fn_decl = Some(decl);
625 hir::map::NodeTraitItem(item) => {
627 hir::TraitItemKind::Const(_, Some(body)) => body,
628 hir::TraitItemKind::Method(ref sig,
629 hir::TraitMethod::Provided(body)) => {
630 fn_decl = Some(&sig.decl);
636 hir::map::NodeImplItem(item) => {
638 hir::ImplItemKind::Const(_, body) => body,
639 hir::ImplItemKind::Method(ref sig, body) => {
640 fn_decl = Some(&sig.decl);
646 hir::map::NodeExpr(expr) => {
647 // FIXME(eddyb) Closures should have separate
648 // function definition IDs and expression IDs.
649 // Type-checking should not let closures get
650 // this far in a constant position.
651 // Assume that everything other than closures
652 // is a constant "initializer" expression.
654 hir::ExprClosure(..) => {
655 // We should've bailed out above for closures.
656 span_bug!(expr.span, "unexpected closure")
658 _ => hir::BodyId { node_id: expr.id }
663 let body = tcx.hir.body(body_id);
665 Inherited::build(tcx, id).enter(|inh| {
666 let fcx = if let Some(decl) = fn_decl {
667 let fn_sig = tcx.item_type(def_id).fn_sig();
669 check_abi(tcx, span, fn_sig.abi());
671 // Compute the fty from point of view of inside fn.
672 let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id);
674 fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
676 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
678 inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
680 check_fn(&inh, fn_sig, decl, id, body)
682 let fcx = FnCtxt::new(&inh, None, body.value.id);
683 let expected_type = tcx.item_type(def_id);
684 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
685 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
687 // Gather locals in statics (because of block expressions).
688 // This is technically unnecessary because locals in static items are forbidden,
689 // but prevents type checking from blowing up before const checking can properly
691 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
693 fcx.check_expr_coercable_to_type(&body.value, expected_type);
698 fcx.select_all_obligations_and_apply_defaults();
699 fcx.closure_analyze(body);
700 fcx.select_obligations_where_possible();
702 fcx.select_all_obligations_or_error();
704 if fn_decl.is_some() {
705 fcx.regionck_fn(id, body);
707 fcx.regionck_expr(body);
710 fcx.resolve_type_vars_in_body(body)
714 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
715 if !tcx.sess.target.target.is_abi_supported(abi) {
716 struct_span_err!(tcx.sess, span, E0570,
717 "The ABI `{}` is not supported for the current target", abi).emit()
721 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
722 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
725 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
726 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
729 // infer the variable's type
730 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
731 self.fcx.locals.borrow_mut().insert(nid, var_ty);
735 // take type that the user specified
736 self.fcx.locals.borrow_mut().insert(nid, typ);
743 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
744 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
745 NestedVisitorMap::None
748 // Add explicitly-declared locals.
749 fn visit_local(&mut self, local: &'gcx hir::Local) {
750 let o_ty = match local.ty {
751 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
754 self.assign(local.span, local.id, o_ty);
755 debug!("Local variable {:?} is assigned type {}",
757 self.fcx.ty_to_string(
758 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
759 intravisit::walk_local(self, local);
762 // Add pattern bindings.
763 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
764 if let PatKind::Binding(_, _, ref path1, _) = p.node {
765 let var_ty = self.assign(p.span, p.id, None);
767 self.fcx.require_type_is_sized(var_ty, p.span,
768 traits::VariableType(p.id));
770 debug!("Pattern binding {} is assigned to {} with type {:?}",
772 self.fcx.ty_to_string(
773 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
776 intravisit::walk_pat(self, p);
779 // Don't descend into the bodies of nested closures
780 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
781 _: hir::BodyId, _: Span, _: ast::NodeId) { }
784 /// Helper used for fns and closures. Does the grungy work of checking a function
785 /// body and returns the function context used for that purpose, since in the case of a fn item
786 /// there is still a bit more to do.
789 /// * inherited: other fields inherited from the enclosing fn (if any)
790 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
791 fn_sig: ty::FnSig<'tcx>,
792 decl: &'gcx hir::FnDecl,
794 body: &'gcx hir::Body)
795 -> FnCtxt<'a, 'gcx, 'tcx>
797 let mut fn_sig = fn_sig.clone();
799 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
801 // Create the function context. This is either derived from scratch or,
802 // in the case of function expressions, based on the outer context.
803 let mut fcx = FnCtxt::new(inherited, None, body.value.id);
804 let ret_ty = fn_sig.output();
805 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
807 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
808 fcx.ret_ty = fcx.instantiate_anon_types(&Some(ret_ty));
809 fn_sig = fcx.tcx.mk_fn_sig(
810 fn_sig.inputs().iter().cloned(),
817 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
819 // Add formal parameters.
820 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
821 // The type of the argument must be well-formed.
823 // NB -- this is now checked in wfcheck, but that
824 // currently only results in warnings, so we issue an
825 // old-style WF obligation here so that we still get the
826 // errors that we used to get.
827 fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
829 // Check the pattern.
830 fcx.check_pat_arg(&arg.pat, arg_ty, true);
831 fcx.write_ty(arg.id, arg_ty);
834 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
836 fcx.check_expr_coercable_to_type(&body.value, fcx.ret_ty.unwrap());
841 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
844 let def_id = tcx.hir.local_def_id(id);
845 let def = tcx.lookup_adt_def(def_id);
846 def.destructor(tcx); // force the destructor to be evaluated
847 check_representable(tcx, span, def_id);
850 check_simd(tcx, span, def_id);
854 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
857 let def_id = tcx.hir.local_def_id(id);
858 let def = tcx.lookup_adt_def(def_id);
859 def.destructor(tcx); // force the destructor to be evaluated
860 check_representable(tcx, span, def_id);
863 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
864 debug!("check_item_type(it.id={}, it.name={})",
866 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
867 let _indenter = indenter();
869 // Consts can play a role in type-checking, so they are included here.
870 hir::ItemStatic(..) |
871 hir::ItemConst(..) => {
872 tcx.item_tables(tcx.hir.local_def_id(it.id));
874 hir::ItemEnum(ref enum_definition, _) => {
877 &enum_definition.variants,
880 hir::ItemFn(..) => {} // entirely within check_item_body
881 hir::ItemImpl(.., ref impl_item_refs) => {
882 debug!("ItemImpl {} with id {}", it.name, it.id);
883 let impl_def_id = tcx.hir.local_def_id(it.id);
884 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
885 check_impl_items_against_trait(tcx,
890 let trait_def_id = impl_trait_ref.def_id;
891 check_on_unimplemented(tcx, trait_def_id, it);
894 hir::ItemTrait(..) => {
895 let def_id = tcx.hir.local_def_id(it.id);
896 check_on_unimplemented(tcx, def_id, it);
898 hir::ItemStruct(..) => {
899 check_struct(tcx, it.id, it.span);
901 hir::ItemUnion(..) => {
902 check_union(tcx, it.id, it.span);
904 hir::ItemTy(_, ref generics) => {
905 let def_id = tcx.hir.local_def_id(it.id);
906 let pty_ty = tcx.item_type(def_id);
907 check_bounds_are_used(tcx, generics, pty_ty);
909 hir::ItemForeignMod(ref m) => {
910 check_abi(tcx, it.span, m.abi);
912 if m.abi == Abi::RustIntrinsic {
913 for item in &m.items {
914 intrinsic::check_intrinsic_type(tcx, item);
916 } else if m.abi == Abi::PlatformIntrinsic {
917 for item in &m.items {
918 intrinsic::check_platform_intrinsic_type(tcx, item);
921 for item in &m.items {
922 let generics = tcx.item_generics(tcx.hir.local_def_id(item.id));
923 if !generics.types.is_empty() {
924 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
925 "foreign items may not have type parameters");
926 span_help!(&mut err, item.span,
927 "consider using specialization instead of \
932 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
933 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
938 _ => {/* nothing to do */ }
942 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
945 let generics = tcx.item_generics(def_id);
946 if let Some(ref attr) = item.attrs.iter().find(|a| {
947 a.check_name("rustc_on_unimplemented")
949 if let Some(istring) = attr.value_str() {
950 let istring = istring.as_str();
951 let parser = Parser::new(&istring);
952 let types = &generics.types;
953 for token in parser {
955 Piece::String(_) => (), // Normal string, no need to check it
956 Piece::NextArgument(a) => match a.position {
957 // `{Self}` is allowed
958 Position::ArgumentNamed(s) if s == "Self" => (),
959 // So is `{A}` if A is a type parameter
960 Position::ArgumentNamed(s) => match types.iter().find(|t| {
965 let name = tcx.item_name(def_id);
966 span_err!(tcx.sess, attr.span, E0230,
967 "there is no type parameter \
972 // `{:1}` and `{}` are not to be used
973 Position::ArgumentIs(_) => {
974 span_err!(tcx.sess, attr.span, E0231,
975 "only named substitution \
976 parameters are allowed");
983 tcx.sess, attr.span, E0232,
984 "this attribute must have a value")
985 .span_label(attr.span, &format!("attribute requires a value"))
986 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
992 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
993 impl_item: &hir::ImplItem,
996 let mut err = struct_span_err!(
997 tcx.sess, impl_item.span, E0520,
998 "`{}` specializes an item from a parent `impl`, but \
999 that item is not marked `default`",
1001 err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
1004 match tcx.span_of_impl(parent_impl) {
1006 err.span_label(span, &"parent `impl` is here");
1007 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1011 err.note(&format!("parent implementation is in crate `{}`", cname));
1018 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1019 trait_def: &ty::TraitDef,
1021 impl_item: &hir::ImplItem)
1023 let ancestors = trait_def.ancestors(impl_id);
1025 let kind = match impl_item.node {
1026 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1027 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1028 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1030 let parent = ancestors.defs(tcx, impl_item.name, kind).skip(1).next()
1031 .map(|node_item| node_item.map(|parent| parent.defaultness));
1033 if let Some(parent) = parent {
1034 if parent.item.is_final() {
1035 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1041 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1044 impl_trait_ref: ty::TraitRef<'tcx>,
1045 impl_item_refs: &[hir::ImplItemRef]) {
1046 // If the trait reference itself is erroneous (so the compilation is going
1047 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1048 // isn't populated for such impls.
1049 if impl_trait_ref.references_error() { return; }
1051 // Locate trait definition and items
1052 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
1053 let mut overridden_associated_type = None;
1055 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1057 // Check existing impl methods to see if they are both present in trait
1058 // and compatible with trait signature
1059 for impl_item in impl_items() {
1060 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1061 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1062 .find(|ac| ac.name == ty_impl_item.name);
1064 // Check that impl definition matches trait definition
1065 if let Some(ty_trait_item) = ty_trait_item {
1066 match impl_item.node {
1067 hir::ImplItemKind::Const(..) => {
1068 // Find associated const definition.
1069 if ty_trait_item.kind == ty::AssociatedKind::Const {
1070 compare_const_impl(tcx,
1076 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1077 "item `{}` is an associated const, \
1078 which doesn't match its trait `{}`",
1081 err.span_label(impl_item.span, &format!("does not match trait"));
1082 // We can only get the spans from local trait definition
1083 // Same for E0324 and E0325
1084 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1085 err.span_label(trait_span, &format!("item in trait"));
1090 hir::ImplItemKind::Method(_, body_id) => {
1091 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1092 if ty_trait_item.kind == ty::AssociatedKind::Method {
1093 let err_count = tcx.sess.err_count();
1094 compare_impl_method(tcx,
1101 true); // start with old-broken-mode
1102 if err_count == tcx.sess.err_count() {
1103 // old broken mode did not report an error. Try with the new mode.
1104 compare_impl_method(tcx,
1111 false); // use the new mode
1114 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1115 "item `{}` is an associated method, \
1116 which doesn't match its trait `{}`",
1119 err.span_label(impl_item.span, &format!("does not match trait"));
1120 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1121 err.span_label(trait_span, &format!("item in trait"));
1126 hir::ImplItemKind::Type(_) => {
1127 if ty_trait_item.kind == ty::AssociatedKind::Type {
1128 if ty_trait_item.defaultness.has_value() {
1129 overridden_associated_type = Some(impl_item);
1132 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1133 "item `{}` is an associated type, \
1134 which doesn't match its trait `{}`",
1137 err.span_label(impl_item.span, &format!("does not match trait"));
1138 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1139 err.span_label(trait_span, &format!("item in trait"));
1147 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1150 // Check for missing items from trait
1151 let mut missing_items = Vec::new();
1152 let mut invalidated_items = Vec::new();
1153 let associated_type_overridden = overridden_associated_type.is_some();
1154 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1155 let is_implemented = trait_def.ancestors(impl_id)
1156 .defs(tcx, trait_item.name, trait_item.kind)
1158 .map(|node_item| !node_item.node.is_from_trait())
1161 if !is_implemented {
1162 if !trait_item.defaultness.has_value() {
1163 missing_items.push(trait_item);
1164 } else if associated_type_overridden {
1165 invalidated_items.push(trait_item.name);
1170 let signature = |item: &ty::AssociatedItem| {
1172 ty::AssociatedKind::Method => {
1173 format!("{}", tcx.item_type(item.def_id).fn_sig().0)
1175 ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
1176 ty::AssociatedKind::Const => {
1177 format!("const {}: {:?};", item.name.to_string(), tcx.item_type(item.def_id))
1182 if !missing_items.is_empty() {
1183 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1184 "not all trait items implemented, missing: `{}`",
1185 missing_items.iter()
1186 .map(|trait_item| trait_item.name.to_string())
1187 .collect::<Vec<_>>().join("`, `"));
1188 err.span_label(impl_span, &format!("missing `{}` in implementation",
1189 missing_items.iter()
1190 .map(|trait_item| trait_item.name.to_string())
1191 .collect::<Vec<_>>().join("`, `")));
1192 for trait_item in missing_items {
1193 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1194 err.span_label(span, &format!("`{}` from trait", trait_item.name));
1196 err.note(&format!("`{}` from trait: `{}`",
1198 signature(&trait_item)));
1204 if !invalidated_items.is_empty() {
1205 let invalidator = overridden_associated_type.unwrap();
1206 span_err!(tcx.sess, invalidator.span, E0399,
1207 "the following trait items need to be reimplemented \
1208 as `{}` was overridden: `{}`",
1210 invalidated_items.iter()
1211 .map(|name| name.to_string())
1212 .collect::<Vec<_>>().join("`, `"))
1216 /// Checks whether a type can be represented in memory. In particular, it
1217 /// identifies types that contain themselves without indirection through a
1218 /// pointer, which would mean their size is unbounded.
1219 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1223 let rty = tcx.item_type(item_def_id);
1225 // Check that it is possible to represent this type. This call identifies
1226 // (1) types that contain themselves and (2) types that contain a different
1227 // recursive type. It is only necessary to throw an error on those that
1228 // contain themselves. For case 2, there must be an inner type that will be
1229 // caught by case 1.
1230 match rty.is_representable(tcx, sp) {
1231 Representability::SelfRecursive => {
1232 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1235 Representability::Representable | Representability::ContainsRecursive => (),
1240 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1241 let t = tcx.item_type(def_id);
1243 ty::TyAdt(def, substs) if def.is_struct() => {
1244 let fields = &def.struct_variant().fields;
1245 if fields.is_empty() {
1246 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1249 let e = fields[0].ty(tcx, substs);
1250 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1251 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1252 .span_label(sp, &format!("SIMD elements must have the same type"))
1257 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1258 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1260 span_err!(tcx.sess, sp, E0077,
1261 "SIMD vector element type should be machine type");
1270 #[allow(trivial_numeric_casts)]
1271 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1273 vs: &'tcx [hir::Variant],
1275 let def_id = tcx.hir.local_def_id(id);
1276 let def = tcx.lookup_adt_def(def_id);
1277 def.destructor(tcx); // force the destructor to be evaluated
1279 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1281 tcx.sess, sp, E0084,
1282 "unsupported representation for zero-variant enum")
1283 .span_label(sp, &format!("unsupported enum representation"))
1287 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1288 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1289 if !tcx.sess.features.borrow().i128_type {
1290 emit_feature_err(&tcx.sess.parse_sess,
1291 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1296 if let Some(e) = v.node.disr_expr {
1297 tcx.item_tables(tcx.hir.local_def_id(e.node_id));
1301 let mut disr_vals: Vec<ConstInt> = Vec::new();
1302 for (discr, v) in def.discriminants(tcx).zip(vs) {
1303 // Check for duplicate discriminant values
1304 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1305 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1306 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1307 let i_span = match variant_i.node.disr_expr {
1308 Some(expr) => tcx.hir.span(expr.node_id),
1309 None => tcx.hir.span(variant_i_node_id)
1311 let span = match v.node.disr_expr {
1312 Some(expr) => tcx.hir.span(expr.node_id),
1315 struct_span_err!(tcx.sess, span, E0081,
1316 "discriminant value `{}` already exists", disr_vals[i])
1317 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1318 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1321 disr_vals.push(discr);
1324 check_representable(tcx, sp, def_id);
1327 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1328 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1330 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1331 &self.ast_ty_to_ty_cache
1334 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1335 Some(&self.parameter_environment.free_substs)
1338 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1339 -> ty::GenericPredicates<'tcx>
1342 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1343 let item_id = tcx.hir.ty_param_owner(node_id);
1344 let item_def_id = tcx.hir.local_def_id(item_id);
1345 let generics = tcx.item_generics(item_def_id);
1346 let index = generics.type_param_to_index[&def_id.index];
1347 ty::GenericPredicates {
1349 predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| {
1351 ty::Predicate::Trait(ref data) => {
1352 data.0.self_ty().is_param(index)
1356 }).cloned().collect()
1360 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1361 -> Option<&'tcx ty::Region> {
1363 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1364 None => infer::MiscVariable(span)
1366 Some(self.next_region_var(v))
1369 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1370 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1373 fn ty_infer_for_def(&self,
1374 ty_param_def: &ty::TypeParameterDef,
1375 substs: &[Kind<'tcx>],
1376 span: Span) -> Ty<'tcx> {
1377 self.type_var_for_def(span, ty_param_def, substs)
1380 fn projected_ty_from_poly_trait_ref(&self,
1382 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1383 item_name: ast::Name)
1386 let (trait_ref, _) =
1387 self.replace_late_bound_regions_with_fresh_var(
1389 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1392 self.tcx().mk_projection(trait_ref, item_name)
1395 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1396 if ty.has_escaping_regions() {
1397 ty // FIXME: normalization and escaping regions
1399 self.normalize_associated_types_in(span, &ty)
1403 fn set_tainted_by_errors(&self) {
1404 self.infcx.set_tainted_by_errors()
1408 /// Controls whether the arguments are tupled. This is used for the call
1411 /// Tupling means that all call-side arguments are packed into a tuple and
1412 /// passed as a single parameter. For example, if tupling is enabled, this
1415 /// fn f(x: (isize, isize))
1417 /// Can be called as:
1424 #[derive(Clone, Eq, PartialEq)]
1425 enum TupleArgumentsFlag {
1430 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1431 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1432 rty: Option<Ty<'tcx>>,
1433 body_id: ast::NodeId)
1434 -> FnCtxt<'a, 'gcx, 'tcx> {
1436 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1438 err_count_on_creation: inh.tcx.sess.err_count(),
1440 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1441 ast::CRATE_NODE_ID)),
1442 diverges: Cell::new(Diverges::Maybe),
1443 has_errors: Cell::new(false),
1444 enclosing_breakables: RefCell::new(EnclosingBreakables {
1452 pub fn sess(&self) -> &Session {
1456 pub fn err_count_since_creation(&self) -> usize {
1457 self.tcx.sess.err_count() - self.err_count_on_creation
1460 /// Produce warning on the given node, if the current point in the
1461 /// function is unreachable, and there hasn't been another warning.
1462 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1463 if self.diverges.get() == Diverges::Always {
1464 self.diverges.set(Diverges::WarnedAlways);
1466 self.tables.borrow_mut().lints.add_lint(
1467 lint::builtin::UNREACHABLE_CODE,
1469 format!("unreachable {}", kind));
1475 code: ObligationCauseCode<'tcx>)
1476 -> ObligationCause<'tcx> {
1477 ObligationCause::new(span, self.body_id, code)
1480 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1481 self.cause(span, ObligationCauseCode::MiscObligation)
1484 /// Resolves type variables in `ty` if possible. Unlike the infcx
1485 /// version (resolve_type_vars_if_possible), this version will
1486 /// also select obligations if it seems useful, in an effort
1487 /// to get more type information.
1488 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1489 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1491 // No TyInfer()? Nothing needs doing.
1492 if !ty.has_infer_types() {
1493 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1497 // If `ty` is a type variable, see whether we already know what it is.
1498 ty = self.resolve_type_vars_if_possible(&ty);
1499 if !ty.has_infer_types() {
1500 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1504 // If not, try resolving pending obligations as much as
1505 // possible. This can help substantially when there are
1506 // indirect dependencies that don't seem worth tracking
1508 self.select_obligations_where_possible();
1509 ty = self.resolve_type_vars_if_possible(&ty);
1511 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1515 fn record_deferred_call_resolution(&self,
1516 closure_def_id: DefId,
1517 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1518 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1519 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1522 fn remove_deferred_call_resolutions(&self,
1523 closure_def_id: DefId)
1524 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1526 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1527 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1530 pub fn tag(&self) -> String {
1531 let self_ptr: *const FnCtxt = self;
1532 format!("{:?}", self_ptr)
1535 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1536 match self.locals.borrow().get(&nid) {
1539 span_bug!(span, "no type for local variable {}",
1540 self.tcx.hir.node_to_string(nid));
1546 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1547 debug!("write_ty({}, {:?}) in fcx {}",
1548 node_id, self.resolve_type_vars_if_possible(&ty), self.tag());
1549 self.tables.borrow_mut().node_types.insert(node_id, ty);
1551 if ty.references_error() {
1552 self.has_errors.set(true);
1553 self.set_tainted_by_errors();
1557 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1558 if !substs.substs.is_noop() {
1559 debug!("write_substs({}, {:?}) in fcx {}",
1564 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1568 pub fn write_autoderef_adjustment(&self,
1569 node_id: ast::NodeId,
1571 adjusted_ty: Ty<'tcx>) {
1572 self.write_adjustment(node_id, adjustment::Adjustment {
1573 kind: adjustment::Adjust::DerefRef {
1582 pub fn write_adjustment(&self,
1583 node_id: ast::NodeId,
1584 adj: adjustment::Adjustment<'tcx>) {
1585 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1587 if adj.is_identity() {
1591 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1594 /// Basically whenever we are converting from a type scheme into
1595 /// the fn body space, we always want to normalize associated
1596 /// types as well. This function combines the two.
1597 fn instantiate_type_scheme<T>(&self,
1599 substs: &Substs<'tcx>,
1602 where T : TypeFoldable<'tcx>
1604 let value = value.subst(self.tcx, substs);
1605 let result = self.normalize_associated_types_in(span, &value);
1606 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1613 /// As `instantiate_type_scheme`, but for the bounds found in a
1614 /// generic type scheme.
1615 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1616 -> ty::InstantiatedPredicates<'tcx> {
1617 let bounds = self.tcx.item_predicates(def_id);
1618 let result = bounds.instantiate(self.tcx, substs);
1619 let result = self.normalize_associated_types_in(span, &result.predicates);
1620 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1624 ty::InstantiatedPredicates {
1629 /// Replace all anonymized types with fresh inference variables
1630 /// and record them for writeback.
1631 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1632 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1633 if let ty::TyAnon(def_id, substs) = ty.sty {
1634 // Use the same type variable if the exact same TyAnon appears more
1635 // than once in the return type (e.g. if it's pased to a type alias).
1636 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1637 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1640 let span = self.tcx.def_span(def_id);
1641 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1642 self.anon_types.borrow_mut().insert(id, ty_var);
1644 let item_predicates = self.tcx.item_predicates(def_id);
1645 let bounds = item_predicates.instantiate(self.tcx, substs);
1647 for predicate in bounds.predicates {
1648 // Change the predicate to refer to the type variable,
1649 // which will be the concrete type, instead of the TyAnon.
1650 // This also instantiates nested `impl Trait`.
1651 let predicate = self.instantiate_anon_types(&predicate);
1653 // Require that the predicate holds for the concrete type.
1654 let cause = traits::ObligationCause::new(span, self.body_id,
1655 traits::ReturnType);
1656 self.register_predicate(traits::Obligation::new(cause, predicate));
1666 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1667 where T : TypeFoldable<'tcx>
1669 self.inh.normalize_associated_types_in(span, self.body_id, value)
1672 pub fn write_nil(&self, node_id: ast::NodeId) {
1673 self.write_ty(node_id, self.tcx.mk_nil());
1676 pub fn write_error(&self, node_id: ast::NodeId) {
1677 self.write_ty(node_id, self.tcx.types.err);
1680 pub fn require_type_meets(&self,
1683 code: traits::ObligationCauseCode<'tcx>,
1686 self.register_bound(
1689 traits::ObligationCause::new(span, self.body_id, code));
1692 pub fn require_type_is_sized(&self,
1695 code: traits::ObligationCauseCode<'tcx>)
1697 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1698 self.require_type_meets(ty, span, code, lang_item);
1701 pub fn register_bound(&self,
1704 cause: traits::ObligationCause<'tcx>)
1706 self.fulfillment_cx.borrow_mut()
1707 .register_bound(self, ty, def_id, cause);
1710 pub fn register_predicate(&self,
1711 obligation: traits::PredicateObligation<'tcx>)
1713 debug!("register_predicate({:?})", obligation);
1714 if obligation.has_escaping_regions() {
1715 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
1720 .register_predicate_obligation(self, obligation);
1723 pub fn register_predicates(&self,
1724 obligations: Vec<traits::PredicateObligation<'tcx>>)
1726 for obligation in obligations {
1727 self.register_predicate(obligation);
1731 pub fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
1732 self.register_predicates(infer_ok.obligations);
1736 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1737 let t = AstConv::ast_ty_to_ty(self, ast_t);
1738 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1742 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1743 match self.tables.borrow().node_types.get(&id) {
1745 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1747 bug!("no type for node {}: {} in fcx {}",
1748 id, self.tcx.hir.node_to_string(id),
1754 pub fn opt_node_ty_substs<F>(&self,
1757 F: FnOnce(&ty::ItemSubsts<'tcx>),
1759 if let Some(s) = self.tables.borrow().item_substs.get(&id) {
1764 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1765 /// outlive the region `r`.
1766 pub fn register_region_obligation(&self,
1768 region: &'tcx ty::Region,
1769 cause: traits::ObligationCause<'tcx>)
1771 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1772 fulfillment_cx.register_region_obligation(ty, region, cause);
1775 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1776 /// outlive the region `r`.
1777 pub fn register_wf_obligation(&self,
1780 code: traits::ObligationCauseCode<'tcx>)
1782 // WF obligations never themselves fail, so no real need to give a detailed cause:
1783 let cause = traits::ObligationCause::new(span, self.body_id, code);
1784 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1787 pub fn register_old_wf_obligation(&self,
1790 code: traits::ObligationCauseCode<'tcx>)
1792 // Registers an "old-style" WF obligation that uses the
1793 // implicator code. This is basically a buggy version of
1794 // `register_wf_obligation` that is being kept around
1795 // temporarily just to help with phasing in the newer rules.
1797 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1798 let cause = traits::ObligationCause::new(span, self.body_id, code);
1799 self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
1802 /// Registers obligations that all types appearing in `substs` are well-formed.
1803 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1805 for ty in substs.types() {
1806 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1810 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1811 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1812 /// trait/region obligations.
1814 /// For example, if there is a function:
1817 /// fn foo<'a,T:'a>(...)
1820 /// and a reference:
1826 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1827 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1828 pub fn add_obligations_for_parameters(&self,
1829 cause: traits::ObligationCause<'tcx>,
1830 predicates: &ty::InstantiatedPredicates<'tcx>)
1832 assert!(!predicates.has_escaping_regions());
1834 debug!("add_obligations_for_parameters(predicates={:?})",
1837 for obligation in traits::predicates_for_generics(cause, predicates) {
1838 self.register_predicate(obligation);
1842 // FIXME(arielb1): use this instead of field.ty everywhere
1843 // Only for fields! Returns <none> for methods>
1844 // Indifferent to privacy flags
1845 pub fn field_ty(&self,
1847 field: &'tcx ty::FieldDef,
1848 substs: &Substs<'tcx>)
1851 self.normalize_associated_types_in(span,
1852 &field.ty(self.tcx, substs))
1855 fn check_casts(&self) {
1856 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1857 for cast in deferred_cast_checks.drain(..) {
1862 /// Apply "fallbacks" to some types
1863 /// unconstrained types get replaced with ! or () (depending on whether
1864 /// feature(never_type) is enabled), unconstrained ints with i32, and
1865 /// unconstrained floats with f64.
1866 fn default_type_parameters(&self) {
1867 use rustc::ty::error::UnconstrainedNumeric::Neither;
1868 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1870 // Defaulting inference variables becomes very dubious if we have
1871 // encountered type-checking errors. Therefore, if we think we saw
1872 // some errors in this function, just resolve all uninstanted type
1873 // varibles to TyError.
1874 if self.is_tainted_by_errors() {
1875 for ty in &self.unsolved_variables() {
1876 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1877 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1878 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
1884 for ty in &self.unsolved_variables() {
1885 let resolved = self.resolve_type_vars_if_possible(ty);
1886 if self.type_var_diverges(resolved) {
1887 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
1889 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1890 self.tcx.mk_diverging_default());
1892 match self.type_is_unconstrained_numeric(resolved) {
1893 UnconstrainedInt => {
1894 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1896 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
1898 UnconstrainedFloat => {
1899 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1901 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
1909 fn select_all_obligations_and_apply_defaults(&self) {
1910 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
1911 self.new_select_all_obligations_and_apply_defaults();
1913 self.old_select_all_obligations_and_apply_defaults();
1917 // Implements old type inference fallback algorithm
1918 fn old_select_all_obligations_and_apply_defaults(&self) {
1919 self.select_obligations_where_possible();
1920 self.default_type_parameters();
1921 self.select_obligations_where_possible();
1924 fn new_select_all_obligations_and_apply_defaults(&self) {
1925 use rustc::ty::error::UnconstrainedNumeric::Neither;
1926 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1928 // For the time being this errs on the side of being memory wasteful but provides better
1930 // let type_variables = self.type_variables.clone();
1932 // There is a possibility that this algorithm will have to run an arbitrary number of times
1933 // to terminate so we bound it by the compiler's recursion limit.
1934 for _ in 0..self.tcx.sess.recursion_limit.get() {
1935 // First we try to solve all obligations, it is possible that the last iteration
1936 // has made it possible to make more progress.
1937 self.select_obligations_where_possible();
1939 let mut conflicts = Vec::new();
1941 // Collect all unsolved type, integral and floating point variables.
1942 let unsolved_variables = self.unsolved_variables();
1944 // We must collect the defaults *before* we do any unification. Because we have
1945 // directly attached defaults to the type variables any unification that occurs
1946 // will erase defaults causing conflicting defaults to be completely ignored.
1947 let default_map: FxHashMap<Ty<'tcx>, _> =
1950 .filter_map(|t| self.default(t).map(|d| (*t, d)))
1953 let mut unbound_tyvars = FxHashSet();
1955 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1957 // We loop over the unsolved variables, resolving them and if they are
1958 // and unconstrainted numeric type we add them to the set of unbound
1959 // variables. We do this so we only apply literal fallback to type
1960 // variables without defaults.
1961 for ty in &unsolved_variables {
1962 let resolved = self.resolve_type_vars_if_possible(ty);
1963 if self.type_var_diverges(resolved) {
1964 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1965 self.tcx.mk_diverging_default());
1967 match self.type_is_unconstrained_numeric(resolved) {
1968 UnconstrainedInt | UnconstrainedFloat => {
1969 unbound_tyvars.insert(resolved);
1976 // We now remove any numeric types that also have defaults, and instead insert
1977 // the type variable with a defined fallback.
1978 for ty in &unsolved_variables {
1979 if let Some(_default) = default_map.get(ty) {
1980 let resolved = self.resolve_type_vars_if_possible(ty);
1982 debug!("select_all_obligations_and_apply_defaults: \
1983 ty: {:?} with default: {:?}",
1986 match resolved.sty {
1987 ty::TyInfer(ty::TyVar(_)) => {
1988 unbound_tyvars.insert(ty);
1991 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1992 unbound_tyvars.insert(ty);
1993 if unbound_tyvars.contains(resolved) {
1994 unbound_tyvars.remove(resolved);
2003 // If there are no more fallbacks to apply at this point we have applied all possible
2004 // defaults and type inference will proceed as normal.
2005 if unbound_tyvars.is_empty() {
2009 // Finally we go through each of the unbound type variables and unify them with
2010 // the proper fallback, reporting a conflicting default error if any of the
2011 // unifications fail. We know it must be a conflicting default because the
2012 // variable would only be in `unbound_tyvars` and have a concrete value if
2013 // it had been solved by previously applying a default.
2015 // We wrap this in a transaction for error reporting, if we detect a conflict
2016 // we will rollback the inference context to its prior state so we can probe
2017 // for conflicts and correctly report them.
2019 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2021 self.apply_defaults_and_return_conflicts(&unbound_tyvars, &default_map, None)
2024 // If there are conflicts we rollback, otherwise commit
2025 if conflicts.len() > 0 {
2032 // Loop through each conflicting default, figuring out the default that caused
2033 // a unification failure and then report an error for each.
2034 for (conflict, default) in conflicts {
2035 let conflicting_default =
2036 self.apply_defaults_and_return_conflicts(
2043 .unwrap_or(type_variable::Default {
2044 ty: self.next_ty_var(
2045 TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)),
2046 origin_span: syntax_pos::DUMMY_SP,
2047 // what do I put here?
2048 def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID)
2051 // This is to ensure that we elimnate any non-determinism from the error
2052 // reporting by fixing an order, it doesn't matter what order we choose
2053 // just that it is consistent.
2054 let (first_default, second_default) =
2055 if default.def_id < conflicting_default.def_id {
2056 (default, conflicting_default)
2058 (conflicting_default, default)
2062 self.report_conflicting_default_types(
2063 first_default.origin_span,
2070 self.select_obligations_where_possible();
2073 // For use in error handling related to default type parameter fallback. We explicitly
2074 // apply the default that caused conflict first to a local version of the type variable
2075 // table then apply defaults until we find a conflict. That default must be the one
2076 // that caused conflict earlier.
2077 fn apply_defaults_and_return_conflicts<'b>(
2079 unbound_vars: &'b FxHashSet<Ty<'tcx>>,
2080 default_map: &'b FxHashMap<Ty<'tcx>, type_variable::Default<'tcx>>,
2081 conflict: Option<Ty<'tcx>>,
2082 ) -> impl Iterator<Item=(Ty<'tcx>, type_variable::Default<'tcx>)> + 'b {
2083 use rustc::ty::error::UnconstrainedNumeric::Neither;
2084 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2086 conflict.into_iter().chain(unbound_vars.iter().cloned()).flat_map(move |ty| {
2087 if self.type_var_diverges(ty) {
2088 self.demand_eqtype(syntax_pos::DUMMY_SP, ty,
2089 self.tcx.mk_diverging_default());
2091 match self.type_is_unconstrained_numeric(ty) {
2092 UnconstrainedInt => {
2093 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.i32)
2095 UnconstrainedFloat => {
2096 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.f64)
2099 if let Some(default) = default_map.get(ty) {
2100 let default = default.clone();
2101 let default_ty = self.normalize_associated_types_in(
2102 default.origin_span, &default.ty);
2103 match self.eq_types(false,
2104 &self.misc(default.origin_span),
2107 Ok(ok) => self.register_infer_ok_obligations(ok),
2109 return Some((ty, default));
2121 fn select_all_obligations_or_error(&self) {
2122 debug!("select_all_obligations_or_error");
2124 // upvar inference should have ensured that all deferred call
2125 // resolutions are handled by now.
2126 assert!(self.deferred_call_resolutions.borrow().is_empty());
2128 self.select_all_obligations_and_apply_defaults();
2130 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2132 match fulfillment_cx.select_all_or_error(self) {
2134 Err(errors) => { self.report_fulfillment_errors(&errors); }
2138 /// Select as many obligations as we can at present.
2139 fn select_obligations_where_possible(&self) {
2140 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2142 Err(errors) => { self.report_fulfillment_errors(&errors); }
2146 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2147 /// returns a type of `&T`, but the actual type we assign to the
2148 /// *expression* is `T`. So this function just peels off the return
2149 /// type by one layer to yield `T`.
2150 fn make_overloaded_lvalue_return_type(&self,
2151 method: MethodCallee<'tcx>)
2152 -> ty::TypeAndMut<'tcx>
2154 // extract method return type, which will be &T;
2155 // all LB regions should have been instantiated during method lookup
2156 let ret_ty = method.ty.fn_ret();
2157 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2159 // method returns &T, but the type as visible to user is T, so deref
2160 ret_ty.builtin_deref(true, NoPreference).unwrap()
2163 fn lookup_indexing(&self,
2165 base_expr: &'gcx hir::Expr,
2168 lvalue_pref: LvaluePreference)
2169 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2171 // FIXME(#18741) -- this is almost but not quite the same as the
2172 // autoderef that normal method probing does. They could likely be
2175 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2177 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2178 if let Some(final_mt) = self.try_index_step(
2179 MethodCall::expr(expr.id),
2180 expr, base_expr, adj_ty, autoderefs,
2181 false, lvalue_pref, idx_ty)
2183 autoderef.finalize(lvalue_pref, Some(base_expr));
2184 return Some(final_mt);
2187 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2188 autoderef.finalize(lvalue_pref, Some(base_expr));
2189 let adjusted_ty = self.tcx.mk_slice(element_ty);
2190 return self.try_index_step(
2191 MethodCall::expr(expr.id), expr, base_expr,
2192 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2195 autoderef.unambiguous_final_ty();
2199 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2200 /// (and otherwise adjust) `base_expr`, looking for a type which either
2201 /// supports builtin indexing or overloaded indexing.
2202 /// This loop implements one step in that search; the autoderef loop
2203 /// is implemented by `lookup_indexing`.
2204 fn try_index_step(&self,
2205 method_call: MethodCall,
2207 base_expr: &'gcx hir::Expr,
2208 adjusted_ty: Ty<'tcx>,
2211 lvalue_pref: LvaluePreference,
2213 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2216 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2217 autoderefs={}, unsize={}, index_ty={:?})",
2225 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2227 // First, try built-in indexing.
2228 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2229 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2230 debug!("try_index_step: success, using built-in indexing");
2231 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2233 self.write_autoderef_adjustment(base_expr.id, autoderefs, adjusted_ty);
2234 return Some((tcx.types.usize, ty));
2239 // Try `IndexMut` first, if preferred.
2240 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2241 (PreferMutLvalue, Some(trait_did)) => {
2242 self.lookup_method_in_trait_adjusted(expr.span,
2244 Symbol::intern("index_mut"),
2249 Some(vec![input_ty]))
2254 // Otherwise, fall back to `Index`.
2255 let method = match (method, tcx.lang_items.index_trait()) {
2256 (None, Some(trait_did)) => {
2257 self.lookup_method_in_trait_adjusted(expr.span,
2259 Symbol::intern("index"),
2264 Some(vec![input_ty]))
2266 (method, _) => method,
2269 // If some lookup succeeds, write callee into table and extract index/element
2270 // type from the method signature.
2271 // If some lookup succeeded, install method in table
2272 method.map(|method| {
2273 debug!("try_index_step: success, using overloaded indexing");
2274 self.tables.borrow_mut().method_map.insert(method_call, method);
2275 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2279 fn check_method_argument_types(&self,
2281 method_fn_ty: Ty<'tcx>,
2282 callee_expr: &'gcx hir::Expr,
2283 args_no_rcvr: &'gcx [hir::Expr],
2284 tuple_arguments: TupleArgumentsFlag,
2285 expected: Expectation<'tcx>)
2287 if method_fn_ty.references_error() {
2288 let err_inputs = self.err_args(args_no_rcvr.len());
2290 let err_inputs = match tuple_arguments {
2291 DontTupleArguments => err_inputs,
2292 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2295 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2296 false, tuple_arguments, None);
2299 match method_fn_ty.sty {
2300 ty::TyFnDef(def_id, .., ref fty) => {
2301 // HACK(eddyb) ignore self in the definition (see above).
2302 let expected_arg_tys = self.expected_inputs_for_expected_output(
2306 &fty.0.inputs()[1..]
2308 self.check_argument_types(sp, &fty.0.inputs()[1..], &expected_arg_tys[..],
2309 args_no_rcvr, fty.0.variadic, tuple_arguments,
2310 self.tcx.hir.span_if_local(def_id));
2314 span_bug!(callee_expr.span, "method without bare fn type");
2320 /// Generic function that factors out common logic from function calls,
2321 /// method calls and overloaded operators.
2322 fn check_argument_types(&self,
2324 fn_inputs: &[Ty<'tcx>],
2325 expected_arg_tys: &[Ty<'tcx>],
2326 args: &'gcx [hir::Expr],
2328 tuple_arguments: TupleArgumentsFlag,
2329 def_span: Option<Span>) {
2332 // Grab the argument types, supplying fresh type variables
2333 // if the wrong number of arguments were supplied
2334 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2340 // All the input types from the fn signature must outlive the call
2341 // so as to validate implied bounds.
2342 for &fn_input_ty in fn_inputs {
2343 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2346 let mut expected_arg_tys = expected_arg_tys;
2347 let expected_arg_count = fn_inputs.len();
2349 let sp_args = if args.len() > 0 {
2350 let (first, args) = args.split_at(1);
2351 let mut sp_tmp = first[0].span;
2353 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2354 if ! sp_opt.is_some() {
2357 sp_tmp = sp_opt.unwrap();
2364 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2365 arg_count: usize, error_code: &str, variadic: bool,
2366 def_span: Option<Span>) {
2367 let mut err = sess.struct_span_err_with_code(sp,
2368 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2369 if variadic {"at least "} else {""},
2371 if expected_count == 1 {""} else {"s"},
2373 if arg_count == 1 {" was"} else {"s were"}),
2376 err.span_label(sp, &format!("expected {}{} parameter{}",
2377 if variadic {"at least "} else {""},
2379 if expected_count == 1 {""} else {"s"}));
2380 if let Some(def_s) = def_span {
2381 err.span_label(def_s, &format!("defined here"));
2386 let formal_tys = if tuple_arguments == TupleArguments {
2387 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2388 match tuple_type.sty {
2389 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2390 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2391 "E0057", false, def_span);
2392 expected_arg_tys = &[];
2393 self.err_args(args.len())
2395 ty::TyTuple(arg_types, _) => {
2396 expected_arg_tys = match expected_arg_tys.get(0) {
2397 Some(&ty) => match ty.sty {
2398 ty::TyTuple(ref tys, _) => &tys,
2406 span_err!(tcx.sess, sp, E0059,
2407 "cannot use call notation; the first type parameter \
2408 for the function trait is neither a tuple nor unit");
2409 expected_arg_tys = &[];
2410 self.err_args(args.len())
2413 } else if expected_arg_count == supplied_arg_count {
2415 } else if variadic {
2416 if supplied_arg_count >= expected_arg_count {
2419 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2420 supplied_arg_count, "E0060", true, def_span);
2421 expected_arg_tys = &[];
2422 self.err_args(supplied_arg_count)
2425 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2426 supplied_arg_count, "E0061", false, def_span);
2427 expected_arg_tys = &[];
2428 self.err_args(supplied_arg_count)
2431 debug!("check_argument_types: formal_tys={:?}",
2432 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2434 // Check the arguments.
2435 // We do this in a pretty awful way: first we typecheck any arguments
2436 // that are not closures, then we typecheck the closures. This is so
2437 // that we have more information about the types of arguments when we
2438 // typecheck the functions. This isn't really the right way to do this.
2439 for &check_closures in &[false, true] {
2440 debug!("check_closures={}", check_closures);
2442 // More awful hacks: before we check argument types, try to do
2443 // an "opportunistic" vtable resolution of any trait bounds on
2444 // the call. This helps coercions.
2446 self.select_obligations_where_possible();
2449 // For variadic functions, we don't have a declared type for all of
2450 // the arguments hence we only do our usual type checking with
2451 // the arguments who's types we do know.
2452 let t = if variadic {
2454 } else if tuple_arguments == TupleArguments {
2459 for (i, arg) in args.iter().take(t).enumerate() {
2460 // Warn only for the first loop (the "no closures" one).
2461 // Closure arguments themselves can't be diverging, but
2462 // a previous argument can, e.g. `foo(panic!(), || {})`.
2463 if !check_closures {
2464 self.warn_if_unreachable(arg.id, arg.span, "expression");
2467 let is_closure = match arg.node {
2468 hir::ExprClosure(..) => true,
2472 if is_closure != check_closures {
2476 debug!("checking the argument");
2477 let formal_ty = formal_tys[i];
2479 // The special-cased logic below has three functions:
2480 // 1. Provide as good of an expected type as possible.
2481 let expected = expected_arg_tys.get(i).map(|&ty| {
2482 Expectation::rvalue_hint(self, ty)
2485 let checked_ty = self.check_expr_with_expectation(&arg,
2486 expected.unwrap_or(ExpectHasType(formal_ty)));
2487 // 2. Coerce to the most detailed type that could be coerced
2488 // to, which is `expected_ty` if `rvalue_hint` returns an
2489 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2490 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2491 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2493 // 3. Relate the expected type and the formal one,
2494 // if the expected type was used for the coercion.
2495 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2499 // We also need to make sure we at least write the ty of the other
2500 // arguments which we skipped above.
2502 for arg in args.iter().skip(expected_arg_count) {
2503 let arg_ty = self.check_expr(&arg);
2505 // There are a few types which get autopromoted when passed via varargs
2506 // in C but we just error out instead and require explicit casts.
2507 let arg_ty = self.structurally_resolved_type(arg.span,
2510 ty::TyFloat(ast::FloatTy::F32) => {
2511 self.type_error_message(arg.span, |t| {
2512 format!("can't pass an `{}` to variadic \
2513 function, cast to `c_double`", t)
2516 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2517 self.type_error_message(arg.span, |t| {
2518 format!("can't pass `{}` to variadic \
2519 function, cast to `c_int`",
2523 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2524 self.type_error_message(arg.span, |t| {
2525 format!("can't pass `{}` to variadic \
2526 function, cast to `c_uint`",
2530 ty::TyFnDef(.., f) => {
2531 let ptr_ty = self.tcx.mk_fn_ptr(f);
2532 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2533 self.type_error_message(arg.span,
2535 format!("can't pass `{}` to variadic \
2536 function, cast to `{}`", t, ptr_ty)
2545 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2546 (0..len).map(|_| self.tcx.types.err).collect()
2549 // AST fragment checking
2552 expected: Expectation<'tcx>)
2558 ast::LitKind::Str(..) => tcx.mk_static_str(),
2559 ast::LitKind::ByteStr(ref v) => {
2560 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2561 tcx.mk_array(tcx.types.u8, v.len()))
2563 ast::LitKind::Byte(_) => tcx.types.u8,
2564 ast::LitKind::Char(_) => tcx.types.char,
2565 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2566 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2567 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2568 let opt_ty = expected.to_option(self).and_then(|ty| {
2570 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2571 ty::TyChar => Some(tcx.types.u8),
2572 ty::TyRawPtr(..) => Some(tcx.types.usize),
2573 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2577 opt_ty.unwrap_or_else(
2578 || tcx.mk_int_var(self.next_int_var_id()))
2580 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2581 ast::LitKind::FloatUnsuffixed(_) => {
2582 let opt_ty = expected.to_option(self).and_then(|ty| {
2584 ty::TyFloat(_) => Some(ty),
2588 opt_ty.unwrap_or_else(
2589 || tcx.mk_float_var(self.next_float_var_id()))
2591 ast::LitKind::Bool(_) => tcx.types.bool
2595 fn check_expr_eq_type(&self,
2596 expr: &'gcx hir::Expr,
2597 expected: Ty<'tcx>) {
2598 let ty = self.check_expr_with_hint(expr, expected);
2599 self.demand_eqtype(expr.span, expected, ty);
2602 pub fn check_expr_has_type(&self,
2603 expr: &'gcx hir::Expr,
2604 expected: Ty<'tcx>) -> Ty<'tcx> {
2605 let ty = self.check_expr_with_hint(expr, expected);
2606 self.demand_suptype(expr.span, expected, ty);
2610 fn check_expr_coercable_to_type(&self,
2611 expr: &'gcx hir::Expr,
2612 expected: Ty<'tcx>) -> Ty<'tcx> {
2613 let ty = self.check_expr_with_hint(expr, expected);
2614 self.demand_coerce(expr, ty, expected);
2618 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2619 expected: Ty<'tcx>) -> Ty<'tcx> {
2620 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2623 fn check_expr_with_expectation(&self,
2624 expr: &'gcx hir::Expr,
2625 expected: Expectation<'tcx>) -> Ty<'tcx> {
2626 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2629 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2630 self.check_expr_with_expectation(expr, NoExpectation)
2633 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2634 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2635 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2638 // determine the `self` type, using fresh variables for all variables
2639 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2640 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2642 pub fn impl_self_ty(&self,
2643 span: Span, // (potential) receiver for this impl
2645 -> TypeAndSubsts<'tcx> {
2646 let ity = self.tcx.item_type(did);
2647 debug!("impl_self_ty: ity={:?}", ity);
2649 let substs = self.fresh_substs_for_item(span, did);
2650 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2652 TypeAndSubsts { substs: substs, ty: substd_ty }
2655 /// Unifies the output type with the expected type early, for more coercions
2656 /// and forward type information on the input expressions.
2657 fn expected_inputs_for_expected_output(&self,
2659 expected_ret: Expectation<'tcx>,
2660 formal_ret: Ty<'tcx>,
2661 formal_args: &[Ty<'tcx>])
2663 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2664 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2665 // Attempt to apply a subtyping relationship between the formal
2666 // return type (likely containing type variables if the function
2667 // is polymorphic) and the expected return type.
2668 // No argument expectations are produced if unification fails.
2669 let origin = self.misc(call_span);
2670 let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
2671 // FIXME(#15760) can't use try! here, FromError doesn't default
2672 // to identity so the resulting type is not constrained.
2674 Ok(ok) => self.register_infer_ok_obligations(ok),
2675 Err(e) => return Err(e),
2678 // Record all the argument types, with the substitutions
2679 // produced from the above subtyping unification.
2680 Ok(formal_args.iter().map(|ty| {
2681 self.resolve_type_vars_if_possible(ty)
2684 }).unwrap_or(vec![]);
2685 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2686 formal_args, formal_ret,
2687 expected_args, expected_ret);
2691 // Checks a method call.
2692 fn check_method_call(&self,
2693 expr: &'gcx hir::Expr,
2694 method_name: Spanned<ast::Name>,
2695 args: &'gcx [hir::Expr],
2697 expected: Expectation<'tcx>,
2698 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2699 let rcvr = &args[0];
2700 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2702 // no need to check for bot/err -- callee does that
2703 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2705 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2706 let fn_ty = match self.lookup_method(method_name.span,
2713 let method_ty = method.ty;
2714 let method_call = MethodCall::expr(expr.id);
2715 self.tables.borrow_mut().method_map.insert(method_call, method);
2719 if method_name.node != keywords::Invalid.name() {
2720 self.report_method_error(method_name.span,
2727 self.write_error(expr.id);
2732 // Call the generic checker.
2733 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2741 // A generic function for checking the then and else in an if
2743 fn check_then_else(&self,
2744 cond_expr: &'gcx hir::Expr,
2745 then_expr: &'gcx hir::Expr,
2746 opt_else_expr: Option<&'gcx hir::Expr>,
2748 expected: Expectation<'tcx>) -> Ty<'tcx> {
2749 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2750 let cond_diverges = self.diverges.get();
2751 self.diverges.set(Diverges::Maybe);
2753 let expected = expected.adjust_for_branches(self);
2754 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2755 let then_diverges = self.diverges.get();
2756 self.diverges.set(Diverges::Maybe);
2758 // We've already taken the expected type's preferences
2759 // into account when typing the `then` branch. To figure
2760 // out the initial shot at a LUB, we thus only consider
2761 // `expected` if it represents a *hard* constraint
2762 // (`only_has_type`); otherwise, we just go with a
2763 // fresh type variable.
2764 let coerce_to_ty = expected.only_has_type_or_fresh_var(self, sp);
2765 let mut coerce = CoerceMany::new(coerce_to_ty);
2767 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2768 coerce.coerce(self, &if_cause, then_expr, then_ty);
2770 if let Some(else_expr) = opt_else_expr {
2771 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2772 let else_diverges = self.diverges.get();
2774 coerce.coerce(self, &if_cause, else_expr, else_ty);
2776 // We won't diverge unless both branches do (or the condition does).
2777 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2779 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2780 coerce.coerce_forced_unit(self, &else_cause);
2782 // If the condition is false we can't diverge.
2783 self.diverges.set(cond_diverges);
2786 let result_ty = coerce.complete(self);
2787 if cond_ty.references_error() {
2794 // Check field access expressions
2795 fn check_field(&self,
2796 expr: &'gcx hir::Expr,
2797 lvalue_pref: LvaluePreference,
2798 base: &'gcx hir::Expr,
2799 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2800 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2801 let expr_t = self.structurally_resolved_type(expr.span,
2803 let mut private_candidate = None;
2804 let mut autoderef = self.autoderef(expr.span, expr_t);
2805 while let Some((base_t, autoderefs)) = autoderef.next() {
2807 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2808 debug!("struct named {:?}", base_t);
2809 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2810 let field_ty = self.field_ty(expr.span, field, substs);
2811 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2812 autoderef.finalize(lvalue_pref, Some(base));
2813 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2815 self.tcx.check_stability(field.did, expr.id, expr.span);
2819 private_candidate = Some((base_def.did, field_ty));
2825 autoderef.unambiguous_final_ty();
2827 if let Some((did, field_ty)) = private_candidate {
2828 let struct_path = self.tcx().item_path_str(did);
2829 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2830 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2831 // Also check if an accessible method exists, which is often what is meant.
2832 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2833 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2838 } else if field.node == keywords::Invalid.name() {
2839 self.tcx().types.err
2840 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2841 self.type_error_struct(field.span, |actual| {
2842 format!("attempted to take value of method `{}` on type \
2843 `{}`", field.node, actual)
2845 .help("maybe a `()` to call it is missing? \
2846 If not, try an anonymous function")
2848 self.tcx().types.err
2850 let mut err = self.type_error_struct(field.span, |actual| {
2851 format!("no field `{}` on type `{}`",
2855 ty::TyAdt(def, _) if !def.is_enum() => {
2856 if let Some(suggested_field_name) =
2857 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2858 err.span_label(field.span,
2859 &format!("did you mean `{}`?", suggested_field_name));
2861 err.span_label(field.span,
2862 &format!("unknown field"));
2865 ty::TyRawPtr(..) => {
2866 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2868 self.tcx.hir.node_to_pretty_string(base.id),
2874 self.tcx().types.err
2878 // Return an hint about the closest match in field names
2879 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2880 field: &Spanned<ast::Name>,
2881 skip : Vec<InternedString>)
2883 let name = field.node.as_str();
2884 let names = variant.fields.iter().filter_map(|field| {
2885 // ignore already set fields and private fields from non-local crates
2886 if skip.iter().any(|x| *x == field.name.as_str()) ||
2887 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2894 // only find fits with at least one matching letter
2895 find_best_match_for_name(names, &name, Some(name.len()))
2898 // Check tuple index expressions
2899 fn check_tup_field(&self,
2900 expr: &'gcx hir::Expr,
2901 lvalue_pref: LvaluePreference,
2902 base: &'gcx hir::Expr,
2903 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2904 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2905 let expr_t = self.structurally_resolved_type(expr.span,
2907 let mut private_candidate = None;
2908 let mut tuple_like = false;
2909 let mut autoderef = self.autoderef(expr.span, expr_t);
2910 while let Some((base_t, autoderefs)) = autoderef.next() {
2911 let field = match base_t.sty {
2912 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2913 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2914 if !tuple_like { continue }
2916 debug!("tuple struct named {:?}", base_t);
2917 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
2918 let field_ty = self.field_ty(expr.span, field, substs);
2919 private_candidate = Some((base_def.did, field_ty));
2920 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2921 self.tcx.check_stability(field.did, expr.id, expr.span);
2928 ty::TyTuple(ref v, _) => {
2930 v.get(idx.node).cloned()
2935 if let Some(field_ty) = field {
2936 autoderef.finalize(lvalue_pref, Some(base));
2937 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2941 autoderef.unambiguous_final_ty();
2943 if let Some((did, field_ty)) = private_candidate {
2944 let struct_path = self.tcx().item_path_str(did);
2945 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
2946 self.tcx().sess.span_err(expr.span, &msg);
2950 self.type_error_message(
2954 format!("attempted out-of-bounds tuple index `{}` on \
2959 format!("attempted tuple index `{}` on type `{}`, but the \
2960 type was not a tuple or tuple struct",
2967 self.tcx().types.err
2970 fn report_unknown_field(&self,
2972 variant: &'tcx ty::VariantDef,
2974 skip_fields: &[hir::Field],
2976 let mut err = self.type_error_struct_with_diag(
2978 |actual| match ty.sty {
2979 ty::TyAdt(adt, ..) if adt.is_enum() => {
2980 struct_span_err!(self.tcx.sess, field.name.span, E0559,
2981 "{} `{}::{}` has no field named `{}`",
2982 kind_name, actual, variant.name, field.name.node)
2985 struct_span_err!(self.tcx.sess, field.name.span, E0560,
2986 "{} `{}` has no field named `{}`",
2987 kind_name, actual, field.name.node)
2991 // prevent all specified fields from being suggested
2992 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
2993 if let Some(field_name) = Self::suggest_field_name(variant,
2995 skip_fields.collect()) {
2996 err.span_label(field.name.span,
2997 &format!("field does not exist - did you mean `{}`?", field_name));
3000 ty::TyAdt(adt, ..) if adt.is_enum() => {
3001 err.span_label(field.name.span, &format!("`{}::{}` does not have this field",
3005 err.span_label(field.name.span, &format!("`{}` does not have this field", ty));
3012 fn check_expr_struct_fields(&self,
3014 expected: Expectation<'tcx>,
3015 expr_id: ast::NodeId,
3017 variant: &'tcx ty::VariantDef,
3018 ast_fields: &'gcx [hir::Field],
3019 check_completeness: bool) {
3023 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3024 .get(0).cloned().unwrap_or(adt_ty);
3026 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3027 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3028 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3030 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3033 let mut remaining_fields = FxHashMap();
3034 for field in &variant.fields {
3035 remaining_fields.insert(field.name, field);
3038 let mut seen_fields = FxHashMap();
3040 let mut error_happened = false;
3042 // Typecheck each field.
3043 for field in ast_fields {
3044 let final_field_type;
3045 let field_type_hint;
3047 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3048 final_field_type = self.field_ty(field.span, v_field, substs);
3049 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3051 seen_fields.insert(field.name.node, field.span);
3053 // we don't look at stability attributes on
3054 // struct-like enums (yet...), but it's definitely not
3055 // a bug to have construct one.
3056 if adt_kind != ty::AdtKind::Enum {
3057 tcx.check_stability(v_field.did, expr_id, field.span);
3060 error_happened = true;
3061 final_field_type = tcx.types.err;
3062 field_type_hint = tcx.types.err;
3063 if let Some(_) = variant.find_field_named(field.name.node) {
3064 let mut err = struct_span_err!(self.tcx.sess,
3067 "field `{}` specified more than once",
3070 err.span_label(field.name.span, &format!("used more than once"));
3072 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3073 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3078 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3082 // Make sure to give a type to the field even if there's
3083 // an error, so we can continue typechecking
3084 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3085 self.demand_coerce(&field.expr, ty, final_field_type);
3088 // Make sure the programmer specified correct number of fields.
3089 if kind_name == "union" {
3090 if ast_fields.len() != 1 {
3091 tcx.sess.span_err(span, "union expressions should have exactly one field");
3093 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3094 let len = remaining_fields.len();
3096 let mut displayable_field_names = remaining_fields
3098 .map(|x| x.as_str())
3099 .collect::<Vec<_>>();
3101 displayable_field_names.sort();
3103 let truncated_fields_error = if len <= 3 {
3106 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3109 let remaining_fields_names = displayable_field_names.iter().take(3)
3110 .map(|n| format!("`{}`", n))
3111 .collect::<Vec<_>>()
3114 struct_span_err!(tcx.sess, span, E0063,
3115 "missing field{} {}{} in initializer of `{}`",
3116 if remaining_fields.len() == 1 {""} else {"s"},
3117 remaining_fields_names,
3118 truncated_fields_error,
3120 .span_label(span, &format!("missing {}{}",
3121 remaining_fields_names,
3122 truncated_fields_error))
3127 fn check_struct_fields_on_error(&self,
3128 fields: &'gcx [hir::Field],
3129 base_expr: &'gcx Option<P<hir::Expr>>) {
3130 for field in fields {
3131 self.check_expr(&field.expr);
3135 self.check_expr(&base);
3141 pub fn check_struct_path(&self,
3143 node_id: ast::NodeId)
3144 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3145 let path_span = match *qpath {
3146 hir::QPath::Resolved(_, ref path) => path.span,
3147 hir::QPath::TypeRelative(ref qself, _) => qself.span
3149 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3150 let variant = match def {
3152 self.set_tainted_by_errors();
3155 Def::Variant(..) => {
3157 ty::TyAdt(adt, substs) => {
3158 Some((adt.variant_of_def(def), adt.did, substs))
3160 _ => bug!("unexpected type: {:?}", ty.sty)
3163 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3164 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3166 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3167 Some((adt.struct_variant(), adt.did, substs))
3172 _ => bug!("unexpected definition: {:?}", def)
3175 if let Some((variant, did, substs)) = variant {
3176 // Check bounds on type arguments used in the path.
3177 let bounds = self.instantiate_bounds(path_span, did, substs);
3178 let cause = traits::ObligationCause::new(path_span, self.body_id,
3179 traits::ItemObligation(did));
3180 self.add_obligations_for_parameters(cause, &bounds);
3184 struct_span_err!(self.tcx.sess, path_span, E0071,
3185 "expected struct, variant or union type, found {}",
3186 ty.sort_string(self.tcx))
3187 .span_label(path_span, &format!("not a struct"))
3193 fn check_expr_struct(&self,
3195 expected: Expectation<'tcx>,
3197 fields: &'gcx [hir::Field],
3198 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3200 // Find the relevant variant
3201 let (variant, struct_ty) =
3202 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3205 self.check_struct_fields_on_error(fields, base_expr);
3206 return self.tcx.types.err;
3209 let path_span = match *qpath {
3210 hir::QPath::Resolved(_, ref path) => path.span,
3211 hir::QPath::TypeRelative(ref qself, _) => qself.span
3214 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3215 base_expr.is_none());
3216 if let &Some(ref base_expr) = base_expr {
3217 self.check_expr_has_type(base_expr, struct_ty);
3218 match struct_ty.sty {
3219 ty::TyAdt(adt, substs) if adt.is_struct() => {
3220 self.tables.borrow_mut().fru_field_types.insert(
3222 adt.struct_variant().fields.iter().map(|f| {
3223 self.normalize_associated_types_in(
3224 expr.span, &f.ty(self.tcx, substs)
3230 span_err!(self.tcx.sess, base_expr.span, E0436,
3231 "functional record update syntax requires a struct");
3235 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3241 /// If an expression has any sub-expressions that result in a type error,
3242 /// inspecting that expression's type with `ty.references_error()` will return
3243 /// true. Likewise, if an expression is known to diverge, inspecting its
3244 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3245 /// strict, _|_ can appear in the type of an expression that does not,
3246 /// itself, diverge: for example, fn() -> _|_.)
3247 /// Note that inspecting a type's structure *directly* may expose the fact
3248 /// that there are actually multiple representations for `TyError`, so avoid
3249 /// that when err needs to be handled differently.
3250 fn check_expr_with_expectation_and_lvalue_pref(&self,
3251 expr: &'gcx hir::Expr,
3252 expected: Expectation<'tcx>,
3253 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3254 debug!(">> typechecking: expr={:?} expected={:?}",
3257 // Warn for expressions after diverging siblings.
3258 self.warn_if_unreachable(expr.id, expr.span, "expression");
3260 // Hide the outer diverging and has_errors flags.
3261 let old_diverges = self.diverges.get();
3262 let old_has_errors = self.has_errors.get();
3263 self.diverges.set(Diverges::Maybe);
3264 self.has_errors.set(false);
3266 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3268 // Warn for non-block expressions with diverging children.
3271 hir::ExprLoop(..) | hir::ExprWhile(..) |
3272 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3274 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3277 // Any expression that produces a value of type `!` must have diverged
3279 self.diverges.set(self.diverges.get() | Diverges::Always);
3282 // Record the type, which applies it effects.
3283 // We need to do this after the warning above, so that
3284 // we don't warn for the diverging expression itself.
3285 self.write_ty(expr.id, ty);
3287 // Combine the diverging and has_error flags.
3288 self.diverges.set(self.diverges.get() | old_diverges);
3289 self.has_errors.set(self.has_errors.get() | old_has_errors);
3291 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3292 debug!("... {:?}, expected is {:?}", ty, expected);
3294 // Add adjustments to !-expressions
3296 if let Some(hir::map::NodeExpr(node_expr)) = self.tcx.hir.find(expr.id) {
3297 let adj_ty = self.next_diverging_ty_var(
3298 TypeVariableOrigin::AdjustmentType(node_expr.span));
3299 self.write_adjustment(expr.id, adjustment::Adjustment {
3300 kind: adjustment::Adjust::NeverToAny,
3309 fn check_expr_kind(&self,
3310 expr: &'gcx hir::Expr,
3311 expected: Expectation<'tcx>,
3312 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3316 hir::ExprBox(ref subexpr) => {
3317 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3319 ty::TyAdt(def, _) if def.is_box()
3320 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3324 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3325 tcx.mk_box(referent_ty)
3328 hir::ExprLit(ref lit) => {
3329 self.check_lit(&lit, expected)
3331 hir::ExprBinary(op, ref lhs, ref rhs) => {
3332 self.check_binop(expr, op, lhs, rhs)
3334 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3335 self.check_binop_assign(expr, op, lhs, rhs)
3337 hir::ExprUnary(unop, ref oprnd) => {
3338 let expected_inner = match unop {
3339 hir::UnNot | hir::UnNeg => {
3346 let lvalue_pref = match unop {
3347 hir::UnDeref => lvalue_pref,
3350 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3354 if !oprnd_t.references_error() {
3357 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3359 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3361 } else if let Some(method) = self.try_overloaded_deref(
3362 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3363 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3364 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3367 self.type_error_message(expr.span, |actual| {
3368 format!("type `{}` cannot be \
3369 dereferenced", actual)
3371 oprnd_t = tcx.types.err;
3375 oprnd_t = self.structurally_resolved_type(oprnd.span,
3377 let result = self.check_user_unop("!", "not",
3378 tcx.lang_items.not_trait(),
3379 expr, &oprnd, oprnd_t, unop);
3380 // If it's builtin, we can reuse the type, this helps inference.
3381 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3386 oprnd_t = self.structurally_resolved_type(oprnd.span,
3388 let result = self.check_user_unop("-", "neg",
3389 tcx.lang_items.neg_trait(),
3390 expr, &oprnd, oprnd_t, unop);
3391 // If it's builtin, we can reuse the type, this helps inference.
3392 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3400 hir::ExprAddrOf(mutbl, ref oprnd) => {
3401 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3403 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3404 if self.tcx.expr_is_lval(&oprnd) {
3405 // Lvalues may legitimately have unsized types.
3406 // For example, dereferences of a fat pointer and
3407 // the last field of a struct can be unsized.
3408 ExpectHasType(mt.ty)
3410 Expectation::rvalue_hint(self, mt.ty)
3416 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3417 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3419 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3420 if tm.ty.references_error() {
3423 // Note: at this point, we cannot say what the best lifetime
3424 // is to use for resulting pointer. We want to use the
3425 // shortest lifetime possible so as to avoid spurious borrowck
3426 // errors. Moreover, the longest lifetime will depend on the
3427 // precise details of the value whose address is being taken
3428 // (and how long it is valid), which we don't know yet until type
3429 // inference is complete.
3431 // Therefore, here we simply generate a region variable. The
3432 // region inferencer will then select the ultimate value.
3433 // Finally, borrowck is charged with guaranteeing that the
3434 // value whose address was taken can actually be made to live
3435 // as long as it needs to live.
3436 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3437 tcx.mk_ref(region, tm)
3440 hir::ExprPath(ref qpath) => {
3441 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3442 expr.id, expr.span);
3443 let ty = if def != Def::Err {
3444 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3446 self.set_tainted_by_errors();
3450 // We always require that the type provided as the value for
3451 // a type parameter outlives the moment of instantiation.
3452 self.opt_node_ty_substs(expr.id, |item_substs| {
3453 self.add_wf_bounds(&item_substs.substs, expr);
3458 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3459 for output in outputs {
3460 self.check_expr(output);
3462 for input in inputs {
3463 self.check_expr(input);
3467 hir::ExprBreak(destination, ref expr_opt) => {
3468 if let Some(target_id) = destination.target_id.opt_id() {
3470 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3471 enclosing_breakables.find_breakable(target_id).coerce_to
3476 if let Some(ref e) = *expr_opt {
3477 // Recurse without `enclosing_loops` borrowed.
3478 e_ty = self.check_expr_with_hint(e, coerce_to);
3479 cause = self.misc(e.span);
3480 // Notably, the recursive call may alter coerce_to - must not keep using it!
3482 // `break` without argument acts like `break ()`.
3483 e_ty = tcx.mk_nil();
3484 cause = self.misc(expr.span);
3487 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3488 let ctxt = enclosing_breakables.find_breakable(target_id);
3490 let result = if let Some(ref e) = *expr_opt {
3491 // Special-case the first element, as it has no "previous expressions".
3492 let result = if !ctxt.may_break {
3493 self.try_coerce(e, e_ty, ctxt.coerce_to)
3495 self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
3496 ctxt.unified, e, e_ty)
3499 ctxt.break_exprs.push(e);
3502 self.eq_types(true, &cause, e_ty, ctxt.unified)
3503 .map(|InferOk { obligations, .. }| {
3504 // FIXME(#32730) propagate obligations
3505 assert!(obligations.is_empty());
3510 Ok(ty) => ctxt.unified = ty,
3512 self.report_mismatched_types(&cause, ctxt.unified, e_ty, err).emit();
3516 ctxt.may_break = true;
3518 // Otherwise, we failed to find the enclosing breakable; this can only happen if the
3519 // `break` target was not found, which is caught in HIR lowering and reported by the
3520 // loop-checking pass.
3523 hir::ExprAgain(_) => { tcx.types.never }
3524 hir::ExprRet(ref expr_opt) => {
3525 if self.ret_ty.is_none() {
3526 struct_span_err!(self.tcx.sess, expr.span, E0572,
3527 "return statement outside of function body").emit();
3528 } else if let Some(ref e) = *expr_opt {
3529 self.check_expr_coercable_to_type(&e, self.ret_ty.unwrap());
3531 match self.eq_types(false,
3532 &self.misc(expr.span),
3533 self.ret_ty.unwrap(),
3535 Ok(ok) => self.register_infer_ok_obligations(ok),
3537 struct_span_err!(tcx.sess, expr.span, E0069,
3538 "`return;` in a function whose return type is not `()`")
3539 .span_label(expr.span, &format!("return type is not ()"))
3546 hir::ExprAssign(ref lhs, ref rhs) => {
3547 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3550 if !tcx.expr_is_lval(&lhs) {
3552 tcx.sess, expr.span, E0070,
3553 "invalid left-hand side expression")
3556 &format!("left-hand of expression not valid"))
3560 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3562 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3564 if lhs_ty.references_error() || rhs_ty.references_error() {
3570 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3571 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3572 expr.span, expected)
3574 hir::ExprWhile(ref cond, ref body, _) => {
3575 let unified = self.tcx.mk_nil();
3576 let coerce_to = unified;
3577 let ctxt = BreakableCtxt {
3579 coerce_to: coerce_to,
3580 break_exprs: vec![],
3583 self.with_breakable_ctxt(expr.id, ctxt, || {
3584 self.check_expr_has_type(&cond, tcx.types.bool);
3585 let cond_diverging = self.diverges.get();
3586 self.check_block_no_value(&body);
3588 // We may never reach the body so it diverging means nothing.
3589 self.diverges.set(cond_diverging);
3592 if self.has_errors.get() {
3598 hir::ExprLoop(ref body, _, _) => {
3599 let unified = self.next_ty_var(TypeVariableOrigin::TypeInference(body.span));
3600 let coerce_to = expected.only_has_type(self).unwrap_or(unified);
3601 let ctxt = BreakableCtxt {
3603 coerce_to: coerce_to,
3604 break_exprs: vec![],
3608 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3609 self.check_block_no_value(&body);
3612 // No way to know whether it's diverging because
3613 // of a `break` or an outer `break` or `return.
3614 self.diverges.set(Diverges::Maybe);
3621 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3622 self.check_match(expr, &discrim, arms, expected, match_src)
3624 hir::ExprClosure(capture, ref decl, body_id, _) => {
3625 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3627 hir::ExprBlock(ref body) => {
3628 self.check_block_with_expected(&body, expected)
3630 hir::ExprCall(ref callee, ref args) => {
3631 self.check_call(expr, &callee, args, expected)
3633 hir::ExprMethodCall(name, ref tps, ref args) => {
3634 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3636 hir::ExprCast(ref e, ref t) => {
3637 // Find the type of `e`. Supply hints based on the type we are casting to,
3639 let t_cast = self.to_ty(t);
3640 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3641 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3642 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3644 // Eagerly check for some obvious errors.
3645 if t_expr.references_error() || t_cast.references_error() {
3648 // Defer other checks until we're done type checking.
3649 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3650 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3652 deferred_cast_checks.push(cast_check);
3655 Err(ErrorReported) => {
3661 hir::ExprType(ref e, ref t) => {
3662 let typ = self.to_ty(&t);
3663 self.check_expr_eq_type(&e, typ);
3666 hir::ExprArray(ref args) => {
3667 let uty = expected.to_option(self).and_then(|uty| {
3669 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3674 let mut unified = self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span));
3675 let coerce_to = uty.unwrap_or(unified);
3677 for (i, e) in args.iter().enumerate() {
3678 let e_ty = self.check_expr_with_hint(e, coerce_to);
3679 let cause = self.misc(e.span);
3681 // Special-case the first element, as it has no "previous expressions".
3682 let result = if i == 0 {
3683 self.try_coerce(e, e_ty, coerce_to)
3685 let prev_elems = || args[..i].iter().map(|e| &*e);
3686 self.try_find_coercion_lub(&cause, prev_elems, unified, e, e_ty)
3690 Ok(ty) => unified = ty,
3692 self.report_mismatched_types(&cause, unified, e_ty, e).emit();
3696 tcx.mk_array(unified, args.len())
3698 hir::ExprRepeat(ref element, count) => {
3699 let count = eval_length(self.tcx.global_tcx(), count, "repeat count")
3702 let uty = match expected {
3703 ExpectHasType(uty) => {
3705 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3712 let (element_ty, t) = match uty {
3714 self.check_expr_coercable_to_type(&element, uty);
3718 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3719 let element_ty = self.check_expr_has_type(&element, t);
3725 // For [foo, ..n] where n > 1, `foo` must have
3727 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3728 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3731 if element_ty.references_error() {
3734 tcx.mk_array(t, count)
3737 hir::ExprTup(ref elts) => {
3738 let flds = expected.only_has_type(self).and_then(|ty| {
3740 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3745 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3746 let t = match flds {
3747 Some(ref fs) if i < fs.len() => {
3749 self.check_expr_coercable_to_type(&e, ety);
3753 self.check_expr_with_expectation(&e, NoExpectation)
3758 let tuple = tcx.mk_tup(elt_ts_iter, false);
3759 if tuple.references_error() {
3765 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3766 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3768 hir::ExprField(ref base, ref field) => {
3769 self.check_field(expr, lvalue_pref, &base, field)
3771 hir::ExprTupField(ref base, idx) => {
3772 self.check_tup_field(expr, lvalue_pref, &base, idx)
3774 hir::ExprIndex(ref base, ref idx) => {
3775 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3776 let idx_t = self.check_expr(&idx);
3778 if base_t.references_error() {
3780 } else if idx_t.references_error() {
3783 let base_t = self.structurally_resolved_type(expr.span, base_t);
3784 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3785 Some((index_ty, element_ty)) => {
3786 self.demand_coerce(idx, idx_t, index_ty);
3790 self.check_expr_has_type(&idx, self.tcx.types.err);
3791 let mut err = self.type_error_struct(
3794 format!("cannot index a value of type `{}`",
3798 // Try to give some advice about indexing tuples.
3799 if let ty::TyTuple(..) = base_t.sty {
3800 let mut needs_note = true;
3801 // If the index is an integer, we can show the actual
3802 // fixed expression:
3803 if let hir::ExprLit(ref lit) = idx.node {
3804 if let ast::LitKind::Int(i,
3805 ast::LitIntType::Unsuffixed) = lit.node {
3806 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3807 if let Ok(snip) = snip {
3808 err.span_suggestion(expr.span,
3809 "to access tuple elements, \
3810 use tuple indexing syntax \
3812 format!("{}.{}", snip, i));
3818 err.help("to access tuple elements, use tuple indexing \
3819 syntax (e.g. `tuple.0`)");
3831 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3832 // The newly resolved definition is written into `type_relative_path_defs`.
3833 fn finish_resolving_struct_path(&self,
3836 node_id: ast::NodeId)
3840 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3841 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3842 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3845 hir::QPath::TypeRelative(ref qself, ref segment) => {
3846 let ty = self.to_ty(qself);
3848 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3853 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3856 // Write back the new resolution.
3857 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3864 // Resolve associated value path into a base type and associated constant or method definition.
3865 // The newly resolved definition is written into `type_relative_path_defs`.
3866 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3867 qpath: &'b hir::QPath,
3868 node_id: ast::NodeId,
3870 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3872 let (ty, item_segment) = match *qpath {
3873 hir::QPath::Resolved(ref opt_qself, ref path) => {
3875 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3876 &path.segments[..]);
3878 hir::QPath::TypeRelative(ref qself, ref segment) => {
3879 (self.to_ty(qself), segment)
3882 let item_name = item_segment.name;
3883 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3886 let def = match error {
3887 method::MethodError::PrivateMatch(def) => def,
3890 if item_name != keywords::Invalid.name() {
3891 self.report_method_error(span, ty, item_name, None, error, None);
3897 // Write back the new resolution.
3898 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3899 (def, Some(ty), slice::ref_slice(&**item_segment))
3902 pub fn check_decl_initializer(&self,
3903 local: &'gcx hir::Local,
3904 init: &'gcx hir::Expr) -> Ty<'tcx>
3906 let ref_bindings = local.pat.contains_ref_binding();
3908 let local_ty = self.local_ty(init.span, local.id);
3909 if let Some(m) = ref_bindings {
3910 // Somewhat subtle: if we have a `ref` binding in the pattern,
3911 // we want to avoid introducing coercions for the RHS. This is
3912 // both because it helps preserve sanity and, in the case of
3913 // ref mut, for soundness (issue #23116). In particular, in
3914 // the latter case, we need to be clear that the type of the
3915 // referent for the reference that results is *equal to* the
3916 // type of the lvalue it is referencing, and not some
3917 // supertype thereof.
3918 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3919 self.demand_eqtype(init.span, init_ty, local_ty);
3922 self.check_expr_coercable_to_type(init, local_ty)
3926 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3927 let t = self.local_ty(local.span, local.id);
3928 self.write_ty(local.id, t);
3930 if let Some(ref init) = local.init {
3931 let init_ty = self.check_decl_initializer(local, &init);
3932 if init_ty.references_error() {
3933 self.write_ty(local.id, init_ty);
3937 self.check_pat(&local.pat, t);
3938 let pat_ty = self.node_ty(local.pat.id);
3939 if pat_ty.references_error() {
3940 self.write_ty(local.id, pat_ty);
3944 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3945 // Don't do all the complex logic below for DeclItem.
3947 hir::StmtDecl(ref decl, id) => {
3949 hir::DeclLocal(_) => {}
3950 hir::DeclItem(_) => {
3956 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
3959 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
3961 // Hide the outer diverging and has_errors flags.
3962 let old_diverges = self.diverges.get();
3963 let old_has_errors = self.has_errors.get();
3964 self.diverges.set(Diverges::Maybe);
3965 self.has_errors.set(false);
3967 let (node_id, _span) = match stmt.node {
3968 hir::StmtDecl(ref decl, id) => {
3969 let span = match decl.node {
3970 hir::DeclLocal(ref l) => {
3971 self.check_decl_local(&l);
3974 hir::DeclItem(_) => {/* ignore for now */
3980 hir::StmtExpr(ref expr, id) => {
3981 // Check with expected type of ()
3982 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3985 hir::StmtSemi(ref expr, id) => {
3986 self.check_expr(&expr);
3991 if self.has_errors.get() {
3992 self.write_error(node_id);
3994 self.write_nil(node_id);
3997 // Combine the diverging and has_error flags.
3998 self.diverges.set(self.diverges.get() | old_diverges);
3999 self.has_errors.set(self.has_errors.get() | old_has_errors);
4002 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4003 let unit = self.tcx.mk_nil();
4004 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4005 self.demand_suptype(blk.span, unit, ty);
4008 fn check_block_with_expected(&self,
4009 blk: &'gcx hir::Block,
4010 expected: Expectation<'tcx>) -> Ty<'tcx> {
4012 let mut fcx_ps = self.ps.borrow_mut();
4013 let unsafety_state = fcx_ps.recurse(blk);
4014 replace(&mut *fcx_ps, unsafety_state)
4017 let mut ty = if blk.targeted_by_break {
4018 let unified = self.next_ty_var(TypeVariableOrigin::TypeInference(blk.span));
4019 let coerce_to = expected.only_has_type(self).unwrap_or(unified);
4020 let ctxt = BreakableCtxt {
4022 coerce_to: coerce_to,
4023 break_exprs: vec![],
4027 let (mut ctxt, (e_ty, cause)) = self.with_breakable_ctxt(blk.id, ctxt, || {
4028 for s in &blk.stmts {
4032 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4033 enclosing_breakables.find_breakable(blk.id).coerce_to
4039 e_ty = self.check_expr_with_hint(e, coerce_to);
4040 cause = self.misc(e.span);
4043 e_ty = if self.diverges.get().always() {
4044 self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span))
4048 cause = self.misc(blk.span);
4055 if let ExpectHasType(ety) = expected {
4056 if let Some(ref e) = blk.expr {
4057 let result = if !ctxt.may_break {
4058 self.try_coerce(e, e_ty, ctxt.coerce_to)
4060 self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
4061 ctxt.unified, e, e_ty)
4064 Ok(ty) => ctxt.unified = ty,
4066 self.report_mismatched_types(&cause, ctxt.unified, e_ty, err).emit(),
4069 self.check_block_no_expr(blk, self.tcx.mk_nil(), e_ty);
4074 for s in &blk.stmts {
4078 let mut ty = match blk.expr {
4079 Some(ref e) => self.check_expr_with_expectation(e, expected),
4080 None => self.tcx.mk_nil()
4083 if self.diverges.get().always() {
4084 if let ExpectHasType(ety) = expected {
4085 // Avoid forcing a type (only `!` for now) in unreachable code.
4086 // FIXME(aburka) do we need this special case? and should it be is_uninhabited?
4087 if !ety.is_never() {
4088 if let Some(ref e) = blk.expr {
4089 // Coerce the tail expression to the right type.
4090 self.demand_coerce(e, ty, ety);
4095 ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
4096 } else if let ExpectHasType(ety) = expected {
4097 if let Some(ref e) = blk.expr {
4098 // Coerce the tail expression to the right type.
4099 self.demand_coerce(e, ty, ety);
4101 self.check_block_no_expr(blk, ty, ety);
4104 // We already applied the type (and potentially errored),
4105 // use the expected type to avoid further errors out.
4111 if self.has_errors.get() || ty.references_error() {
4112 ty = self.tcx.types.err
4115 self.write_ty(blk.id, ty);
4117 *self.ps.borrow_mut() = prev;
4121 pub fn check_block_no_expr(&self, blk: &'gcx hir::Block, ty: Ty<'tcx>, ety: Ty<'tcx>) {
4122 // We're not diverging and there's an expected type, which,
4123 // in case it's not `()`, could result in an error higher-up.
4124 // We have a chance to error here early and be more helpful.
4125 let cause = self.misc(blk.span);
4126 let trace = TypeTrace::types(&cause, false, ty, ety);
4127 match self.sub_types(false, &cause, ty, ety) {
4128 Ok(InferOk { obligations, .. }) => {
4129 // FIXME(#32730) propagate obligations
4130 assert!(obligations.is_empty());
4133 let mut err = self.report_and_explain_type_error(trace, &err);
4135 // Be helpful when the user wrote `{... expr;}` and
4136 // taking the `;` off is enough to fix the error.
4137 let mut extra_semi = None;
4138 if let Some(stmt) = blk.stmts.last() {
4139 if let hir::StmtSemi(ref e, _) = stmt.node {
4140 if self.can_sub_types(self.node_ty(e.id), ety).is_ok() {
4141 extra_semi = Some(stmt);
4145 if let Some(last_stmt) = extra_semi {
4146 let original_span = original_sp(last_stmt.span, blk.span);
4147 let span_semi = Span {
4148 lo: original_span.hi - BytePos(1),
4149 hi: original_span.hi,
4150 ctxt: original_span.ctxt,
4152 err.span_help(span_semi, "consider removing this semicolon:");
4160 // Instantiates the given path, which must refer to an item with the given
4161 // number of type parameters and type.
4162 pub fn instantiate_value_path(&self,
4163 segments: &[hir::PathSegment],
4164 opt_self_ty: Option<Ty<'tcx>>,
4167 node_id: ast::NodeId)
4169 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4174 // We need to extract the type parameters supplied by the user in
4175 // the path `path`. Due to the current setup, this is a bit of a
4176 // tricky-process; the problem is that resolve only tells us the
4177 // end-point of the path resolution, and not the intermediate steps.
4178 // Luckily, we can (at least for now) deduce the intermediate steps
4179 // just from the end-point.
4181 // There are basically four cases to consider:
4183 // 1. Reference to a constructor of enum variant or struct:
4185 // struct Foo<T>(...)
4186 // enum E<T> { Foo(...) }
4188 // In these cases, the parameters are declared in the type
4191 // 2. Reference to a fn item or a free constant:
4195 // In this case, the path will again always have the form
4196 // `a::b::foo::<T>` where only the final segment should have
4197 // type parameters. However, in this case, those parameters are
4198 // declared on a value, and hence are in the `FnSpace`.
4200 // 3. Reference to a method or an associated constant:
4202 // impl<A> SomeStruct<A> {
4206 // Here we can have a path like
4207 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4208 // may appear in two places. The penultimate segment,
4209 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4210 // final segment, `foo::<B>` contains parameters in fn space.
4212 // 4. Reference to a local variable
4214 // Local variables can't have any type parameters.
4216 // The first step then is to categorize the segments appropriately.
4218 assert!(!segments.is_empty());
4220 let mut ufcs_associated = None;
4221 let mut type_segment = None;
4222 let mut fn_segment = None;
4224 // Case 1. Reference to a struct/variant constructor.
4225 Def::StructCtor(def_id, ..) |
4226 Def::VariantCtor(def_id, ..) => {
4227 // Everything but the final segment should have no
4228 // parameters at all.
4229 let mut generics = self.tcx.item_generics(def_id);
4230 if let Some(def_id) = generics.parent {
4231 // Variant and struct constructors use the
4232 // generics of their parent type definition.
4233 generics = self.tcx.item_generics(def_id);
4235 type_segment = Some((segments.last().unwrap(), generics));
4238 // Case 2. Reference to a top-level value.
4240 Def::Const(def_id) |
4241 Def::Static(def_id, _) => {
4242 fn_segment = Some((segments.last().unwrap(),
4243 self.tcx.item_generics(def_id)));
4246 // Case 3. Reference to a method or associated const.
4247 Def::Method(def_id) |
4248 Def::AssociatedConst(def_id) => {
4249 let container = self.tcx.associated_item(def_id).container;
4251 ty::TraitContainer(trait_did) => {
4252 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4254 ty::ImplContainer(_) => {}
4257 let generics = self.tcx.item_generics(def_id);
4258 if segments.len() >= 2 {
4259 let parent_generics = self.tcx.item_generics(generics.parent.unwrap());
4260 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4262 // `<T>::assoc` will end up here, and so can `T::assoc`.
4263 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4264 ufcs_associated = Some((container, self_ty));
4266 fn_segment = Some((segments.last().unwrap(), generics));
4269 // Case 4. Local variable, no generics.
4270 Def::Local(..) | Def::Upvar(..) => {}
4272 _ => bug!("unexpected definition: {:?}", def),
4275 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4277 // Now that we have categorized what space the parameters for each
4278 // segment belong to, let's sort out the parameters that the user
4279 // provided (if any) into their appropriate spaces. We'll also report
4280 // errors if type parameters are provided in an inappropriate place.
4281 let poly_segments = type_segment.is_some() as usize +
4282 fn_segment.is_some() as usize;
4283 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4286 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4287 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4288 let ty = self.local_ty(span, nid);
4289 let ty = self.normalize_associated_types_in(span, &ty);
4290 self.write_ty(node_id, ty);
4291 self.write_substs(node_id, ty::ItemSubsts {
4292 substs: self.tcx.intern_substs(&[])
4299 // Now we have to compare the types that the user *actually*
4300 // provided against the types that were *expected*. If the user
4301 // did not provide any types, then we want to substitute inference
4302 // variables. If the user provided some types, we may still need
4303 // to add defaults. If the user provided *too many* types, that's
4305 self.check_path_parameter_count(span, &mut type_segment);
4306 self.check_path_parameter_count(span, &mut fn_segment);
4308 let (fn_start, has_self) = match (type_segment, fn_segment) {
4309 (_, Some((_, generics))) => {
4310 (generics.parent_count(), generics.has_self)
4312 (Some((_, generics)), None) => {
4313 (generics.own_count(), generics.has_self)
4315 (None, None) => (0, false)
4317 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4318 let mut i = def.index as usize;
4320 let segment = if i < fn_start {
4321 i -= has_self as usize;
4327 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4328 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4329 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4333 if let Some(lifetime) = lifetimes.get(i) {
4334 AstConv::ast_region_to_region(self, lifetime, Some(def))
4336 self.re_infer(span, Some(def)).unwrap()
4339 let mut i = def.index as usize;
4341 let segment = if i < fn_start {
4342 // Handle Self first, so we can adjust the index to match the AST.
4343 if has_self && i == 0 {
4344 return opt_self_ty.unwrap_or_else(|| {
4345 self.type_var_for_def(span, def, substs)
4348 i -= has_self as usize;
4354 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4355 Some(&hir::AngleBracketedParameters(ref data)) => {
4356 (&data.types[..], data.infer_types)
4358 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4359 None => (&[][..], true)
4362 // Skip over the lifetimes in the same segment.
4363 if let Some((_, generics)) = segment {
4364 i -= generics.regions.len();
4367 if let Some(ast_ty) = types.get(i) {
4368 // A provided type parameter.
4370 } else if !infer_types && def.has_default {
4371 // No type parameter provided, but a default exists.
4372 let default = self.tcx.item_type(def.def_id);
4375 default.subst_spanned(self.tcx, substs, Some(span))
4378 // No type parameters were provided, we can infer all.
4379 // This can also be reached in some error cases:
4380 // We prefer to use inference variables instead of
4381 // TyError to let type inference recover somewhat.
4382 self.type_var_for_def(span, def, substs)
4386 // The things we are substituting into the type should not contain
4387 // escaping late-bound regions, and nor should the base type scheme.
4388 let ty = self.tcx.item_type(def.def_id());
4389 assert!(!substs.has_escaping_regions());
4390 assert!(!ty.has_escaping_regions());
4392 // Add all the obligations that are required, substituting and
4393 // normalized appropriately.
4394 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4395 self.add_obligations_for_parameters(
4396 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4399 // Substitute the values for the type parameters into the type of
4400 // the referenced item.
4401 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4403 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4404 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4405 // is inherent, there is no `Self` parameter, instead, the impl needs
4406 // type parameters, which we can infer by unifying the provided `Self`
4407 // with the substituted impl type.
4408 let ty = self.tcx.item_type(impl_def_id);
4410 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4411 match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
4412 Ok(ok) => self.register_infer_ok_obligations(ok),
4415 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4422 debug!("instantiate_value_path: type of {:?} is {:?}",
4425 self.write_substs(node_id, ty::ItemSubsts {
4431 /// Report errors if the provided parameters are too few or too many.
4432 fn check_path_parameter_count(&self,
4434 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4435 let (lifetimes, types, infer_types, bindings) = {
4436 match segment.map(|(s, _)| &s.parameters) {
4437 Some(&hir::AngleBracketedParameters(ref data)) => {
4438 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4440 Some(&hir::ParenthesizedParameters(_)) => {
4441 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4443 None => (&[][..], &[][..], true, &[][..])
4447 let count_lifetime_params = |n| {
4448 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4450 let count_type_params = |n| {
4451 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4454 // Check provided lifetime parameters.
4455 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4456 if lifetimes.len() > lifetime_defs.len() {
4457 let expected_text = count_lifetime_params(lifetime_defs.len());
4458 let actual_text = count_lifetime_params(lifetimes.len());
4459 struct_span_err!(self.tcx.sess, span, E0088,
4460 "too many lifetime parameters provided: \
4461 expected at most {}, found {}",
4462 expected_text, actual_text)
4463 .span_label(span, &format!("expected {}", expected_text))
4465 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4466 let expected_text = count_lifetime_params(lifetime_defs.len());
4467 let actual_text = count_lifetime_params(lifetimes.len());
4468 struct_span_err!(self.tcx.sess, span, E0090,
4469 "too few lifetime parameters provided: \
4470 expected {}, found {}",
4471 expected_text, actual_text)
4472 .span_label(span, &format!("expected {}", expected_text))
4476 // The case where there is not enough lifetime parameters is not checked,
4477 // because this is not possible - a function never takes lifetime parameters.
4478 // See discussion for Pull Request 36208.
4480 // Check provided type parameters.
4481 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4482 if generics.parent.is_none() {
4483 &generics.types[generics.has_self as usize..]
4488 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4489 if types.len() > type_defs.len() {
4490 let span = types[type_defs.len()].span;
4491 let expected_text = count_type_params(type_defs.len());
4492 let actual_text = count_type_params(types.len());
4493 struct_span_err!(self.tcx.sess, span, E0087,
4494 "too many type parameters provided: \
4495 expected at most {}, found {}",
4496 expected_text, actual_text)
4497 .span_label(span, &format!("expected {}", expected_text))
4500 // To prevent derived errors to accumulate due to extra
4501 // type parameters, we force instantiate_value_path to
4502 // use inference variables instead of the provided types.
4504 } else if !infer_types && types.len() < required_len {
4505 let expected_text = count_type_params(required_len);
4506 let actual_text = count_type_params(types.len());
4507 struct_span_err!(self.tcx.sess, span, E0089,
4508 "too few type parameters provided: \
4509 expected {}, found {}",
4510 expected_text, actual_text)
4511 .span_label(span, &format!("expected {}", expected_text))
4515 if !bindings.is_empty() {
4516 span_err!(self.tcx.sess, bindings[0].span, E0182,
4517 "unexpected binding of associated item in expression path \
4518 (only allowed in type paths)");
4522 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4524 where F: Fn() -> Ty<'tcx>
4526 let mut ty = self.resolve_type_vars_with_obligations(ty);
4529 let alternative = f();
4532 if alternative.is_ty_var() || alternative.references_error() {
4533 if !self.is_tainted_by_errors() {
4534 self.type_error_message(sp, |_actual| {
4535 "the type of this value must be known in this context".to_string()
4538 self.demand_suptype(sp, self.tcx.types.err, ty);
4539 ty = self.tcx.types.err;
4541 self.demand_suptype(sp, alternative, ty);
4549 // Resolves `typ` by a single level if `typ` is a type variable. If no
4550 // resolution is possible, then an error is reported.
4551 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4552 self.structurally_resolve_type_or_else(sp, ty, || {
4557 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4558 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4559 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4562 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4563 index = enclosing_breakables.stack.len();
4564 enclosing_breakables.by_id.insert(id, index);
4565 enclosing_breakables.stack.push(ctxt);
4569 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4570 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4571 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4572 enclosing_breakables.stack.pop().expect("missing breakable context")
4578 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4579 generics: &hir::Generics,
4581 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4582 generics.ty_params.len(), ty);
4584 // make a vector of booleans initially false, set to true when used
4585 if generics.ty_params.is_empty() { return; }
4586 let mut tps_used = vec![false; generics.ty_params.len()];
4588 for leaf_ty in ty.walk() {
4589 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4590 debug!("Found use of ty param num {}", idx);
4591 tps_used[idx as usize - generics.lifetimes.len()] = true;
4595 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4597 struct_span_err!(tcx.sess, param.span, E0091,
4598 "type parameter `{}` is unused",
4600 .span_label(param.span, &format!("unused type parameter"))