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::{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 LoopCtxt<'gcx, 'tcx> {
408 break_exprs: Vec<&'gcx hir::Expr>,
413 pub struct EnclosingLoops<'gcx, 'tcx> {
414 stack: Vec<LoopCtxt<'gcx, 'tcx>>,
415 by_id: NodeMap<usize>,
418 impl<'gcx, 'tcx> EnclosingLoops<'gcx, 'tcx> {
419 fn find_loop(&mut self, id: hir::LoopIdResult) -> Option<&mut LoopCtxt<'gcx, 'tcx>> {
420 let id_res: Result<_,_> = id.into();
421 if let Some(ix) = id_res.ok().and_then(|id| self.by_id.get(&id).cloned()) {
422 Some(&mut self.stack[ix])
430 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
431 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
433 body_id: ast::NodeId,
435 // Number of errors that had been reported when we started
436 // checking this function. On exit, if we find that *more* errors
437 // have been reported, we will skip regionck and other work that
438 // expects the types within the function to be consistent.
439 err_count_on_creation: usize,
441 ret_ty: Option<Ty<'tcx>>,
443 ps: RefCell<UnsafetyState>,
445 /// Whether the last checked node can ever exit.
446 diverges: Cell<Diverges>,
448 /// Whether any child nodes have any type errors.
449 has_errors: Cell<bool>,
451 enclosing_loops: RefCell<EnclosingLoops<'gcx, 'tcx>>,
453 inh: &'a Inherited<'a, 'gcx, 'tcx>,
456 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
457 type Target = Inherited<'a, 'gcx, 'tcx>;
458 fn deref(&self) -> &Self::Target {
463 /// Helper type of a temporary returned by Inherited::build(...).
464 /// Necessary because we can't write the following bound:
465 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
466 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
467 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
470 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
471 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId)
472 -> InheritedBuilder<'a, 'gcx, 'tcx> {
473 let tables = ty::TypeckTables::empty();
474 let param_env = ParameterEnvironment::for_item(tcx, id);
476 infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing)
481 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
482 fn enter<F, R>(&'tcx mut self, f: F) -> R
483 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
485 self.infcx.enter(|infcx| f(Inherited::new(infcx)))
489 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
490 pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
493 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
494 locals: RefCell::new(NodeMap()),
495 deferred_call_resolutions: RefCell::new(DefIdMap()),
496 deferred_cast_checks: RefCell::new(Vec::new()),
497 anon_types: RefCell::new(NodeMap()),
501 fn normalize_associated_types_in<T>(&self,
503 body_id: ast::NodeId,
506 where T : TypeFoldable<'tcx>
508 assoc::normalize_associated_types_in(self,
509 &mut self.fulfillment_cx.borrow_mut(),
517 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
519 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
520 fn visit_item(&mut self, i: &'tcx hir::Item) {
521 check_item_type(self.tcx, i);
523 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
524 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
527 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
528 tcx.sess.track_errors(|| {
529 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
530 tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor());
534 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
535 tcx.sess.track_errors(|| {
536 tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType,
537 &mut CheckItemTypesVisitor { tcx });
541 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
542 tcx.sess.track_errors(|| {
543 tcx.dep_graph.with_task(DepNode::TypeckBodiesKrate, || {
544 tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
545 tcx.item_tables(body_owner_def_id);
551 pub fn provide(providers: &mut Providers) {
552 *providers = Providers {
561 fn closure_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
563 -> ty::PolyFnSig<'tcx> {
564 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
565 tcx.item_tables(def_id).closure_tys[&node_id]
568 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
571 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
572 tcx.item_tables(def_id).closure_kinds[&node_id]
575 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
577 -> Option<ty::Destructor> {
578 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
581 fn typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
583 -> &'tcx ty::TypeckTables<'tcx> {
584 // Closures' tables come from their outermost function,
585 // as they are part of the same "inference environment".
586 let outer_def_id = tcx.closure_base_def_id(def_id);
587 if outer_def_id != def_id {
588 return tcx.item_tables(outer_def_id);
591 let id = tcx.hir.as_local_node_id(def_id).unwrap();
592 let span = tcx.hir.span(id);
593 let unsupported = || {
594 span_bug!(span, "can't type-check body of {:?}", def_id);
597 // Figure out what primary body this item has.
598 let mut fn_decl = None;
599 let body_id = match tcx.hir.get(id) {
600 hir::map::NodeItem(item) => {
602 hir::ItemConst(_, body) |
603 hir::ItemStatic(_, _, body) => body,
604 hir::ItemFn(ref decl, .., body) => {
605 fn_decl = Some(decl);
611 hir::map::NodeTraitItem(item) => {
613 hir::TraitItemKind::Const(_, Some(body)) => body,
614 hir::TraitItemKind::Method(ref sig,
615 hir::TraitMethod::Provided(body)) => {
616 fn_decl = Some(&sig.decl);
622 hir::map::NodeImplItem(item) => {
624 hir::ImplItemKind::Const(_, body) => body,
625 hir::ImplItemKind::Method(ref sig, body) => {
626 fn_decl = Some(&sig.decl);
632 hir::map::NodeExpr(expr) => {
633 // FIXME(eddyb) Closures should have separate
634 // function definition IDs and expression IDs.
635 // Type-checking should not let closures get
636 // this far in a constant position.
637 // Assume that everything other than closures
638 // is a constant "initializer" expression.
640 hir::ExprClosure(..) => {
641 // We should've bailed out above for closures.
642 span_bug!(expr.span, "unexpected closure")
644 _ => hir::BodyId { node_id: expr.id }
649 let body = tcx.hir.body(body_id);
651 Inherited::build(tcx, id).enter(|inh| {
652 let fcx = if let Some(decl) = fn_decl {
653 let fn_sig = tcx.item_type(def_id).fn_sig();
655 check_abi(tcx, span, fn_sig.abi());
657 // Compute the fty from point of view of inside fn.
658 let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id);
660 fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
662 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
664 inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
666 check_fn(&inh, fn_sig, decl, id, body)
668 let fcx = FnCtxt::new(&inh, None, body.value.id);
669 let expected_type = tcx.item_type(def_id);
670 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
671 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
673 // Gather locals in statics (because of block expressions).
674 // This is technically unnecessary because locals in static items are forbidden,
675 // but prevents type checking from blowing up before const checking can properly
677 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
679 fcx.check_expr_coercable_to_type(&body.value, expected_type);
684 fcx.select_all_obligations_and_apply_defaults();
685 fcx.closure_analyze(body);
686 fcx.select_obligations_where_possible();
688 fcx.select_all_obligations_or_error();
690 if fn_decl.is_some() {
691 fcx.regionck_fn(id, body);
693 fcx.regionck_expr(body);
696 fcx.resolve_type_vars_in_body(body)
700 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
701 if !tcx.sess.target.target.is_abi_supported(abi) {
702 struct_span_err!(tcx.sess, span, E0570,
703 "The ABI `{}` is not supported for the current target", abi).emit()
707 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
708 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
711 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
712 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
715 // infer the variable's type
716 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
717 self.fcx.locals.borrow_mut().insert(nid, var_ty);
721 // take type that the user specified
722 self.fcx.locals.borrow_mut().insert(nid, typ);
729 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
730 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
731 NestedVisitorMap::None
734 // Add explicitly-declared locals.
735 fn visit_local(&mut self, local: &'gcx hir::Local) {
736 let o_ty = match local.ty {
737 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
740 self.assign(local.span, local.id, o_ty);
741 debug!("Local variable {:?} is assigned type {}",
743 self.fcx.ty_to_string(
744 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
745 intravisit::walk_local(self, local);
748 // Add pattern bindings.
749 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
750 if let PatKind::Binding(_, _, ref path1, _) = p.node {
751 let var_ty = self.assign(p.span, p.id, None);
753 self.fcx.require_type_is_sized(var_ty, p.span,
754 traits::VariableType(p.id));
756 debug!("Pattern binding {} is assigned to {} with type {:?}",
758 self.fcx.ty_to_string(
759 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
762 intravisit::walk_pat(self, p);
765 // Don't descend into the bodies of nested closures
766 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
767 _: hir::BodyId, _: Span, _: ast::NodeId) { }
770 /// Helper used for fns and closures. Does the grungy work of checking a function
771 /// body and returns the function context used for that purpose, since in the case of a fn item
772 /// there is still a bit more to do.
775 /// * inherited: other fields inherited from the enclosing fn (if any)
776 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
777 fn_sig: ty::FnSig<'tcx>,
778 decl: &'gcx hir::FnDecl,
780 body: &'gcx hir::Body)
781 -> FnCtxt<'a, 'gcx, 'tcx>
783 let mut fn_sig = fn_sig.clone();
785 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
787 // Create the function context. This is either derived from scratch or,
788 // in the case of function expressions, based on the outer context.
789 let mut fcx = FnCtxt::new(inherited, None, body.value.id);
790 let ret_ty = fn_sig.output();
791 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
793 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
794 fcx.ret_ty = fcx.instantiate_anon_types(&Some(ret_ty));
795 fn_sig = fcx.tcx.mk_fn_sig(
796 fn_sig.inputs().iter().cloned(),
803 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
805 // Add formal parameters.
806 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
807 // The type of the argument must be well-formed.
809 // NB -- this is now checked in wfcheck, but that
810 // currently only results in warnings, so we issue an
811 // old-style WF obligation here so that we still get the
812 // errors that we used to get.
813 fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
815 // Check the pattern.
816 fcx.check_pat_arg(&arg.pat, arg_ty, true);
817 fcx.write_ty(arg.id, arg_ty);
820 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
822 fcx.check_expr_coercable_to_type(&body.value, fcx.ret_ty.unwrap());
827 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
830 let def_id = tcx.hir.local_def_id(id);
831 let def = tcx.lookup_adt_def(def_id);
832 def.destructor(tcx); // force the destructor to be evaluated
833 check_representable(tcx, span, def_id);
836 check_simd(tcx, span, def_id);
840 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
843 let def_id = tcx.hir.local_def_id(id);
844 let def = tcx.lookup_adt_def(def_id);
845 def.destructor(tcx); // force the destructor to be evaluated
846 check_representable(tcx, span, def_id);
849 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
850 debug!("check_item_type(it.id={}, it.name={})",
852 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
853 let _indenter = indenter();
855 // Consts can play a role in type-checking, so they are included here.
856 hir::ItemStatic(..) |
857 hir::ItemConst(..) => {
858 tcx.item_tables(tcx.hir.local_def_id(it.id));
860 hir::ItemEnum(ref enum_definition, _) => {
863 &enum_definition.variants,
866 hir::ItemFn(..) => {} // entirely within check_item_body
867 hir::ItemImpl(.., ref impl_item_refs) => {
868 debug!("ItemImpl {} with id {}", it.name, it.id);
869 let impl_def_id = tcx.hir.local_def_id(it.id);
870 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
871 check_impl_items_against_trait(tcx,
876 let trait_def_id = impl_trait_ref.def_id;
877 check_on_unimplemented(tcx, trait_def_id, it);
880 hir::ItemTrait(..) => {
881 let def_id = tcx.hir.local_def_id(it.id);
882 check_on_unimplemented(tcx, def_id, it);
884 hir::ItemStruct(..) => {
885 check_struct(tcx, it.id, it.span);
887 hir::ItemUnion(..) => {
888 check_union(tcx, it.id, it.span);
890 hir::ItemTy(_, ref generics) => {
891 let def_id = tcx.hir.local_def_id(it.id);
892 let pty_ty = tcx.item_type(def_id);
893 check_bounds_are_used(tcx, generics, pty_ty);
895 hir::ItemForeignMod(ref m) => {
896 check_abi(tcx, it.span, m.abi);
898 if m.abi == Abi::RustIntrinsic {
899 for item in &m.items {
900 intrinsic::check_intrinsic_type(tcx, item);
902 } else if m.abi == Abi::PlatformIntrinsic {
903 for item in &m.items {
904 intrinsic::check_platform_intrinsic_type(tcx, item);
907 for item in &m.items {
908 let generics = tcx.item_generics(tcx.hir.local_def_id(item.id));
909 if !generics.types.is_empty() {
910 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
911 "foreign items may not have type parameters");
912 span_help!(&mut err, item.span,
913 "consider using specialization instead of \
918 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
919 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
924 _ => {/* nothing to do */ }
928 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
931 let generics = tcx.item_generics(def_id);
932 if let Some(ref attr) = item.attrs.iter().find(|a| {
933 a.check_name("rustc_on_unimplemented")
935 if let Some(istring) = attr.value_str() {
936 let istring = istring.as_str();
937 let parser = Parser::new(&istring);
938 let types = &generics.types;
939 for token in parser {
941 Piece::String(_) => (), // Normal string, no need to check it
942 Piece::NextArgument(a) => match a.position {
943 // `{Self}` is allowed
944 Position::ArgumentNamed(s) if s == "Self" => (),
945 // So is `{A}` if A is a type parameter
946 Position::ArgumentNamed(s) => match types.iter().find(|t| {
951 let name = tcx.item_name(def_id);
952 span_err!(tcx.sess, attr.span, E0230,
953 "there is no type parameter \
958 // `{:1}` and `{}` are not to be used
959 Position::ArgumentIs(_) => {
960 span_err!(tcx.sess, attr.span, E0231,
961 "only named substitution \
962 parameters are allowed");
969 tcx.sess, attr.span, E0232,
970 "this attribute must have a value")
971 .span_label(attr.span, &format!("attribute requires a value"))
972 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
978 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
979 impl_item: &hir::ImplItem,
982 let mut err = struct_span_err!(
983 tcx.sess, impl_item.span, E0520,
984 "`{}` specializes an item from a parent `impl`, but \
985 that item is not marked `default`",
987 err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
990 match tcx.span_of_impl(parent_impl) {
992 err.span_label(span, &"parent `impl` is here");
993 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
997 err.note(&format!("parent implementation is in crate `{}`", cname));
1004 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1005 trait_def: &ty::TraitDef,
1007 impl_item: &hir::ImplItem)
1009 let ancestors = trait_def.ancestors(impl_id);
1011 let kind = match impl_item.node {
1012 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1013 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1014 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1016 let parent = ancestors.defs(tcx, impl_item.name, kind).skip(1).next()
1017 .map(|node_item| node_item.map(|parent| parent.defaultness));
1019 if let Some(parent) = parent {
1020 if parent.item.is_final() {
1021 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1027 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1030 impl_trait_ref: ty::TraitRef<'tcx>,
1031 impl_item_refs: &[hir::ImplItemRef]) {
1032 // If the trait reference itself is erroneous (so the compilation is going
1033 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1034 // isn't populated for such impls.
1035 if impl_trait_ref.references_error() { return; }
1037 // Locate trait definition and items
1038 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
1039 let mut overridden_associated_type = None;
1041 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1043 // Check existing impl methods to see if they are both present in trait
1044 // and compatible with trait signature
1045 for impl_item in impl_items() {
1046 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1047 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1048 .find(|ac| ac.name == ty_impl_item.name);
1050 // Check that impl definition matches trait definition
1051 if let Some(ty_trait_item) = ty_trait_item {
1052 match impl_item.node {
1053 hir::ImplItemKind::Const(..) => {
1054 // Find associated const definition.
1055 if ty_trait_item.kind == ty::AssociatedKind::Const {
1056 compare_const_impl(tcx,
1062 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1063 "item `{}` is an associated const, \
1064 which doesn't match its trait `{}`",
1067 err.span_label(impl_item.span, &format!("does not match trait"));
1068 // We can only get the spans from local trait definition
1069 // Same for E0324 and E0325
1070 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1071 err.span_label(trait_span, &format!("item in trait"));
1076 hir::ImplItemKind::Method(_, body_id) => {
1077 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1078 if ty_trait_item.kind == ty::AssociatedKind::Method {
1079 let err_count = tcx.sess.err_count();
1080 compare_impl_method(tcx,
1087 true); // start with old-broken-mode
1088 if err_count == tcx.sess.err_count() {
1089 // old broken mode did not report an error. Try with the new mode.
1090 compare_impl_method(tcx,
1097 false); // use the new mode
1100 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1101 "item `{}` is an associated method, \
1102 which doesn't match its trait `{}`",
1105 err.span_label(impl_item.span, &format!("does not match trait"));
1106 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1107 err.span_label(trait_span, &format!("item in trait"));
1112 hir::ImplItemKind::Type(_) => {
1113 if ty_trait_item.kind == ty::AssociatedKind::Type {
1114 if ty_trait_item.defaultness.has_value() {
1115 overridden_associated_type = Some(impl_item);
1118 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1119 "item `{}` is an associated type, \
1120 which doesn't match its trait `{}`",
1123 err.span_label(impl_item.span, &format!("does not match trait"));
1124 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1125 err.span_label(trait_span, &format!("item in trait"));
1133 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1136 // Check for missing items from trait
1137 let mut missing_items = Vec::new();
1138 let mut invalidated_items = Vec::new();
1139 let associated_type_overridden = overridden_associated_type.is_some();
1140 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1141 let is_implemented = trait_def.ancestors(impl_id)
1142 .defs(tcx, trait_item.name, trait_item.kind)
1144 .map(|node_item| !node_item.node.is_from_trait())
1147 if !is_implemented {
1148 if !trait_item.defaultness.has_value() {
1149 missing_items.push(trait_item);
1150 } else if associated_type_overridden {
1151 invalidated_items.push(trait_item.name);
1156 let signature = |item: &ty::AssociatedItem| {
1158 ty::AssociatedKind::Method => {
1159 format!("{}", tcx.item_type(item.def_id).fn_sig().0)
1161 ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
1162 ty::AssociatedKind::Const => {
1163 format!("const {}: {:?};", item.name.to_string(), tcx.item_type(item.def_id))
1168 if !missing_items.is_empty() {
1169 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1170 "not all trait items implemented, missing: `{}`",
1171 missing_items.iter()
1172 .map(|trait_item| trait_item.name.to_string())
1173 .collect::<Vec<_>>().join("`, `"));
1174 err.span_label(impl_span, &format!("missing `{}` in implementation",
1175 missing_items.iter()
1176 .map(|trait_item| trait_item.name.to_string())
1177 .collect::<Vec<_>>().join("`, `")));
1178 for trait_item in missing_items {
1179 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1180 err.span_label(span, &format!("`{}` from trait", trait_item.name));
1182 err.note(&format!("`{}` from trait: `{}`",
1184 signature(&trait_item)));
1190 if !invalidated_items.is_empty() {
1191 let invalidator = overridden_associated_type.unwrap();
1192 span_err!(tcx.sess, invalidator.span, E0399,
1193 "the following trait items need to be reimplemented \
1194 as `{}` was overridden: `{}`",
1196 invalidated_items.iter()
1197 .map(|name| name.to_string())
1198 .collect::<Vec<_>>().join("`, `"))
1202 /// Checks whether a type can be represented in memory. In particular, it
1203 /// identifies types that contain themselves without indirection through a
1204 /// pointer, which would mean their size is unbounded.
1205 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1209 let rty = tcx.item_type(item_def_id);
1211 // Check that it is possible to represent this type. This call identifies
1212 // (1) types that contain themselves and (2) types that contain a different
1213 // recursive type. It is only necessary to throw an error on those that
1214 // contain themselves. For case 2, there must be an inner type that will be
1215 // caught by case 1.
1216 match rty.is_representable(tcx, sp) {
1217 Representability::SelfRecursive => {
1218 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1221 Representability::Representable | Representability::ContainsRecursive => (),
1226 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1227 let t = tcx.item_type(def_id);
1229 ty::TyAdt(def, substs) if def.is_struct() => {
1230 let fields = &def.struct_variant().fields;
1231 if fields.is_empty() {
1232 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1235 let e = fields[0].ty(tcx, substs);
1236 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1237 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1238 .span_label(sp, &format!("SIMD elements must have the same type"))
1243 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1244 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1246 span_err!(tcx.sess, sp, E0077,
1247 "SIMD vector element type should be machine type");
1256 #[allow(trivial_numeric_casts)]
1257 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1259 vs: &'tcx [hir::Variant],
1261 let def_id = tcx.hir.local_def_id(id);
1262 let def = tcx.lookup_adt_def(def_id);
1263 def.destructor(tcx); // force the destructor to be evaluated
1265 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1267 tcx.sess, sp, E0084,
1268 "unsupported representation for zero-variant enum")
1269 .span_label(sp, &format!("unsupported enum representation"))
1273 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1274 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1275 if !tcx.sess.features.borrow().i128_type {
1276 emit_feature_err(&tcx.sess.parse_sess,
1277 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1282 if let Some(e) = v.node.disr_expr {
1283 tcx.item_tables(tcx.hir.local_def_id(e.node_id));
1287 let mut disr_vals: Vec<ConstInt> = Vec::new();
1288 for (discr, v) in def.discriminants(tcx).zip(vs) {
1289 // Check for duplicate discriminant values
1290 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1291 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1292 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1293 let i_span = match variant_i.node.disr_expr {
1294 Some(expr) => tcx.hir.span(expr.node_id),
1295 None => tcx.hir.span(variant_i_node_id)
1297 let span = match v.node.disr_expr {
1298 Some(expr) => tcx.hir.span(expr.node_id),
1301 struct_span_err!(tcx.sess, span, E0081,
1302 "discriminant value `{}` already exists", disr_vals[i])
1303 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1304 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1307 disr_vals.push(discr);
1310 check_representable(tcx, sp, def_id);
1313 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1314 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1316 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1317 &self.ast_ty_to_ty_cache
1320 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1321 Some(&self.parameter_environment.free_substs)
1324 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1325 -> ty::GenericPredicates<'tcx>
1328 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1329 let item_id = tcx.hir.ty_param_owner(node_id);
1330 let item_def_id = tcx.hir.local_def_id(item_id);
1331 let generics = tcx.item_generics(item_def_id);
1332 let index = generics.type_param_to_index[&def_id.index];
1333 ty::GenericPredicates {
1335 predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| {
1337 ty::Predicate::Trait(ref data) => {
1338 data.0.self_ty().is_param(index)
1342 }).cloned().collect()
1346 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1347 -> Option<&'tcx ty::Region> {
1349 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1350 None => infer::MiscVariable(span)
1352 Some(self.next_region_var(v))
1355 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1356 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1359 fn ty_infer_for_def(&self,
1360 ty_param_def: &ty::TypeParameterDef,
1361 substs: &[Kind<'tcx>],
1362 span: Span) -> Ty<'tcx> {
1363 self.type_var_for_def(span, ty_param_def, substs)
1366 fn projected_ty_from_poly_trait_ref(&self,
1368 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1369 item_name: ast::Name)
1372 let (trait_ref, _) =
1373 self.replace_late_bound_regions_with_fresh_var(
1375 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1378 self.tcx().mk_projection(trait_ref, item_name)
1381 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1382 if ty.has_escaping_regions() {
1383 ty // FIXME: normalization and escaping regions
1385 self.normalize_associated_types_in(span, &ty)
1389 fn set_tainted_by_errors(&self) {
1390 self.infcx.set_tainted_by_errors()
1394 /// Controls whether the arguments are tupled. This is used for the call
1397 /// Tupling means that all call-side arguments are packed into a tuple and
1398 /// passed as a single parameter. For example, if tupling is enabled, this
1401 /// fn f(x: (isize, isize))
1403 /// Can be called as:
1410 #[derive(Clone, Eq, PartialEq)]
1411 enum TupleArgumentsFlag {
1416 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1417 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1418 rty: Option<Ty<'tcx>>,
1419 body_id: ast::NodeId)
1420 -> FnCtxt<'a, 'gcx, 'tcx> {
1422 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1424 err_count_on_creation: inh.tcx.sess.err_count(),
1426 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1427 ast::CRATE_NODE_ID)),
1428 diverges: Cell::new(Diverges::Maybe),
1429 has_errors: Cell::new(false),
1430 enclosing_loops: RefCell::new(EnclosingLoops {
1438 pub fn sess(&self) -> &Session {
1442 pub fn err_count_since_creation(&self) -> usize {
1443 self.tcx.sess.err_count() - self.err_count_on_creation
1446 /// Produce warning on the given node, if the current point in the
1447 /// function is unreachable, and there hasn't been another warning.
1448 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1449 if self.diverges.get() == Diverges::Always {
1450 self.diverges.set(Diverges::WarnedAlways);
1452 self.tables.borrow_mut().lints.add_lint(
1453 lint::builtin::UNREACHABLE_CODE,
1455 format!("unreachable {}", kind));
1461 code: ObligationCauseCode<'tcx>)
1462 -> ObligationCause<'tcx> {
1463 ObligationCause::new(span, self.body_id, code)
1466 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1467 self.cause(span, ObligationCauseCode::MiscObligation)
1470 /// Resolves type variables in `ty` if possible. Unlike the infcx
1471 /// version (resolve_type_vars_if_possible), this version will
1472 /// also select obligations if it seems useful, in an effort
1473 /// to get more type information.
1474 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1475 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1477 // No TyInfer()? Nothing needs doing.
1478 if !ty.has_infer_types() {
1479 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1483 // If `ty` is a type variable, see whether we already know what it is.
1484 ty = self.resolve_type_vars_if_possible(&ty);
1485 if !ty.has_infer_types() {
1486 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1490 // If not, try resolving pending obligations as much as
1491 // possible. This can help substantially when there are
1492 // indirect dependencies that don't seem worth tracking
1494 self.select_obligations_where_possible();
1495 ty = self.resolve_type_vars_if_possible(&ty);
1497 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1501 fn record_deferred_call_resolution(&self,
1502 closure_def_id: DefId,
1503 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1504 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1505 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1508 fn remove_deferred_call_resolutions(&self,
1509 closure_def_id: DefId)
1510 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1512 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1513 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1516 pub fn tag(&self) -> String {
1517 let self_ptr: *const FnCtxt = self;
1518 format!("{:?}", self_ptr)
1521 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1522 match self.locals.borrow().get(&nid) {
1525 span_bug!(span, "no type for local variable {}",
1526 self.tcx.hir.node_to_string(nid));
1532 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1533 debug!("write_ty({}, {:?}) in fcx {}",
1534 node_id, ty, self.tag());
1535 self.tables.borrow_mut().node_types.insert(node_id, ty);
1537 if ty.references_error() {
1538 self.has_errors.set(true);
1539 self.set_tainted_by_errors();
1542 // FIXME(canndrew): This is_never should probably be an is_uninhabited
1543 if ty.is_never() || self.type_var_diverges(ty) {
1544 self.diverges.set(self.diverges.get() | Diverges::Always);
1548 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1549 if !substs.substs.is_noop() {
1550 debug!("write_substs({}, {:?}) in fcx {}",
1555 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1559 pub fn write_autoderef_adjustment(&self,
1560 node_id: ast::NodeId,
1562 adjusted_ty: Ty<'tcx>) {
1563 self.write_adjustment(node_id, adjustment::Adjustment {
1564 kind: adjustment::Adjust::DerefRef {
1573 pub fn write_adjustment(&self,
1574 node_id: ast::NodeId,
1575 adj: adjustment::Adjustment<'tcx>) {
1576 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1578 if adj.is_identity() {
1582 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1585 /// Basically whenever we are converting from a type scheme into
1586 /// the fn body space, we always want to normalize associated
1587 /// types as well. This function combines the two.
1588 fn instantiate_type_scheme<T>(&self,
1590 substs: &Substs<'tcx>,
1593 where T : TypeFoldable<'tcx>
1595 let value = value.subst(self.tcx, substs);
1596 let result = self.normalize_associated_types_in(span, &value);
1597 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1604 /// As `instantiate_type_scheme`, but for the bounds found in a
1605 /// generic type scheme.
1606 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1607 -> ty::InstantiatedPredicates<'tcx> {
1608 let bounds = self.tcx.item_predicates(def_id);
1609 let result = bounds.instantiate(self.tcx, substs);
1610 let result = self.normalize_associated_types_in(span, &result.predicates);
1611 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1615 ty::InstantiatedPredicates {
1620 /// Replace all anonymized types with fresh inference variables
1621 /// and record them for writeback.
1622 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1623 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1624 if let ty::TyAnon(def_id, substs) = ty.sty {
1625 // Use the same type variable if the exact same TyAnon appears more
1626 // than once in the return type (e.g. if it's pased to a type alias).
1627 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1628 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1631 let span = self.tcx.def_span(def_id);
1632 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1633 self.anon_types.borrow_mut().insert(id, ty_var);
1635 let item_predicates = self.tcx.item_predicates(def_id);
1636 let bounds = item_predicates.instantiate(self.tcx, substs);
1638 for predicate in bounds.predicates {
1639 // Change the predicate to refer to the type variable,
1640 // which will be the concrete type, instead of the TyAnon.
1641 // This also instantiates nested `impl Trait`.
1642 let predicate = self.instantiate_anon_types(&predicate);
1644 // Require that the predicate holds for the concrete type.
1645 let cause = traits::ObligationCause::new(span, self.body_id,
1646 traits::ReturnType);
1647 self.register_predicate(traits::Obligation::new(cause, predicate));
1657 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1658 where T : TypeFoldable<'tcx>
1660 self.inh.normalize_associated_types_in(span, self.body_id, value)
1663 pub fn write_nil(&self, node_id: ast::NodeId) {
1664 self.write_ty(node_id, self.tcx.mk_nil());
1667 pub fn write_error(&self, node_id: ast::NodeId) {
1668 self.write_ty(node_id, self.tcx.types.err);
1671 pub fn require_type_meets(&self,
1674 code: traits::ObligationCauseCode<'tcx>,
1677 self.register_bound(
1680 traits::ObligationCause::new(span, self.body_id, code));
1683 pub fn require_type_is_sized(&self,
1686 code: traits::ObligationCauseCode<'tcx>)
1688 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1689 self.require_type_meets(ty, span, code, lang_item);
1692 pub fn register_bound(&self,
1695 cause: traits::ObligationCause<'tcx>)
1697 self.fulfillment_cx.borrow_mut()
1698 .register_bound(self, ty, def_id, cause);
1701 pub fn register_predicate(&self,
1702 obligation: traits::PredicateObligation<'tcx>)
1704 debug!("register_predicate({:?})", obligation);
1705 if obligation.has_escaping_regions() {
1706 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
1711 .register_predicate_obligation(self, obligation);
1714 pub fn register_predicates(&self,
1715 obligations: Vec<traits::PredicateObligation<'tcx>>)
1717 for obligation in obligations {
1718 self.register_predicate(obligation);
1722 pub fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
1723 self.register_predicates(infer_ok.obligations);
1727 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1728 let t = AstConv::ast_ty_to_ty(self, ast_t);
1729 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1733 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1734 match self.tables.borrow().node_types.get(&id) {
1736 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1738 bug!("no type for node {}: {} in fcx {}",
1739 id, self.tcx.hir.node_to_string(id),
1745 pub fn opt_node_ty_substs<F>(&self,
1748 F: FnOnce(&ty::ItemSubsts<'tcx>),
1750 if let Some(s) = self.tables.borrow().item_substs.get(&id) {
1755 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1756 /// outlive the region `r`.
1757 pub fn register_region_obligation(&self,
1759 region: &'tcx ty::Region,
1760 cause: traits::ObligationCause<'tcx>)
1762 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1763 fulfillment_cx.register_region_obligation(ty, region, cause);
1766 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1767 /// outlive the region `r`.
1768 pub fn register_wf_obligation(&self,
1771 code: traits::ObligationCauseCode<'tcx>)
1773 // WF obligations never themselves fail, so no real need to give a detailed cause:
1774 let cause = traits::ObligationCause::new(span, self.body_id, code);
1775 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1778 pub fn register_old_wf_obligation(&self,
1781 code: traits::ObligationCauseCode<'tcx>)
1783 // Registers an "old-style" WF obligation that uses the
1784 // implicator code. This is basically a buggy version of
1785 // `register_wf_obligation` that is being kept around
1786 // temporarily just to help with phasing in the newer rules.
1788 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1789 let cause = traits::ObligationCause::new(span, self.body_id, code);
1790 self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
1793 /// Registers obligations that all types appearing in `substs` are well-formed.
1794 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1796 for ty in substs.types() {
1797 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1801 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1802 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1803 /// trait/region obligations.
1805 /// For example, if there is a function:
1808 /// fn foo<'a,T:'a>(...)
1811 /// and a reference:
1817 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1818 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1819 pub fn add_obligations_for_parameters(&self,
1820 cause: traits::ObligationCause<'tcx>,
1821 predicates: &ty::InstantiatedPredicates<'tcx>)
1823 assert!(!predicates.has_escaping_regions());
1825 debug!("add_obligations_for_parameters(predicates={:?})",
1828 for obligation in traits::predicates_for_generics(cause, predicates) {
1829 self.register_predicate(obligation);
1833 // FIXME(arielb1): use this instead of field.ty everywhere
1834 // Only for fields! Returns <none> for methods>
1835 // Indifferent to privacy flags
1836 pub fn field_ty(&self,
1838 field: &'tcx ty::FieldDef,
1839 substs: &Substs<'tcx>)
1842 self.normalize_associated_types_in(span,
1843 &field.ty(self.tcx, substs))
1846 fn check_casts(&self) {
1847 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1848 for cast in deferred_cast_checks.drain(..) {
1853 /// Apply "fallbacks" to some types
1854 /// unconstrained types get replaced with ! or () (depending on whether
1855 /// feature(never_type) is enabled), unconstrained ints with i32, and
1856 /// unconstrained floats with f64.
1857 fn default_type_parameters(&self) {
1858 use rustc::ty::error::UnconstrainedNumeric::Neither;
1859 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1861 // Defaulting inference variables becomes very dubious if we have
1862 // encountered type-checking errors. Therefore, if we think we saw
1863 // some errors in this function, just resolve all uninstanted type
1864 // varibles to TyError.
1865 if self.is_tainted_by_errors() {
1866 for ty in &self.unsolved_variables() {
1867 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1868 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1869 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
1875 for ty in &self.unsolved_variables() {
1876 let resolved = self.resolve_type_vars_if_possible(ty);
1877 if self.type_var_diverges(resolved) {
1878 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
1880 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1881 self.tcx.mk_diverging_default());
1883 match self.type_is_unconstrained_numeric(resolved) {
1884 UnconstrainedInt => {
1885 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1887 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
1889 UnconstrainedFloat => {
1890 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1892 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
1900 fn select_all_obligations_and_apply_defaults(&self) {
1901 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
1902 self.new_select_all_obligations_and_apply_defaults();
1904 self.old_select_all_obligations_and_apply_defaults();
1908 // Implements old type inference fallback algorithm
1909 fn old_select_all_obligations_and_apply_defaults(&self) {
1910 self.select_obligations_where_possible();
1911 self.default_type_parameters();
1912 self.select_obligations_where_possible();
1915 fn new_select_all_obligations_and_apply_defaults(&self) {
1916 use rustc::ty::error::UnconstrainedNumeric::Neither;
1917 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1919 // For the time being this errs on the side of being memory wasteful but provides better
1921 // let type_variables = self.type_variables.clone();
1923 // There is a possibility that this algorithm will have to run an arbitrary number of times
1924 // to terminate so we bound it by the compiler's recursion limit.
1925 for _ in 0..self.tcx.sess.recursion_limit.get() {
1926 // First we try to solve all obligations, it is possible that the last iteration
1927 // has made it possible to make more progress.
1928 self.select_obligations_where_possible();
1930 let mut conflicts = Vec::new();
1932 // Collect all unsolved type, integral and floating point variables.
1933 let unsolved_variables = self.unsolved_variables();
1935 // We must collect the defaults *before* we do any unification. Because we have
1936 // directly attached defaults to the type variables any unification that occurs
1937 // will erase defaults causing conflicting defaults to be completely ignored.
1938 let default_map: FxHashMap<_, _> =
1941 .filter_map(|t| self.default(t).map(|d| (t, d)))
1944 let mut unbound_tyvars = FxHashSet();
1946 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1948 // We loop over the unsolved variables, resolving them and if they are
1949 // and unconstrainted numeric type we add them to the set of unbound
1950 // variables. We do this so we only apply literal fallback to type
1951 // variables without defaults.
1952 for ty in &unsolved_variables {
1953 let resolved = self.resolve_type_vars_if_possible(ty);
1954 if self.type_var_diverges(resolved) {
1955 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1956 self.tcx.mk_diverging_default());
1958 match self.type_is_unconstrained_numeric(resolved) {
1959 UnconstrainedInt | UnconstrainedFloat => {
1960 unbound_tyvars.insert(resolved);
1967 // We now remove any numeric types that also have defaults, and instead insert
1968 // the type variable with a defined fallback.
1969 for ty in &unsolved_variables {
1970 if let Some(_default) = default_map.get(ty) {
1971 let resolved = self.resolve_type_vars_if_possible(ty);
1973 debug!("select_all_obligations_and_apply_defaults: \
1974 ty: {:?} with default: {:?}",
1977 match resolved.sty {
1978 ty::TyInfer(ty::TyVar(_)) => {
1979 unbound_tyvars.insert(ty);
1982 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1983 unbound_tyvars.insert(ty);
1984 if unbound_tyvars.contains(resolved) {
1985 unbound_tyvars.remove(resolved);
1994 // If there are no more fallbacks to apply at this point we have applied all possible
1995 // defaults and type inference will proceed as normal.
1996 if unbound_tyvars.is_empty() {
2000 // Finally we go through each of the unbound type variables and unify them with
2001 // the proper fallback, reporting a conflicting default error if any of the
2002 // unifications fail. We know it must be a conflicting default because the
2003 // variable would only be in `unbound_tyvars` and have a concrete value if
2004 // it had been solved by previously applying a default.
2006 // We wrap this in a transaction for error reporting, if we detect a conflict
2007 // we will rollback the inference context to its prior state so we can probe
2008 // for conflicts and correctly report them.
2011 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2012 for ty in &unbound_tyvars {
2013 if self.type_var_diverges(ty) {
2014 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2015 self.tcx.mk_diverging_default());
2017 match self.type_is_unconstrained_numeric(ty) {
2018 UnconstrainedInt => {
2019 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2021 UnconstrainedFloat => {
2022 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2025 if let Some(default) = default_map.get(ty) {
2026 let default = default.clone();
2027 let default_ty = self.normalize_associated_types_in(
2028 default.origin_span, &default.ty);
2029 match self.eq_types(false,
2030 &self.misc(default.origin_span),
2033 Ok(ok) => self.register_infer_ok_obligations(ok),
2034 Err(_) => conflicts.push((*ty, default)),
2042 // If there are conflicts we rollback, otherwise commit
2043 if conflicts.len() > 0 {
2050 if conflicts.len() > 0 {
2051 // Loop through each conflicting default, figuring out the default that caused
2052 // a unification failure and then report an error for each.
2053 for (conflict, default) in conflicts {
2054 let conflicting_default =
2055 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
2056 .unwrap_or(type_variable::Default {
2057 ty: self.next_ty_var(
2058 TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)),
2059 origin_span: syntax_pos::DUMMY_SP,
2060 // what do I put here?
2061 def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID)
2064 // This is to ensure that we elimnate any non-determinism from the error
2065 // reporting by fixing an order, it doesn't matter what order we choose
2066 // just that it is consistent.
2067 let (first_default, second_default) =
2068 if default.def_id < conflicting_default.def_id {
2069 (default, conflicting_default)
2071 (conflicting_default, default)
2075 self.report_conflicting_default_types(
2076 first_default.origin_span,
2084 self.select_obligations_where_possible();
2087 // For use in error handling related to default type parameter fallback. We explicitly
2088 // apply the default that caused conflict first to a local version of the type variable
2089 // table then apply defaults until we find a conflict. That default must be the one
2090 // that caused conflict earlier.
2091 fn find_conflicting_default(&self,
2092 unbound_vars: &FxHashSet<Ty<'tcx>>,
2093 default_map: &FxHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
2095 -> Option<type_variable::Default<'tcx>> {
2096 use rustc::ty::error::UnconstrainedNumeric::Neither;
2097 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2099 // Ensure that we apply the conflicting default first
2100 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2101 unbound_tyvars.push(conflict);
2102 unbound_tyvars.extend(unbound_vars.iter());
2104 let mut result = None;
2105 // We run the same code as above applying defaults in order, this time when
2106 // we find the conflict we just return it for error reporting above.
2108 // We also run this inside snapshot that never commits so we can do error
2109 // reporting for more then one conflict.
2110 for ty in &unbound_tyvars {
2111 if self.type_var_diverges(ty) {
2112 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2113 self.tcx.mk_diverging_default());
2115 match self.type_is_unconstrained_numeric(ty) {
2116 UnconstrainedInt => {
2117 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2119 UnconstrainedFloat => {
2120 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2123 if let Some(default) = default_map.get(ty) {
2124 let default = default.clone();
2125 match self.eq_types(false,
2126 &self.misc(default.origin_span),
2129 Ok(ok) => self.register_infer_ok_obligations(ok),
2131 result = Some(default);
2143 fn select_all_obligations_or_error(&self) {
2144 debug!("select_all_obligations_or_error");
2146 // upvar inference should have ensured that all deferred call
2147 // resolutions are handled by now.
2148 assert!(self.deferred_call_resolutions.borrow().is_empty());
2150 self.select_all_obligations_and_apply_defaults();
2152 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2154 match fulfillment_cx.select_all_or_error(self) {
2156 Err(errors) => { self.report_fulfillment_errors(&errors); }
2160 /// Select as many obligations as we can at present.
2161 fn select_obligations_where_possible(&self) {
2162 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2164 Err(errors) => { self.report_fulfillment_errors(&errors); }
2168 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2169 /// returns a type of `&T`, but the actual type we assign to the
2170 /// *expression* is `T`. So this function just peels off the return
2171 /// type by one layer to yield `T`.
2172 fn make_overloaded_lvalue_return_type(&self,
2173 method: MethodCallee<'tcx>)
2174 -> ty::TypeAndMut<'tcx>
2176 // extract method return type, which will be &T;
2177 // all LB regions should have been instantiated during method lookup
2178 let ret_ty = method.ty.fn_ret();
2179 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2181 // method returns &T, but the type as visible to user is T, so deref
2182 ret_ty.builtin_deref(true, NoPreference).unwrap()
2185 fn lookup_indexing(&self,
2187 base_expr: &'gcx hir::Expr,
2190 lvalue_pref: LvaluePreference)
2191 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2193 // FIXME(#18741) -- this is almost but not quite the same as the
2194 // autoderef that normal method probing does. They could likely be
2197 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2199 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2200 if let Some(final_mt) = self.try_index_step(
2201 MethodCall::expr(expr.id),
2202 expr, base_expr, adj_ty, autoderefs,
2203 false, lvalue_pref, idx_ty)
2205 autoderef.finalize(lvalue_pref, Some(base_expr));
2206 return Some(final_mt);
2209 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2210 autoderef.finalize(lvalue_pref, Some(base_expr));
2211 let adjusted_ty = self.tcx.mk_slice(element_ty);
2212 return self.try_index_step(
2213 MethodCall::expr(expr.id), expr, base_expr,
2214 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2217 autoderef.unambiguous_final_ty();
2221 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2222 /// (and otherwise adjust) `base_expr`, looking for a type which either
2223 /// supports builtin indexing or overloaded indexing.
2224 /// This loop implements one step in that search; the autoderef loop
2225 /// is implemented by `lookup_indexing`.
2226 fn try_index_step(&self,
2227 method_call: MethodCall,
2229 base_expr: &'gcx hir::Expr,
2230 adjusted_ty: Ty<'tcx>,
2233 lvalue_pref: LvaluePreference,
2235 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2238 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2239 autoderefs={}, unsize={}, index_ty={:?})",
2247 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2249 // First, try built-in indexing.
2250 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2251 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2252 debug!("try_index_step: success, using built-in indexing");
2253 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2255 self.write_autoderef_adjustment(base_expr.id, autoderefs, adjusted_ty);
2256 return Some((tcx.types.usize, ty));
2261 // Try `IndexMut` first, if preferred.
2262 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2263 (PreferMutLvalue, Some(trait_did)) => {
2264 self.lookup_method_in_trait_adjusted(expr.span,
2266 Symbol::intern("index_mut"),
2271 Some(vec![input_ty]))
2276 // Otherwise, fall back to `Index`.
2277 let method = match (method, tcx.lang_items.index_trait()) {
2278 (None, Some(trait_did)) => {
2279 self.lookup_method_in_trait_adjusted(expr.span,
2281 Symbol::intern("index"),
2286 Some(vec![input_ty]))
2288 (method, _) => method,
2291 // If some lookup succeeds, write callee into table and extract index/element
2292 // type from the method signature.
2293 // If some lookup succeeded, install method in table
2294 method.map(|method| {
2295 debug!("try_index_step: success, using overloaded indexing");
2296 self.tables.borrow_mut().method_map.insert(method_call, method);
2297 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2301 fn check_method_argument_types(&self,
2303 method_fn_ty: Ty<'tcx>,
2304 callee_expr: &'gcx hir::Expr,
2305 args_no_rcvr: &'gcx [hir::Expr],
2306 tuple_arguments: TupleArgumentsFlag,
2307 expected: Expectation<'tcx>)
2309 if method_fn_ty.references_error() {
2310 let err_inputs = self.err_args(args_no_rcvr.len());
2312 let err_inputs = match tuple_arguments {
2313 DontTupleArguments => err_inputs,
2314 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2317 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2318 false, tuple_arguments, None);
2321 match method_fn_ty.sty {
2322 ty::TyFnDef(def_id, .., ref fty) => {
2323 // HACK(eddyb) ignore self in the definition (see above).
2324 let expected_arg_tys = self.expected_inputs_for_expected_output(
2328 &fty.0.inputs()[1..]
2330 self.check_argument_types(sp, &fty.0.inputs()[1..], &expected_arg_tys[..],
2331 args_no_rcvr, fty.0.variadic, tuple_arguments,
2332 self.tcx.hir.span_if_local(def_id));
2336 span_bug!(callee_expr.span, "method without bare fn type");
2342 /// Generic function that factors out common logic from function calls,
2343 /// method calls and overloaded operators.
2344 fn check_argument_types(&self,
2346 fn_inputs: &[Ty<'tcx>],
2347 expected_arg_tys: &[Ty<'tcx>],
2348 args: &'gcx [hir::Expr],
2350 tuple_arguments: TupleArgumentsFlag,
2351 def_span: Option<Span>) {
2354 // Grab the argument types, supplying fresh type variables
2355 // if the wrong number of arguments were supplied
2356 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2362 // All the input types from the fn signature must outlive the call
2363 // so as to validate implied bounds.
2364 for &fn_input_ty in fn_inputs {
2365 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2368 let mut expected_arg_tys = expected_arg_tys;
2369 let expected_arg_count = fn_inputs.len();
2371 let sp_args = if args.len() > 0 {
2372 let (first, args) = args.split_at(1);
2373 let mut sp_tmp = first[0].span;
2375 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2376 if ! sp_opt.is_some() {
2379 sp_tmp = sp_opt.unwrap();
2386 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2387 arg_count: usize, error_code: &str, variadic: bool,
2388 def_span: Option<Span>) {
2389 let mut err = sess.struct_span_err_with_code(sp,
2390 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2391 if variadic {"at least "} else {""},
2393 if expected_count == 1 {""} else {"s"},
2395 if arg_count == 1 {" was"} else {"s were"}),
2398 err.span_label(sp, &format!("expected {}{} parameter{}",
2399 if variadic {"at least "} else {""},
2401 if expected_count == 1 {""} else {"s"}));
2402 if let Some(def_s) = def_span {
2403 err.span_label(def_s, &format!("defined here"));
2408 let formal_tys = if tuple_arguments == TupleArguments {
2409 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2410 match tuple_type.sty {
2411 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2412 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2413 "E0057", false, def_span);
2414 expected_arg_tys = &[];
2415 self.err_args(args.len())
2417 ty::TyTuple(arg_types, _) => {
2418 expected_arg_tys = match expected_arg_tys.get(0) {
2419 Some(&ty) => match ty.sty {
2420 ty::TyTuple(ref tys, _) => &tys,
2428 span_err!(tcx.sess, sp, E0059,
2429 "cannot use call notation; the first type parameter \
2430 for the function trait is neither a tuple nor unit");
2431 expected_arg_tys = &[];
2432 self.err_args(args.len())
2435 } else if expected_arg_count == supplied_arg_count {
2437 } else if variadic {
2438 if supplied_arg_count >= expected_arg_count {
2441 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2442 supplied_arg_count, "E0060", true, def_span);
2443 expected_arg_tys = &[];
2444 self.err_args(supplied_arg_count)
2447 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2448 supplied_arg_count, "E0061", false, def_span);
2449 expected_arg_tys = &[];
2450 self.err_args(supplied_arg_count)
2453 debug!("check_argument_types: formal_tys={:?}",
2454 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2456 // Check the arguments.
2457 // We do this in a pretty awful way: first we typecheck any arguments
2458 // that are not closures, then we typecheck the closures. This is so
2459 // that we have more information about the types of arguments when we
2460 // typecheck the functions. This isn't really the right way to do this.
2461 for &check_closures in &[false, true] {
2462 debug!("check_closures={}", check_closures);
2464 // More awful hacks: before we check argument types, try to do
2465 // an "opportunistic" vtable resolution of any trait bounds on
2466 // the call. This helps coercions.
2468 self.select_obligations_where_possible();
2471 // For variadic functions, we don't have a declared type for all of
2472 // the arguments hence we only do our usual type checking with
2473 // the arguments who's types we do know.
2474 let t = if variadic {
2476 } else if tuple_arguments == TupleArguments {
2481 for (i, arg) in args.iter().take(t).enumerate() {
2482 // Warn only for the first loop (the "no closures" one).
2483 // Closure arguments themselves can't be diverging, but
2484 // a previous argument can, e.g. `foo(panic!(), || {})`.
2485 if !check_closures {
2486 self.warn_if_unreachable(arg.id, arg.span, "expression");
2489 let is_closure = match arg.node {
2490 hir::ExprClosure(..) => true,
2494 if is_closure != check_closures {
2498 debug!("checking the argument");
2499 let formal_ty = formal_tys[i];
2501 // The special-cased logic below has three functions:
2502 // 1. Provide as good of an expected type as possible.
2503 let expected = expected_arg_tys.get(i).map(|&ty| {
2504 Expectation::rvalue_hint(self, ty)
2507 let checked_ty = self.check_expr_with_expectation(&arg,
2508 expected.unwrap_or(ExpectHasType(formal_ty)));
2509 // 2. Coerce to the most detailed type that could be coerced
2510 // to, which is `expected_ty` if `rvalue_hint` returns an
2511 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2512 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2513 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2515 // 3. Relate the expected type and the formal one,
2516 // if the expected type was used for the coercion.
2517 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2521 // We also need to make sure we at least write the ty of the other
2522 // arguments which we skipped above.
2524 for arg in args.iter().skip(expected_arg_count) {
2525 let arg_ty = self.check_expr(&arg);
2527 // There are a few types which get autopromoted when passed via varargs
2528 // in C but we just error out instead and require explicit casts.
2529 let arg_ty = self.structurally_resolved_type(arg.span,
2532 ty::TyFloat(ast::FloatTy::F32) => {
2533 self.type_error_message(arg.span, |t| {
2534 format!("can't pass an `{}` to variadic \
2535 function, cast to `c_double`", t)
2538 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2539 self.type_error_message(arg.span, |t| {
2540 format!("can't pass `{}` to variadic \
2541 function, cast to `c_int`",
2545 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2546 self.type_error_message(arg.span, |t| {
2547 format!("can't pass `{}` to variadic \
2548 function, cast to `c_uint`",
2552 ty::TyFnDef(.., f) => {
2553 let ptr_ty = self.tcx.mk_fn_ptr(f);
2554 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2555 self.type_error_message(arg.span,
2557 format!("can't pass `{}` to variadic \
2558 function, cast to `{}`", t, ptr_ty)
2567 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2568 (0..len).map(|_| self.tcx.types.err).collect()
2571 // AST fragment checking
2574 expected: Expectation<'tcx>)
2580 ast::LitKind::Str(..) => tcx.mk_static_str(),
2581 ast::LitKind::ByteStr(ref v) => {
2582 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2583 tcx.mk_array(tcx.types.u8, v.len()))
2585 ast::LitKind::Byte(_) => tcx.types.u8,
2586 ast::LitKind::Char(_) => tcx.types.char,
2587 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2588 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2589 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2590 let opt_ty = expected.to_option(self).and_then(|ty| {
2592 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2593 ty::TyChar => Some(tcx.types.u8),
2594 ty::TyRawPtr(..) => Some(tcx.types.usize),
2595 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2599 opt_ty.unwrap_or_else(
2600 || tcx.mk_int_var(self.next_int_var_id()))
2602 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2603 ast::LitKind::FloatUnsuffixed(_) => {
2604 let opt_ty = expected.to_option(self).and_then(|ty| {
2606 ty::TyFloat(_) => Some(ty),
2610 opt_ty.unwrap_or_else(
2611 || tcx.mk_float_var(self.next_float_var_id()))
2613 ast::LitKind::Bool(_) => tcx.types.bool
2617 fn check_expr_eq_type(&self,
2618 expr: &'gcx hir::Expr,
2619 expected: Ty<'tcx>) {
2620 let ty = self.check_expr_with_hint(expr, expected);
2621 self.demand_eqtype(expr.span, expected, ty);
2624 pub fn check_expr_has_type(&self,
2625 expr: &'gcx hir::Expr,
2626 expected: Ty<'tcx>) -> Ty<'tcx> {
2627 let ty = self.check_expr_with_hint(expr, expected);
2628 self.demand_suptype(expr.span, expected, ty);
2632 fn check_expr_coercable_to_type(&self,
2633 expr: &'gcx hir::Expr,
2634 expected: Ty<'tcx>) -> Ty<'tcx> {
2635 let ty = self.check_expr_with_hint(expr, expected);
2636 self.demand_coerce(expr, ty, expected);
2640 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2641 expected: Ty<'tcx>) -> Ty<'tcx> {
2642 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2645 fn check_expr_with_expectation(&self,
2646 expr: &'gcx hir::Expr,
2647 expected: Expectation<'tcx>) -> Ty<'tcx> {
2648 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2651 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2652 self.check_expr_with_expectation(expr, NoExpectation)
2655 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2656 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2657 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2660 // determine the `self` type, using fresh variables for all variables
2661 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2662 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2664 pub fn impl_self_ty(&self,
2665 span: Span, // (potential) receiver for this impl
2667 -> TypeAndSubsts<'tcx> {
2668 let ity = self.tcx.item_type(did);
2669 debug!("impl_self_ty: ity={:?}", ity);
2671 let substs = self.fresh_substs_for_item(span, did);
2672 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2674 TypeAndSubsts { substs: substs, ty: substd_ty }
2677 /// Unifies the output type with the expected type early, for more coercions
2678 /// and forward type information on the input expressions.
2679 fn expected_inputs_for_expected_output(&self,
2681 expected_ret: Expectation<'tcx>,
2682 formal_ret: Ty<'tcx>,
2683 formal_args: &[Ty<'tcx>])
2685 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2686 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2687 // Attempt to apply a subtyping relationship between the formal
2688 // return type (likely containing type variables if the function
2689 // is polymorphic) and the expected return type.
2690 // No argument expectations are produced if unification fails.
2691 let origin = self.misc(call_span);
2692 let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
2693 // FIXME(#15760) can't use try! here, FromError doesn't default
2694 // to identity so the resulting type is not constrained.
2696 Ok(ok) => self.register_infer_ok_obligations(ok),
2697 Err(e) => return Err(e),
2700 // Record all the argument types, with the substitutions
2701 // produced from the above subtyping unification.
2702 Ok(formal_args.iter().map(|ty| {
2703 self.resolve_type_vars_if_possible(ty)
2706 }).unwrap_or(vec![]);
2707 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2708 formal_args, formal_ret,
2709 expected_args, expected_ret);
2713 // Checks a method call.
2714 fn check_method_call(&self,
2715 expr: &'gcx hir::Expr,
2716 method_name: Spanned<ast::Name>,
2717 args: &'gcx [hir::Expr],
2719 expected: Expectation<'tcx>,
2720 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2721 let rcvr = &args[0];
2722 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2724 // no need to check for bot/err -- callee does that
2725 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2727 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2728 let fn_ty = match self.lookup_method(method_name.span,
2735 let method_ty = method.ty;
2736 let method_call = MethodCall::expr(expr.id);
2737 self.tables.borrow_mut().method_map.insert(method_call, method);
2741 if method_name.node != keywords::Invalid.name() {
2742 self.report_method_error(method_name.span,
2749 self.write_error(expr.id);
2754 // Call the generic checker.
2755 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2763 // A generic function for checking the then and else in an if
2765 fn check_then_else(&self,
2766 cond_expr: &'gcx hir::Expr,
2767 then_blk: &'gcx hir::Block,
2768 opt_else_expr: Option<&'gcx hir::Expr>,
2770 expected: Expectation<'tcx>) -> Ty<'tcx> {
2771 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2772 let cond_diverges = self.diverges.get();
2773 self.diverges.set(Diverges::Maybe);
2775 let expected = expected.adjust_for_branches(self);
2776 let then_ty = self.check_block_with_expected(then_blk, expected);
2777 let then_diverges = self.diverges.get();
2778 self.diverges.set(Diverges::Maybe);
2780 let unit = self.tcx.mk_nil();
2781 let (cause, expected_ty, found_ty, result);
2782 if let Some(else_expr) = opt_else_expr {
2783 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2784 let else_diverges = self.diverges.get();
2785 cause = self.cause(sp, ObligationCauseCode::IfExpression);
2787 // Only try to coerce-unify if we have a then expression
2788 // to assign coercions to, otherwise it's () or diverging.
2789 expected_ty = then_ty;
2791 result = if let Some(ref then) = then_blk.expr {
2792 let res = self.try_find_coercion_lub(&cause, || Some(&**then),
2793 then_ty, else_expr, else_ty);
2795 // In case we did perform an adjustment, we have to update
2796 // the type of the block, because old trans still uses it.
2798 let adj = self.tables.borrow().adjustments.get(&then.id).cloned();
2799 if let Some(adj) = adj {
2800 self.write_ty(then_blk.id, adj.target);
2806 self.commit_if_ok(|_| {
2807 let trace = TypeTrace::types(&cause, true, then_ty, else_ty);
2808 self.lub(true, trace, &then_ty, &else_ty)
2809 .map(|ok| self.register_infer_ok_obligations(ok))
2813 // We won't diverge unless both branches do (or the condition does).
2814 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2816 // If the condition is false we can't diverge.
2817 self.diverges.set(cond_diverges);
2819 cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2822 result = self.eq_types(true, &cause, unit, then_ty)
2824 self.register_infer_ok_obligations(ok);
2831 if cond_ty.references_error() {
2838 self.report_mismatched_types(&cause, expected_ty, found_ty, e).emit();
2844 // Check field access expressions
2845 fn check_field(&self,
2846 expr: &'gcx hir::Expr,
2847 lvalue_pref: LvaluePreference,
2848 base: &'gcx hir::Expr,
2849 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2850 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2851 let expr_t = self.structurally_resolved_type(expr.span,
2853 let mut private_candidate = None;
2854 let mut autoderef = self.autoderef(expr.span, expr_t);
2855 while let Some((base_t, autoderefs)) = autoderef.next() {
2857 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2858 debug!("struct named {:?}", base_t);
2859 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2860 let field_ty = self.field_ty(expr.span, field, substs);
2861 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2862 autoderef.finalize(lvalue_pref, Some(base));
2863 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2865 self.tcx.check_stability(field.did, expr.id, expr.span);
2869 private_candidate = Some((base_def.did, field_ty));
2875 autoderef.unambiguous_final_ty();
2877 if let Some((did, field_ty)) = private_candidate {
2878 let struct_path = self.tcx().item_path_str(did);
2879 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2880 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2881 // Also check if an accessible method exists, which is often what is meant.
2882 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2883 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2888 } else if field.node == keywords::Invalid.name() {
2889 self.tcx().types.err
2890 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2891 self.type_error_struct(field.span, |actual| {
2892 format!("attempted to take value of method `{}` on type \
2893 `{}`", field.node, actual)
2895 .help("maybe a `()` to call it is missing? \
2896 If not, try an anonymous function")
2898 self.tcx().types.err
2900 let mut err = self.type_error_struct(field.span, |actual| {
2901 format!("no field `{}` on type `{}`",
2905 ty::TyAdt(def, _) if !def.is_enum() => {
2906 if let Some(suggested_field_name) =
2907 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2908 err.span_label(field.span,
2909 &format!("did you mean `{}`?", suggested_field_name));
2911 err.span_label(field.span,
2912 &format!("unknown field"));
2915 ty::TyRawPtr(..) => {
2916 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2918 self.tcx.hir.node_to_pretty_string(base.id),
2924 self.tcx().types.err
2928 // Return an hint about the closest match in field names
2929 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2930 field: &Spanned<ast::Name>,
2931 skip : Vec<InternedString>)
2933 let name = field.node.as_str();
2934 let names = variant.fields.iter().filter_map(|field| {
2935 // ignore already set fields and private fields from non-local crates
2936 if skip.iter().any(|x| *x == field.name.as_str()) ||
2937 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2944 // only find fits with at least one matching letter
2945 find_best_match_for_name(names, &name, Some(name.len()))
2948 // Check tuple index expressions
2949 fn check_tup_field(&self,
2950 expr: &'gcx hir::Expr,
2951 lvalue_pref: LvaluePreference,
2952 base: &'gcx hir::Expr,
2953 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2954 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2955 let expr_t = self.structurally_resolved_type(expr.span,
2957 let mut private_candidate = None;
2958 let mut tuple_like = false;
2959 let mut autoderef = self.autoderef(expr.span, expr_t);
2960 while let Some((base_t, autoderefs)) = autoderef.next() {
2961 let field = match base_t.sty {
2962 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2963 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2964 if !tuple_like { continue }
2966 debug!("tuple struct named {:?}", base_t);
2967 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
2968 let field_ty = self.field_ty(expr.span, field, substs);
2969 private_candidate = Some((base_def.did, field_ty));
2970 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2971 self.tcx.check_stability(field.did, expr.id, expr.span);
2978 ty::TyTuple(ref v, _) => {
2980 v.get(idx.node).cloned()
2985 if let Some(field_ty) = field {
2986 autoderef.finalize(lvalue_pref, Some(base));
2987 self.write_autoderef_adjustment(base.id, autoderefs, base_t);
2991 autoderef.unambiguous_final_ty();
2993 if let Some((did, field_ty)) = private_candidate {
2994 let struct_path = self.tcx().item_path_str(did);
2995 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
2996 self.tcx().sess.span_err(expr.span, &msg);
3000 self.type_error_message(
3004 format!("attempted out-of-bounds tuple index `{}` on \
3009 format!("attempted tuple index `{}` on type `{}`, but the \
3010 type was not a tuple or tuple struct",
3017 self.tcx().types.err
3020 fn report_unknown_field(&self,
3022 variant: &'tcx ty::VariantDef,
3024 skip_fields: &[hir::Field],
3026 let mut err = self.type_error_struct_with_diag(
3028 |actual| match ty.sty {
3029 ty::TyAdt(adt, ..) if adt.is_enum() => {
3030 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3031 "{} `{}::{}` has no field named `{}`",
3032 kind_name, actual, variant.name, field.name.node)
3035 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3036 "{} `{}` has no field named `{}`",
3037 kind_name, actual, field.name.node)
3041 // prevent all specified fields from being suggested
3042 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3043 if let Some(field_name) = Self::suggest_field_name(variant,
3045 skip_fields.collect()) {
3046 err.span_label(field.name.span,
3047 &format!("field does not exist - did you mean `{}`?", field_name));
3050 ty::TyAdt(adt, ..) if adt.is_enum() => {
3051 err.span_label(field.name.span, &format!("`{}::{}` does not have this field",
3055 err.span_label(field.name.span, &format!("`{}` does not have this field", ty));
3062 fn check_expr_struct_fields(&self,
3064 expected: Expectation<'tcx>,
3065 expr_id: ast::NodeId,
3067 variant: &'tcx ty::VariantDef,
3068 ast_fields: &'gcx [hir::Field],
3069 check_completeness: bool) {
3073 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3074 .get(0).cloned().unwrap_or(adt_ty);
3076 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3077 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3078 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3080 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3083 let mut remaining_fields = FxHashMap();
3084 for field in &variant.fields {
3085 remaining_fields.insert(field.name, field);
3088 let mut seen_fields = FxHashMap();
3090 let mut error_happened = false;
3092 // Typecheck each field.
3093 for field in ast_fields {
3094 let final_field_type;
3095 let field_type_hint;
3097 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3098 final_field_type = self.field_ty(field.span, v_field, substs);
3099 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3101 seen_fields.insert(field.name.node, field.span);
3103 // we don't look at stability attributes on
3104 // struct-like enums (yet...), but it's definitely not
3105 // a bug to have construct one.
3106 if adt_kind != ty::AdtKind::Enum {
3107 tcx.check_stability(v_field.did, expr_id, field.span);
3110 error_happened = true;
3111 final_field_type = tcx.types.err;
3112 field_type_hint = tcx.types.err;
3113 if let Some(_) = variant.find_field_named(field.name.node) {
3114 let mut err = struct_span_err!(self.tcx.sess,
3117 "field `{}` specified more than once",
3120 err.span_label(field.name.span, &format!("used more than once"));
3122 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3123 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3128 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3132 // Make sure to give a type to the field even if there's
3133 // an error, so we can continue typechecking
3134 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3135 self.demand_coerce(&field.expr, ty, final_field_type);
3138 // Make sure the programmer specified correct number of fields.
3139 if kind_name == "union" {
3140 if ast_fields.len() != 1 {
3141 tcx.sess.span_err(span, "union expressions should have exactly one field");
3143 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3144 let len = remaining_fields.len();
3146 let mut displayable_field_names = remaining_fields
3148 .map(|x| x.as_str())
3149 .collect::<Vec<_>>();
3151 displayable_field_names.sort();
3153 let truncated_fields_error = if len <= 3 {
3156 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3159 let remaining_fields_names = displayable_field_names.iter().take(3)
3160 .map(|n| format!("`{}`", n))
3161 .collect::<Vec<_>>()
3164 struct_span_err!(tcx.sess, span, E0063,
3165 "missing field{} {}{} in initializer of `{}`",
3166 if remaining_fields.len() == 1 {""} else {"s"},
3167 remaining_fields_names,
3168 truncated_fields_error,
3170 .span_label(span, &format!("missing {}{}",
3171 remaining_fields_names,
3172 truncated_fields_error))
3177 fn check_struct_fields_on_error(&self,
3178 fields: &'gcx [hir::Field],
3179 base_expr: &'gcx Option<P<hir::Expr>>) {
3180 for field in fields {
3181 self.check_expr(&field.expr);
3185 self.check_expr(&base);
3191 pub fn check_struct_path(&self,
3193 node_id: ast::NodeId)
3194 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3195 let path_span = match *qpath {
3196 hir::QPath::Resolved(_, ref path) => path.span,
3197 hir::QPath::TypeRelative(ref qself, _) => qself.span
3199 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3200 let variant = match def {
3202 self.set_tainted_by_errors();
3205 Def::Variant(..) => {
3207 ty::TyAdt(adt, substs) => {
3208 Some((adt.variant_of_def(def), adt.did, substs))
3210 _ => bug!("unexpected type: {:?}", ty.sty)
3213 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3214 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3216 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3217 Some((adt.struct_variant(), adt.did, substs))
3222 _ => bug!("unexpected definition: {:?}", def)
3225 if let Some((variant, did, substs)) = variant {
3226 // Check bounds on type arguments used in the path.
3227 let bounds = self.instantiate_bounds(path_span, did, substs);
3228 let cause = traits::ObligationCause::new(path_span, self.body_id,
3229 traits::ItemObligation(did));
3230 self.add_obligations_for_parameters(cause, &bounds);
3234 struct_span_err!(self.tcx.sess, path_span, E0071,
3235 "expected struct, variant or union type, found {}",
3236 ty.sort_string(self.tcx))
3237 .span_label(path_span, &format!("not a struct"))
3243 fn check_expr_struct(&self,
3245 expected: Expectation<'tcx>,
3247 fields: &'gcx [hir::Field],
3248 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3250 // Find the relevant variant
3251 let (variant, struct_ty) =
3252 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3255 self.check_struct_fields_on_error(fields, base_expr);
3256 return self.tcx.types.err;
3259 let path_span = match *qpath {
3260 hir::QPath::Resolved(_, ref path) => path.span,
3261 hir::QPath::TypeRelative(ref qself, _) => qself.span
3264 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3265 base_expr.is_none());
3266 if let &Some(ref base_expr) = base_expr {
3267 self.check_expr_has_type(base_expr, struct_ty);
3268 match struct_ty.sty {
3269 ty::TyAdt(adt, substs) if adt.is_struct() => {
3270 self.tables.borrow_mut().fru_field_types.insert(
3272 adt.struct_variant().fields.iter().map(|f| {
3273 self.normalize_associated_types_in(
3274 expr.span, &f.ty(self.tcx, substs)
3280 span_err!(self.tcx.sess, base_expr.span, E0436,
3281 "functional record update syntax requires a struct");
3285 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3291 /// If an expression has any sub-expressions that result in a type error,
3292 /// inspecting that expression's type with `ty.references_error()` will return
3293 /// true. Likewise, if an expression is known to diverge, inspecting its
3294 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3295 /// strict, _|_ can appear in the type of an expression that does not,
3296 /// itself, diverge: for example, fn() -> _|_.)
3297 /// Note that inspecting a type's structure *directly* may expose the fact
3298 /// that there are actually multiple representations for `TyError`, so avoid
3299 /// that when err needs to be handled differently.
3300 fn check_expr_with_expectation_and_lvalue_pref(&self,
3301 expr: &'gcx hir::Expr,
3302 expected: Expectation<'tcx>,
3303 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3304 debug!(">> typechecking: expr={:?} expected={:?}",
3307 // Warn for expressions after diverging siblings.
3308 self.warn_if_unreachable(expr.id, expr.span, "expression");
3310 // Hide the outer diverging and has_errors flags.
3311 let old_diverges = self.diverges.get();
3312 let old_has_errors = self.has_errors.get();
3313 self.diverges.set(Diverges::Maybe);
3314 self.has_errors.set(false);
3316 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3318 // Warn for non-block expressions with diverging children.
3321 hir::ExprLoop(..) | hir::ExprWhile(..) |
3322 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3324 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3327 // Record the type, which applies it effects.
3328 // We need to do this after the warning above, so that
3329 // we don't warn for the diverging expression itself.
3330 self.write_ty(expr.id, ty);
3332 // Combine the diverging and has_error flags.
3333 self.diverges.set(self.diverges.get() | old_diverges);
3334 self.has_errors.set(self.has_errors.get() | old_has_errors);
3336 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3337 debug!("... {:?}, expected is {:?}", ty, expected);
3339 // Add adjustments to !-expressions
3341 if let Some(hir::map::NodeExpr(node_expr)) = self.tcx.hir.find(expr.id) {
3342 let adj_ty = self.next_diverging_ty_var(
3343 TypeVariableOrigin::AdjustmentType(node_expr.span));
3344 self.write_adjustment(expr.id, adjustment::Adjustment {
3345 kind: adjustment::Adjust::NeverToAny,
3354 fn check_expr_kind(&self,
3355 expr: &'gcx hir::Expr,
3356 expected: Expectation<'tcx>,
3357 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3361 hir::ExprBox(ref subexpr) => {
3362 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3364 ty::TyAdt(def, _) if def.is_box()
3365 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3369 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3370 tcx.mk_box(referent_ty)
3373 hir::ExprLit(ref lit) => {
3374 self.check_lit(&lit, expected)
3376 hir::ExprBinary(op, ref lhs, ref rhs) => {
3377 self.check_binop(expr, op, lhs, rhs)
3379 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3380 self.check_binop_assign(expr, op, lhs, rhs)
3382 hir::ExprUnary(unop, ref oprnd) => {
3383 let expected_inner = match unop {
3384 hir::UnNot | hir::UnNeg => {
3391 let lvalue_pref = match unop {
3392 hir::UnDeref => lvalue_pref,
3395 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3399 if !oprnd_t.references_error() {
3402 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3404 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3406 } else if let Some(method) = self.try_overloaded_deref(
3407 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3408 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3409 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3412 self.type_error_message(expr.span, |actual| {
3413 format!("type `{}` cannot be \
3414 dereferenced", actual)
3416 oprnd_t = tcx.types.err;
3420 oprnd_t = self.structurally_resolved_type(oprnd.span,
3422 let result = self.check_user_unop("!", "not",
3423 tcx.lang_items.not_trait(),
3424 expr, &oprnd, oprnd_t, unop);
3425 // If it's builtin, we can reuse the type, this helps inference.
3426 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3431 oprnd_t = self.structurally_resolved_type(oprnd.span,
3433 let result = self.check_user_unop("-", "neg",
3434 tcx.lang_items.neg_trait(),
3435 expr, &oprnd, oprnd_t, unop);
3436 // If it's builtin, we can reuse the type, this helps inference.
3437 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3445 hir::ExprAddrOf(mutbl, ref oprnd) => {
3446 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3448 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3449 if self.tcx.expr_is_lval(&oprnd) {
3450 // Lvalues may legitimately have unsized types.
3451 // For example, dereferences of a fat pointer and
3452 // the last field of a struct can be unsized.
3453 ExpectHasType(mt.ty)
3455 Expectation::rvalue_hint(self, mt.ty)
3461 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3462 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3464 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3465 if tm.ty.references_error() {
3468 // Note: at this point, we cannot say what the best lifetime
3469 // is to use for resulting pointer. We want to use the
3470 // shortest lifetime possible so as to avoid spurious borrowck
3471 // errors. Moreover, the longest lifetime will depend on the
3472 // precise details of the value whose address is being taken
3473 // (and how long it is valid), which we don't know yet until type
3474 // inference is complete.
3476 // Therefore, here we simply generate a region variable. The
3477 // region inferencer will then select the ultimate value.
3478 // Finally, borrowck is charged with guaranteeing that the
3479 // value whose address was taken can actually be made to live
3480 // as long as it needs to live.
3481 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3482 tcx.mk_ref(region, tm)
3485 hir::ExprPath(ref qpath) => {
3486 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3487 expr.id, expr.span);
3488 let ty = if def != Def::Err {
3489 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3491 self.set_tainted_by_errors();
3495 // We always require that the type provided as the value for
3496 // a type parameter outlives the moment of instantiation.
3497 self.opt_node_ty_substs(expr.id, |item_substs| {
3498 self.add_wf_bounds(&item_substs.substs, expr);
3503 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3504 for output in outputs {
3505 self.check_expr(output);
3507 for input in inputs {
3508 self.check_expr(input);
3512 hir::ExprBreak(label, ref expr_opt) => {
3514 let mut enclosing_loops = self.enclosing_loops.borrow_mut();
3515 enclosing_loops.find_loop(label.loop_id).map(|ctxt| ctxt.coerce_to)
3517 if let Some(coerce_to) = coerce_to {
3520 if let Some(ref e) = *expr_opt {
3521 // Recurse without `enclosing_loops` borrowed.
3522 e_ty = self.check_expr_with_hint(e, coerce_to);
3523 cause = self.misc(e.span);
3524 // Notably, the recursive call may alter coerce_to - must not keep using it!
3526 // `break` without argument acts like `break ()`.
3527 e_ty = tcx.mk_nil();
3528 cause = self.misc(expr.span);
3531 let mut enclosing_loops = self.enclosing_loops.borrow_mut();
3532 let ctxt = enclosing_loops.find_loop(label.loop_id).unwrap();
3534 let result = if let Some(ref e) = *expr_opt {
3535 // Special-case the first element, as it has no "previous expressions".
3536 let result = if !ctxt.may_break {
3537 self.try_coerce(e, e_ty, ctxt.coerce_to)
3539 self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
3540 ctxt.unified, e, e_ty)
3543 ctxt.break_exprs.push(e);
3546 self.eq_types(true, &cause, e_ty, ctxt.unified)
3547 .map(|InferOk { obligations, .. }| {
3548 // FIXME(#32730) propagate obligations
3549 assert!(obligations.is_empty());
3554 Ok(ty) => ctxt.unified = ty,
3556 self.report_mismatched_types(&cause, ctxt.unified, e_ty, err).emit();
3560 ctxt.may_break = true;
3562 // Otherwise, we failed to find the enclosing loop; this can only happen if the
3563 // `break` was not inside a loop at all, which is caught by the loop-checking pass.
3566 hir::ExprAgain(_) => { tcx.types.never }
3567 hir::ExprRet(ref expr_opt) => {
3568 if self.ret_ty.is_none() {
3569 struct_span_err!(self.tcx.sess, expr.span, E0572,
3570 "return statement outside of function body").emit();
3571 } else if let Some(ref e) = *expr_opt {
3572 self.check_expr_coercable_to_type(&e, self.ret_ty.unwrap());
3574 match self.eq_types(false,
3575 &self.misc(expr.span),
3576 self.ret_ty.unwrap(),
3578 Ok(ok) => self.register_infer_ok_obligations(ok),
3580 struct_span_err!(tcx.sess, expr.span, E0069,
3581 "`return;` in a function whose return type is not `()`")
3582 .span_label(expr.span, &format!("return type is not ()"))
3589 hir::ExprAssign(ref lhs, ref rhs) => {
3590 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3593 if !tcx.expr_is_lval(&lhs) {
3595 tcx.sess, expr.span, E0070,
3596 "invalid left-hand side expression")
3599 &format!("left-hand of expression not valid"))
3603 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3605 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3607 if lhs_ty.references_error() || rhs_ty.references_error() {
3613 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3614 self.check_then_else(&cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3615 expr.span, expected)
3617 hir::ExprWhile(ref cond, ref body, _) => {
3618 let unified = self.tcx.mk_nil();
3619 let coerce_to = unified;
3620 let ctxt = LoopCtxt {
3622 coerce_to: coerce_to,
3623 break_exprs: vec![],
3626 self.with_loop_ctxt(expr.id, ctxt, || {
3627 self.check_expr_has_type(&cond, tcx.types.bool);
3628 let cond_diverging = self.diverges.get();
3629 self.check_block_no_value(&body);
3631 // We may never reach the body so it diverging means nothing.
3632 self.diverges.set(cond_diverging);
3635 if self.has_errors.get() {
3641 hir::ExprLoop(ref body, _, _) => {
3642 let unified = self.next_ty_var(TypeVariableOrigin::TypeInference(body.span));
3643 let coerce_to = expected.only_has_type(self).unwrap_or(unified);
3644 let ctxt = LoopCtxt {
3646 coerce_to: coerce_to,
3647 break_exprs: vec![],
3651 let ctxt = self.with_loop_ctxt(expr.id, ctxt, || {
3652 self.check_block_no_value(&body);
3655 // No way to know whether it's diverging because
3656 // of a `break` or an outer `break` or `return.
3657 self.diverges.set(Diverges::Maybe);
3664 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3665 self.check_match(expr, &discrim, arms, expected, match_src)
3667 hir::ExprClosure(capture, ref decl, body_id, _) => {
3668 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3670 hir::ExprBlock(ref b) => {
3671 self.check_block_with_expected(&b, expected)
3673 hir::ExprCall(ref callee, ref args) => {
3674 self.check_call(expr, &callee, args, expected)
3676 hir::ExprMethodCall(name, ref tps, ref args) => {
3677 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3679 hir::ExprCast(ref e, ref t) => {
3680 // Find the type of `e`. Supply hints based on the type we are casting to,
3682 let t_cast = self.to_ty(t);
3683 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3684 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3685 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3687 // Eagerly check for some obvious errors.
3688 if t_expr.references_error() || t_cast.references_error() {
3691 // Defer other checks until we're done type checking.
3692 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3693 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3695 deferred_cast_checks.push(cast_check);
3698 Err(ErrorReported) => {
3704 hir::ExprType(ref e, ref t) => {
3705 let typ = self.to_ty(&t);
3706 self.check_expr_eq_type(&e, typ);
3709 hir::ExprArray(ref args) => {
3710 let uty = expected.to_option(self).and_then(|uty| {
3712 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3717 let mut unified = self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span));
3718 let coerce_to = uty.unwrap_or(unified);
3720 for (i, e) in args.iter().enumerate() {
3721 let e_ty = self.check_expr_with_hint(e, coerce_to);
3722 let cause = self.misc(e.span);
3724 // Special-case the first element, as it has no "previous expressions".
3725 let result = if i == 0 {
3726 self.try_coerce(e, e_ty, coerce_to)
3728 let prev_elems = || args[..i].iter().map(|e| &*e);
3729 self.try_find_coercion_lub(&cause, prev_elems, unified, e, e_ty)
3733 Ok(ty) => unified = ty,
3735 self.report_mismatched_types(&cause, unified, e_ty, e).emit();
3739 tcx.mk_array(unified, args.len())
3741 hir::ExprRepeat(ref element, count) => {
3742 let count = eval_length(self.tcx.global_tcx(), count, "repeat count")
3745 let uty = match expected {
3746 ExpectHasType(uty) => {
3748 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3755 let (element_ty, t) = match uty {
3757 self.check_expr_coercable_to_type(&element, uty);
3761 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3762 let element_ty = self.check_expr_has_type(&element, t);
3768 // For [foo, ..n] where n > 1, `foo` must have
3770 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3771 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3774 if element_ty.references_error() {
3777 tcx.mk_array(t, count)
3780 hir::ExprTup(ref elts) => {
3781 let flds = expected.only_has_type(self).and_then(|ty| {
3783 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3788 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3789 let t = match flds {
3790 Some(ref fs) if i < fs.len() => {
3792 self.check_expr_coercable_to_type(&e, ety);
3796 self.check_expr_with_expectation(&e, NoExpectation)
3801 let tuple = tcx.mk_tup(elt_ts_iter, false);
3802 if tuple.references_error() {
3808 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3809 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3811 hir::ExprField(ref base, ref field) => {
3812 self.check_field(expr, lvalue_pref, &base, field)
3814 hir::ExprTupField(ref base, idx) => {
3815 self.check_tup_field(expr, lvalue_pref, &base, idx)
3817 hir::ExprIndex(ref base, ref idx) => {
3818 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3819 let idx_t = self.check_expr(&idx);
3821 if base_t.references_error() {
3823 } else if idx_t.references_error() {
3826 let base_t = self.structurally_resolved_type(expr.span, base_t);
3827 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3828 Some((index_ty, element_ty)) => {
3829 self.demand_coerce(idx, idx_t, index_ty);
3833 self.check_expr_has_type(&idx, self.tcx.types.err);
3834 let mut err = self.type_error_struct(
3837 format!("cannot index a value of type `{}`",
3841 // Try to give some advice about indexing tuples.
3842 if let ty::TyTuple(..) = base_t.sty {
3843 let mut needs_note = true;
3844 // If the index is an integer, we can show the actual
3845 // fixed expression:
3846 if let hir::ExprLit(ref lit) = idx.node {
3847 if let ast::LitKind::Int(i,
3848 ast::LitIntType::Unsuffixed) = lit.node {
3849 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3850 if let Ok(snip) = snip {
3851 err.span_suggestion(expr.span,
3852 "to access tuple elements, \
3853 use tuple indexing syntax \
3855 format!("{}.{}", snip, i));
3861 err.help("to access tuple elements, use tuple indexing \
3862 syntax (e.g. `tuple.0`)");
3874 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3875 // The newly resolved definition is written into `type_relative_path_defs`.
3876 fn finish_resolving_struct_path(&self,
3879 node_id: ast::NodeId)
3883 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3884 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3885 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3888 hir::QPath::TypeRelative(ref qself, ref segment) => {
3889 let ty = self.to_ty(qself);
3891 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3896 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3899 // Write back the new resolution.
3900 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3907 // Resolve associated value path into a base type and associated constant or method definition.
3908 // The newly resolved definition is written into `type_relative_path_defs`.
3909 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3910 qpath: &'b hir::QPath,
3911 node_id: ast::NodeId,
3913 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3915 let (ty, item_segment) = match *qpath {
3916 hir::QPath::Resolved(ref opt_qself, ref path) => {
3918 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3919 &path.segments[..]);
3921 hir::QPath::TypeRelative(ref qself, ref segment) => {
3922 (self.to_ty(qself), segment)
3925 let item_name = item_segment.name;
3926 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3929 let def = match error {
3930 method::MethodError::PrivateMatch(def) => def,
3933 if item_name != keywords::Invalid.name() {
3934 self.report_method_error(span, ty, item_name, None, error, None);
3940 // Write back the new resolution.
3941 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3942 (def, Some(ty), slice::ref_slice(&**item_segment))
3945 pub fn check_decl_initializer(&self,
3946 local: &'gcx hir::Local,
3947 init: &'gcx hir::Expr) -> Ty<'tcx>
3949 let ref_bindings = local.pat.contains_ref_binding();
3951 let local_ty = self.local_ty(init.span, local.id);
3952 if let Some(m) = ref_bindings {
3953 // Somewhat subtle: if we have a `ref` binding in the pattern,
3954 // we want to avoid introducing coercions for the RHS. This is
3955 // both because it helps preserve sanity and, in the case of
3956 // ref mut, for soundness (issue #23116). In particular, in
3957 // the latter case, we need to be clear that the type of the
3958 // referent for the reference that results is *equal to* the
3959 // type of the lvalue it is referencing, and not some
3960 // supertype thereof.
3961 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3962 self.demand_eqtype(init.span, init_ty, local_ty);
3965 self.check_expr_coercable_to_type(init, local_ty)
3969 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3970 let t = self.local_ty(local.span, local.id);
3971 self.write_ty(local.id, t);
3973 if let Some(ref init) = local.init {
3974 let init_ty = self.check_decl_initializer(local, &init);
3975 if init_ty.references_error() {
3976 self.write_ty(local.id, init_ty);
3980 self.check_pat(&local.pat, t);
3981 let pat_ty = self.node_ty(local.pat.id);
3982 if pat_ty.references_error() {
3983 self.write_ty(local.id, pat_ty);
3987 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3988 // Don't do all the complex logic below for DeclItem.
3990 hir::StmtDecl(ref decl, id) => {
3992 hir::DeclLocal(_) => {}
3993 hir::DeclItem(_) => {
3999 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4002 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4004 // Hide the outer diverging and has_errors flags.
4005 let old_diverges = self.diverges.get();
4006 let old_has_errors = self.has_errors.get();
4007 self.diverges.set(Diverges::Maybe);
4008 self.has_errors.set(false);
4010 let (node_id, span) = match stmt.node {
4011 hir::StmtDecl(ref decl, id) => {
4012 let span = match decl.node {
4013 hir::DeclLocal(ref l) => {
4014 self.check_decl_local(&l);
4017 hir::DeclItem(_) => {/* ignore for now */
4023 hir::StmtExpr(ref expr, id) => {
4024 // Check with expected type of ()
4025 self.check_expr_has_type(&expr, self.tcx.mk_nil());
4028 hir::StmtSemi(ref expr, id) => {
4029 self.check_expr(&expr);
4034 if self.has_errors.get() {
4035 self.write_error(node_id);
4036 } else if self.diverges.get().always() {
4037 self.write_ty(node_id, self.next_diverging_ty_var(
4038 TypeVariableOrigin::DivergingStmt(span)));
4040 self.write_nil(node_id);
4043 // Combine the diverging and has_error flags.
4044 self.diverges.set(self.diverges.get() | old_diverges);
4045 self.has_errors.set(self.has_errors.get() | old_has_errors);
4048 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4049 let unit = self.tcx.mk_nil();
4050 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4051 self.demand_suptype(blk.span, unit, ty);
4054 fn check_block_with_expected(&self,
4055 blk: &'gcx hir::Block,
4056 expected: Expectation<'tcx>) -> Ty<'tcx> {
4058 let mut fcx_ps = self.ps.borrow_mut();
4059 let unsafety_state = fcx_ps.recurse(blk);
4060 replace(&mut *fcx_ps, unsafety_state)
4063 for s in &blk.stmts {
4067 let mut ty = match blk.expr {
4068 Some(ref e) => self.check_expr_with_expectation(e, expected),
4069 None => self.tcx.mk_nil()
4072 if self.diverges.get().always() {
4073 ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
4074 } else if let ExpectHasType(ety) = expected {
4075 if let Some(ref e) = blk.expr {
4076 // Coerce the tail expression to the right type.
4077 self.demand_coerce(e, ty, ety);
4079 // We're not diverging and there's an expected type, which,
4080 // in case it's not `()`, could result in an error higher-up.
4081 // We have a chance to error here early and be more helpful.
4082 let cause = self.misc(blk.span);
4083 let trace = TypeTrace::types(&cause, false, ty, ety);
4084 match self.sub_types(false, &cause, ty, ety) {
4085 Ok(InferOk { obligations, .. }) => {
4086 // FIXME(#32730) propagate obligations
4087 assert!(obligations.is_empty());
4090 let mut err = self.report_and_explain_type_error(trace, &err);
4092 // Be helpful when the user wrote `{... expr;}` and
4093 // taking the `;` off is enough to fix the error.
4094 let mut extra_semi = None;
4095 if let Some(stmt) = blk.stmts.last() {
4096 if let hir::StmtSemi(ref e, _) = stmt.node {
4097 if self.can_sub_types(self.node_ty(e.id), ety).is_ok() {
4098 extra_semi = Some(stmt);
4102 if let Some(last_stmt) = extra_semi {
4103 let original_span = original_sp(self.tcx.sess.codemap(),
4104 last_stmt.span, blk.span);
4105 let span_semi = Span {
4106 lo: original_span.hi - BytePos(1),
4107 hi: original_span.hi,
4108 expn_id: original_span.expn_id
4110 err.span_help(span_semi, "consider removing this semicolon:");
4118 // We already applied the type (and potentially errored),
4119 // use the expected type to avoid further errors out.
4123 if self.has_errors.get() || ty.references_error() {
4124 ty = self.tcx.types.err
4127 self.write_ty(blk.id, ty);
4129 *self.ps.borrow_mut() = prev;
4133 // Instantiates the given path, which must refer to an item with the given
4134 // number of type parameters and type.
4135 pub fn instantiate_value_path(&self,
4136 segments: &[hir::PathSegment],
4137 opt_self_ty: Option<Ty<'tcx>>,
4140 node_id: ast::NodeId)
4142 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4147 // We need to extract the type parameters supplied by the user in
4148 // the path `path`. Due to the current setup, this is a bit of a
4149 // tricky-process; the problem is that resolve only tells us the
4150 // end-point of the path resolution, and not the intermediate steps.
4151 // Luckily, we can (at least for now) deduce the intermediate steps
4152 // just from the end-point.
4154 // There are basically four cases to consider:
4156 // 1. Reference to a constructor of enum variant or struct:
4158 // struct Foo<T>(...)
4159 // enum E<T> { Foo(...) }
4161 // In these cases, the parameters are declared in the type
4164 // 2. Reference to a fn item or a free constant:
4168 // In this case, the path will again always have the form
4169 // `a::b::foo::<T>` where only the final segment should have
4170 // type parameters. However, in this case, those parameters are
4171 // declared on a value, and hence are in the `FnSpace`.
4173 // 3. Reference to a method or an associated constant:
4175 // impl<A> SomeStruct<A> {
4179 // Here we can have a path like
4180 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4181 // may appear in two places. The penultimate segment,
4182 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4183 // final segment, `foo::<B>` contains parameters in fn space.
4185 // 4. Reference to a local variable
4187 // Local variables can't have any type parameters.
4189 // The first step then is to categorize the segments appropriately.
4191 assert!(!segments.is_empty());
4193 let mut ufcs_associated = None;
4194 let mut type_segment = None;
4195 let mut fn_segment = None;
4197 // Case 1. Reference to a struct/variant constructor.
4198 Def::StructCtor(def_id, ..) |
4199 Def::VariantCtor(def_id, ..) => {
4200 // Everything but the final segment should have no
4201 // parameters at all.
4202 let mut generics = self.tcx.item_generics(def_id);
4203 if let Some(def_id) = generics.parent {
4204 // Variant and struct constructors use the
4205 // generics of their parent type definition.
4206 generics = self.tcx.item_generics(def_id);
4208 type_segment = Some((segments.last().unwrap(), generics));
4211 // Case 2. Reference to a top-level value.
4213 Def::Const(def_id) |
4214 Def::Static(def_id, _) => {
4215 fn_segment = Some((segments.last().unwrap(),
4216 self.tcx.item_generics(def_id)));
4219 // Case 3. Reference to a method or associated const.
4220 Def::Method(def_id) |
4221 Def::AssociatedConst(def_id) => {
4222 let container = self.tcx.associated_item(def_id).container;
4224 ty::TraitContainer(trait_did) => {
4225 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4227 ty::ImplContainer(_) => {}
4230 let generics = self.tcx.item_generics(def_id);
4231 if segments.len() >= 2 {
4232 let parent_generics = self.tcx.item_generics(generics.parent.unwrap());
4233 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4235 // `<T>::assoc` will end up here, and so can `T::assoc`.
4236 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4237 ufcs_associated = Some((container, self_ty));
4239 fn_segment = Some((segments.last().unwrap(), generics));
4242 // Case 4. Local variable, no generics.
4243 Def::Local(..) | Def::Upvar(..) => {}
4245 _ => bug!("unexpected definition: {:?}", def),
4248 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4250 // Now that we have categorized what space the parameters for each
4251 // segment belong to, let's sort out the parameters that the user
4252 // provided (if any) into their appropriate spaces. We'll also report
4253 // errors if type parameters are provided in an inappropriate place.
4254 let poly_segments = type_segment.is_some() as usize +
4255 fn_segment.is_some() as usize;
4256 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4259 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4260 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4261 let ty = self.local_ty(span, nid);
4262 let ty = self.normalize_associated_types_in(span, &ty);
4263 self.write_ty(node_id, ty);
4264 self.write_substs(node_id, ty::ItemSubsts {
4265 substs: self.tcx.intern_substs(&[])
4272 // Now we have to compare the types that the user *actually*
4273 // provided against the types that were *expected*. If the user
4274 // did not provide any types, then we want to substitute inference
4275 // variables. If the user provided some types, we may still need
4276 // to add defaults. If the user provided *too many* types, that's
4278 self.check_path_parameter_count(span, &mut type_segment);
4279 self.check_path_parameter_count(span, &mut fn_segment);
4281 let (fn_start, has_self) = match (type_segment, fn_segment) {
4282 (_, Some((_, generics))) => {
4283 (generics.parent_count(), generics.has_self)
4285 (Some((_, generics)), None) => {
4286 (generics.own_count(), generics.has_self)
4288 (None, None) => (0, false)
4290 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4291 let mut i = def.index as usize;
4293 let segment = if i < fn_start {
4294 i -= has_self as usize;
4300 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4301 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4302 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4306 if let Some(lifetime) = lifetimes.get(i) {
4307 AstConv::ast_region_to_region(self, lifetime, Some(def))
4309 self.re_infer(span, Some(def)).unwrap()
4312 let mut i = def.index as usize;
4314 let segment = if i < fn_start {
4315 // Handle Self first, so we can adjust the index to match the AST.
4316 if has_self && i == 0 {
4317 return opt_self_ty.unwrap_or_else(|| {
4318 self.type_var_for_def(span, def, substs)
4321 i -= has_self as usize;
4327 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4328 Some(&hir::AngleBracketedParameters(ref data)) => {
4329 (&data.types[..], data.infer_types)
4331 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4332 None => (&[][..], true)
4335 // Skip over the lifetimes in the same segment.
4336 if let Some((_, generics)) = segment {
4337 i -= generics.regions.len();
4340 if let Some(ast_ty) = types.get(i) {
4341 // A provided type parameter.
4343 } else if !infer_types && def.has_default {
4344 // No type parameter provided, but a default exists.
4345 let default = self.tcx.item_type(def.def_id);
4348 default.subst_spanned(self.tcx, substs, Some(span))
4351 // No type parameters were provided, we can infer all.
4352 // This can also be reached in some error cases:
4353 // We prefer to use inference variables instead of
4354 // TyError to let type inference recover somewhat.
4355 self.type_var_for_def(span, def, substs)
4359 // The things we are substituting into the type should not contain
4360 // escaping late-bound regions, and nor should the base type scheme.
4361 let ty = self.tcx.item_type(def.def_id());
4362 assert!(!substs.has_escaping_regions());
4363 assert!(!ty.has_escaping_regions());
4365 // Add all the obligations that are required, substituting and
4366 // normalized appropriately.
4367 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4368 self.add_obligations_for_parameters(
4369 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4372 // Substitute the values for the type parameters into the type of
4373 // the referenced item.
4374 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4376 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4377 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4378 // is inherent, there is no `Self` parameter, instead, the impl needs
4379 // type parameters, which we can infer by unifying the provided `Self`
4380 // with the substituted impl type.
4381 let ty = self.tcx.item_type(impl_def_id);
4383 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4384 match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
4385 Ok(ok) => self.register_infer_ok_obligations(ok),
4388 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4395 debug!("instantiate_value_path: type of {:?} is {:?}",
4398 self.write_substs(node_id, ty::ItemSubsts {
4404 /// Report errors if the provided parameters are too few or too many.
4405 fn check_path_parameter_count(&self,
4407 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4408 let (lifetimes, types, infer_types, bindings) = {
4409 match segment.map(|(s, _)| &s.parameters) {
4410 Some(&hir::AngleBracketedParameters(ref data)) => {
4411 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4413 Some(&hir::ParenthesizedParameters(_)) => {
4414 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4416 None => (&[][..], &[][..], true, &[][..])
4420 let count_lifetime_params = |n| {
4421 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4423 let count_type_params = |n| {
4424 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4427 // Check provided lifetime parameters.
4428 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4429 if lifetimes.len() > lifetime_defs.len() {
4430 let expected_text = count_lifetime_params(lifetime_defs.len());
4431 let actual_text = count_lifetime_params(lifetimes.len());
4432 struct_span_err!(self.tcx.sess, span, E0088,
4433 "too many lifetime parameters provided: \
4434 expected at most {}, found {}",
4435 expected_text, actual_text)
4436 .span_label(span, &format!("expected {}", expected_text))
4438 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4439 let expected_text = count_lifetime_params(lifetime_defs.len());
4440 let actual_text = count_lifetime_params(lifetimes.len());
4441 struct_span_err!(self.tcx.sess, span, E0090,
4442 "too few lifetime parameters provided: \
4443 expected {}, found {}",
4444 expected_text, actual_text)
4445 .span_label(span, &format!("expected {}", expected_text))
4449 // The case where there is not enough lifetime parameters is not checked,
4450 // because this is not possible - a function never takes lifetime parameters.
4451 // See discussion for Pull Request 36208.
4453 // Check provided type parameters.
4454 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4455 if generics.parent.is_none() {
4456 &generics.types[generics.has_self as usize..]
4461 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4462 if types.len() > type_defs.len() {
4463 let span = types[type_defs.len()].span;
4464 let expected_text = count_type_params(type_defs.len());
4465 let actual_text = count_type_params(types.len());
4466 struct_span_err!(self.tcx.sess, span, E0087,
4467 "too many type parameters provided: \
4468 expected at most {}, found {}",
4469 expected_text, actual_text)
4470 .span_label(span, &format!("expected {}", expected_text))
4473 // To prevent derived errors to accumulate due to extra
4474 // type parameters, we force instantiate_value_path to
4475 // use inference variables instead of the provided types.
4477 } else if !infer_types && types.len() < required_len {
4478 let expected_text = count_type_params(required_len);
4479 let actual_text = count_type_params(types.len());
4480 struct_span_err!(self.tcx.sess, span, E0089,
4481 "too few type parameters provided: \
4482 expected {}, found {}",
4483 expected_text, actual_text)
4484 .span_label(span, &format!("expected {}", expected_text))
4488 if !bindings.is_empty() {
4489 span_err!(self.tcx.sess, bindings[0].span, E0182,
4490 "unexpected binding of associated item in expression path \
4491 (only allowed in type paths)");
4495 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4497 where F: Fn() -> Ty<'tcx>
4499 let mut ty = self.resolve_type_vars_with_obligations(ty);
4502 let alternative = f();
4505 if alternative.is_ty_var() || alternative.references_error() {
4506 if !self.is_tainted_by_errors() {
4507 self.type_error_message(sp, |_actual| {
4508 "the type of this value must be known in this context".to_string()
4511 self.demand_suptype(sp, self.tcx.types.err, ty);
4512 ty = self.tcx.types.err;
4514 self.demand_suptype(sp, alternative, ty);
4522 // Resolves `typ` by a single level if `typ` is a type variable. If no
4523 // resolution is possible, then an error is reported.
4524 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4525 self.structurally_resolve_type_or_else(sp, ty, || {
4530 fn with_loop_ctxt<F: FnOnce()>(&self, id: ast::NodeId, ctxt: LoopCtxt<'gcx, 'tcx>, f: F)
4531 -> LoopCtxt<'gcx, 'tcx> {
4534 let mut enclosing_loops = self.enclosing_loops.borrow_mut();
4535 index = enclosing_loops.stack.len();
4536 enclosing_loops.by_id.insert(id, index);
4537 enclosing_loops.stack.push(ctxt);
4541 let mut enclosing_loops = self.enclosing_loops.borrow_mut();
4542 debug_assert!(enclosing_loops.stack.len() == index + 1);
4543 enclosing_loops.by_id.remove(&id).expect("missing loop context");
4544 (enclosing_loops.stack.pop().expect("missing loop context"))
4549 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4550 generics: &hir::Generics,
4552 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4553 generics.ty_params.len(), ty);
4555 // make a vector of booleans initially false, set to true when used
4556 if generics.ty_params.is_empty() { return; }
4557 let mut tps_used = vec![false; generics.ty_params.len()];
4559 for leaf_ty in ty.walk() {
4560 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4561 debug!("Found use of ty param num {}", idx);
4562 tps_used[idx as usize - generics.lifetimes.len()] = true;
4566 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4568 struct_span_err!(tcx.sess, param.span, E0091,
4569 "type parameter `{}` is unused",
4571 .span_label(param.span, &format!("unused type parameter"))