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 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
84 use dep_graph::DepNode;
85 use fmt_macros::{Parser, Piece, Position};
86 use hir::def::{Def, CtorKind};
87 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
88 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin, TypeTrace};
89 use rustc::infer::type_variable::{self, TypeVariableOrigin};
90 use rustc::ty::subst::{Kind, Subst, Substs};
91 use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
92 use rustc::ty::{ParamTy, ParameterEnvironment};
93 use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
94 use rustc::ty::{self, Ty, TyCtxt, Visibility};
95 use rustc::ty::{MethodCall, MethodCallee};
96 use rustc::ty::adjustment;
97 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
98 use rustc::ty::maps::Providers;
99 use rustc::ty::util::{Representability, IntTypeExt};
100 use require_c_abi_if_variadic;
101 use session::{Session, CompileResult};
104 use util::common::{ErrorReported, indenter};
105 use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap};
107 use std::cell::{Cell, RefCell};
109 use std::mem::replace;
110 use std::ops::{self, Deref};
111 use syntax::abi::Abi;
113 use syntax::codemap::{self, original_sp, Spanned};
114 use syntax::feature_gate::{GateIssue, emit_feature_err};
116 use syntax::symbol::{Symbol, InternedString, keywords};
117 use syntax::util::lev_distance::find_best_match_for_name;
118 use syntax_pos::{self, BytePos, Span, DUMMY_SP};
120 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
121 use rustc::hir::itemlikevisit::ItemLikeVisitor;
122 use rustc::hir::{self, PatKind};
123 use rustc::middle::lang_items;
124 use rustc_back::slice;
125 use rustc_const_eval::eval_length;
126 use rustc_const_math::ConstInt;
146 /// closures defined within the function. For example:
149 /// bar(move|| { ... })
152 /// Here, the function `foo()` and the closure passed to
153 /// `bar()` will each have their own `FnCtxt`, but they will
154 /// share the inherited fields.
155 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
156 infcx: InferCtxt<'a, 'gcx, 'tcx>,
158 locals: RefCell<NodeMap<Ty<'tcx>>>,
160 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
162 // When we process a call like `c()` where `c` is a closure type,
163 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
164 // `FnOnce` closure. In that case, we defer full resolution of the
165 // call until upvar inference can kick in and make the
166 // decision. We keep these deferred resolutions grouped by the
167 // def-id of the closure, so that once we decide, we can easily go
168 // back and process them.
169 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
171 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
173 // Anonymized types found in explicit return types and their
174 // associated fresh inference variable. Writeback resolves these
175 // variables to get the concrete type, which can be used to
176 // deanonymize TyAnon, after typeck is done with all functions.
177 anon_types: RefCell<NodeMap<Ty<'tcx>>>,
180 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
181 type Target = InferCtxt<'a, 'gcx, 'tcx>;
182 fn deref(&self) -> &Self::Target {
187 trait DeferredCallResolution<'gcx, 'tcx> {
188 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
191 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
193 /// When type-checking an expression, we propagate downward
194 /// whatever type hint we are able in the form of an `Expectation`.
195 #[derive(Copy, Clone, Debug)]
196 pub enum Expectation<'tcx> {
197 /// We know nothing about what type this expression should have.
200 /// This expression should have the type given (or some subtype)
201 ExpectHasType(Ty<'tcx>),
203 /// This expression will be cast to the `Ty`
204 ExpectCastableToType(Ty<'tcx>),
206 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
207 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
208 ExpectRvalueLikeUnsized(Ty<'tcx>),
211 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
212 // Disregard "castable to" expectations because they
213 // can lead us astray. Consider for example `if cond
214 // {22} else {c} as u8` -- if we propagate the
215 // "castable to u8" constraint to 22, it will pick the
216 // type 22u8, which is overly constrained (c might not
217 // be a u8). In effect, the problem is that the
218 // "castable to" expectation is not the tightest thing
219 // we can say, so we want to drop it in this case.
220 // The tightest thing we can say is "must unify with
221 // else branch". Note that in the case of a "has type"
222 // constraint, this limitation does not hold.
224 // If the expected type is just a type variable, then don't use
225 // an expected type. Otherwise, we might write parts of the type
226 // when checking the 'then' block which are incompatible with the
228 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
230 ExpectHasType(ety) => {
231 let ety = fcx.shallow_resolve(ety);
232 if !ety.is_ty_var() {
238 ExpectRvalueLikeUnsized(ety) => {
239 ExpectRvalueLikeUnsized(ety)
245 /// Provide an expectation for an rvalue expression given an *optional*
246 /// hint, which is not required for type safety (the resulting type might
247 /// be checked higher up, as is the case with `&expr` and `box expr`), but
248 /// is useful in determining the concrete type.
250 /// The primary use case is where the expected type is a fat pointer,
251 /// like `&[isize]`. For example, consider the following statement:
253 /// let x: &[isize] = &[1, 2, 3];
255 /// In this case, the expected type for the `&[1, 2, 3]` expression is
256 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
257 /// expectation `ExpectHasType([isize])`, that would be too strong --
258 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
259 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
260 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
261 /// which still is useful, because it informs integer literals and the like.
262 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
263 /// for examples of where this comes up,.
264 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
265 match fcx.tcx.struct_tail(ty).sty {
266 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
267 ExpectRvalueLikeUnsized(ty)
269 _ => ExpectHasType(ty)
273 // Resolves `expected` by a single level if it is a variable. If
274 // there is no expected type or resolution is not possible (e.g.,
275 // no constraints yet present), just returns `None`.
276 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
281 ExpectCastableToType(t) => {
282 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
284 ExpectHasType(t) => {
285 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
287 ExpectRvalueLikeUnsized(t) => {
288 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
293 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
294 match self.resolve(fcx) {
295 NoExpectation => None,
296 ExpectCastableToType(ty) |
298 ExpectRvalueLikeUnsized(ty) => Some(ty),
302 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
303 match self.resolve(fcx) {
304 ExpectHasType(ty) => Some(ty),
310 #[derive(Copy, Clone)]
311 pub struct UnsafetyState {
312 pub def: ast::NodeId,
313 pub unsafety: hir::Unsafety,
314 pub unsafe_push_count: u32,
319 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
320 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
323 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
324 match self.unsafety {
325 // If this unsafe, then if the outer function was already marked as
326 // unsafe we shouldn't attribute the unsafe'ness to the block. This
327 // way the block can be warned about instead of ignoring this
328 // extraneous block (functions are never warned about).
329 hir::Unsafety::Unsafe if self.from_fn => *self,
332 let (unsafety, def, count) = match blk.rules {
333 hir::PushUnsafeBlock(..) =>
334 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
335 hir::PopUnsafeBlock(..) =>
336 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
337 hir::UnsafeBlock(..) =>
338 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
340 (unsafety, self.def, self.unsafe_push_count),
342 UnsafetyState{ def: def,
344 unsafe_push_count: count,
351 /// Whether a node ever exits normally or not.
352 /// Tracked semi-automatically (through type variables
353 /// marked as diverging), with some manual adjustments
354 /// for control-flow primitives (approximating a CFG).
355 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
357 /// Potentially unknown, some cases converge,
358 /// others require a CFG to determine them.
361 /// Definitely known to diverge and therefore
362 /// not reach the next sibling or its parent.
365 /// Same as `Always` but with a reachability
366 /// warning already emitted
370 // Convenience impls for combinig `Diverges`.
372 impl ops::BitAnd for Diverges {
374 fn bitand(self, other: Self) -> Self {
375 cmp::min(self, other)
379 impl ops::BitOr for Diverges {
381 fn bitor(self, other: Self) -> Self {
382 cmp::max(self, other)
386 impl ops::BitAndAssign for Diverges {
387 fn bitand_assign(&mut self, other: Self) {
388 *self = *self & other;
392 impl ops::BitOrAssign for Diverges {
393 fn bitor_assign(&mut self, other: Self) {
394 *self = *self | other;
399 fn always(self) -> bool {
400 self >= Diverges::Always
405 pub struct BreakableCtxt<'gcx, 'tcx> {
408 break_exprs: Vec<&'gcx hir::Expr>,
413 pub struct EnclosingBreakables<'gcx, 'tcx> {
414 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
415 by_id: NodeMap<usize>,
418 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
419 fn find_breakable(&mut self, target: hir::ScopeTarget)
420 -> Option<&mut BreakableCtxt<'gcx, 'tcx>>
422 let opt_index = target.opt_id().and_then(|id| self.by_id.get(&id).cloned());
423 if let Some(ix) = opt_index {
424 Some(&mut self.stack[ix])
432 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
433 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
435 body_id: ast::NodeId,
437 // Number of errors that had been reported when we started
438 // checking this function. On exit, if we find that *more* errors
439 // have been reported, we will skip regionck and other work that
440 // expects the types within the function to be consistent.
441 err_count_on_creation: usize,
443 ret_ty: Option<Ty<'tcx>>,
445 ps: RefCell<UnsafetyState>,
447 /// Whether the last checked node can ever exit.
448 diverges: Cell<Diverges>,
450 /// Whether any child nodes have any type errors.
451 has_errors: Cell<bool>,
453 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
455 inh: &'a Inherited<'a, 'gcx, 'tcx>,
458 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
459 type Target = Inherited<'a, 'gcx, 'tcx>;
460 fn deref(&self) -> &Self::Target {
465 /// Helper type of a temporary returned by Inherited::build(...).
466 /// Necessary because we can't write the following bound:
467 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
468 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
469 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
472 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
473 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId)
474 -> InheritedBuilder<'a, 'gcx, 'tcx> {
475 let tables = ty::TypeckTables::empty();
476 let param_env = ParameterEnvironment::for_item(tcx, id);
478 infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing)
483 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
484 fn enter<F, R>(&'tcx mut self, f: F) -> R
485 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
487 self.infcx.enter(|infcx| f(Inherited::new(infcx)))
491 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
492 pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
495 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
496 locals: RefCell::new(NodeMap()),
497 deferred_call_resolutions: RefCell::new(DefIdMap()),
498 deferred_cast_checks: RefCell::new(Vec::new()),
499 anon_types: RefCell::new(NodeMap()),
503 fn normalize_associated_types_in<T>(&self,
505 body_id: ast::NodeId,
508 where T : TypeFoldable<'tcx>
510 assoc::normalize_associated_types_in(self,
511 &mut self.fulfillment_cx.borrow_mut(),
519 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
521 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
522 fn visit_item(&mut self, i: &'tcx hir::Item) {
523 check_item_type(self.tcx, i);
525 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
526 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
529 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
530 tcx.sess.track_errors(|| {
531 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
532 tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor());
536 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
537 tcx.sess.track_errors(|| {
538 tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType,
539 &mut CheckItemTypesVisitor { tcx });
543 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
544 ty::queries::typeck_item_bodies::get(tcx, DUMMY_SP, LOCAL_CRATE)
547 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
548 debug_assert!(crate_num == LOCAL_CRATE);
549 tcx.sess.track_errors(|| {
550 tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
551 tcx.item_tables(body_owner_def_id);
556 pub fn provide(providers: &mut Providers) {
557 *providers = Providers {
567 fn closure_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
569 -> ty::PolyFnSig<'tcx> {
570 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
571 tcx.item_tables(def_id).closure_tys[&node_id]
574 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
577 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
578 tcx.item_tables(def_id).closure_kinds[&node_id]
581 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
583 -> Option<ty::Destructor> {
584 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
587 fn typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
589 -> &'tcx ty::TypeckTables<'tcx> {
590 // Closures' tables come from their outermost function,
591 // as they are part of the same "inference environment".
592 let outer_def_id = tcx.closure_base_def_id(def_id);
593 if outer_def_id != def_id {
594 return tcx.item_tables(outer_def_id);
597 let id = tcx.hir.as_local_node_id(def_id).unwrap();
598 let span = tcx.hir.span(id);
599 let unsupported = || {
600 span_bug!(span, "can't type-check body of {:?}", def_id);
603 // Figure out what primary body this item has.
604 let mut fn_decl = None;
605 let body_id = match tcx.hir.get(id) {
606 hir::map::NodeItem(item) => {
608 hir::ItemConst(_, body) |
609 hir::ItemStatic(_, _, body) => body,
610 hir::ItemFn(ref decl, .., body) => {
611 fn_decl = Some(decl);
617 hir::map::NodeTraitItem(item) => {
619 hir::TraitItemKind::Const(_, Some(body)) => body,
620 hir::TraitItemKind::Method(ref sig,
621 hir::TraitMethod::Provided(body)) => {
622 fn_decl = Some(&sig.decl);
628 hir::map::NodeImplItem(item) => {
630 hir::ImplItemKind::Const(_, body) => body,
631 hir::ImplItemKind::Method(ref sig, body) => {
632 fn_decl = Some(&sig.decl);
638 hir::map::NodeExpr(expr) => {
639 // FIXME(eddyb) Closures should have separate
640 // function definition IDs and expression IDs.
641 // Type-checking should not let closures get
642 // this far in a constant position.
643 // Assume that everything other than closures
644 // is a constant "initializer" expression.
646 hir::ExprClosure(..) => {
647 // We should've bailed out above for closures.
648 span_bug!(expr.span, "unexpected closure")
650 _ => hir::BodyId { node_id: expr.id }
655 let body = tcx.hir.body(body_id);
657 Inherited::build(tcx, id).enter(|inh| {
658 let fcx = if let Some(decl) = fn_decl {
659 let fn_sig = tcx.item_type(def_id).fn_sig();
661 check_abi(tcx, span, fn_sig.abi());
663 // Compute the fty from point of view of inside fn.
664 let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id);
666 fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
668 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
670 inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
672 check_fn(&inh, fn_sig, decl, id, body)
674 let fcx = FnCtxt::new(&inh, None, body.value.id);
675 let expected_type = tcx.item_type(def_id);
676 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
677 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
679 // Gather locals in statics (because of block expressions).
680 // This is technically unnecessary because locals in static items are forbidden,
681 // but prevents type checking from blowing up before const checking can properly
683 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
685 fcx.check_expr_coercable_to_type(&body.value, expected_type);
690 fcx.select_all_obligations_and_apply_defaults();
691 fcx.closure_analyze(body);
692 fcx.select_obligations_where_possible();
694 fcx.select_all_obligations_or_error();
696 if fn_decl.is_some() {
697 fcx.regionck_fn(id, body);
699 fcx.regionck_expr(body);
702 fcx.resolve_type_vars_in_body(body)
706 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
707 if !tcx.sess.target.target.is_abi_supported(abi) {
708 struct_span_err!(tcx.sess, span, E0570,
709 "The ABI `{}` is not supported for the current target", abi).emit()
713 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
714 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
717 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
718 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
721 // infer the variable's type
722 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
723 self.fcx.locals.borrow_mut().insert(nid, var_ty);
727 // take type that the user specified
728 self.fcx.locals.borrow_mut().insert(nid, typ);
735 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
736 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
737 NestedVisitorMap::None
740 // Add explicitly-declared locals.
741 fn visit_local(&mut self, local: &'gcx hir::Local) {
742 let o_ty = match local.ty {
743 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
746 self.assign(local.span, local.id, o_ty);
747 debug!("Local variable {:?} is assigned type {}",
749 self.fcx.ty_to_string(
750 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
751 intravisit::walk_local(self, local);
754 // Add pattern bindings.
755 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
756 if let PatKind::Binding(_, _, ref path1, _) = p.node {
757 let var_ty = self.assign(p.span, p.id, None);
759 self.fcx.require_type_is_sized(var_ty, p.span,
760 traits::VariableType(p.id));
762 debug!("Pattern binding {} is assigned to {} with type {:?}",
764 self.fcx.ty_to_string(
765 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
768 intravisit::walk_pat(self, p);
771 // Don't descend into the bodies of nested closures
772 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
773 _: hir::BodyId, _: Span, _: ast::NodeId) { }
776 /// Helper used for fns and closures. Does the grungy work of checking a function
777 /// body and returns the function context used for that purpose, since in the case of a fn item
778 /// there is still a bit more to do.
781 /// * inherited: other fields inherited from the enclosing fn (if any)
782 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
783 fn_sig: ty::FnSig<'tcx>,
784 decl: &'gcx hir::FnDecl,
786 body: &'gcx hir::Body)
787 -> FnCtxt<'a, 'gcx, 'tcx>
789 let mut fn_sig = fn_sig.clone();
791 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
793 // Create the function context. This is either derived from scratch or,
794 // in the case of function expressions, based on the outer context.
795 let mut fcx = FnCtxt::new(inherited, None, body.value.id);
796 let ret_ty = fn_sig.output();
797 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
799 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
800 fcx.ret_ty = fcx.instantiate_anon_types(&Some(ret_ty));
801 fn_sig = fcx.tcx.mk_fn_sig(
802 fn_sig.inputs().iter().cloned(),
809 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
811 // Add formal parameters.
812 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
813 // The type of the argument must be well-formed.
815 // NB -- this is now checked in wfcheck, but that
816 // currently only results in warnings, so we issue an
817 // old-style WF obligation here so that we still get the
818 // errors that we used to get.
819 fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
821 // Check the pattern.
822 fcx.check_pat_arg(&arg.pat, arg_ty, true);
823 fcx.write_ty(arg.id, arg_ty);
826 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
828 fcx.check_expr_coercable_to_type(&body.value, fcx.ret_ty.unwrap());
833 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
836 let def_id = tcx.hir.local_def_id(id);
837 let def = tcx.lookup_adt_def(def_id);
838 def.destructor(tcx); // force the destructor to be evaluated
839 check_representable(tcx, span, def_id);
842 check_simd(tcx, span, def_id);
846 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
849 let def_id = tcx.hir.local_def_id(id);
850 let def = tcx.lookup_adt_def(def_id);
851 def.destructor(tcx); // force the destructor to be evaluated
852 check_representable(tcx, span, def_id);
855 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
856 debug!("check_item_type(it.id={}, it.name={})",
858 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
859 let _indenter = indenter();
861 // Consts can play a role in type-checking, so they are included here.
862 hir::ItemStatic(..) |
863 hir::ItemConst(..) => {
864 tcx.item_tables(tcx.hir.local_def_id(it.id));
866 hir::ItemEnum(ref enum_definition, _) => {
869 &enum_definition.variants,
872 hir::ItemFn(..) => {} // entirely within check_item_body
873 hir::ItemImpl(.., ref impl_item_refs) => {
874 debug!("ItemImpl {} with id {}", it.name, it.id);
875 let impl_def_id = tcx.hir.local_def_id(it.id);
876 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
877 check_impl_items_against_trait(tcx,
882 let trait_def_id = impl_trait_ref.def_id;
883 check_on_unimplemented(tcx, trait_def_id, it);
886 hir::ItemTrait(..) => {
887 let def_id = tcx.hir.local_def_id(it.id);
888 check_on_unimplemented(tcx, def_id, it);
890 hir::ItemStruct(..) => {
891 check_struct(tcx, it.id, it.span);
893 hir::ItemUnion(..) => {
894 check_union(tcx, it.id, it.span);
896 hir::ItemTy(_, ref generics) => {
897 let def_id = tcx.hir.local_def_id(it.id);
898 let pty_ty = tcx.item_type(def_id);
899 check_bounds_are_used(tcx, generics, pty_ty);
901 hir::ItemForeignMod(ref m) => {
902 check_abi(tcx, it.span, m.abi);
904 if m.abi == Abi::RustIntrinsic {
905 for item in &m.items {
906 intrinsic::check_intrinsic_type(tcx, item);
908 } else if m.abi == Abi::PlatformIntrinsic {
909 for item in &m.items {
910 intrinsic::check_platform_intrinsic_type(tcx, item);
913 for item in &m.items {
914 let generics = tcx.item_generics(tcx.hir.local_def_id(item.id));
915 if !generics.types.is_empty() {
916 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
917 "foreign items may not have type parameters");
918 span_help!(&mut err, item.span,
919 "consider using specialization instead of \
924 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
925 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
930 _ => {/* nothing to do */ }
934 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
937 let generics = tcx.item_generics(def_id);
938 if let Some(ref attr) = item.attrs.iter().find(|a| {
939 a.check_name("rustc_on_unimplemented")
941 if let Some(istring) = attr.value_str() {
942 let istring = istring.as_str();
943 let parser = Parser::new(&istring);
944 let types = &generics.types;
945 for token in parser {
947 Piece::String(_) => (), // Normal string, no need to check it
948 Piece::NextArgument(a) => match a.position {
949 // `{Self}` is allowed
950 Position::ArgumentNamed(s) if s == "Self" => (),
951 // So is `{A}` if A is a type parameter
952 Position::ArgumentNamed(s) => match types.iter().find(|t| {
957 let name = tcx.item_name(def_id);
958 span_err!(tcx.sess, attr.span, E0230,
959 "there is no type parameter \
964 // `{:1}` and `{}` are not to be used
965 Position::ArgumentIs(_) => {
966 span_err!(tcx.sess, attr.span, E0231,
967 "only named substitution \
968 parameters are allowed");
975 tcx.sess, attr.span, E0232,
976 "this attribute must have a value")
977 .span_label(attr.span, &format!("attribute requires a value"))
978 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
984 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
985 impl_item: &hir::ImplItem,
988 let mut err = struct_span_err!(
989 tcx.sess, impl_item.span, E0520,
990 "`{}` specializes an item from a parent `impl`, but \
991 that item is not marked `default`",
993 err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
996 match tcx.span_of_impl(parent_impl) {
998 err.span_label(span, &"parent `impl` is here");
999 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1003 err.note(&format!("parent implementation is in crate `{}`", cname));
1010 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1011 trait_def: &ty::TraitDef,
1013 impl_item: &hir::ImplItem)
1015 let ancestors = trait_def.ancestors(impl_id);
1017 let kind = match impl_item.node {
1018 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1019 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1020 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1022 let parent = ancestors.defs(tcx, impl_item.name, kind).skip(1).next()
1023 .map(|node_item| node_item.map(|parent| parent.defaultness));
1025 if let Some(parent) = parent {
1026 if parent.item.is_final() {
1027 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1033 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1036 impl_trait_ref: ty::TraitRef<'tcx>,
1037 impl_item_refs: &[hir::ImplItemRef]) {
1038 // If the trait reference itself is erroneous (so the compilation is going
1039 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1040 // isn't populated for such impls.
1041 if impl_trait_ref.references_error() { return; }
1043 // Locate trait definition and items
1044 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
1045 let mut overridden_associated_type = None;
1047 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1049 // Check existing impl methods to see if they are both present in trait
1050 // and compatible with trait signature
1051 for impl_item in impl_items() {
1052 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1053 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1054 .find(|ac| ac.name == ty_impl_item.name);
1056 // Check that impl definition matches trait definition
1057 if let Some(ty_trait_item) = ty_trait_item {
1058 match impl_item.node {
1059 hir::ImplItemKind::Const(..) => {
1060 // Find associated const definition.
1061 if ty_trait_item.kind == ty::AssociatedKind::Const {
1062 compare_const_impl(tcx,
1068 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1069 "item `{}` is an associated const, \
1070 which doesn't match its trait `{}`",
1073 err.span_label(impl_item.span, &format!("does not match trait"));
1074 // We can only get the spans from local trait definition
1075 // Same for E0324 and E0325
1076 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1077 err.span_label(trait_span, &format!("item in trait"));
1082 hir::ImplItemKind::Method(_, body_id) => {
1083 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1084 if ty_trait_item.kind == ty::AssociatedKind::Method {
1085 let err_count = tcx.sess.err_count();
1086 compare_impl_method(tcx,
1093 true); // start with old-broken-mode
1094 if err_count == tcx.sess.err_count() {
1095 // old broken mode did not report an error. Try with the new mode.
1096 compare_impl_method(tcx,
1103 false); // use the new mode
1106 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1107 "item `{}` is an associated method, \
1108 which doesn't match its trait `{}`",
1111 err.span_label(impl_item.span, &format!("does not match trait"));
1112 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1113 err.span_label(trait_span, &format!("item in trait"));
1118 hir::ImplItemKind::Type(_) => {
1119 if ty_trait_item.kind == ty::AssociatedKind::Type {
1120 if ty_trait_item.defaultness.has_value() {
1121 overridden_associated_type = Some(impl_item);
1124 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1125 "item `{}` is an associated type, \
1126 which doesn't match its trait `{}`",
1129 err.span_label(impl_item.span, &format!("does not match trait"));
1130 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1131 err.span_label(trait_span, &format!("item in trait"));
1139 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1142 // Check for missing items from trait
1143 let mut missing_items = Vec::new();
1144 let mut invalidated_items = Vec::new();
1145 let associated_type_overridden = overridden_associated_type.is_some();
1146 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1147 let is_implemented = trait_def.ancestors(impl_id)
1148 .defs(tcx, trait_item.name, trait_item.kind)
1150 .map(|node_item| !node_item.node.is_from_trait())
1153 if !is_implemented {
1154 if !trait_item.defaultness.has_value() {
1155 missing_items.push(trait_item);
1156 } else if associated_type_overridden {
1157 invalidated_items.push(trait_item.name);
1162 let signature = |item: &ty::AssociatedItem| {
1164 ty::AssociatedKind::Method => {
1165 format!("{}", tcx.item_type(item.def_id).fn_sig().0)
1167 ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
1168 ty::AssociatedKind::Const => {
1169 format!("const {}: {:?};", item.name.to_string(), tcx.item_type(item.def_id))
1174 if !missing_items.is_empty() {
1175 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1176 "not all trait items implemented, missing: `{}`",
1177 missing_items.iter()
1178 .map(|trait_item| trait_item.name.to_string())
1179 .collect::<Vec<_>>().join("`, `"));
1180 err.span_label(impl_span, &format!("missing `{}` in implementation",
1181 missing_items.iter()
1182 .map(|trait_item| trait_item.name.to_string())
1183 .collect::<Vec<_>>().join("`, `")));
1184 for trait_item in missing_items {
1185 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1186 err.span_label(span, &format!("`{}` from trait", trait_item.name));
1188 err.note(&format!("`{}` from trait: `{}`",
1190 signature(&trait_item)));
1196 if !invalidated_items.is_empty() {
1197 let invalidator = overridden_associated_type.unwrap();
1198 span_err!(tcx.sess, invalidator.span, E0399,
1199 "the following trait items need to be reimplemented \
1200 as `{}` was overridden: `{}`",
1202 invalidated_items.iter()
1203 .map(|name| name.to_string())
1204 .collect::<Vec<_>>().join("`, `"))
1208 /// Checks whether a type can be represented in memory. In particular, it
1209 /// identifies types that contain themselves without indirection through a
1210 /// pointer, which would mean their size is unbounded.
1211 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1215 let rty = tcx.item_type(item_def_id);
1217 // Check that it is possible to represent this type. This call identifies
1218 // (1) types that contain themselves and (2) types that contain a different
1219 // recursive type. It is only necessary to throw an error on those that
1220 // contain themselves. For case 2, there must be an inner type that will be
1221 // caught by case 1.
1222 match rty.is_representable(tcx, sp) {
1223 Representability::SelfRecursive => {
1224 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1227 Representability::Representable | Representability::ContainsRecursive => (),
1232 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1233 let t = tcx.item_type(def_id);
1235 ty::TyAdt(def, substs) if def.is_struct() => {
1236 let fields = &def.struct_variant().fields;
1237 if fields.is_empty() {
1238 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1241 let e = fields[0].ty(tcx, substs);
1242 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1243 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1244 .span_label(sp, &format!("SIMD elements must have the same type"))
1249 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1250 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1252 span_err!(tcx.sess, sp, E0077,
1253 "SIMD vector element type should be machine type");
1262 #[allow(trivial_numeric_casts)]
1263 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1265 vs: &'tcx [hir::Variant],
1267 let def_id = tcx.hir.local_def_id(id);
1268 let def = tcx.lookup_adt_def(def_id);
1269 def.destructor(tcx); // force the destructor to be evaluated
1271 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1273 tcx.sess, sp, E0084,
1274 "unsupported representation for zero-variant enum")
1275 .span_label(sp, &format!("unsupported enum representation"))
1279 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1280 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1281 if !tcx.sess.features.borrow().i128_type {
1282 emit_feature_err(&tcx.sess.parse_sess,
1283 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1288 if let Some(e) = v.node.disr_expr {
1289 tcx.item_tables(tcx.hir.local_def_id(e.node_id));
1293 let mut disr_vals: Vec<ConstInt> = Vec::new();
1294 for (discr, v) in def.discriminants(tcx).zip(vs) {
1295 // Check for duplicate discriminant values
1296 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1297 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1298 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1299 let i_span = match variant_i.node.disr_expr {
1300 Some(expr) => tcx.hir.span(expr.node_id),
1301 None => tcx.hir.span(variant_i_node_id)
1303 let span = match v.node.disr_expr {
1304 Some(expr) => tcx.hir.span(expr.node_id),
1307 struct_span_err!(tcx.sess, span, E0081,
1308 "discriminant value `{}` already exists", disr_vals[i])
1309 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1310 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1313 disr_vals.push(discr);
1316 check_representable(tcx, sp, def_id);
1319 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1320 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1322 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1323 &self.ast_ty_to_ty_cache
1326 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1327 Some(&self.parameter_environment.free_substs)
1330 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1331 -> ty::GenericPredicates<'tcx>
1334 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1335 let item_id = tcx.hir.ty_param_owner(node_id);
1336 let item_def_id = tcx.hir.local_def_id(item_id);
1337 let generics = tcx.item_generics(item_def_id);
1338 let index = generics.type_param_to_index[&def_id.index];
1339 ty::GenericPredicates {
1341 predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| {
1343 ty::Predicate::Trait(ref data) => {
1344 data.0.self_ty().is_param(index)
1348 }).cloned().collect()
1352 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1353 -> Option<&'tcx ty::Region> {
1355 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1356 None => infer::MiscVariable(span)
1358 Some(self.next_region_var(v))
1361 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1362 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1365 fn ty_infer_for_def(&self,
1366 ty_param_def: &ty::TypeParameterDef,
1367 substs: &[Kind<'tcx>],
1368 span: Span) -> Ty<'tcx> {
1369 self.type_var_for_def(span, ty_param_def, substs)
1372 fn projected_ty_from_poly_trait_ref(&self,
1374 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1375 item_name: ast::Name)
1378 let (trait_ref, _) =
1379 self.replace_late_bound_regions_with_fresh_var(
1381 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1384 self.tcx().mk_projection(trait_ref, item_name)
1387 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1388 if ty.has_escaping_regions() {
1389 ty // FIXME: normalization and escaping regions
1391 self.normalize_associated_types_in(span, &ty)
1395 fn set_tainted_by_errors(&self) {
1396 self.infcx.set_tainted_by_errors()
1400 /// Controls whether the arguments are tupled. This is used for the call
1403 /// Tupling means that all call-side arguments are packed into a tuple and
1404 /// passed as a single parameter. For example, if tupling is enabled, this
1407 /// fn f(x: (isize, isize))
1409 /// Can be called as:
1416 #[derive(Clone, Eq, PartialEq)]
1417 enum TupleArgumentsFlag {
1422 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1423 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1424 rty: Option<Ty<'tcx>>,
1425 body_id: ast::NodeId)
1426 -> FnCtxt<'a, 'gcx, 'tcx> {
1428 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1430 err_count_on_creation: inh.tcx.sess.err_count(),
1432 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1433 ast::CRATE_NODE_ID)),
1434 diverges: Cell::new(Diverges::Maybe),
1435 has_errors: Cell::new(false),
1436 enclosing_breakables: RefCell::new(EnclosingBreakables {
1444 pub fn sess(&self) -> &Session {
1448 pub fn err_count_since_creation(&self) -> usize {
1449 self.tcx.sess.err_count() - self.err_count_on_creation
1452 /// Produce warning on the given node, if the current point in the
1453 /// function is unreachable, and there hasn't been another warning.
1454 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1455 if self.diverges.get() == Diverges::Always {
1456 self.diverges.set(Diverges::WarnedAlways);
1458 self.tables.borrow_mut().lints.add_lint(
1459 lint::builtin::UNREACHABLE_CODE,
1461 format!("unreachable {}", kind));
1467 code: ObligationCauseCode<'tcx>)
1468 -> ObligationCause<'tcx> {
1469 ObligationCause::new(span, self.body_id, code)
1472 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1473 self.cause(span, ObligationCauseCode::MiscObligation)
1476 /// Resolves type variables in `ty` if possible. Unlike the infcx
1477 /// version (resolve_type_vars_if_possible), this version will
1478 /// also select obligations if it seems useful, in an effort
1479 /// to get more type information.
1480 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1481 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1483 // No TyInfer()? Nothing needs doing.
1484 if !ty.has_infer_types() {
1485 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1489 // If `ty` is a type variable, see whether we already know what it is.
1490 ty = self.resolve_type_vars_if_possible(&ty);
1491 if !ty.has_infer_types() {
1492 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1496 // If not, try resolving pending obligations as much as
1497 // possible. This can help substantially when there are
1498 // indirect dependencies that don't seem worth tracking
1500 self.select_obligations_where_possible();
1501 ty = self.resolve_type_vars_if_possible(&ty);
1503 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1507 fn record_deferred_call_resolution(&self,
1508 closure_def_id: DefId,
1509 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1510 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1511 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1514 fn remove_deferred_call_resolutions(&self,
1515 closure_def_id: DefId)
1516 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1518 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1519 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1522 pub fn tag(&self) -> String {
1523 let self_ptr: *const FnCtxt = self;
1524 format!("{:?}", self_ptr)
1527 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1528 match self.locals.borrow().get(&nid) {
1531 span_bug!(span, "no type for local variable {}",
1532 self.tcx.hir.node_to_string(nid));
1538 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1539 debug!("write_ty({}, {:?}) in fcx {}",
1540 node_id, ty, self.tag());
1541 self.tables.borrow_mut().node_types.insert(node_id, ty);
1543 if ty.references_error() {
1544 self.has_errors.set(true);
1545 self.set_tainted_by_errors();
1548 // FIXME(canndrew): This is_never should probably be an is_uninhabited
1549 if ty.is_never() || self.type_var_diverges(ty) {
1550 self.diverges.set(self.diverges.get() | Diverges::Always);
1554 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1555 if !substs.substs.is_noop() {
1556 debug!("write_substs({}, {:?}) in fcx {}",
1561 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1565 pub fn write_autoderef_adjustment(&self,
1566 node_id: ast::NodeId,
1568 adjusted_ty: Ty<'tcx>) {
1569 self.write_adjustment(node_id, adjustment::Adjustment {
1570 kind: adjustment::Adjust::DerefRef {
1579 pub fn write_adjustment(&self,
1580 node_id: ast::NodeId,
1581 adj: adjustment::Adjustment<'tcx>) {
1582 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1584 if adj.is_identity() {
1588 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1591 /// Basically whenever we are converting from a type scheme into
1592 /// the fn body space, we always want to normalize associated
1593 /// types as well. This function combines the two.
1594 fn instantiate_type_scheme<T>(&self,
1596 substs: &Substs<'tcx>,
1599 where T : TypeFoldable<'tcx>
1601 let value = value.subst(self.tcx, substs);
1602 let result = self.normalize_associated_types_in(span, &value);
1603 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1610 /// As `instantiate_type_scheme`, but for the bounds found in a
1611 /// generic type scheme.
1612 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1613 -> ty::InstantiatedPredicates<'tcx> {
1614 let bounds = self.tcx.item_predicates(def_id);
1615 let result = bounds.instantiate(self.tcx, substs);
1616 let result = self.normalize_associated_types_in(span, &result.predicates);
1617 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1621 ty::InstantiatedPredicates {
1626 /// Replace all anonymized types with fresh inference variables
1627 /// and record them for writeback.
1628 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1629 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1630 if let ty::TyAnon(def_id, substs) = ty.sty {
1631 // Use the same type variable if the exact same TyAnon appears more
1632 // than once in the return type (e.g. if it's pased to a type alias).
1633 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1634 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1637 let span = self.tcx.def_span(def_id);
1638 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1639 self.anon_types.borrow_mut().insert(id, ty_var);
1641 let item_predicates = self.tcx.item_predicates(def_id);
1642 let bounds = item_predicates.instantiate(self.tcx, substs);
1644 for predicate in bounds.predicates {
1645 // Change the predicate to refer to the type variable,
1646 // which will be the concrete type, instead of the TyAnon.
1647 // This also instantiates nested `impl Trait`.
1648 let predicate = self.instantiate_anon_types(&predicate);
1650 // Require that the predicate holds for the concrete type.
1651 let cause = traits::ObligationCause::new(span, self.body_id,
1652 traits::ReturnType);
1653 self.register_predicate(traits::Obligation::new(cause, predicate));
1663 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1664 where T : TypeFoldable<'tcx>
1666 self.inh.normalize_associated_types_in(span, self.body_id, value)
1669 pub fn write_nil(&self, node_id: ast::NodeId) {
1670 self.write_ty(node_id, self.tcx.mk_nil());
1673 pub fn write_error(&self, node_id: ast::NodeId) {
1674 self.write_ty(node_id, self.tcx.types.err);
1677 pub fn require_type_meets(&self,
1680 code: traits::ObligationCauseCode<'tcx>,
1683 self.register_bound(
1686 traits::ObligationCause::new(span, self.body_id, code));
1689 pub fn require_type_is_sized(&self,
1692 code: traits::ObligationCauseCode<'tcx>)
1694 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1695 self.require_type_meets(ty, span, code, lang_item);
1698 pub fn register_bound(&self,
1701 cause: traits::ObligationCause<'tcx>)
1703 self.fulfillment_cx.borrow_mut()
1704 .register_bound(self, ty, def_id, cause);
1707 pub fn register_predicate(&self,
1708 obligation: traits::PredicateObligation<'tcx>)
1710 debug!("register_predicate({:?})", obligation);
1711 if obligation.has_escaping_regions() {
1712 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
1717 .register_predicate_obligation(self, obligation);
1720 pub fn register_predicates(&self,
1721 obligations: Vec<traits::PredicateObligation<'tcx>>)
1723 for obligation in obligations {
1724 self.register_predicate(obligation);
1728 pub fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
1729 self.register_predicates(infer_ok.obligations);
1733 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1734 let t = AstConv::ast_ty_to_ty(self, ast_t);
1735 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1739 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1740 match self.tables.borrow().node_types.get(&id) {
1742 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1744 bug!("no type for node {}: {} in fcx {}",
1745 id, self.tcx.hir.node_to_string(id),
1751 pub fn opt_node_ty_substs<F>(&self,
1754 F: FnOnce(&ty::ItemSubsts<'tcx>),
1756 if let Some(s) = self.tables.borrow().item_substs.get(&id) {
1761 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1762 /// outlive the region `r`.
1763 pub fn register_region_obligation(&self,
1765 region: &'tcx ty::Region,
1766 cause: traits::ObligationCause<'tcx>)
1768 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1769 fulfillment_cx.register_region_obligation(ty, region, cause);
1772 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1773 /// outlive the region `r`.
1774 pub fn register_wf_obligation(&self,
1777 code: traits::ObligationCauseCode<'tcx>)
1779 // WF obligations never themselves fail, so no real need to give a detailed cause:
1780 let cause = traits::ObligationCause::new(span, self.body_id, code);
1781 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1784 pub fn register_old_wf_obligation(&self,
1787 code: traits::ObligationCauseCode<'tcx>)
1789 // Registers an "old-style" WF obligation that uses the
1790 // implicator code. This is basically a buggy version of
1791 // `register_wf_obligation` that is being kept around
1792 // temporarily just to help with phasing in the newer rules.
1794 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1795 let cause = traits::ObligationCause::new(span, self.body_id, code);
1796 self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
1799 /// Registers obligations that all types appearing in `substs` are well-formed.
1800 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1802 for ty in substs.types() {
1803 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1807 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1808 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1809 /// trait/region obligations.
1811 /// For example, if there is a function:
1814 /// fn foo<'a,T:'a>(...)
1817 /// and a reference:
1823 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1824 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1825 pub fn add_obligations_for_parameters(&self,
1826 cause: traits::ObligationCause<'tcx>,
1827 predicates: &ty::InstantiatedPredicates<'tcx>)
1829 assert!(!predicates.has_escaping_regions());
1831 debug!("add_obligations_for_parameters(predicates={:?})",
1834 for obligation in traits::predicates_for_generics(cause, predicates) {
1835 self.register_predicate(obligation);
1839 // FIXME(arielb1): use this instead of field.ty everywhere
1840 // Only for fields! Returns <none> for methods>
1841 // Indifferent to privacy flags
1842 pub fn field_ty(&self,
1844 field: &'tcx ty::FieldDef,
1845 substs: &Substs<'tcx>)
1848 self.normalize_associated_types_in(span,
1849 &field.ty(self.tcx, substs))
1852 fn check_casts(&self) {
1853 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1854 for cast in deferred_cast_checks.drain(..) {
1859 /// Apply "fallbacks" to some types
1860 /// unconstrained types get replaced with ! or () (depending on whether
1861 /// feature(never_type) is enabled), unconstrained ints with i32, and
1862 /// unconstrained floats with f64.
1863 fn default_type_parameters(&self) {
1864 use rustc::ty::error::UnconstrainedNumeric::Neither;
1865 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1867 // Defaulting inference variables becomes very dubious if we have
1868 // encountered type-checking errors. Therefore, if we think we saw
1869 // some errors in this function, just resolve all uninstanted type
1870 // varibles to TyError.
1871 if self.is_tainted_by_errors() {
1872 for ty in &self.unsolved_variables() {
1873 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1874 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1875 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
1881 for ty in &self.unsolved_variables() {
1882 let resolved = self.resolve_type_vars_if_possible(ty);
1883 if self.type_var_diverges(resolved) {
1884 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
1886 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1887 self.tcx.mk_diverging_default());
1889 match self.type_is_unconstrained_numeric(resolved) {
1890 UnconstrainedInt => {
1891 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1893 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
1895 UnconstrainedFloat => {
1896 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1898 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
1906 fn select_all_obligations_and_apply_defaults(&self) {
1907 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
1908 self.new_select_all_obligations_and_apply_defaults();
1910 self.old_select_all_obligations_and_apply_defaults();
1914 // Implements old type inference fallback algorithm
1915 fn old_select_all_obligations_and_apply_defaults(&self) {
1916 self.select_obligations_where_possible();
1917 self.default_type_parameters();
1918 self.select_obligations_where_possible();
1921 fn new_select_all_obligations_and_apply_defaults(&self) {
1922 use rustc::ty::error::UnconstrainedNumeric::Neither;
1923 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1925 // For the time being this errs on the side of being memory wasteful but provides better
1927 // let type_variables = self.type_variables.clone();
1929 // There is a possibility that this algorithm will have to run an arbitrary number of times
1930 // to terminate so we bound it by the compiler's recursion limit.
1931 for _ in 0..self.tcx.sess.recursion_limit.get() {
1932 // First we try to solve all obligations, it is possible that the last iteration
1933 // has made it possible to make more progress.
1934 self.select_obligations_where_possible();
1936 let mut conflicts = Vec::new();
1938 // Collect all unsolved type, integral and floating point variables.
1939 let unsolved_variables = self.unsolved_variables();
1941 // We must collect the defaults *before* we do any unification. Because we have
1942 // directly attached defaults to the type variables any unification that occurs
1943 // will erase defaults causing conflicting defaults to be completely ignored.
1944 let default_map: FxHashMap<Ty<'tcx>, _> =
1947 .filter_map(|t| self.default(t).map(|d| (*t, d)))
1950 let mut unbound_tyvars = FxHashSet();
1952 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1954 // We loop over the unsolved variables, resolving them and if they are
1955 // and unconstrainted numeric type we add them to the set of unbound
1956 // variables. We do this so we only apply literal fallback to type
1957 // variables without defaults.
1958 for ty in &unsolved_variables {
1959 let resolved = self.resolve_type_vars_if_possible(ty);
1960 if self.type_var_diverges(resolved) {
1961 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1962 self.tcx.mk_diverging_default());
1964 match self.type_is_unconstrained_numeric(resolved) {
1965 UnconstrainedInt | UnconstrainedFloat => {
1966 unbound_tyvars.insert(resolved);
1973 // We now remove any numeric types that also have defaults, and instead insert
1974 // the type variable with a defined fallback.
1975 for ty in &unsolved_variables {
1976 if let Some(_default) = default_map.get(ty) {
1977 let resolved = self.resolve_type_vars_if_possible(ty);
1979 debug!("select_all_obligations_and_apply_defaults: \
1980 ty: {:?} with default: {:?}",
1983 match resolved.sty {
1984 ty::TyInfer(ty::TyVar(_)) => {
1985 unbound_tyvars.insert(ty);
1988 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1989 unbound_tyvars.insert(ty);
1990 if unbound_tyvars.contains(resolved) {
1991 unbound_tyvars.remove(resolved);
2000 // If there are no more fallbacks to apply at this point we have applied all possible
2001 // defaults and type inference will proceed as normal.
2002 if unbound_tyvars.is_empty() {
2006 // Finally we go through each of the unbound type variables and unify them with
2007 // the proper fallback, reporting a conflicting default error if any of the
2008 // unifications fail. We know it must be a conflicting default because the
2009 // variable would only be in `unbound_tyvars` and have a concrete value if
2010 // it had been solved by previously applying a default.
2012 // We wrap this in a transaction for error reporting, if we detect a conflict
2013 // we will rollback the inference context to its prior state so we can probe
2014 // for conflicts and correctly report them.
2016 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2018 self.apply_defaults_and_return_conflicts(&unbound_tyvars, &default_map, None)
2021 // If there are conflicts we rollback, otherwise commit
2022 if conflicts.len() > 0 {
2029 // Loop through each conflicting default, figuring out the default that caused
2030 // a unification failure and then report an error for each.
2031 for (conflict, default) in conflicts {
2032 let conflicting_default =
2033 self.apply_defaults_and_return_conflicts(
2040 .unwrap_or(type_variable::Default {
2041 ty: self.next_ty_var(
2042 TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)),
2043 origin_span: syntax_pos::DUMMY_SP,
2044 // what do I put here?
2045 def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID)
2048 // This is to ensure that we elimnate any non-determinism from the error
2049 // reporting by fixing an order, it doesn't matter what order we choose
2050 // just that it is consistent.
2051 let (first_default, second_default) =
2052 if default.def_id < conflicting_default.def_id {
2053 (default, conflicting_default)
2055 (conflicting_default, default)
2059 self.report_conflicting_default_types(
2060 first_default.origin_span,
2067 self.select_obligations_where_possible();
2070 // For use in error handling related to default type parameter fallback. We explicitly
2071 // apply the default that caused conflict first to a local version of the type variable
2072 // table then apply defaults until we find a conflict. That default must be the one
2073 // that caused conflict earlier.
2074 fn apply_defaults_and_return_conflicts<'b>(
2076 unbound_vars: &'b FxHashSet<Ty<'tcx>>,
2077 default_map: &'b FxHashMap<Ty<'tcx>, type_variable::Default<'tcx>>,
2078 conflict: Option<Ty<'tcx>>,
2079 ) -> impl Iterator<Item=(Ty<'tcx>, type_variable::Default<'tcx>)> + 'b {
2080 use rustc::ty::error::UnconstrainedNumeric::Neither;
2081 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2083 conflict.into_iter().chain(unbound_vars.iter().cloned()).flat_map(move |ty| {
2084 if self.type_var_diverges(ty) {
2085 self.demand_eqtype(syntax_pos::DUMMY_SP, ty,
2086 self.tcx.mk_diverging_default());
2088 match self.type_is_unconstrained_numeric(ty) {
2089 UnconstrainedInt => {
2090 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.i32)
2092 UnconstrainedFloat => {
2093 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.f64)
2096 if let Some(default) = default_map.get(ty) {
2097 let default = default.clone();
2098 let default_ty = self.normalize_associated_types_in(
2099 default.origin_span, &default.ty);
2100 match self.eq_types(false,
2101 &self.misc(default.origin_span),
2104 Ok(ok) => self.register_infer_ok_obligations(ok),
2106 return Some((ty, default));
2118 fn select_all_obligations_or_error(&self) {
2119 debug!("select_all_obligations_or_error");
2121 // upvar inference should have ensured that all deferred call
2122 // resolutions are handled by now.
2123 assert!(self.deferred_call_resolutions.borrow().is_empty());
2125 self.select_all_obligations_and_apply_defaults();
2127 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2129 match fulfillment_cx.select_all_or_error(self) {
2131 Err(errors) => { self.report_fulfillment_errors(&errors); }
2135 /// Select as many obligations as we can at present.
2136 fn select_obligations_where_possible(&self) {
2137 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2139 Err(errors) => { self.report_fulfillment_errors(&errors); }
2143 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2144 /// returns a type of `&T`, but the actual type we assign to the
2145 /// *expression* is `T`. So this function just peels off the return
2146 /// type by one layer to yield `T`.
2147 fn make_overloaded_lvalue_return_type(&self,
2148 method: MethodCallee<'tcx>)
2149 -> ty::TypeAndMut<'tcx>
2151 // extract method return type, which will be &T;
2152 // all LB regions should have been instantiated during method lookup
2153 let ret_ty = method.ty.fn_ret();
2154 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2156 // method returns &T, but the type as visible to user is T, so deref
2157 ret_ty.builtin_deref(true, NoPreference).unwrap()
2160 fn lookup_indexing(&self,
2162 base_expr: &'gcx hir::Expr,
2165 lvalue_pref: LvaluePreference)
2166 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2168 // FIXME(#18741) -- this is almost but not quite the same as the
2169 // autoderef that normal method probing does. They could likely be
2172 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2174 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2175 if let Some(final_mt) = self.try_index_step(
2176 MethodCall::expr(expr.id),
2177 expr, base_expr, adj_ty, autoderefs,
2178 false, lvalue_pref, idx_ty)
2180 autoderef.finalize(lvalue_pref, Some(base_expr));
2181 return Some(final_mt);
2184 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2185 autoderef.finalize(lvalue_pref, Some(base_expr));
2186 let adjusted_ty = self.tcx.mk_slice(element_ty);
2187 return self.try_index_step(
2188 MethodCall::expr(expr.id), expr, base_expr,
2189 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2192 autoderef.unambiguous_final_ty();
2196 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2197 /// (and otherwise adjust) `base_expr`, looking for a type which either
2198 /// supports builtin indexing or overloaded indexing.
2199 /// This loop implements one step in that search; the autoderef loop
2200 /// is implemented by `lookup_indexing`.
2201 fn try_index_step(&self,
2202 method_call: MethodCall,
2204 base_expr: &'gcx hir::Expr,
2205 adjusted_ty: Ty<'tcx>,
2208 lvalue_pref: LvaluePreference,
2210 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2213 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2214 autoderefs={}, unsize={}, index_ty={:?})",
2222 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2224 // First, try built-in indexing.
2225 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2226 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2227 debug!("try_index_step: success, using built-in indexing");
2228 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2230 self.write_autoderef_adjustment(base_expr.id, autoderefs, adjusted_ty);
2231 return Some((tcx.types.usize, ty));
2236 // Try `IndexMut` first, if preferred.
2237 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2238 (PreferMutLvalue, Some(trait_did)) => {
2239 self.lookup_method_in_trait_adjusted(expr.span,
2241 Symbol::intern("index_mut"),
2246 Some(vec![input_ty]))
2251 // Otherwise, fall back to `Index`.
2252 let method = match (method, tcx.lang_items.index_trait()) {
2253 (None, Some(trait_did)) => {
2254 self.lookup_method_in_trait_adjusted(expr.span,
2256 Symbol::intern("index"),
2261 Some(vec![input_ty]))
2263 (method, _) => method,
2266 // If some lookup succeeds, write callee into table and extract index/element
2267 // type from the method signature.
2268 // If some lookup succeeded, install method in table
2269 method.map(|method| {
2270 debug!("try_index_step: success, using overloaded indexing");
2271 self.tables.borrow_mut().method_map.insert(method_call, method);
2272 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2276 fn check_method_argument_types(&self,
2278 method_fn_ty: Ty<'tcx>,
2279 callee_expr: &'gcx hir::Expr,
2280 args_no_rcvr: &'gcx [hir::Expr],
2281 tuple_arguments: TupleArgumentsFlag,
2282 expected: Expectation<'tcx>)
2284 if method_fn_ty.references_error() {
2285 let err_inputs = self.err_args(args_no_rcvr.len());
2287 let err_inputs = match tuple_arguments {
2288 DontTupleArguments => err_inputs,
2289 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2292 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2293 false, tuple_arguments, None);
2296 match method_fn_ty.sty {
2297 ty::TyFnDef(def_id, .., ref fty) => {
2298 // HACK(eddyb) ignore self in the definition (see above).
2299 let expected_arg_tys = self.expected_inputs_for_expected_output(
2303 &fty.0.inputs()[1..]
2305 self.check_argument_types(sp, &fty.0.inputs()[1..], &expected_arg_tys[..],
2306 args_no_rcvr, fty.0.variadic, tuple_arguments,
2307 self.tcx.hir.span_if_local(def_id));
2311 span_bug!(callee_expr.span, "method without bare fn type");
2317 /// Generic function that factors out common logic from function calls,
2318 /// method calls and overloaded operators.
2319 fn check_argument_types(&self,
2321 fn_inputs: &[Ty<'tcx>],
2322 expected_arg_tys: &[Ty<'tcx>],
2323 args: &'gcx [hir::Expr],
2325 tuple_arguments: TupleArgumentsFlag,
2326 def_span: Option<Span>) {
2329 // Grab the argument types, supplying fresh type variables
2330 // if the wrong number of arguments were supplied
2331 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2337 // All the input types from the fn signature must outlive the call
2338 // so as to validate implied bounds.
2339 for &fn_input_ty in fn_inputs {
2340 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2343 let mut expected_arg_tys = expected_arg_tys;
2344 let expected_arg_count = fn_inputs.len();
2346 let sp_args = if args.len() > 0 {
2347 let (first, args) = args.split_at(1);
2348 let mut sp_tmp = first[0].span;
2350 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2351 if ! sp_opt.is_some() {
2354 sp_tmp = sp_opt.unwrap();
2361 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2362 arg_count: usize, error_code: &str, variadic: bool,
2363 def_span: Option<Span>) {
2364 let mut err = sess.struct_span_err_with_code(sp,
2365 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2366 if variadic {"at least "} else {""},
2368 if expected_count == 1 {""} else {"s"},
2370 if arg_count == 1 {" was"} else {"s were"}),
2373 err.span_label(sp, &format!("expected {}{} parameter{}",
2374 if variadic {"at least "} else {""},
2376 if expected_count == 1 {""} else {"s"}));
2377 if let Some(def_s) = def_span {
2378 err.span_label(def_s, &format!("defined here"));
2383 let formal_tys = if tuple_arguments == TupleArguments {
2384 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2385 match tuple_type.sty {
2386 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2387 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2388 "E0057", false, def_span);
2389 expected_arg_tys = &[];
2390 self.err_args(args.len())
2392 ty::TyTuple(arg_types, _) => {
2393 expected_arg_tys = match expected_arg_tys.get(0) {
2394 Some(&ty) => match ty.sty {
2395 ty::TyTuple(ref tys, _) => &tys,
2403 span_err!(tcx.sess, sp, E0059,
2404 "cannot use call notation; the first type parameter \
2405 for the function trait is neither a tuple nor unit");
2406 expected_arg_tys = &[];
2407 self.err_args(args.len())
2410 } else if expected_arg_count == supplied_arg_count {
2412 } else if variadic {
2413 if supplied_arg_count >= expected_arg_count {
2416 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2417 supplied_arg_count, "E0060", true, def_span);
2418 expected_arg_tys = &[];
2419 self.err_args(supplied_arg_count)
2422 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2423 supplied_arg_count, "E0061", false, def_span);
2424 expected_arg_tys = &[];
2425 self.err_args(supplied_arg_count)
2428 debug!("check_argument_types: formal_tys={:?}",
2429 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2431 // Check the arguments.
2432 // We do this in a pretty awful way: first we typecheck any arguments
2433 // that are not closures, then we typecheck the closures. This is so
2434 // that we have more information about the types of arguments when we
2435 // typecheck the functions. This isn't really the right way to do this.
2436 for &check_closures in &[false, true] {
2437 debug!("check_closures={}", check_closures);
2439 // More awful hacks: before we check argument types, try to do
2440 // an "opportunistic" vtable resolution of any trait bounds on
2441 // the call. This helps coercions.
2443 self.select_obligations_where_possible();
2446 // For variadic functions, we don't have a declared type for all of
2447 // the arguments hence we only do our usual type checking with
2448 // the arguments who's types we do know.
2449 let t = if variadic {
2451 } else if tuple_arguments == TupleArguments {
2456 for (i, arg) in args.iter().take(t).enumerate() {
2457 // Warn only for the first loop (the "no closures" one).
2458 // Closure arguments themselves can't be diverging, but
2459 // a previous argument can, e.g. `foo(panic!(), || {})`.
2460 if !check_closures {
2461 self.warn_if_unreachable(arg.id, arg.span, "expression");
2464 let is_closure = match arg.node {
2465 hir::ExprClosure(..) => true,
2469 if is_closure != check_closures {
2473 debug!("checking the argument");
2474 let formal_ty = formal_tys[i];
2476 // The special-cased logic below has three functions:
2477 // 1. Provide as good of an expected type as possible.
2478 let expected = expected_arg_tys.get(i).map(|&ty| {
2479 Expectation::rvalue_hint(self, ty)
2482 let checked_ty = self.check_expr_with_expectation(&arg,
2483 expected.unwrap_or(ExpectHasType(formal_ty)));
2484 // 2. Coerce to the most detailed type that could be coerced
2485 // to, which is `expected_ty` if `rvalue_hint` returns an
2486 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2487 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2488 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2490 // 3. Relate the expected type and the formal one,
2491 // if the expected type was used for the coercion.
2492 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2496 // We also need to make sure we at least write the ty of the other
2497 // arguments which we skipped above.
2499 for arg in args.iter().skip(expected_arg_count) {
2500 let arg_ty = self.check_expr(&arg);
2502 // There are a few types which get autopromoted when passed via varargs
2503 // in C but we just error out instead and require explicit casts.
2504 let arg_ty = self.structurally_resolved_type(arg.span,
2507 ty::TyFloat(ast::FloatTy::F32) => {
2508 self.type_error_message(arg.span, |t| {
2509 format!("can't pass an `{}` to variadic \
2510 function, cast to `c_double`", t)
2513 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2514 self.type_error_message(arg.span, |t| {
2515 format!("can't pass `{}` to variadic \
2516 function, cast to `c_int`",
2520 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2521 self.type_error_message(arg.span, |t| {
2522 format!("can't pass `{}` to variadic \
2523 function, cast to `c_uint`",
2527 ty::TyFnDef(.., f) => {
2528 let ptr_ty = self.tcx.mk_fn_ptr(f);
2529 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2530 self.type_error_message(arg.span,
2532 format!("can't pass `{}` to variadic \
2533 function, cast to `{}`", t, ptr_ty)
2542 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2543 (0..len).map(|_| self.tcx.types.err).collect()
2546 // AST fragment checking
2549 expected: Expectation<'tcx>)
2555 ast::LitKind::Str(..) => tcx.mk_static_str(),
2556 ast::LitKind::ByteStr(ref v) => {
2557 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2558 tcx.mk_array(tcx.types.u8, v.len()))
2560 ast::LitKind::Byte(_) => tcx.types.u8,
2561 ast::LitKind::Char(_) => tcx.types.char,
2562 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2563 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2564 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2565 let opt_ty = expected.to_option(self).and_then(|ty| {
2567 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2568 ty::TyChar => Some(tcx.types.u8),
2569 ty::TyRawPtr(..) => Some(tcx.types.usize),
2570 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2574 opt_ty.unwrap_or_else(
2575 || tcx.mk_int_var(self.next_int_var_id()))
2577 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2578 ast::LitKind::FloatUnsuffixed(_) => {
2579 let opt_ty = expected.to_option(self).and_then(|ty| {
2581 ty::TyFloat(_) => Some(ty),
2585 opt_ty.unwrap_or_else(
2586 || tcx.mk_float_var(self.next_float_var_id()))
2588 ast::LitKind::Bool(_) => tcx.types.bool
2592 fn check_expr_eq_type(&self,
2593 expr: &'gcx hir::Expr,
2594 expected: Ty<'tcx>) {
2595 let ty = self.check_expr_with_hint(expr, expected);
2596 self.demand_eqtype(expr.span, expected, ty);
2599 pub fn check_expr_has_type(&self,
2600 expr: &'gcx hir::Expr,
2601 expected: Ty<'tcx>) -> Ty<'tcx> {
2602 let ty = self.check_expr_with_hint(expr, expected);
2603 self.demand_suptype(expr.span, expected, ty);
2607 fn check_expr_coercable_to_type(&self,
2608 expr: &'gcx hir::Expr,
2609 expected: Ty<'tcx>) -> Ty<'tcx> {
2610 let ty = self.check_expr_with_hint(expr, expected);
2611 self.demand_coerce(expr, ty, expected);
2615 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2616 expected: Ty<'tcx>) -> Ty<'tcx> {
2617 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2620 fn check_expr_with_expectation(&self,
2621 expr: &'gcx hir::Expr,
2622 expected: Expectation<'tcx>) -> Ty<'tcx> {
2623 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2626 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2627 self.check_expr_with_expectation(expr, NoExpectation)
2630 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2631 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2632 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2635 // determine the `self` type, using fresh variables for all variables
2636 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2637 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2639 pub fn impl_self_ty(&self,
2640 span: Span, // (potential) receiver for this impl
2642 -> TypeAndSubsts<'tcx> {
2643 let ity = self.tcx.item_type(did);
2644 debug!("impl_self_ty: ity={:?}", ity);
2646 let substs = self.fresh_substs_for_item(span, did);
2647 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2649 TypeAndSubsts { substs: substs, ty: substd_ty }
2652 /// Unifies the output type with the expected type early, for more coercions
2653 /// and forward type information on the input expressions.
2654 fn expected_inputs_for_expected_output(&self,
2656 expected_ret: Expectation<'tcx>,
2657 formal_ret: Ty<'tcx>,
2658 formal_args: &[Ty<'tcx>])
2660 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2661 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2662 // Attempt to apply a subtyping relationship between the formal
2663 // return type (likely containing type variables if the function
2664 // is polymorphic) and the expected return type.
2665 // No argument expectations are produced if unification fails.
2666 let origin = self.misc(call_span);
2667 let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
2668 // FIXME(#15760) can't use try! here, FromError doesn't default
2669 // to identity so the resulting type is not constrained.
2671 Ok(ok) => self.register_infer_ok_obligations(ok),
2672 Err(e) => return Err(e),
2675 // Record all the argument types, with the substitutions
2676 // produced from the above subtyping unification.
2677 Ok(formal_args.iter().map(|ty| {
2678 self.resolve_type_vars_if_possible(ty)
2681 }).unwrap_or(vec![]);
2682 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2683 formal_args, formal_ret,
2684 expected_args, expected_ret);
2688 // Checks a method call.
2689 fn check_method_call(&self,
2690 expr: &'gcx hir::Expr,
2691 method_name: Spanned<ast::Name>,
2692 args: &'gcx [hir::Expr],
2694 expected: Expectation<'tcx>,
2695 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2696 let rcvr = &args[0];
2697 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2699 // no need to check for bot/err -- callee does that
2700 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2702 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2703 let fn_ty = match self.lookup_method(method_name.span,
2710 let method_ty = method.ty;
2711 let method_call = MethodCall::expr(expr.id);
2712 self.tables.borrow_mut().method_map.insert(method_call, method);
2716 if method_name.node != keywords::Invalid.name() {
2717 self.report_method_error(method_name.span,
2724 self.write_error(expr.id);
2729 // Call the generic checker.
2730 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2738 // A generic function for checking the then and else in an if
2740 fn check_then_else(&self,
2741 cond_expr: &'gcx hir::Expr,
2742 then_expr: &'gcx hir::Expr,
2743 opt_else_expr: Option<&'gcx hir::Expr>,
2745 expected: Expectation<'tcx>) -> Ty<'tcx> {
2746 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2747 let cond_diverges = self.diverges.get();
2748 self.diverges.set(Diverges::Maybe);
2750 let expected = expected.adjust_for_branches(self);
2751 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2752 let then_diverges = self.diverges.get();
2753 self.diverges.set(Diverges::Maybe);
2755 let unit = self.tcx.mk_nil();
2756 let (cause, expected_ty, found_ty, result);
2757 if let Some(else_expr) = opt_else_expr {
2758 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2759 let else_diverges = self.diverges.get();
2760 cause = self.cause(sp, ObligationCauseCode::IfExpression);
2762 // Only try to coerce-unify if we have a then expression
2763 // to assign coercions to, otherwise it's () or diverging.
2764 expected_ty = then_ty;
2767 let coerce_to = expected.only_has_type(self).unwrap_or(then_ty);
2769 self.try_coerce(then_expr, then_ty, coerce_to)
2771 self.try_find_coercion_lub(&cause, || Some(then_expr), t, else_expr, else_ty)
2775 // We won't diverge unless both branches do (or the condition does).
2776 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2778 // If the condition is false we can't diverge.
2779 self.diverges.set(cond_diverges);
2781 cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2784 result = self.eq_types(true, &cause, unit, then_ty)
2786 self.register_infer_ok_obligations(ok);
2793 if cond_ty.references_error() {
2800 self.report_mismatched_types(&cause, expected_ty, found_ty, e).emit();
2806 // Check field access expressions
2807 fn check_field(&self,
2808 expr: &'gcx hir::Expr,
2809 lvalue_pref: LvaluePreference,
2810 base: &'gcx hir::Expr,
2811 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2812 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2813 let expr_t = self.structurally_resolved_type(expr.span,
2815 let mut private_candidate = None;
2816 let mut autoderef = self.autoderef(expr.span, expr_t);
2817 while let Some((base_t, autoderefs)) = autoderef.next() {
2819 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2820 debug!("struct named {:?}", base_t);
2821 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2822 let field_ty = self.field_ty(expr.span, field, substs);
2823 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2824 autoderef.finalize(lvalue_pref, Some(base));
2825 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2827 self.tcx.check_stability(field.did, expr.id, expr.span);
2831 private_candidate = Some((base_def.did, field_ty));
2837 autoderef.unambiguous_final_ty();
2839 if let Some((did, field_ty)) = private_candidate {
2840 let struct_path = self.tcx().item_path_str(did);
2841 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2842 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2843 // Also check if an accessible method exists, which is often what is meant.
2844 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2845 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2850 } else if field.node == keywords::Invalid.name() {
2851 self.tcx().types.err
2852 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2853 self.type_error_struct(field.span, |actual| {
2854 format!("attempted to take value of method `{}` on type \
2855 `{}`", field.node, actual)
2857 .help("maybe a `()` to call it is missing? \
2858 If not, try an anonymous function")
2860 self.tcx().types.err
2862 let mut err = self.type_error_struct(field.span, |actual| {
2863 format!("no field `{}` on type `{}`",
2867 ty::TyAdt(def, _) if !def.is_enum() => {
2868 if let Some(suggested_field_name) =
2869 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2870 err.span_label(field.span,
2871 &format!("did you mean `{}`?", suggested_field_name));
2873 err.span_label(field.span,
2874 &format!("unknown field"));
2877 ty::TyRawPtr(..) => {
2878 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2880 self.tcx.hir.node_to_pretty_string(base.id),
2886 self.tcx().types.err
2890 // Return an hint about the closest match in field names
2891 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2892 field: &Spanned<ast::Name>,
2893 skip : Vec<InternedString>)
2895 let name = field.node.as_str();
2896 let names = variant.fields.iter().filter_map(|field| {
2897 // ignore already set fields and private fields from non-local crates
2898 if skip.iter().any(|x| *x == field.name.as_str()) ||
2899 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2906 // only find fits with at least one matching letter
2907 find_best_match_for_name(names, &name, Some(name.len()))
2910 // Check tuple index expressions
2911 fn check_tup_field(&self,
2912 expr: &'gcx hir::Expr,
2913 lvalue_pref: LvaluePreference,
2914 base: &'gcx hir::Expr,
2915 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2916 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2917 let expr_t = self.structurally_resolved_type(expr.span,
2919 let mut private_candidate = None;
2920 let mut tuple_like = false;
2921 let mut autoderef = self.autoderef(expr.span, expr_t);
2922 while let Some((base_t, autoderefs)) = autoderef.next() {
2923 let field = match base_t.sty {
2924 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2925 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2926 if !tuple_like { continue }
2928 debug!("tuple struct named {:?}", base_t);
2929 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
2930 let field_ty = self.field_ty(expr.span, field, substs);
2931 private_candidate = Some((base_def.did, field_ty));
2932 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2933 self.tcx.check_stability(field.did, expr.id, expr.span);
2940 ty::TyTuple(ref v, _) => {
2942 v.get(idx.node).cloned()
2947 if let Some(field_ty) = field {
2948 autoderef.finalize(lvalue_pref, Some(base));
2949 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2953 autoderef.unambiguous_final_ty();
2955 if let Some((did, field_ty)) = private_candidate {
2956 let struct_path = self.tcx().item_path_str(did);
2957 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
2958 self.tcx().sess.span_err(expr.span, &msg);
2962 self.type_error_message(
2966 format!("attempted out-of-bounds tuple index `{}` on \
2971 format!("attempted tuple index `{}` on type `{}`, but the \
2972 type was not a tuple or tuple struct",
2979 self.tcx().types.err
2982 fn report_unknown_field(&self,
2984 variant: &'tcx ty::VariantDef,
2986 skip_fields: &[hir::Field],
2988 let mut err = self.type_error_struct_with_diag(
2990 |actual| match ty.sty {
2991 ty::TyAdt(adt, ..) if adt.is_enum() => {
2992 struct_span_err!(self.tcx.sess, field.name.span, E0559,
2993 "{} `{}::{}` has no field named `{}`",
2994 kind_name, actual, variant.name, field.name.node)
2997 struct_span_err!(self.tcx.sess, field.name.span, E0560,
2998 "{} `{}` has no field named `{}`",
2999 kind_name, actual, field.name.node)
3003 // prevent all specified fields from being suggested
3004 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3005 if let Some(field_name) = Self::suggest_field_name(variant,
3007 skip_fields.collect()) {
3008 err.span_label(field.name.span,
3009 &format!("field does not exist - did you mean `{}`?", field_name));
3012 ty::TyAdt(adt, ..) if adt.is_enum() => {
3013 err.span_label(field.name.span, &format!("`{}::{}` does not have this field",
3017 err.span_label(field.name.span, &format!("`{}` does not have this field", ty));
3024 fn check_expr_struct_fields(&self,
3026 expected: Expectation<'tcx>,
3027 expr_id: ast::NodeId,
3029 variant: &'tcx ty::VariantDef,
3030 ast_fields: &'gcx [hir::Field],
3031 check_completeness: bool) {
3035 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3036 .get(0).cloned().unwrap_or(adt_ty);
3038 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3039 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3040 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3042 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3045 let mut remaining_fields = FxHashMap();
3046 for field in &variant.fields {
3047 remaining_fields.insert(field.name, field);
3050 let mut seen_fields = FxHashMap();
3052 let mut error_happened = false;
3054 // Typecheck each field.
3055 for field in ast_fields {
3056 let final_field_type;
3057 let field_type_hint;
3059 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3060 final_field_type = self.field_ty(field.span, v_field, substs);
3061 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3063 seen_fields.insert(field.name.node, field.span);
3065 // we don't look at stability attributes on
3066 // struct-like enums (yet...), but it's definitely not
3067 // a bug to have construct one.
3068 if adt_kind != ty::AdtKind::Enum {
3069 tcx.check_stability(v_field.did, expr_id, field.span);
3072 error_happened = true;
3073 final_field_type = tcx.types.err;
3074 field_type_hint = tcx.types.err;
3075 if let Some(_) = variant.find_field_named(field.name.node) {
3076 let mut err = struct_span_err!(self.tcx.sess,
3079 "field `{}` specified more than once",
3082 err.span_label(field.name.span, &format!("used more than once"));
3084 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3085 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3090 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3094 // Make sure to give a type to the field even if there's
3095 // an error, so we can continue typechecking
3096 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3097 self.demand_coerce(&field.expr, ty, final_field_type);
3100 // Make sure the programmer specified correct number of fields.
3101 if kind_name == "union" {
3102 if ast_fields.len() != 1 {
3103 tcx.sess.span_err(span, "union expressions should have exactly one field");
3105 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3106 let len = remaining_fields.len();
3108 let mut displayable_field_names = remaining_fields
3110 .map(|x| x.as_str())
3111 .collect::<Vec<_>>();
3113 displayable_field_names.sort();
3115 let truncated_fields_error = if len <= 3 {
3118 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3121 let remaining_fields_names = displayable_field_names.iter().take(3)
3122 .map(|n| format!("`{}`", n))
3123 .collect::<Vec<_>>()
3126 struct_span_err!(tcx.sess, span, E0063,
3127 "missing field{} {}{} in initializer of `{}`",
3128 if remaining_fields.len() == 1 {""} else {"s"},
3129 remaining_fields_names,
3130 truncated_fields_error,
3132 .span_label(span, &format!("missing {}{}",
3133 remaining_fields_names,
3134 truncated_fields_error))
3139 fn check_struct_fields_on_error(&self,
3140 fields: &'gcx [hir::Field],
3141 base_expr: &'gcx Option<P<hir::Expr>>) {
3142 for field in fields {
3143 self.check_expr(&field.expr);
3147 self.check_expr(&base);
3153 pub fn check_struct_path(&self,
3155 node_id: ast::NodeId)
3156 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3157 let path_span = match *qpath {
3158 hir::QPath::Resolved(_, ref path) => path.span,
3159 hir::QPath::TypeRelative(ref qself, _) => qself.span
3161 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3162 let variant = match def {
3164 self.set_tainted_by_errors();
3167 Def::Variant(..) => {
3169 ty::TyAdt(adt, substs) => {
3170 Some((adt.variant_of_def(def), adt.did, substs))
3172 _ => bug!("unexpected type: {:?}", ty.sty)
3175 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3176 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3178 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3179 Some((adt.struct_variant(), adt.did, substs))
3184 _ => bug!("unexpected definition: {:?}", def)
3187 if let Some((variant, did, substs)) = variant {
3188 // Check bounds on type arguments used in the path.
3189 let bounds = self.instantiate_bounds(path_span, did, substs);
3190 let cause = traits::ObligationCause::new(path_span, self.body_id,
3191 traits::ItemObligation(did));
3192 self.add_obligations_for_parameters(cause, &bounds);
3196 struct_span_err!(self.tcx.sess, path_span, E0071,
3197 "expected struct, variant or union type, found {}",
3198 ty.sort_string(self.tcx))
3199 .span_label(path_span, &format!("not a struct"))
3205 fn check_expr_struct(&self,
3207 expected: Expectation<'tcx>,
3209 fields: &'gcx [hir::Field],
3210 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3212 // Find the relevant variant
3213 let (variant, struct_ty) =
3214 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3217 self.check_struct_fields_on_error(fields, base_expr);
3218 return self.tcx.types.err;
3221 let path_span = match *qpath {
3222 hir::QPath::Resolved(_, ref path) => path.span,
3223 hir::QPath::TypeRelative(ref qself, _) => qself.span
3226 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3227 base_expr.is_none());
3228 if let &Some(ref base_expr) = base_expr {
3229 self.check_expr_has_type(base_expr, struct_ty);
3230 match struct_ty.sty {
3231 ty::TyAdt(adt, substs) if adt.is_struct() => {
3232 self.tables.borrow_mut().fru_field_types.insert(
3234 adt.struct_variant().fields.iter().map(|f| {
3235 self.normalize_associated_types_in(
3236 expr.span, &f.ty(self.tcx, substs)
3242 span_err!(self.tcx.sess, base_expr.span, E0436,
3243 "functional record update syntax requires a struct");
3247 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3253 /// If an expression has any sub-expressions that result in a type error,
3254 /// inspecting that expression's type with `ty.references_error()` will return
3255 /// true. Likewise, if an expression is known to diverge, inspecting its
3256 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3257 /// strict, _|_ can appear in the type of an expression that does not,
3258 /// itself, diverge: for example, fn() -> _|_.)
3259 /// Note that inspecting a type's structure *directly* may expose the fact
3260 /// that there are actually multiple representations for `TyError`, so avoid
3261 /// that when err needs to be handled differently.
3262 fn check_expr_with_expectation_and_lvalue_pref(&self,
3263 expr: &'gcx hir::Expr,
3264 expected: Expectation<'tcx>,
3265 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3266 debug!(">> typechecking: expr={:?} expected={:?}",
3269 // Warn for expressions after diverging siblings.
3270 self.warn_if_unreachable(expr.id, expr.span, "expression");
3272 // Hide the outer diverging and has_errors flags.
3273 let old_diverges = self.diverges.get();
3274 let old_has_errors = self.has_errors.get();
3275 self.diverges.set(Diverges::Maybe);
3276 self.has_errors.set(false);
3278 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3280 // Warn for non-block expressions with diverging children.
3283 hir::ExprLoop(..) | hir::ExprWhile(..) |
3284 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3286 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3289 // Record the type, which applies it effects.
3290 // We need to do this after the warning above, so that
3291 // we don't warn for the diverging expression itself.
3292 self.write_ty(expr.id, ty);
3294 // Combine the diverging and has_error flags.
3295 self.diverges.set(self.diverges.get() | old_diverges);
3296 self.has_errors.set(self.has_errors.get() | old_has_errors);
3298 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3299 debug!("... {:?}, expected is {:?}", ty, expected);
3301 // Add adjustments to !-expressions
3303 if let Some(hir::map::NodeExpr(node_expr)) = self.tcx.hir.find(expr.id) {
3304 let adj_ty = self.next_diverging_ty_var(
3305 TypeVariableOrigin::AdjustmentType(node_expr.span));
3306 self.write_adjustment(expr.id, adjustment::Adjustment {
3307 kind: adjustment::Adjust::NeverToAny,
3316 fn check_expr_kind(&self,
3317 expr: &'gcx hir::Expr,
3318 expected: Expectation<'tcx>,
3319 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3323 hir::ExprBox(ref subexpr) => {
3324 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3326 ty::TyAdt(def, _) if def.is_box()
3327 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3331 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3332 tcx.mk_box(referent_ty)
3335 hir::ExprLit(ref lit) => {
3336 self.check_lit(&lit, expected)
3338 hir::ExprBinary(op, ref lhs, ref rhs) => {
3339 self.check_binop(expr, op, lhs, rhs)
3341 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3342 self.check_binop_assign(expr, op, lhs, rhs)
3344 hir::ExprUnary(unop, ref oprnd) => {
3345 let expected_inner = match unop {
3346 hir::UnNot | hir::UnNeg => {
3353 let lvalue_pref = match unop {
3354 hir::UnDeref => lvalue_pref,
3357 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3361 if !oprnd_t.references_error() {
3364 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3366 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3368 } else if let Some(method) = self.try_overloaded_deref(
3369 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3370 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3371 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3374 self.type_error_message(expr.span, |actual| {
3375 format!("type `{}` cannot be \
3376 dereferenced", actual)
3378 oprnd_t = tcx.types.err;
3382 oprnd_t = self.structurally_resolved_type(oprnd.span,
3384 let result = self.check_user_unop("!", "not",
3385 tcx.lang_items.not_trait(),
3386 expr, &oprnd, oprnd_t, unop);
3387 // If it's builtin, we can reuse the type, this helps inference.
3388 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3393 oprnd_t = self.structurally_resolved_type(oprnd.span,
3395 let result = self.check_user_unop("-", "neg",
3396 tcx.lang_items.neg_trait(),
3397 expr, &oprnd, oprnd_t, unop);
3398 // If it's builtin, we can reuse the type, this helps inference.
3399 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3407 hir::ExprAddrOf(mutbl, ref oprnd) => {
3408 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3410 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3411 if self.tcx.expr_is_lval(&oprnd) {
3412 // Lvalues may legitimately have unsized types.
3413 // For example, dereferences of a fat pointer and
3414 // the last field of a struct can be unsized.
3415 ExpectHasType(mt.ty)
3417 Expectation::rvalue_hint(self, mt.ty)
3423 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3424 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3426 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3427 if tm.ty.references_error() {
3430 // Note: at this point, we cannot say what the best lifetime
3431 // is to use for resulting pointer. We want to use the
3432 // shortest lifetime possible so as to avoid spurious borrowck
3433 // errors. Moreover, the longest lifetime will depend on the
3434 // precise details of the value whose address is being taken
3435 // (and how long it is valid), which we don't know yet until type
3436 // inference is complete.
3438 // Therefore, here we simply generate a region variable. The
3439 // region inferencer will then select the ultimate value.
3440 // Finally, borrowck is charged with guaranteeing that the
3441 // value whose address was taken can actually be made to live
3442 // as long as it needs to live.
3443 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3444 tcx.mk_ref(region, tm)
3447 hir::ExprPath(ref qpath) => {
3448 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3449 expr.id, expr.span);
3450 let ty = if def != Def::Err {
3451 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3453 self.set_tainted_by_errors();
3457 // We always require that the type provided as the value for
3458 // a type parameter outlives the moment of instantiation.
3459 self.opt_node_ty_substs(expr.id, |item_substs| {
3460 self.add_wf_bounds(&item_substs.substs, expr);
3465 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3466 for output in outputs {
3467 self.check_expr(output);
3469 for input in inputs {
3470 self.check_expr(input);
3474 hir::ExprBreak(destination, ref expr_opt) => {
3476 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3477 enclosing_breakables
3478 .find_breakable(destination.target_id).map(|ctxt| ctxt.coerce_to)
3480 if let Some(coerce_to) = coerce_to {
3483 if let Some(ref e) = *expr_opt {
3484 // Recurse without `enclosing_loops` borrowed.
3485 e_ty = self.check_expr_with_hint(e, coerce_to);
3486 cause = self.misc(e.span);
3487 // Notably, the recursive call may alter coerce_to - must not keep using it!
3489 // `break` without argument acts like `break ()`.
3490 e_ty = tcx.mk_nil();
3491 cause = self.misc(expr.span);
3494 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3495 let ctxt = enclosing_breakables.find_breakable(destination.target_id).unwrap();
3497 let result = if let Some(ref e) = *expr_opt {
3498 // Special-case the first element, as it has no "previous expressions".
3499 let result = if !ctxt.may_break {
3500 self.try_coerce(e, e_ty, ctxt.coerce_to)
3502 self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
3503 ctxt.unified, e, e_ty)
3506 ctxt.break_exprs.push(e);
3509 self.eq_types(true, &cause, e_ty, ctxt.unified)
3510 .map(|InferOk { obligations, .. }| {
3511 // FIXME(#32730) propagate obligations
3512 assert!(obligations.is_empty());
3517 Ok(ty) => ctxt.unified = ty,
3519 self.report_mismatched_types(&cause, ctxt.unified, e_ty, err).emit();
3523 ctxt.may_break = true;
3525 // Otherwise, we failed to find the enclosing breakable; this can only happen if the
3526 // `break` target was not found, which is caught in HIR lowering and reported by the
3527 // loop-checking pass.
3530 hir::ExprAgain(_) => { tcx.types.never }
3531 hir::ExprRet(ref expr_opt) => {
3532 if self.ret_ty.is_none() {
3533 struct_span_err!(self.tcx.sess, expr.span, E0572,
3534 "return statement outside of function body").emit();
3535 } else if let Some(ref e) = *expr_opt {
3536 self.check_expr_coercable_to_type(&e, self.ret_ty.unwrap());
3538 match self.eq_types(false,
3539 &self.misc(expr.span),
3540 self.ret_ty.unwrap(),
3542 Ok(ok) => self.register_infer_ok_obligations(ok),
3544 struct_span_err!(tcx.sess, expr.span, E0069,
3545 "`return;` in a function whose return type is not `()`")
3546 .span_label(expr.span, &format!("return type is not ()"))
3553 hir::ExprAssign(ref lhs, ref rhs) => {
3554 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3557 if !tcx.expr_is_lval(&lhs) {
3559 tcx.sess, expr.span, E0070,
3560 "invalid left-hand side expression")
3563 &format!("left-hand of expression not valid"))
3567 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3569 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3571 if lhs_ty.references_error() || rhs_ty.references_error() {
3577 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3578 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3579 expr.span, expected)
3581 hir::ExprWhile(ref cond, ref body, _) => {
3582 let unified = self.tcx.mk_nil();
3583 let coerce_to = unified;
3584 let ctxt = BreakableCtxt {
3586 coerce_to: coerce_to,
3587 break_exprs: vec![],
3590 self.with_breakable_ctxt(expr.id, ctxt, || {
3591 self.check_expr_has_type(&cond, tcx.types.bool);
3592 let cond_diverging = self.diverges.get();
3593 self.check_block_no_value(&body);
3595 // We may never reach the body so it diverging means nothing.
3596 self.diverges.set(cond_diverging);
3599 if self.has_errors.get() {
3605 hir::ExprLoop(ref body, _, _) => {
3606 let unified = self.next_ty_var(TypeVariableOrigin::TypeInference(body.span));
3607 let coerce_to = expected.only_has_type(self).unwrap_or(unified);
3608 let ctxt = BreakableCtxt {
3610 coerce_to: coerce_to,
3611 break_exprs: vec![],
3615 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3616 self.check_block_no_value(&body);
3619 // No way to know whether it's diverging because
3620 // of a `break` or an outer `break` or `return.
3621 self.diverges.set(Diverges::Maybe);
3628 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3629 self.check_match(expr, &discrim, arms, expected, match_src)
3631 hir::ExprClosure(capture, ref decl, body_id, _) => {
3632 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3634 hir::ExprBlock(ref body) => {
3635 self.check_block_with_expected(&body, expected)
3637 hir::ExprCall(ref callee, ref args) => {
3638 self.check_call(expr, &callee, args, expected)
3640 hir::ExprMethodCall(name, ref tps, ref args) => {
3641 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3643 hir::ExprCast(ref e, ref t) => {
3644 // Find the type of `e`. Supply hints based on the type we are casting to,
3646 let t_cast = self.to_ty(t);
3647 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3648 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3649 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3651 // Eagerly check for some obvious errors.
3652 if t_expr.references_error() || t_cast.references_error() {
3655 // Defer other checks until we're done type checking.
3656 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3657 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3659 deferred_cast_checks.push(cast_check);
3662 Err(ErrorReported) => {
3668 hir::ExprType(ref e, ref t) => {
3669 let typ = self.to_ty(&t);
3670 self.check_expr_eq_type(&e, typ);
3673 hir::ExprArray(ref args) => {
3674 let uty = expected.to_option(self).and_then(|uty| {
3676 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3681 let mut unified = self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span));
3682 let coerce_to = uty.unwrap_or(unified);
3684 for (i, e) in args.iter().enumerate() {
3685 let e_ty = self.check_expr_with_hint(e, coerce_to);
3686 let cause = self.misc(e.span);
3688 // Special-case the first element, as it has no "previous expressions".
3689 let result = if i == 0 {
3690 self.try_coerce(e, e_ty, coerce_to)
3692 let prev_elems = || args[..i].iter().map(|e| &*e);
3693 self.try_find_coercion_lub(&cause, prev_elems, unified, e, e_ty)
3697 Ok(ty) => unified = ty,
3699 self.report_mismatched_types(&cause, unified, e_ty, e).emit();
3703 tcx.mk_array(unified, args.len())
3705 hir::ExprRepeat(ref element, count) => {
3706 let count = eval_length(self.tcx.global_tcx(), count, "repeat count")
3709 let uty = match expected {
3710 ExpectHasType(uty) => {
3712 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3719 let (element_ty, t) = match uty {
3721 self.check_expr_coercable_to_type(&element, uty);
3725 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3726 let element_ty = self.check_expr_has_type(&element, t);
3732 // For [foo, ..n] where n > 1, `foo` must have
3734 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3735 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3738 if element_ty.references_error() {
3741 tcx.mk_array(t, count)
3744 hir::ExprTup(ref elts) => {
3745 let flds = expected.only_has_type(self).and_then(|ty| {
3747 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3752 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3753 let t = match flds {
3754 Some(ref fs) if i < fs.len() => {
3756 self.check_expr_coercable_to_type(&e, ety);
3760 self.check_expr_with_expectation(&e, NoExpectation)
3765 let tuple = tcx.mk_tup(elt_ts_iter, false);
3766 if tuple.references_error() {
3772 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3773 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3775 hir::ExprField(ref base, ref field) => {
3776 self.check_field(expr, lvalue_pref, &base, field)
3778 hir::ExprTupField(ref base, idx) => {
3779 self.check_tup_field(expr, lvalue_pref, &base, idx)
3781 hir::ExprIndex(ref base, ref idx) => {
3782 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3783 let idx_t = self.check_expr(&idx);
3785 if base_t.references_error() {
3787 } else if idx_t.references_error() {
3790 let base_t = self.structurally_resolved_type(expr.span, base_t);
3791 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3792 Some((index_ty, element_ty)) => {
3793 self.demand_coerce(idx, idx_t, index_ty);
3797 self.check_expr_has_type(&idx, self.tcx.types.err);
3798 let mut err = self.type_error_struct(
3801 format!("cannot index a value of type `{}`",
3805 // Try to give some advice about indexing tuples.
3806 if let ty::TyTuple(..) = base_t.sty {
3807 let mut needs_note = true;
3808 // If the index is an integer, we can show the actual
3809 // fixed expression:
3810 if let hir::ExprLit(ref lit) = idx.node {
3811 if let ast::LitKind::Int(i,
3812 ast::LitIntType::Unsuffixed) = lit.node {
3813 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3814 if let Ok(snip) = snip {
3815 err.span_suggestion(expr.span,
3816 "to access tuple elements, \
3817 use tuple indexing syntax \
3819 format!("{}.{}", snip, i));
3825 err.help("to access tuple elements, use tuple indexing \
3826 syntax (e.g. `tuple.0`)");
3838 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3839 // The newly resolved definition is written into `type_relative_path_defs`.
3840 fn finish_resolving_struct_path(&self,
3843 node_id: ast::NodeId)
3847 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3848 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3849 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3852 hir::QPath::TypeRelative(ref qself, ref segment) => {
3853 let ty = self.to_ty(qself);
3855 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3860 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3863 // Write back the new resolution.
3864 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3871 // Resolve associated value path into a base type and associated constant or method definition.
3872 // The newly resolved definition is written into `type_relative_path_defs`.
3873 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3874 qpath: &'b hir::QPath,
3875 node_id: ast::NodeId,
3877 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3879 let (ty, item_segment) = match *qpath {
3880 hir::QPath::Resolved(ref opt_qself, ref path) => {
3882 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3883 &path.segments[..]);
3885 hir::QPath::TypeRelative(ref qself, ref segment) => {
3886 (self.to_ty(qself), segment)
3889 let item_name = item_segment.name;
3890 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3893 let def = match error {
3894 method::MethodError::PrivateMatch(def) => def,
3897 if item_name != keywords::Invalid.name() {
3898 self.report_method_error(span, ty, item_name, None, error, None);
3904 // Write back the new resolution.
3905 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3906 (def, Some(ty), slice::ref_slice(&**item_segment))
3909 pub fn check_decl_initializer(&self,
3910 local: &'gcx hir::Local,
3911 init: &'gcx hir::Expr) -> Ty<'tcx>
3913 let ref_bindings = local.pat.contains_ref_binding();
3915 let local_ty = self.local_ty(init.span, local.id);
3916 if let Some(m) = ref_bindings {
3917 // Somewhat subtle: if we have a `ref` binding in the pattern,
3918 // we want to avoid introducing coercions for the RHS. This is
3919 // both because it helps preserve sanity and, in the case of
3920 // ref mut, for soundness (issue #23116). In particular, in
3921 // the latter case, we need to be clear that the type of the
3922 // referent for the reference that results is *equal to* the
3923 // type of the lvalue it is referencing, and not some
3924 // supertype thereof.
3925 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3926 self.demand_eqtype(init.span, init_ty, local_ty);
3929 self.check_expr_coercable_to_type(init, local_ty)
3933 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3934 let t = self.local_ty(local.span, local.id);
3935 self.write_ty(local.id, t);
3937 if let Some(ref init) = local.init {
3938 let init_ty = self.check_decl_initializer(local, &init);
3939 if init_ty.references_error() {
3940 self.write_ty(local.id, init_ty);
3944 self.check_pat(&local.pat, t);
3945 let pat_ty = self.node_ty(local.pat.id);
3946 if pat_ty.references_error() {
3947 self.write_ty(local.id, pat_ty);
3951 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3952 // Don't do all the complex logic below for DeclItem.
3954 hir::StmtDecl(ref decl, id) => {
3956 hir::DeclLocal(_) => {}
3957 hir::DeclItem(_) => {
3963 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
3966 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
3968 // Hide the outer diverging and has_errors flags.
3969 let old_diverges = self.diverges.get();
3970 let old_has_errors = self.has_errors.get();
3971 self.diverges.set(Diverges::Maybe);
3972 self.has_errors.set(false);
3974 let (node_id, span) = match stmt.node {
3975 hir::StmtDecl(ref decl, id) => {
3976 let span = match decl.node {
3977 hir::DeclLocal(ref l) => {
3978 self.check_decl_local(&l);
3981 hir::DeclItem(_) => {/* ignore for now */
3987 hir::StmtExpr(ref expr, id) => {
3988 // Check with expected type of ()
3989 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3992 hir::StmtSemi(ref expr, id) => {
3993 self.check_expr(&expr);
3998 if self.has_errors.get() {
3999 self.write_error(node_id);
4000 } else if self.diverges.get().always() {
4001 self.write_ty(node_id, self.next_diverging_ty_var(
4002 TypeVariableOrigin::DivergingStmt(span)));
4004 self.write_nil(node_id);
4007 // Combine the diverging and has_error flags.
4008 self.diverges.set(self.diverges.get() | old_diverges);
4009 self.has_errors.set(self.has_errors.get() | old_has_errors);
4012 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4013 let unit = self.tcx.mk_nil();
4014 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4015 self.demand_suptype(blk.span, unit, ty);
4018 fn check_block_with_expected(&self,
4019 blk: &'gcx hir::Block,
4020 expected: Expectation<'tcx>) -> Ty<'tcx> {
4022 let mut fcx_ps = self.ps.borrow_mut();
4023 let unsafety_state = fcx_ps.recurse(blk);
4024 replace(&mut *fcx_ps, unsafety_state)
4027 let mut ty = if let Some(break_to_expr_id) = blk.break_to_expr_id {
4028 let unified = self.next_ty_var(TypeVariableOrigin::TypeInference(blk.span));
4029 let coerce_to = expected.only_has_type(self).unwrap_or(unified);
4030 let ctxt = BreakableCtxt {
4032 coerce_to: coerce_to,
4033 break_exprs: vec![],
4037 let (mut ctxt, (e_ty, cause)) = self.with_breakable_ctxt(break_to_expr_id, ctxt, || {
4038 for s in &blk.stmts {
4042 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4043 enclosing_breakables.find_breakable(
4044 hir::ScopeTarget::Block(break_to_expr_id)
4045 ).unwrap().coerce_to
4051 e_ty = self.check_expr_with_hint(e, coerce_to);
4052 cause = self.misc(e.span);
4055 e_ty = self.tcx.mk_nil();
4056 cause = self.misc(blk.span);
4063 if let Some(ref e) = blk.expr {
4064 let result = if !ctxt.may_break {
4065 self.try_coerce(e, e_ty, ctxt.coerce_to)
4067 self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
4068 ctxt.unified, e, e_ty)
4071 Ok(ty) => ctxt.unified = ty,
4073 self.report_mismatched_types(&cause, ctxt.unified, e_ty, err).emit(),
4076 self.check_block_no_expr(blk, self.tcx.mk_nil(), e_ty);
4081 for s in &blk.stmts {
4085 let mut ty = match blk.expr {
4086 Some(ref e) => self.check_expr_with_expectation(e, expected),
4087 None => self.tcx.mk_nil()
4090 if self.diverges.get().always() {
4091 if let ExpectHasType(ety) = expected {
4092 // Avoid forcing a type (only `!` for now) in unreachable code.
4093 // FIXME(aburka) do we need this special case? and should it be is_uninhabited?
4094 if !ety.is_never() {
4095 if let Some(ref e) = blk.expr {
4096 // Coerce the tail expression to the right type.
4097 self.demand_coerce(e, ty, ety);
4102 ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
4103 } else if let ExpectHasType(ety) = expected {
4104 if let Some(ref e) = blk.expr {
4105 // Coerce the tail expression to the right type.
4106 self.demand_coerce(e, ty, ety);
4108 self.check_block_no_expr(blk, ty, ety);
4111 // We already applied the type (and potentially errored),
4112 // use the expected type to avoid further errors out.
4118 if self.has_errors.get() || ty.references_error() {
4119 ty = self.tcx.types.err
4122 self.write_ty(blk.id, ty);
4124 *self.ps.borrow_mut() = prev;
4128 pub fn check_block_no_expr(&self, blk: &'gcx hir::Block, ty: Ty<'tcx>, ety: Ty<'tcx>) {
4129 // We're not diverging and there's an expected type, which,
4130 // in case it's not `()`, could result in an error higher-up.
4131 // We have a chance to error here early and be more helpful.
4132 let cause = self.misc(blk.span);
4133 let trace = TypeTrace::types(&cause, false, ty, ety);
4134 match self.sub_types(false, &cause, ty, ety) {
4135 Ok(InferOk { obligations, .. }) => {
4136 // FIXME(#32730) propagate obligations
4137 assert!(obligations.is_empty());
4140 let mut err = self.report_and_explain_type_error(trace, &err);
4142 // Be helpful when the user wrote `{... expr;}` and
4143 // taking the `;` off is enough to fix the error.
4144 let mut extra_semi = None;
4145 if let Some(stmt) = blk.stmts.last() {
4146 if let hir::StmtSemi(ref e, _) = stmt.node {
4147 if self.can_sub_types(self.node_ty(e.id), ety).is_ok() {
4148 extra_semi = Some(stmt);
4152 if let Some(last_stmt) = extra_semi {
4153 let original_span = original_sp(last_stmt.span, blk.span);
4154 let span_semi = Span {
4155 lo: original_span.hi - BytePos(1),
4156 hi: original_span.hi,
4157 ctxt: original_span.ctxt,
4159 err.span_help(span_semi, "consider removing this semicolon:");
4167 // Instantiates the given path, which must refer to an item with the given
4168 // number of type parameters and type.
4169 pub fn instantiate_value_path(&self,
4170 segments: &[hir::PathSegment],
4171 opt_self_ty: Option<Ty<'tcx>>,
4174 node_id: ast::NodeId)
4176 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4181 // We need to extract the type parameters supplied by the user in
4182 // the path `path`. Due to the current setup, this is a bit of a
4183 // tricky-process; the problem is that resolve only tells us the
4184 // end-point of the path resolution, and not the intermediate steps.
4185 // Luckily, we can (at least for now) deduce the intermediate steps
4186 // just from the end-point.
4188 // There are basically four cases to consider:
4190 // 1. Reference to a constructor of enum variant or struct:
4192 // struct Foo<T>(...)
4193 // enum E<T> { Foo(...) }
4195 // In these cases, the parameters are declared in the type
4198 // 2. Reference to a fn item or a free constant:
4202 // In this case, the path will again always have the form
4203 // `a::b::foo::<T>` where only the final segment should have
4204 // type parameters. However, in this case, those parameters are
4205 // declared on a value, and hence are in the `FnSpace`.
4207 // 3. Reference to a method or an associated constant:
4209 // impl<A> SomeStruct<A> {
4213 // Here we can have a path like
4214 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4215 // may appear in two places. The penultimate segment,
4216 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4217 // final segment, `foo::<B>` contains parameters in fn space.
4219 // 4. Reference to a local variable
4221 // Local variables can't have any type parameters.
4223 // The first step then is to categorize the segments appropriately.
4225 assert!(!segments.is_empty());
4227 let mut ufcs_associated = None;
4228 let mut type_segment = None;
4229 let mut fn_segment = None;
4231 // Case 1. Reference to a struct/variant constructor.
4232 Def::StructCtor(def_id, ..) |
4233 Def::VariantCtor(def_id, ..) => {
4234 // Everything but the final segment should have no
4235 // parameters at all.
4236 let mut generics = self.tcx.item_generics(def_id);
4237 if let Some(def_id) = generics.parent {
4238 // Variant and struct constructors use the
4239 // generics of their parent type definition.
4240 generics = self.tcx.item_generics(def_id);
4242 type_segment = Some((segments.last().unwrap(), generics));
4245 // Case 2. Reference to a top-level value.
4247 Def::Const(def_id) |
4248 Def::Static(def_id, _) => {
4249 fn_segment = Some((segments.last().unwrap(),
4250 self.tcx.item_generics(def_id)));
4253 // Case 3. Reference to a method or associated const.
4254 Def::Method(def_id) |
4255 Def::AssociatedConst(def_id) => {
4256 let container = self.tcx.associated_item(def_id).container;
4258 ty::TraitContainer(trait_did) => {
4259 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4261 ty::ImplContainer(_) => {}
4264 let generics = self.tcx.item_generics(def_id);
4265 if segments.len() >= 2 {
4266 let parent_generics = self.tcx.item_generics(generics.parent.unwrap());
4267 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4269 // `<T>::assoc` will end up here, and so can `T::assoc`.
4270 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4271 ufcs_associated = Some((container, self_ty));
4273 fn_segment = Some((segments.last().unwrap(), generics));
4276 // Case 4. Local variable, no generics.
4277 Def::Local(..) | Def::Upvar(..) => {}
4279 _ => bug!("unexpected definition: {:?}", def),
4282 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4284 // Now that we have categorized what space the parameters for each
4285 // segment belong to, let's sort out the parameters that the user
4286 // provided (if any) into their appropriate spaces. We'll also report
4287 // errors if type parameters are provided in an inappropriate place.
4288 let poly_segments = type_segment.is_some() as usize +
4289 fn_segment.is_some() as usize;
4290 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4293 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4294 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4295 let ty = self.local_ty(span, nid);
4296 let ty = self.normalize_associated_types_in(span, &ty);
4297 self.write_ty(node_id, ty);
4298 self.write_substs(node_id, ty::ItemSubsts {
4299 substs: self.tcx.intern_substs(&[])
4306 // Now we have to compare the types that the user *actually*
4307 // provided against the types that were *expected*. If the user
4308 // did not provide any types, then we want to substitute inference
4309 // variables. If the user provided some types, we may still need
4310 // to add defaults. If the user provided *too many* types, that's
4312 self.check_path_parameter_count(span, &mut type_segment);
4313 self.check_path_parameter_count(span, &mut fn_segment);
4315 let (fn_start, has_self) = match (type_segment, fn_segment) {
4316 (_, Some((_, generics))) => {
4317 (generics.parent_count(), generics.has_self)
4319 (Some((_, generics)), None) => {
4320 (generics.own_count(), generics.has_self)
4322 (None, None) => (0, false)
4324 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4325 let mut i = def.index as usize;
4327 let segment = if i < fn_start {
4328 i -= has_self as usize;
4334 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4335 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4336 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4340 if let Some(lifetime) = lifetimes.get(i) {
4341 AstConv::ast_region_to_region(self, lifetime, Some(def))
4343 self.re_infer(span, Some(def)).unwrap()
4346 let mut i = def.index as usize;
4348 let segment = if i < fn_start {
4349 // Handle Self first, so we can adjust the index to match the AST.
4350 if has_self && i == 0 {
4351 return opt_self_ty.unwrap_or_else(|| {
4352 self.type_var_for_def(span, def, substs)
4355 i -= has_self as usize;
4361 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4362 Some(&hir::AngleBracketedParameters(ref data)) => {
4363 (&data.types[..], data.infer_types)
4365 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4366 None => (&[][..], true)
4369 // Skip over the lifetimes in the same segment.
4370 if let Some((_, generics)) = segment {
4371 i -= generics.regions.len();
4374 if let Some(ast_ty) = types.get(i) {
4375 // A provided type parameter.
4377 } else if !infer_types && def.has_default {
4378 // No type parameter provided, but a default exists.
4379 let default = self.tcx.item_type(def.def_id);
4382 default.subst_spanned(self.tcx, substs, Some(span))
4385 // No type parameters were provided, we can infer all.
4386 // This can also be reached in some error cases:
4387 // We prefer to use inference variables instead of
4388 // TyError to let type inference recover somewhat.
4389 self.type_var_for_def(span, def, substs)
4393 // The things we are substituting into the type should not contain
4394 // escaping late-bound regions, and nor should the base type scheme.
4395 let ty = self.tcx.item_type(def.def_id());
4396 assert!(!substs.has_escaping_regions());
4397 assert!(!ty.has_escaping_regions());
4399 // Add all the obligations that are required, substituting and
4400 // normalized appropriately.
4401 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4402 self.add_obligations_for_parameters(
4403 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4406 // Substitute the values for the type parameters into the type of
4407 // the referenced item.
4408 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4410 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4411 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4412 // is inherent, there is no `Self` parameter, instead, the impl needs
4413 // type parameters, which we can infer by unifying the provided `Self`
4414 // with the substituted impl type.
4415 let ty = self.tcx.item_type(impl_def_id);
4417 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4418 match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
4419 Ok(ok) => self.register_infer_ok_obligations(ok),
4422 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4429 debug!("instantiate_value_path: type of {:?} is {:?}",
4432 self.write_substs(node_id, ty::ItemSubsts {
4438 /// Report errors if the provided parameters are too few or too many.
4439 fn check_path_parameter_count(&self,
4441 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4442 let (lifetimes, types, infer_types, bindings) = {
4443 match segment.map(|(s, _)| &s.parameters) {
4444 Some(&hir::AngleBracketedParameters(ref data)) => {
4445 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4447 Some(&hir::ParenthesizedParameters(_)) => {
4448 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4450 None => (&[][..], &[][..], true, &[][..])
4454 let count_lifetime_params = |n| {
4455 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4457 let count_type_params = |n| {
4458 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4461 // Check provided lifetime parameters.
4462 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4463 if lifetimes.len() > lifetime_defs.len() {
4464 let expected_text = count_lifetime_params(lifetime_defs.len());
4465 let actual_text = count_lifetime_params(lifetimes.len());
4466 struct_span_err!(self.tcx.sess, span, E0088,
4467 "too many lifetime parameters provided: \
4468 expected at most {}, found {}",
4469 expected_text, actual_text)
4470 .span_label(span, &format!("expected {}", expected_text))
4472 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4473 let expected_text = count_lifetime_params(lifetime_defs.len());
4474 let actual_text = count_lifetime_params(lifetimes.len());
4475 struct_span_err!(self.tcx.sess, span, E0090,
4476 "too few lifetime parameters provided: \
4477 expected {}, found {}",
4478 expected_text, actual_text)
4479 .span_label(span, &format!("expected {}", expected_text))
4483 // The case where there is not enough lifetime parameters is not checked,
4484 // because this is not possible - a function never takes lifetime parameters.
4485 // See discussion for Pull Request 36208.
4487 // Check provided type parameters.
4488 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4489 if generics.parent.is_none() {
4490 &generics.types[generics.has_self as usize..]
4495 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4496 if types.len() > type_defs.len() {
4497 let span = types[type_defs.len()].span;
4498 let expected_text = count_type_params(type_defs.len());
4499 let actual_text = count_type_params(types.len());
4500 struct_span_err!(self.tcx.sess, span, E0087,
4501 "too many type parameters provided: \
4502 expected at most {}, found {}",
4503 expected_text, actual_text)
4504 .span_label(span, &format!("expected {}", expected_text))
4507 // To prevent derived errors to accumulate due to extra
4508 // type parameters, we force instantiate_value_path to
4509 // use inference variables instead of the provided types.
4511 } else if !infer_types && types.len() < required_len {
4512 let expected_text = count_type_params(required_len);
4513 let actual_text = count_type_params(types.len());
4514 struct_span_err!(self.tcx.sess, span, E0089,
4515 "too few type parameters provided: \
4516 expected {}, found {}",
4517 expected_text, actual_text)
4518 .span_label(span, &format!("expected {}", expected_text))
4522 if !bindings.is_empty() {
4523 span_err!(self.tcx.sess, bindings[0].span, E0182,
4524 "unexpected binding of associated item in expression path \
4525 (only allowed in type paths)");
4529 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4531 where F: Fn() -> Ty<'tcx>
4533 let mut ty = self.resolve_type_vars_with_obligations(ty);
4536 let alternative = f();
4539 if alternative.is_ty_var() || alternative.references_error() {
4540 if !self.is_tainted_by_errors() {
4541 self.type_error_message(sp, |_actual| {
4542 "the type of this value must be known in this context".to_string()
4545 self.demand_suptype(sp, self.tcx.types.err, ty);
4546 ty = self.tcx.types.err;
4548 self.demand_suptype(sp, alternative, ty);
4556 // Resolves `typ` by a single level if `typ` is a type variable. If no
4557 // resolution is possible, then an error is reported.
4558 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4559 self.structurally_resolve_type_or_else(sp, ty, || {
4564 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4565 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4566 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4569 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4570 index = enclosing_breakables.stack.len();
4571 enclosing_breakables.by_id.insert(id, index);
4572 enclosing_breakables.stack.push(ctxt);
4576 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4577 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4578 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4579 enclosing_breakables.stack.pop().expect("missing breakable context")
4585 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4586 generics: &hir::Generics,
4588 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4589 generics.ty_params.len(), ty);
4591 // make a vector of booleans initially false, set to true when used
4592 if generics.ty_params.is_empty() { return; }
4593 let mut tps_used = vec![false; generics.ty_params.len()];
4595 for leaf_ty in ty.walk() {
4596 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4597 debug!("Found use of ty param num {}", idx);
4598 tps_used[idx as usize - generics.lifetimes.len()] = true;
4602 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4604 struct_span_err!(tcx.sess, param.span, E0091,
4605 "type parameter `{}` is unused",
4607 .span_label(param.span, &format!("unused type parameter"))