1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function). Inference is used to supply types wherever they are
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
26 - main: the main pass does the lion's share of the work: it
27 determines the types of all expressions, resolves
28 methods, checks for most invalid conditions, and so forth. In
29 some cases, where a type is unknown, it may create a type or region
30 variable and use that as the type of an expression.
32 In the process of checking, various constraints will be placed on
33 these type variables through the subtyping relationships requested
34 through the `demand` module. The `infer` module is in charge
35 of resolving those constraints.
37 - regionck: after main is complete, the regionck pass goes over all
38 types looking for regions and making sure that they did not escape
39 into places they are not in scope. This may also influence the
40 final assignments of the various region variables if there is some
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
46 - writeback: writes the final types within a function body, replacing
47 type variables with their final inferred types. These final types
48 are written into the `tcx.node_types` table, which should *never* contain
49 any reference to a type variable.
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.item_substs`. These types
56 may contain unresolved type variables. After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `tcx`.
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
68 n.b.: A type variable is not the same thing as a type parameter. A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract. When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`. This variable will
74 eventually be resolved to some concrete type (which might itself be
79 pub use self::Expectation::*;
80 use self::coercion::{CoerceMany, DynamicCoerceMany};
81 pub use self::compare_method::{compare_impl_method, compare_const_impl};
82 use self::TupleArgumentsFlag::*;
85 use fmt_macros::{Parser, Piece, Position};
86 use hir::def::{Def, CtorKind};
87 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
88 use rustc_back::slice::ref_slice;
89 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
90 use rustc::infer::type_variable::{TypeVariableOrigin};
91 use rustc::ty::subst::{Kind, Subst, Substs};
92 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
93 use rustc::ty::{ParamTy, ParameterEnvironment};
94 use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
95 use rustc::ty::{self, Ty, TyCtxt, Visibility};
96 use rustc::ty::{MethodCall, MethodCallee};
97 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
98 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
99 use rustc::ty::maps::Providers;
100 use rustc::ty::util::{Representability, IntTypeExt};
101 use errors::DiagnosticBuilder;
102 use require_c_abi_if_variadic;
103 use session::{Session, CompileResult};
106 use util::common::{ErrorReported, indenter};
107 use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
109 use std::cell::{Cell, RefCell};
110 use std::collections::hash_map::Entry;
112 use std::mem::replace;
113 use std::ops::{self, Deref};
114 use syntax::abi::Abi;
116 use syntax::codemap::{self, original_sp, Spanned};
117 use syntax::feature_gate::{GateIssue, emit_feature_err};
119 use syntax::symbol::{Symbol, InternedString, keywords};
120 use syntax::util::lev_distance::find_best_match_for_name;
121 use syntax_pos::{self, BytePos, Span, DUMMY_SP};
123 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
124 use rustc::hir::itemlikevisit::ItemLikeVisitor;
125 use rustc::hir::{self, PatKind};
126 use rustc::middle::lang_items;
127 use rustc_back::slice;
128 use rustc::middle::const_val::eval_length;
129 use rustc_const_math::ConstInt;
148 /// closures defined within the function. For example:
151 /// bar(move|| { ... })
154 /// Here, the function `foo()` and the closure passed to
155 /// `bar()` will each have their own `FnCtxt`, but they will
156 /// share the inherited fields.
157 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
158 infcx: InferCtxt<'a, 'gcx, 'tcx>,
160 locals: RefCell<NodeMap<Ty<'tcx>>>,
162 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
164 // When we process a call like `c()` where `c` is a closure type,
165 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
166 // `FnOnce` closure. In that case, we defer full resolution of the
167 // call until upvar inference can kick in and make the
168 // decision. We keep these deferred resolutions grouped by the
169 // def-id of the closure, so that once we decide, we can easily go
170 // back and process them.
171 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
173 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
175 // Anonymized types found in explicit return types and their
176 // associated fresh inference variable. Writeback resolves these
177 // variables to get the concrete type, which can be used to
178 // deanonymize TyAnon, after typeck is done with all functions.
179 anon_types: RefCell<NodeMap<Ty<'tcx>>>,
182 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
183 type Target = InferCtxt<'a, 'gcx, 'tcx>;
184 fn deref(&self) -> &Self::Target {
189 trait DeferredCallResolution<'gcx, 'tcx> {
190 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
193 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
195 /// When type-checking an expression, we propagate downward
196 /// whatever type hint we are able in the form of an `Expectation`.
197 #[derive(Copy, Clone, Debug)]
198 pub enum Expectation<'tcx> {
199 /// We know nothing about what type this expression should have.
202 /// This expression should have the type given (or some subtype)
203 ExpectHasType(Ty<'tcx>),
205 /// This expression will be cast to the `Ty`
206 ExpectCastableToType(Ty<'tcx>),
208 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
209 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
210 ExpectRvalueLikeUnsized(Ty<'tcx>),
213 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
214 // Disregard "castable to" expectations because they
215 // can lead us astray. Consider for example `if cond
216 // {22} else {c} as u8` -- if we propagate the
217 // "castable to u8" constraint to 22, it will pick the
218 // type 22u8, which is overly constrained (c might not
219 // be a u8). In effect, the problem is that the
220 // "castable to" expectation is not the tightest thing
221 // we can say, so we want to drop it in this case.
222 // The tightest thing we can say is "must unify with
223 // else branch". Note that in the case of a "has type"
224 // constraint, this limitation does not hold.
226 // If the expected type is just a type variable, then don't use
227 // an expected type. Otherwise, we might write parts of the type
228 // when checking the 'then' block which are incompatible with the
230 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
232 ExpectHasType(ety) => {
233 let ety = fcx.shallow_resolve(ety);
234 if !ety.is_ty_var() {
240 ExpectRvalueLikeUnsized(ety) => {
241 ExpectRvalueLikeUnsized(ety)
247 /// Provide an expectation for an rvalue expression given an *optional*
248 /// hint, which is not required for type safety (the resulting type might
249 /// be checked higher up, as is the case with `&expr` and `box expr`), but
250 /// is useful in determining the concrete type.
252 /// The primary use case is where the expected type is a fat pointer,
253 /// like `&[isize]`. For example, consider the following statement:
255 /// let x: &[isize] = &[1, 2, 3];
257 /// In this case, the expected type for the `&[1, 2, 3]` expression is
258 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
259 /// expectation `ExpectHasType([isize])`, that would be too strong --
260 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
261 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
262 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
263 /// which still is useful, because it informs integer literals and the like.
264 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
265 /// for examples of where this comes up,.
266 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
267 match fcx.tcx.struct_tail(ty).sty {
268 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
269 ExpectRvalueLikeUnsized(ty)
271 _ => ExpectHasType(ty)
275 // Resolves `expected` by a single level if it is a variable. If
276 // there is no expected type or resolution is not possible (e.g.,
277 // no constraints yet present), just returns `None`.
278 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
283 ExpectCastableToType(t) => {
284 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
286 ExpectHasType(t) => {
287 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
289 ExpectRvalueLikeUnsized(t) => {
290 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
295 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
296 match self.resolve(fcx) {
297 NoExpectation => None,
298 ExpectCastableToType(ty) |
300 ExpectRvalueLikeUnsized(ty) => Some(ty),
304 /// It sometimes happens that we want to turn an expectation into
305 /// a **hard constraint** (i.e., something that must be satisfied
306 /// for the program to type-check). `only_has_type` will return
307 /// such a constraint, if it exists.
308 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
309 match self.resolve(fcx) {
310 ExpectHasType(ty) => Some(ty),
315 /// Like `only_has_type`, but instead of returning `None` if no
316 /// hard constraint exists, creates a fresh type variable.
317 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
318 self.only_has_type(fcx)
319 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
323 #[derive(Copy, Clone)]
324 pub struct UnsafetyState {
325 pub def: ast::NodeId,
326 pub unsafety: hir::Unsafety,
327 pub unsafe_push_count: u32,
332 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
333 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
336 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
337 match self.unsafety {
338 // If this unsafe, then if the outer function was already marked as
339 // unsafe we shouldn't attribute the unsafe'ness to the block. This
340 // way the block can be warned about instead of ignoring this
341 // extraneous block (functions are never warned about).
342 hir::Unsafety::Unsafe if self.from_fn => *self,
345 let (unsafety, def, count) = match blk.rules {
346 hir::PushUnsafeBlock(..) =>
347 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
348 hir::PopUnsafeBlock(..) =>
349 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
350 hir::UnsafeBlock(..) =>
351 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
353 (unsafety, self.def, self.unsafe_push_count),
355 UnsafetyState{ def: def,
357 unsafe_push_count: count,
364 /// Tracks whether executing a node may exit normally (versus
365 /// return/break/panic, which "diverge", leaving dead code in their
366 /// wake). Tracked semi-automatically (through type variables marked
367 /// as diverging), with some manual adjustments for control-flow
368 /// primitives (approximating a CFG).
369 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
371 /// Potentially unknown, some cases converge,
372 /// others require a CFG to determine them.
375 /// Definitely known to diverge and therefore
376 /// not reach the next sibling or its parent.
379 /// Same as `Always` but with a reachability
380 /// warning already emitted
384 // Convenience impls for combinig `Diverges`.
386 impl ops::BitAnd for Diverges {
388 fn bitand(self, other: Self) -> Self {
389 cmp::min(self, other)
393 impl ops::BitOr for Diverges {
395 fn bitor(self, other: Self) -> Self {
396 cmp::max(self, other)
400 impl ops::BitAndAssign for Diverges {
401 fn bitand_assign(&mut self, other: Self) {
402 *self = *self & other;
406 impl ops::BitOrAssign for Diverges {
407 fn bitor_assign(&mut self, other: Self) {
408 *self = *self | other;
413 fn always(self) -> bool {
414 self >= Diverges::Always
418 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
421 // this is `null` for loops where break with a value is illegal,
422 // such as `while`, `for`, and `while let`
423 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
426 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
427 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
428 by_id: NodeMap<usize>,
431 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
432 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
433 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
434 bug!("could not find enclosing breakable with id {}", target_id);
440 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
441 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
443 body_id: ast::NodeId,
445 // Number of errors that had been reported when we started
446 // checking this function. On exit, if we find that *more* errors
447 // have been reported, we will skip regionck and other work that
448 // expects the types within the function to be consistent.
449 err_count_on_creation: usize,
451 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
453 ps: RefCell<UnsafetyState>,
455 /// Whether the last checked node generates a divergence (e.g.,
456 /// `return` will set this to Always). In general, when entering
457 /// an expression or other node in the tree, the initial value
458 /// indicates whether prior parts of the containing expression may
459 /// have diverged. It is then typically set to `Maybe` (and the
460 /// old value remembered) for processing the subparts of the
461 /// current expression. As each subpart is processed, they may set
462 /// the flag to `Always` etc. Finally, at the end, we take the
463 /// result and "union" it with the original value, so that when we
464 /// return the flag indicates if any subpart of the the parent
465 /// expression (up to and including this part) has diverged. So,
466 /// if you read it after evaluating a subexpression `X`, the value
467 /// you get indicates whether any subexpression that was
468 /// evaluating up to and including `X` diverged.
470 /// We use this flag for two purposes:
472 /// - To warn about unreachable code: if, after processing a
473 /// sub-expression but before we have applied the effects of the
474 /// current node, we see that the flag is set to `Always`, we
475 /// can issue a warning. This corresponds to something like
476 /// `foo(return)`; we warn on the `foo()` expression. (We then
477 /// update the flag to `WarnedAlways` to suppress duplicate
478 /// reports.) Similarly, if we traverse to a fresh statement (or
479 /// tail expression) from a `Always` setting, we will isssue a
480 /// warning. This corresponds to something like `{return;
481 /// foo();}` or `{return; 22}`, where we would warn on the
484 /// - To permit assignment into a local variable or other lvalue
485 /// (including the "return slot") of type `!`. This is allowed
486 /// if **either** the type of value being assigned is `!`, which
487 /// means the current code is dead, **or** the expression's
488 /// divering flag is true, which means that a divering value was
489 /// wrapped (e.g., `let x: ! = foo(return)`).
491 /// To repeat the last point: an expression represents dead-code
492 /// if, after checking it, **either** its type is `!` OR the
493 /// diverges flag is set to something other than `Maybe`.
494 diverges: Cell<Diverges>,
496 /// Whether any child nodes have any type errors.
497 has_errors: Cell<bool>,
499 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
501 inh: &'a Inherited<'a, 'gcx, 'tcx>,
504 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
505 type Target = Inherited<'a, 'gcx, 'tcx>;
506 fn deref(&self) -> &Self::Target {
511 /// Helper type of a temporary returned by Inherited::build(...).
512 /// Necessary because we can't write the following bound:
513 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
514 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
515 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
518 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
519 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId)
520 -> InheritedBuilder<'a, 'gcx, 'tcx> {
521 let tables = ty::TypeckTables::empty();
522 let param_env = ParameterEnvironment::for_item(tcx, id);
524 infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing)
529 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
530 fn enter<F, R>(&'tcx mut self, f: F) -> R
531 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
533 self.infcx.enter(|infcx| f(Inherited::new(infcx)))
537 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
538 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
541 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
542 locals: RefCell::new(NodeMap()),
543 deferred_call_resolutions: RefCell::new(DefIdMap()),
544 deferred_cast_checks: RefCell::new(Vec::new()),
545 anon_types: RefCell::new(NodeMap()),
549 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
550 debug!("register_predicate({:?})", obligation);
551 if obligation.has_escaping_regions() {
552 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
557 .register_predicate_obligation(self, obligation);
560 fn register_predicates(&self, obligations: Vec<traits::PredicateObligation<'tcx>>) {
561 for obligation in obligations {
562 self.register_predicate(obligation);
566 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
567 self.register_predicates(infer_ok.obligations);
571 fn normalize_associated_types_in<T>(&self,
573 body_id: ast::NodeId,
575 where T : TypeFoldable<'tcx>
577 let ok = self.normalize_associated_types_in_as_infer_ok(span, body_id, value);
578 self.register_infer_ok_obligations(ok)
581 fn normalize_associated_types_in_as_infer_ok<T>(&self,
583 body_id: ast::NodeId,
586 where T : TypeFoldable<'tcx>
588 debug!("normalize_associated_types_in(value={:?})", value);
589 let mut selcx = traits::SelectionContext::new(self);
590 let cause = ObligationCause::misc(span, body_id);
591 let traits::Normalized { value, obligations } =
592 traits::normalize(&mut selcx, cause, value);
593 debug!("normalize_associated_types_in: result={:?} predicates={:?}",
596 InferOk { value, obligations }
600 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
602 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
603 fn visit_item(&mut self, i: &'tcx hir::Item) {
604 check_item_type(self.tcx, i);
606 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
607 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
610 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
611 tcx.sess.track_errors(|| {
612 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
613 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
617 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
618 tcx.sess.track_errors(|| {
619 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
623 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
624 ty::queries::typeck_item_bodies::get(tcx, DUMMY_SP, LOCAL_CRATE)
627 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
628 debug_assert!(crate_num == LOCAL_CRATE);
629 tcx.sess.track_errors(|| {
630 tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
631 tcx.item_tables(body_owner_def_id);
636 pub fn provide(providers: &mut Providers) {
637 *providers = Providers {
647 fn closure_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
649 -> ty::PolyFnSig<'tcx> {
650 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
651 tcx.item_tables(def_id).closure_tys[&node_id]
654 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
657 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
658 tcx.item_tables(def_id).closure_kinds[&node_id]
661 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
663 -> Option<ty::Destructor> {
664 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
667 fn typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
669 -> &'tcx ty::TypeckTables<'tcx> {
670 // Closures' tables come from their outermost function,
671 // as they are part of the same "inference environment".
672 let outer_def_id = tcx.closure_base_def_id(def_id);
673 if outer_def_id != def_id {
674 return tcx.item_tables(outer_def_id);
677 let id = tcx.hir.as_local_node_id(def_id).unwrap();
678 let span = tcx.hir.span(id);
679 let unsupported = || {
680 span_bug!(span, "can't type-check body of {:?}", def_id);
683 // Figure out what primary body this item has.
684 let mut fn_decl = None;
685 let body_id = match tcx.hir.get(id) {
686 hir::map::NodeItem(item) => {
688 hir::ItemConst(_, body) |
689 hir::ItemStatic(_, _, body) => body,
690 hir::ItemFn(ref decl, .., body) => {
691 fn_decl = Some(decl);
697 hir::map::NodeTraitItem(item) => {
699 hir::TraitItemKind::Const(_, Some(body)) => body,
700 hir::TraitItemKind::Method(ref sig,
701 hir::TraitMethod::Provided(body)) => {
702 fn_decl = Some(&sig.decl);
708 hir::map::NodeImplItem(item) => {
710 hir::ImplItemKind::Const(_, body) => body,
711 hir::ImplItemKind::Method(ref sig, body) => {
712 fn_decl = Some(&sig.decl);
718 hir::map::NodeExpr(expr) => {
719 // FIXME(eddyb) Closures should have separate
720 // function definition IDs and expression IDs.
721 // Type-checking should not let closures get
722 // this far in a constant position.
723 // Assume that everything other than closures
724 // is a constant "initializer" expression.
726 hir::ExprClosure(..) => {
727 // We should've bailed out above for closures.
728 span_bug!(expr.span, "unexpected closure")
730 _ => hir::BodyId { node_id: expr.id }
735 let body = tcx.hir.body(body_id);
737 Inherited::build(tcx, id).enter(|inh| {
738 let fcx = if let Some(decl) = fn_decl {
739 let fn_sig = tcx.item_type(def_id).fn_sig();
741 check_abi(tcx, span, fn_sig.abi());
743 // Compute the fty from point of view of inside fn.
744 let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id);
746 fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
748 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
750 inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
752 check_fn(&inh, fn_sig, decl, id, body)
754 let fcx = FnCtxt::new(&inh, body.value.id);
755 let expected_type = tcx.item_type(def_id);
756 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
757 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
759 // Gather locals in statics (because of block expressions).
760 // This is technically unnecessary because locals in static items are forbidden,
761 // but prevents type checking from blowing up before const checking can properly
763 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
765 fcx.check_expr_coercable_to_type(&body.value, expected_type);
770 fcx.select_all_obligations_and_apply_defaults();
771 fcx.closure_analyze(body);
772 fcx.select_obligations_where_possible();
774 fcx.select_all_obligations_or_error();
776 if fn_decl.is_some() {
777 fcx.regionck_fn(id, body);
779 fcx.regionck_expr(body);
782 fcx.resolve_type_vars_in_body(body)
786 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
787 if !tcx.sess.target.target.is_abi_supported(abi) {
788 struct_span_err!(tcx.sess, span, E0570,
789 "The ABI `{}` is not supported for the current target", abi).emit()
793 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
794 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
797 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
798 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
801 // infer the variable's type
802 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
803 self.fcx.locals.borrow_mut().insert(nid, var_ty);
807 // take type that the user specified
808 self.fcx.locals.borrow_mut().insert(nid, typ);
815 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
816 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
817 NestedVisitorMap::None
820 // Add explicitly-declared locals.
821 fn visit_local(&mut self, local: &'gcx hir::Local) {
822 let o_ty = match local.ty {
823 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
826 self.assign(local.span, local.id, o_ty);
827 debug!("Local variable {:?} is assigned type {}",
829 self.fcx.ty_to_string(
830 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
831 intravisit::walk_local(self, local);
834 // Add pattern bindings.
835 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
836 if let PatKind::Binding(_, _, ref path1, _) = p.node {
837 let var_ty = self.assign(p.span, p.id, None);
839 self.fcx.require_type_is_sized(var_ty, p.span,
840 traits::VariableType(p.id));
842 debug!("Pattern binding {} is assigned to {} with type {:?}",
844 self.fcx.ty_to_string(
845 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
848 intravisit::walk_pat(self, p);
851 // Don't descend into the bodies of nested closures
852 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
853 _: hir::BodyId, _: Span, _: ast::NodeId) { }
856 /// Helper used for fns and closures. Does the grungy work of checking a function
857 /// body and returns the function context used for that purpose, since in the case of a fn item
858 /// there is still a bit more to do.
861 /// * inherited: other fields inherited from the enclosing fn (if any)
862 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
863 fn_sig: ty::FnSig<'tcx>,
864 decl: &'gcx hir::FnDecl,
866 body: &'gcx hir::Body)
867 -> FnCtxt<'a, 'gcx, 'tcx>
869 let mut fn_sig = fn_sig.clone();
871 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
873 // Create the function context. This is either derived from scratch or,
874 // in the case of function expressions, based on the outer context.
875 let mut fcx = FnCtxt::new(inherited, body.value.id);
876 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
878 let ret_ty = fn_sig.output();
879 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
880 let ret_ty = fcx.instantiate_anon_types(&ret_ty);
881 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
882 fn_sig = fcx.tcx.mk_fn_sig(
883 fn_sig.inputs().iter().cloned(),
890 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
892 // Add formal parameters.
893 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
894 // The type of the argument must be well-formed.
896 // NB -- this is now checked in wfcheck, but that
897 // currently only results in warnings, so we issue an
898 // old-style WF obligation here so that we still get the
899 // errors that we used to get.
900 fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
902 // Check the pattern.
903 fcx.check_pat_arg(&arg.pat, arg_ty, true);
904 fcx.write_ty(arg.id, arg_ty);
907 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
909 fcx.check_return_expr(&body.value);
911 // Finalize the return check by taking the LUB of the return types
912 // we saw and assigning it to the expected return type. This isn't
913 // really expected to fail, since the coercions would have failed
914 // earlier when trying to find a LUB.
916 // However, the behavior around `!` is sort of complex. In the
917 // event that the `actual_return_ty` comes back as `!`, that
918 // indicates that the fn either does not return or "returns" only
919 // values of type `!`. In this case, if there is an expected
920 // return type that is *not* `!`, that should be ok. But if the
921 // return type is being inferred, we want to "fallback" to `!`:
923 // let x = move || panic!();
925 // To allow for that, I am creating a type variable with diverging
926 // fallback. This was deemed ever so slightly better than unifying
927 // the return value with `!` because it allows for the caller to
928 // make more assumptions about the return type (e.g., they could do
930 // let y: Option<u32> = Some(x());
932 // which would then cause this return type to become `u32`, not
934 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
935 let mut actual_return_ty = coercion.complete(&fcx);
936 if actual_return_ty.is_never() {
937 actual_return_ty = fcx.next_diverging_ty_var(
938 TypeVariableOrigin::DivergingFn(body.value.span));
940 fcx.demand_suptype(body.value.span, ret_ty, actual_return_ty);
945 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
948 let def_id = tcx.hir.local_def_id(id);
949 let def = tcx.lookup_adt_def(def_id);
950 def.destructor(tcx); // force the destructor to be evaluated
951 check_representable(tcx, span, def_id);
954 check_simd(tcx, span, def_id);
957 // if struct is packed and not aligned, check fields for alignment.
958 // Checks for combining packed and align attrs on single struct are done elsewhere.
959 if tcx.lookup_adt_def(def_id).repr.packed() && tcx.lookup_adt_def(def_id).repr.align == 0 {
960 check_packed(tcx, span, def_id);
964 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
967 let def_id = tcx.hir.local_def_id(id);
968 let def = tcx.lookup_adt_def(def_id);
969 def.destructor(tcx); // force the destructor to be evaluated
970 check_representable(tcx, span, def_id);
973 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
974 debug!("check_item_type(it.id={}, it.name={})",
976 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
977 let _indenter = indenter();
979 // Consts can play a role in type-checking, so they are included here.
980 hir::ItemStatic(..) |
981 hir::ItemConst(..) => {
982 tcx.item_tables(tcx.hir.local_def_id(it.id));
984 hir::ItemEnum(ref enum_definition, _) => {
987 &enum_definition.variants,
990 hir::ItemFn(..) => {} // entirely within check_item_body
991 hir::ItemImpl(.., ref impl_item_refs) => {
992 debug!("ItemImpl {} with id {}", it.name, it.id);
993 let impl_def_id = tcx.hir.local_def_id(it.id);
994 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
995 check_impl_items_against_trait(tcx,
1000 let trait_def_id = impl_trait_ref.def_id;
1001 check_on_unimplemented(tcx, trait_def_id, it);
1004 hir::ItemTrait(..) => {
1005 let def_id = tcx.hir.local_def_id(it.id);
1006 check_on_unimplemented(tcx, def_id, it);
1008 hir::ItemStruct(..) => {
1009 check_struct(tcx, it.id, it.span);
1011 hir::ItemUnion(..) => {
1012 check_union(tcx, it.id, it.span);
1014 hir::ItemTy(_, ref generics) => {
1015 let def_id = tcx.hir.local_def_id(it.id);
1016 let pty_ty = tcx.item_type(def_id);
1017 check_bounds_are_used(tcx, generics, pty_ty);
1019 hir::ItemForeignMod(ref m) => {
1020 check_abi(tcx, it.span, m.abi);
1022 if m.abi == Abi::RustIntrinsic {
1023 for item in &m.items {
1024 intrinsic::check_intrinsic_type(tcx, item);
1026 } else if m.abi == Abi::PlatformIntrinsic {
1027 for item in &m.items {
1028 intrinsic::check_platform_intrinsic_type(tcx, item);
1031 for item in &m.items {
1032 let generics = tcx.item_generics(tcx.hir.local_def_id(item.id));
1033 if !generics.types.is_empty() {
1034 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1035 "foreign items may not have type parameters");
1036 span_help!(&mut err, item.span,
1037 "consider using specialization instead of \
1042 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1043 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1048 _ => {/* nothing to do */ }
1052 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1055 let generics = tcx.item_generics(def_id);
1056 if let Some(ref attr) = item.attrs.iter().find(|a| {
1057 a.check_name("rustc_on_unimplemented")
1059 if let Some(istring) = attr.value_str() {
1060 let istring = istring.as_str();
1061 let parser = Parser::new(&istring);
1062 let types = &generics.types;
1063 for token in parser {
1065 Piece::String(_) => (), // Normal string, no need to check it
1066 Piece::NextArgument(a) => match a.position {
1067 // `{Self}` is allowed
1068 Position::ArgumentNamed(s) if s == "Self" => (),
1069 // So is `{A}` if A is a type parameter
1070 Position::ArgumentNamed(s) => match types.iter().find(|t| {
1075 let name = tcx.item_name(def_id);
1076 span_err!(tcx.sess, attr.span, E0230,
1077 "there is no type parameter \
1082 // `{:1}` and `{}` are not to be used
1083 Position::ArgumentIs(_) => {
1084 span_err!(tcx.sess, attr.span, E0231,
1085 "only named substitution \
1086 parameters are allowed");
1093 tcx.sess, attr.span, E0232,
1094 "this attribute must have a value")
1095 .span_label(attr.span, &format!("attribute requires a value"))
1096 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
1102 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1103 impl_item: &hir::ImplItem,
1106 let mut err = struct_span_err!(
1107 tcx.sess, impl_item.span, E0520,
1108 "`{}` specializes an item from a parent `impl`, but \
1109 that item is not marked `default`",
1111 err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
1114 match tcx.span_of_impl(parent_impl) {
1116 err.span_label(span, &"parent `impl` is here");
1117 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1121 err.note(&format!("parent implementation is in crate `{}`", cname));
1128 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1129 trait_def: &ty::TraitDef,
1131 impl_item: &hir::ImplItem)
1133 let ancestors = trait_def.ancestors(impl_id);
1135 let kind = match impl_item.node {
1136 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1137 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1138 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1140 let parent = ancestors.defs(tcx, impl_item.name, kind).skip(1).next()
1141 .map(|node_item| node_item.map(|parent| parent.defaultness));
1143 if let Some(parent) = parent {
1144 if parent.item.is_final() {
1145 let is_final = match tcx.map.as_local_node_id(parent.node.def_id()) {
1147 let item = tcx.map.expect_item(node_id);
1148 if let hir::ItemImpl(_, _, defaultness, ..) = item.node {
1149 defaultness.is_final()
1155 tcx.global_tcx().sess.cstore.impl_defaultness(parent.node.def_id()).is_final()
1160 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1167 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1170 impl_trait_ref: ty::TraitRef<'tcx>,
1171 impl_item_refs: &[hir::ImplItemRef]) {
1172 // If the trait reference itself is erroneous (so the compilation is going
1173 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1174 // isn't populated for such impls.
1175 if impl_trait_ref.references_error() { return; }
1177 // Locate trait definition and items
1178 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
1179 let mut overridden_associated_type = None;
1181 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1183 // Check existing impl methods to see if they are both present in trait
1184 // and compatible with trait signature
1185 for impl_item in impl_items() {
1186 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1187 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1188 .find(|ac| ac.name == ty_impl_item.name);
1190 // Check that impl definition matches trait definition
1191 if let Some(ty_trait_item) = ty_trait_item {
1192 match impl_item.node {
1193 hir::ImplItemKind::Const(..) => {
1194 // Find associated const definition.
1195 if ty_trait_item.kind == ty::AssociatedKind::Const {
1196 compare_const_impl(tcx,
1202 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1203 "item `{}` is an associated const, \
1204 which doesn't match its trait `{}`",
1207 err.span_label(impl_item.span, &format!("does not match trait"));
1208 // We can only get the spans from local trait definition
1209 // Same for E0324 and E0325
1210 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1211 err.span_label(trait_span, &format!("item in trait"));
1216 hir::ImplItemKind::Method(_, body_id) => {
1217 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1218 if ty_trait_item.kind == ty::AssociatedKind::Method {
1219 let err_count = tcx.sess.err_count();
1220 compare_impl_method(tcx,
1227 true); // start with old-broken-mode
1228 if err_count == tcx.sess.err_count() {
1229 // old broken mode did not report an error. Try with the new mode.
1230 compare_impl_method(tcx,
1237 false); // use the new mode
1240 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1241 "item `{}` is an associated method, \
1242 which doesn't match its trait `{}`",
1245 err.span_label(impl_item.span, &format!("does not match trait"));
1246 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1247 err.span_label(trait_span, &format!("item in trait"));
1252 hir::ImplItemKind::Type(_) => {
1253 if ty_trait_item.kind == ty::AssociatedKind::Type {
1254 if ty_trait_item.defaultness.has_value() {
1255 overridden_associated_type = Some(impl_item);
1258 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1259 "item `{}` is an associated type, \
1260 which doesn't match its trait `{}`",
1263 err.span_label(impl_item.span, &format!("does not match trait"));
1264 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1265 err.span_label(trait_span, &format!("item in trait"));
1273 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1276 // Check for missing items from trait
1277 let mut missing_items = Vec::new();
1278 let mut invalidated_items = Vec::new();
1279 let associated_type_overridden = overridden_associated_type.is_some();
1280 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1281 let is_implemented = trait_def.ancestors(impl_id)
1282 .defs(tcx, trait_item.name, trait_item.kind)
1284 .map(|node_item| !node_item.node.is_from_trait())
1287 if !is_implemented {
1288 if !trait_item.defaultness.has_value() {
1289 missing_items.push(trait_item);
1290 } else if associated_type_overridden {
1291 invalidated_items.push(trait_item.name);
1296 let signature = |item: &ty::AssociatedItem| {
1298 ty::AssociatedKind::Method => {
1299 format!("{}", tcx.item_type(item.def_id).fn_sig().0)
1301 ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
1302 ty::AssociatedKind::Const => {
1303 format!("const {}: {:?};", item.name.to_string(), tcx.item_type(item.def_id))
1308 if !missing_items.is_empty() {
1309 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1310 "not all trait items implemented, missing: `{}`",
1311 missing_items.iter()
1312 .map(|trait_item| trait_item.name.to_string())
1313 .collect::<Vec<_>>().join("`, `"));
1314 err.span_label(impl_span, &format!("missing `{}` in implementation",
1315 missing_items.iter()
1316 .map(|trait_item| trait_item.name.to_string())
1317 .collect::<Vec<_>>().join("`, `")));
1318 for trait_item in missing_items {
1319 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1320 err.span_label(span, &format!("`{}` from trait", trait_item.name));
1322 err.note(&format!("`{}` from trait: `{}`",
1324 signature(&trait_item)));
1330 if !invalidated_items.is_empty() {
1331 let invalidator = overridden_associated_type.unwrap();
1332 span_err!(tcx.sess, invalidator.span, E0399,
1333 "the following trait items need to be reimplemented \
1334 as `{}` was overridden: `{}`",
1336 invalidated_items.iter()
1337 .map(|name| name.to_string())
1338 .collect::<Vec<_>>().join("`, `"))
1342 /// Checks whether a type can be represented in memory. In particular, it
1343 /// identifies types that contain themselves without indirection through a
1344 /// pointer, which would mean their size is unbounded.
1345 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1349 let rty = tcx.item_type(item_def_id);
1351 // Check that it is possible to represent this type. This call identifies
1352 // (1) types that contain themselves and (2) types that contain a different
1353 // recursive type. It is only necessary to throw an error on those that
1354 // contain themselves. For case 2, there must be an inner type that will be
1355 // caught by case 1.
1356 match rty.is_representable(tcx, sp) {
1357 Representability::SelfRecursive => {
1358 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1361 Representability::Representable | Representability::ContainsRecursive => (),
1366 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1367 let t = tcx.item_type(def_id);
1369 ty::TyAdt(def, substs) if def.is_struct() => {
1370 let fields = &def.struct_variant().fields;
1371 if fields.is_empty() {
1372 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1375 let e = fields[0].ty(tcx, substs);
1376 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1377 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1378 .span_label(sp, &format!("SIMD elements must have the same type"))
1383 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1384 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1386 span_err!(tcx.sess, sp, E0077,
1387 "SIMD vector element type should be machine type");
1396 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1397 if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1398 struct_span_err!(tcx.sess, sp, E0588,
1399 "packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1403 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1405 stack: &mut Vec<DefId>) -> bool {
1406 let t = tcx.item_type(def_id);
1407 if stack.contains(&def_id) {
1408 debug!("check_packed_inner: {:?} is recursive", t);
1412 ty::TyAdt(def, substs) if def.is_struct() => {
1413 if tcx.lookup_adt_def(def.did).repr.align > 0 {
1416 // push struct def_id before checking fields
1418 for field in &def.struct_variant().fields {
1419 let f = field.ty(tcx, substs);
1421 ty::TyAdt(def, _) => {
1422 if check_packed_inner(tcx, def.did, stack) {
1429 // only need to pop if not early out
1437 #[allow(trivial_numeric_casts)]
1438 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1440 vs: &'tcx [hir::Variant],
1442 let def_id = tcx.hir.local_def_id(id);
1443 let def = tcx.lookup_adt_def(def_id);
1444 def.destructor(tcx); // force the destructor to be evaluated
1446 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1448 tcx.sess, sp, E0084,
1449 "unsupported representation for zero-variant enum")
1450 .span_label(sp, &format!("unsupported enum representation"))
1454 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1455 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1456 if !tcx.sess.features.borrow().i128_type {
1457 emit_feature_err(&tcx.sess.parse_sess,
1458 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1463 if let Some(e) = v.node.disr_expr {
1464 tcx.item_tables(tcx.hir.local_def_id(e.node_id));
1468 let mut disr_vals: Vec<ConstInt> = Vec::new();
1469 for (discr, v) in def.discriminants(tcx).zip(vs) {
1470 // Check for duplicate discriminant values
1471 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1472 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1473 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1474 let i_span = match variant_i.node.disr_expr {
1475 Some(expr) => tcx.hir.span(expr.node_id),
1476 None => tcx.hir.span(variant_i_node_id)
1478 let span = match v.node.disr_expr {
1479 Some(expr) => tcx.hir.span(expr.node_id),
1482 struct_span_err!(tcx.sess, span, E0081,
1483 "discriminant value `{}` already exists", disr_vals[i])
1484 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1485 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1488 disr_vals.push(discr);
1491 check_representable(tcx, sp, def_id);
1494 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1495 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1497 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1498 &self.ast_ty_to_ty_cache
1501 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1502 Some(&self.parameter_environment.free_substs)
1505 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1506 -> ty::GenericPredicates<'tcx>
1509 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1510 let item_id = tcx.hir.ty_param_owner(node_id);
1511 let item_def_id = tcx.hir.local_def_id(item_id);
1512 let generics = tcx.item_generics(item_def_id);
1513 let index = generics.type_param_to_index[&def_id.index];
1514 ty::GenericPredicates {
1516 predicates: self.parameter_environment.caller_bounds.iter().filter(|predicate| {
1518 ty::Predicate::Trait(ref data) => {
1519 data.0.self_ty().is_param(index)
1523 }).cloned().collect()
1527 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1528 -> Option<&'tcx ty::Region> {
1530 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1531 None => infer::MiscVariable(span)
1533 Some(self.next_region_var(v))
1536 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1537 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1540 fn ty_infer_for_def(&self,
1541 ty_param_def: &ty::TypeParameterDef,
1542 substs: &[Kind<'tcx>],
1543 span: Span) -> Ty<'tcx> {
1544 self.type_var_for_def(span, ty_param_def, substs)
1547 fn projected_ty_from_poly_trait_ref(&self,
1549 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1550 item_name: ast::Name)
1553 let (trait_ref, _) =
1554 self.replace_late_bound_regions_with_fresh_var(
1556 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1559 self.tcx().mk_projection(trait_ref, item_name)
1562 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1563 if ty.has_escaping_regions() {
1564 ty // FIXME: normalization and escaping regions
1566 self.normalize_associated_types_in(span, &ty)
1570 fn set_tainted_by_errors(&self) {
1571 self.infcx.set_tainted_by_errors()
1575 /// Controls whether the arguments are tupled. This is used for the call
1578 /// Tupling means that all call-side arguments are packed into a tuple and
1579 /// passed as a single parameter. For example, if tupling is enabled, this
1582 /// fn f(x: (isize, isize))
1584 /// Can be called as:
1591 #[derive(Clone, Eq, PartialEq)]
1592 enum TupleArgumentsFlag {
1597 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1598 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1599 body_id: ast::NodeId)
1600 -> FnCtxt<'a, 'gcx, 'tcx> {
1602 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1604 err_count_on_creation: inh.tcx.sess.err_count(),
1606 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1607 ast::CRATE_NODE_ID)),
1608 diverges: Cell::new(Diverges::Maybe),
1609 has_errors: Cell::new(false),
1610 enclosing_breakables: RefCell::new(EnclosingBreakables {
1618 pub fn sess(&self) -> &Session {
1622 pub fn err_count_since_creation(&self) -> usize {
1623 self.tcx.sess.err_count() - self.err_count_on_creation
1626 /// Produce warning on the given node, if the current point in the
1627 /// function is unreachable, and there hasn't been another warning.
1628 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1629 if self.diverges.get() == Diverges::Always {
1630 self.diverges.set(Diverges::WarnedAlways);
1632 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1634 self.tables.borrow_mut().lints.add_lint(
1635 lint::builtin::UNREACHABLE_CODE,
1637 format!("unreachable {}", kind));
1643 code: ObligationCauseCode<'tcx>)
1644 -> ObligationCause<'tcx> {
1645 ObligationCause::new(span, self.body_id, code)
1648 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1649 self.cause(span, ObligationCauseCode::MiscObligation)
1652 /// Resolves type variables in `ty` if possible. Unlike the infcx
1653 /// version (resolve_type_vars_if_possible), this version will
1654 /// also select obligations if it seems useful, in an effort
1655 /// to get more type information.
1656 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1657 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1659 // No TyInfer()? Nothing needs doing.
1660 if !ty.has_infer_types() {
1661 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1665 // If `ty` is a type variable, see whether we already know what it is.
1666 ty = self.resolve_type_vars_if_possible(&ty);
1667 if !ty.has_infer_types() {
1668 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1672 // If not, try resolving pending obligations as much as
1673 // possible. This can help substantially when there are
1674 // indirect dependencies that don't seem worth tracking
1676 self.select_obligations_where_possible();
1677 ty = self.resolve_type_vars_if_possible(&ty);
1679 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1683 fn record_deferred_call_resolution(&self,
1684 closure_def_id: DefId,
1685 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1686 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1687 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1690 fn remove_deferred_call_resolutions(&self,
1691 closure_def_id: DefId)
1692 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1694 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1695 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1698 pub fn tag(&self) -> String {
1699 let self_ptr: *const FnCtxt = self;
1700 format!("{:?}", self_ptr)
1703 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1704 match self.locals.borrow().get(&nid) {
1707 span_bug!(span, "no type for local variable {}",
1708 self.tcx.hir.node_to_string(nid));
1714 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1715 debug!("write_ty({}, {:?}) in fcx {}",
1716 node_id, self.resolve_type_vars_if_possible(&ty), self.tag());
1717 self.tables.borrow_mut().node_types.insert(node_id, ty);
1719 if ty.references_error() {
1720 self.has_errors.set(true);
1721 self.set_tainted_by_errors();
1725 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1726 if !substs.substs.is_noop() {
1727 debug!("write_substs({}, {:?}) in fcx {}",
1732 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1736 pub fn apply_autoderef_adjustment(&self,
1737 node_id: ast::NodeId,
1739 adjusted_ty: Ty<'tcx>) {
1740 self.apply_adjustment(node_id, Adjustment {
1741 kind: Adjust::DerefRef {
1750 pub fn apply_adjustment(&self, node_id: ast::NodeId, adj: Adjustment<'tcx>) {
1751 debug!("apply_adjustment(node_id={}, adj={:?})", node_id, adj);
1753 if adj.is_identity() {
1757 match self.tables.borrow_mut().adjustments.entry(node_id) {
1758 Entry::Vacant(entry) => { entry.insert(adj); },
1759 Entry::Occupied(mut entry) => {
1760 debug!(" - composing on top of {:?}", entry.get());
1761 let composed_kind = match (entry.get().kind, adj.kind) {
1762 // Applying any adjustment on top of a NeverToAny
1763 // is a valid NeverToAny adjustment, because it can't
1765 (Adjust::NeverToAny, _) => Adjust::NeverToAny,
1768 autoref: Some(AutoBorrow::Ref(..)),
1770 }, Adjust::DerefRef { autoderefs, .. }) if autoderefs > 0 => {
1771 // A reborrow has no effect before a dereference.
1774 // FIXME: currently we never try to compose autoderefs
1775 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1777 bug!("while adjusting {}, can't compose {:?} and {:?}",
1778 node_id, entry.get(), adj)
1780 *entry.get_mut() = Adjustment {
1781 kind: composed_kind,
1788 /// Basically whenever we are converting from a type scheme into
1789 /// the fn body space, we always want to normalize associated
1790 /// types as well. This function combines the two.
1791 fn instantiate_type_scheme<T>(&self,
1793 substs: &Substs<'tcx>,
1796 where T : TypeFoldable<'tcx>
1798 let value = value.subst(self.tcx, substs);
1799 let result = self.normalize_associated_types_in(span, &value);
1800 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1807 /// As `instantiate_type_scheme`, but for the bounds found in a
1808 /// generic type scheme.
1809 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1810 -> ty::InstantiatedPredicates<'tcx> {
1811 let bounds = self.tcx.item_predicates(def_id);
1812 let result = bounds.instantiate(self.tcx, substs);
1813 let result = self.normalize_associated_types_in(span, &result);
1814 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1821 /// Replace all anonymized types with fresh inference variables
1822 /// and record them for writeback.
1823 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1824 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1825 if let ty::TyAnon(def_id, substs) = ty.sty {
1826 // Use the same type variable if the exact same TyAnon appears more
1827 // than once in the return type (e.g. if it's pased to a type alias).
1828 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1829 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1832 let span = self.tcx.def_span(def_id);
1833 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1834 self.anon_types.borrow_mut().insert(id, ty_var);
1836 let item_predicates = self.tcx.item_predicates(def_id);
1837 let bounds = item_predicates.instantiate(self.tcx, substs);
1839 for predicate in bounds.predicates {
1840 // Change the predicate to refer to the type variable,
1841 // which will be the concrete type, instead of the TyAnon.
1842 // This also instantiates nested `impl Trait`.
1843 let predicate = self.instantiate_anon_types(&predicate);
1845 // Require that the predicate holds for the concrete type.
1846 let cause = traits::ObligationCause::new(span, self.body_id,
1847 traits::ReturnType);
1848 self.register_predicate(traits::Obligation::new(cause, predicate));
1858 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1859 where T : TypeFoldable<'tcx>
1861 let ok = self.normalize_associated_types_in_as_infer_ok(span, value);
1862 self.register_infer_ok_obligations(ok)
1865 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
1867 where T : TypeFoldable<'tcx>
1869 self.inh.normalize_associated_types_in_as_infer_ok(span, self.body_id, value)
1872 pub fn write_nil(&self, node_id: ast::NodeId) {
1873 self.write_ty(node_id, self.tcx.mk_nil());
1876 pub fn write_error(&self, node_id: ast::NodeId) {
1877 self.write_ty(node_id, self.tcx.types.err);
1880 pub fn require_type_meets(&self,
1883 code: traits::ObligationCauseCode<'tcx>,
1886 self.register_bound(
1889 traits::ObligationCause::new(span, self.body_id, code));
1892 pub fn require_type_is_sized(&self,
1895 code: traits::ObligationCauseCode<'tcx>)
1897 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1898 self.require_type_meets(ty, span, code, lang_item);
1901 pub fn register_bound(&self,
1904 cause: traits::ObligationCause<'tcx>)
1906 self.fulfillment_cx.borrow_mut()
1907 .register_bound(self, ty, def_id, cause);
1910 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1911 let t = AstConv::ast_ty_to_ty(self, ast_t);
1912 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1916 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1917 match self.tables.borrow().node_types.get(&id) {
1919 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1921 bug!("no type for node {}: {} in fcx {}",
1922 id, self.tcx.hir.node_to_string(id),
1928 pub fn opt_node_ty_substs<F>(&self,
1931 F: FnOnce(&ty::ItemSubsts<'tcx>),
1933 if let Some(s) = self.tables.borrow().item_substs.get(&id) {
1938 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1939 /// outlive the region `r`.
1940 pub fn register_region_obligation(&self,
1942 region: &'tcx ty::Region,
1943 cause: traits::ObligationCause<'tcx>)
1945 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1946 fulfillment_cx.register_region_obligation(ty, region, cause);
1949 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1950 /// outlive the region `r`.
1951 pub fn register_wf_obligation(&self,
1954 code: traits::ObligationCauseCode<'tcx>)
1956 // WF obligations never themselves fail, so no real need to give a detailed cause:
1957 let cause = traits::ObligationCause::new(span, self.body_id, code);
1958 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1961 pub fn register_old_wf_obligation(&self,
1964 code: traits::ObligationCauseCode<'tcx>)
1966 // Registers an "old-style" WF obligation that uses the
1967 // implicator code. This is basically a buggy version of
1968 // `register_wf_obligation` that is being kept around
1969 // temporarily just to help with phasing in the newer rules.
1971 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1972 let cause = traits::ObligationCause::new(span, self.body_id, code);
1973 self.register_region_obligation(ty, self.tcx.types.re_empty, cause);
1976 /// Registers obligations that all types appearing in `substs` are well-formed.
1977 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1979 for ty in substs.types() {
1980 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1984 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1985 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1986 /// trait/region obligations.
1988 /// For example, if there is a function:
1991 /// fn foo<'a,T:'a>(...)
1994 /// and a reference:
2000 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2001 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2002 pub fn add_obligations_for_parameters(&self,
2003 cause: traits::ObligationCause<'tcx>,
2004 predicates: &ty::InstantiatedPredicates<'tcx>)
2006 assert!(!predicates.has_escaping_regions());
2008 debug!("add_obligations_for_parameters(predicates={:?})",
2011 for obligation in traits::predicates_for_generics(cause, predicates) {
2012 self.register_predicate(obligation);
2016 // FIXME(arielb1): use this instead of field.ty everywhere
2017 // Only for fields! Returns <none> for methods>
2018 // Indifferent to privacy flags
2019 pub fn field_ty(&self,
2021 field: &'tcx ty::FieldDef,
2022 substs: &Substs<'tcx>)
2025 self.normalize_associated_types_in(span,
2026 &field.ty(self.tcx, substs))
2029 fn check_casts(&self) {
2030 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2031 for cast in deferred_cast_checks.drain(..) {
2036 /// Apply "fallbacks" to some types
2037 /// unconstrained types get replaced with ! or () (depending on whether
2038 /// feature(never_type) is enabled), unconstrained ints with i32, and
2039 /// unconstrained floats with f64.
2040 fn default_type_parameters(&self) {
2041 use rustc::ty::error::UnconstrainedNumeric::Neither;
2042 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2044 // Defaulting inference variables becomes very dubious if we have
2045 // encountered type-checking errors. Therefore, if we think we saw
2046 // some errors in this function, just resolve all uninstanted type
2047 // varibles to TyError.
2048 if self.is_tainted_by_errors() {
2049 for ty in &self.unsolved_variables() {
2050 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
2051 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2052 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2058 for ty in &self.unsolved_variables() {
2059 let resolved = self.resolve_type_vars_if_possible(ty);
2060 if self.type_var_diverges(resolved) {
2061 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
2063 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2064 self.tcx.mk_diverging_default());
2066 match self.type_is_unconstrained_numeric(resolved) {
2067 UnconstrainedInt => {
2068 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
2070 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2072 UnconstrainedFloat => {
2073 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
2075 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2083 // Implements type inference fallback algorithm
2084 fn select_all_obligations_and_apply_defaults(&self) {
2085 self.select_obligations_where_possible();
2086 self.default_type_parameters();
2087 self.select_obligations_where_possible();
2090 fn select_all_obligations_or_error(&self) {
2091 debug!("select_all_obligations_or_error");
2093 // upvar inference should have ensured that all deferred call
2094 // resolutions are handled by now.
2095 assert!(self.deferred_call_resolutions.borrow().is_empty());
2097 self.select_all_obligations_and_apply_defaults();
2099 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2101 match fulfillment_cx.select_all_or_error(self) {
2103 Err(errors) => { self.report_fulfillment_errors(&errors); }
2107 /// Select as many obligations as we can at present.
2108 fn select_obligations_where_possible(&self) {
2109 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2111 Err(errors) => { self.report_fulfillment_errors(&errors); }
2115 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2116 /// returns a type of `&T`, but the actual type we assign to the
2117 /// *expression* is `T`. So this function just peels off the return
2118 /// type by one layer to yield `T`.
2119 fn make_overloaded_lvalue_return_type(&self,
2120 method: MethodCallee<'tcx>)
2121 -> ty::TypeAndMut<'tcx>
2123 // extract method return type, which will be &T;
2124 // all LB regions should have been instantiated during method lookup
2125 let ret_ty = method.ty.fn_ret();
2126 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2128 // method returns &T, but the type as visible to user is T, so deref
2129 ret_ty.builtin_deref(true, NoPreference).unwrap()
2132 fn lookup_indexing(&self,
2134 base_expr: &'gcx hir::Expr,
2137 lvalue_pref: LvaluePreference)
2138 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2140 // FIXME(#18741) -- this is almost but not quite the same as the
2141 // autoderef that normal method probing does. They could likely be
2144 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2146 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2147 if let Some(final_mt) = self.try_index_step(
2148 MethodCall::expr(expr.id),
2149 expr, base_expr, adj_ty, autoderefs,
2150 false, lvalue_pref, idx_ty)
2152 autoderef.finalize(lvalue_pref, base_expr);
2153 return Some(final_mt);
2156 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2157 autoderef.finalize(lvalue_pref, base_expr);
2158 let adjusted_ty = self.tcx.mk_slice(element_ty);
2159 return self.try_index_step(
2160 MethodCall::expr(expr.id), expr, base_expr,
2161 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2164 autoderef.unambiguous_final_ty();
2168 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2169 /// (and otherwise adjust) `base_expr`, looking for a type which either
2170 /// supports builtin indexing or overloaded indexing.
2171 /// This loop implements one step in that search; the autoderef loop
2172 /// is implemented by `lookup_indexing`.
2173 fn try_index_step(&self,
2174 method_call: MethodCall,
2176 base_expr: &'gcx hir::Expr,
2177 adjusted_ty: Ty<'tcx>,
2180 lvalue_pref: LvaluePreference,
2182 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2185 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2186 autoderefs={}, unsize={}, index_ty={:?})",
2194 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2196 // First, try built-in indexing.
2197 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2198 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2199 debug!("try_index_step: success, using built-in indexing");
2200 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2202 self.apply_autoderef_adjustment(base_expr.id, autoderefs, adjusted_ty);
2203 return Some((tcx.types.usize, ty));
2208 // Try `IndexMut` first, if preferred.
2209 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2210 (PreferMutLvalue, Some(trait_did)) => {
2211 self.lookup_method_in_trait_adjusted(expr.span,
2213 Symbol::intern("index_mut"),
2218 Some(vec![input_ty]))
2223 // Otherwise, fall back to `Index`.
2224 let method = match (method, tcx.lang_items.index_trait()) {
2225 (None, Some(trait_did)) => {
2226 self.lookup_method_in_trait_adjusted(expr.span,
2228 Symbol::intern("index"),
2233 Some(vec![input_ty]))
2235 (method, _) => method,
2238 // If some lookup succeeds, write callee into table and extract index/element
2239 // type from the method signature.
2240 // If some lookup succeeded, install method in table
2242 debug!("try_index_step: success, using overloaded indexing");
2243 let method = self.register_infer_ok_obligations(ok);
2244 self.tables.borrow_mut().method_map.insert(method_call, method);
2245 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2249 fn check_method_argument_types(&self,
2251 method_fn_ty: Ty<'tcx>,
2252 callee_expr: &'gcx hir::Expr,
2253 args_no_rcvr: &'gcx [hir::Expr],
2254 tuple_arguments: TupleArgumentsFlag,
2255 expected: Expectation<'tcx>)
2257 if method_fn_ty.references_error() {
2258 let err_inputs = self.err_args(args_no_rcvr.len());
2260 let err_inputs = match tuple_arguments {
2261 DontTupleArguments => err_inputs,
2262 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2265 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2266 false, tuple_arguments, None);
2269 match method_fn_ty.sty {
2270 ty::TyFnDef(def_id, .., ref fty) => {
2271 // HACK(eddyb) ignore self in the definition (see above).
2272 let expected_arg_tys = self.expected_inputs_for_expected_output(
2276 &fty.0.inputs()[1..]
2278 self.check_argument_types(sp, &fty.0.inputs()[1..], &expected_arg_tys[..],
2279 args_no_rcvr, fty.0.variadic, tuple_arguments,
2280 self.tcx.hir.span_if_local(def_id));
2284 span_bug!(callee_expr.span, "method without bare fn type");
2290 /// Generic function that factors out common logic from function calls,
2291 /// method calls and overloaded operators.
2292 fn check_argument_types(&self,
2294 fn_inputs: &[Ty<'tcx>],
2295 expected_arg_tys: &[Ty<'tcx>],
2296 args: &'gcx [hir::Expr],
2298 tuple_arguments: TupleArgumentsFlag,
2299 def_span: Option<Span>) {
2302 // Grab the argument types, supplying fresh type variables
2303 // if the wrong number of arguments were supplied
2304 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2310 // All the input types from the fn signature must outlive the call
2311 // so as to validate implied bounds.
2312 for &fn_input_ty in fn_inputs {
2313 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2316 let mut expected_arg_tys = expected_arg_tys;
2317 let expected_arg_count = fn_inputs.len();
2319 let sp_args = if args.len() > 0 {
2320 let (first, args) = args.split_at(1);
2321 let mut sp_tmp = first[0].span;
2323 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2324 if ! sp_opt.is_some() {
2327 sp_tmp = sp_opt.unwrap();
2334 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2335 arg_count: usize, error_code: &str, variadic: bool,
2336 def_span: Option<Span>) {
2337 let mut err = sess.struct_span_err_with_code(sp,
2338 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2339 if variadic {"at least "} else {""},
2341 if expected_count == 1 {""} else {"s"},
2343 if arg_count == 1 {" was"} else {"s were"}),
2346 err.span_label(sp, &format!("expected {}{} parameter{}",
2347 if variadic {"at least "} else {""},
2349 if expected_count == 1 {""} else {"s"}));
2350 if let Some(def_s) = def_span {
2351 err.span_label(def_s, &format!("defined here"));
2356 let formal_tys = if tuple_arguments == TupleArguments {
2357 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2358 match tuple_type.sty {
2359 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2360 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2361 "E0057", false, def_span);
2362 expected_arg_tys = &[];
2363 self.err_args(args.len())
2365 ty::TyTuple(arg_types, _) => {
2366 expected_arg_tys = match expected_arg_tys.get(0) {
2367 Some(&ty) => match ty.sty {
2368 ty::TyTuple(ref tys, _) => &tys,
2376 span_err!(tcx.sess, sp, E0059,
2377 "cannot use call notation; the first type parameter \
2378 for the function trait is neither a tuple nor unit");
2379 expected_arg_tys = &[];
2380 self.err_args(args.len())
2383 } else if expected_arg_count == supplied_arg_count {
2385 } else if variadic {
2386 if supplied_arg_count >= expected_arg_count {
2389 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2390 supplied_arg_count, "E0060", true, def_span);
2391 expected_arg_tys = &[];
2392 self.err_args(supplied_arg_count)
2395 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2396 supplied_arg_count, "E0061", false, def_span);
2397 expected_arg_tys = &[];
2398 self.err_args(supplied_arg_count)
2401 debug!("check_argument_types: formal_tys={:?}",
2402 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2404 // Check the arguments.
2405 // We do this in a pretty awful way: first we typecheck any arguments
2406 // that are not closures, then we typecheck the closures. This is so
2407 // that we have more information about the types of arguments when we
2408 // typecheck the functions. This isn't really the right way to do this.
2409 for &check_closures in &[false, true] {
2410 debug!("check_closures={}", check_closures);
2412 // More awful hacks: before we check argument types, try to do
2413 // an "opportunistic" vtable resolution of any trait bounds on
2414 // the call. This helps coercions.
2416 self.select_obligations_where_possible();
2419 // For variadic functions, we don't have a declared type for all of
2420 // the arguments hence we only do our usual type checking with
2421 // the arguments who's types we do know.
2422 let t = if variadic {
2424 } else if tuple_arguments == TupleArguments {
2429 for (i, arg) in args.iter().take(t).enumerate() {
2430 // Warn only for the first loop (the "no closures" one).
2431 // Closure arguments themselves can't be diverging, but
2432 // a previous argument can, e.g. `foo(panic!(), || {})`.
2433 if !check_closures {
2434 self.warn_if_unreachable(arg.id, arg.span, "expression");
2437 let is_closure = match arg.node {
2438 hir::ExprClosure(..) => true,
2442 if is_closure != check_closures {
2446 debug!("checking the argument");
2447 let formal_ty = formal_tys[i];
2449 // The special-cased logic below has three functions:
2450 // 1. Provide as good of an expected type as possible.
2451 let expected = expected_arg_tys.get(i).map(|&ty| {
2452 Expectation::rvalue_hint(self, ty)
2455 let checked_ty = self.check_expr_with_expectation(
2457 expected.unwrap_or(ExpectHasType(formal_ty)));
2459 // 2. Coerce to the most detailed type that could be coerced
2460 // to, which is `expected_ty` if `rvalue_hint` returns an
2461 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2462 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2463 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2465 // 3. Relate the expected type and the formal one,
2466 // if the expected type was used for the coercion.
2467 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2471 // We also need to make sure we at least write the ty of the other
2472 // arguments which we skipped above.
2474 for arg in args.iter().skip(expected_arg_count) {
2475 let arg_ty = self.check_expr(&arg);
2477 // There are a few types which get autopromoted when passed via varargs
2478 // in C but we just error out instead and require explicit casts.
2479 let arg_ty = self.structurally_resolved_type(arg.span,
2482 ty::TyFloat(ast::FloatTy::F32) => {
2483 self.type_error_message(arg.span, |t| {
2484 format!("can't pass an `{}` to variadic \
2485 function, cast to `c_double`", t)
2488 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2489 self.type_error_message(arg.span, |t| {
2490 format!("can't pass `{}` to variadic \
2491 function, cast to `c_int`",
2495 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2496 self.type_error_message(arg.span, |t| {
2497 format!("can't pass `{}` to variadic \
2498 function, cast to `c_uint`",
2502 ty::TyFnDef(.., f) => {
2503 let ptr_ty = self.tcx.mk_fn_ptr(f);
2504 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2505 self.type_error_message(arg.span,
2507 format!("can't pass `{}` to variadic \
2508 function, cast to `{}`", t, ptr_ty)
2517 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2518 (0..len).map(|_| self.tcx.types.err).collect()
2521 // AST fragment checking
2524 expected: Expectation<'tcx>)
2530 ast::LitKind::Str(..) => tcx.mk_static_str(),
2531 ast::LitKind::ByteStr(ref v) => {
2532 tcx.mk_imm_ref(tcx.types.re_static,
2533 tcx.mk_array(tcx.types.u8, v.len()))
2535 ast::LitKind::Byte(_) => tcx.types.u8,
2536 ast::LitKind::Char(_) => tcx.types.char,
2537 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2538 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2539 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2540 let opt_ty = expected.to_option(self).and_then(|ty| {
2542 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2543 ty::TyChar => Some(tcx.types.u8),
2544 ty::TyRawPtr(..) => Some(tcx.types.usize),
2545 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2549 opt_ty.unwrap_or_else(
2550 || tcx.mk_int_var(self.next_int_var_id()))
2552 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2553 ast::LitKind::FloatUnsuffixed(_) => {
2554 let opt_ty = expected.to_option(self).and_then(|ty| {
2556 ty::TyFloat(_) => Some(ty),
2560 opt_ty.unwrap_or_else(
2561 || tcx.mk_float_var(self.next_float_var_id()))
2563 ast::LitKind::Bool(_) => tcx.types.bool
2567 fn check_expr_eq_type(&self,
2568 expr: &'gcx hir::Expr,
2569 expected: Ty<'tcx>) {
2570 let ty = self.check_expr_with_hint(expr, expected);
2571 self.demand_eqtype(expr.span, expected, ty);
2574 pub fn check_expr_has_type(&self,
2575 expr: &'gcx hir::Expr,
2576 expected: Ty<'tcx>) -> Ty<'tcx> {
2577 let mut ty = self.check_expr_with_hint(expr, expected);
2579 // While we don't allow *arbitrary* coercions here, we *do* allow
2580 // coercions from ! to `expected`.
2582 assert!(!self.tables.borrow().adjustments.contains_key(&expr.id),
2583 "expression with never type wound up being adjusted");
2584 let adj_ty = self.next_diverging_ty_var(
2585 TypeVariableOrigin::AdjustmentType(expr.span));
2586 self.apply_adjustment(expr.id, Adjustment {
2587 kind: Adjust::NeverToAny,
2593 self.demand_suptype(expr.span, expected, ty);
2597 fn check_expr_coercable_to_type(&self,
2598 expr: &'gcx hir::Expr,
2599 expected: Ty<'tcx>) -> Ty<'tcx> {
2600 let ty = self.check_expr_with_hint(expr, expected);
2601 self.demand_coerce(expr, ty, expected);
2605 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2606 expected: Ty<'tcx>) -> Ty<'tcx> {
2607 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2610 fn check_expr_with_expectation(&self,
2611 expr: &'gcx hir::Expr,
2612 expected: Expectation<'tcx>) -> Ty<'tcx> {
2613 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2616 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2617 self.check_expr_with_expectation(expr, NoExpectation)
2620 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2621 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2622 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2625 // determine the `self` type, using fresh variables for all variables
2626 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2627 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2629 pub fn impl_self_ty(&self,
2630 span: Span, // (potential) receiver for this impl
2632 -> TypeAndSubsts<'tcx> {
2633 let ity = self.tcx.item_type(did);
2634 debug!("impl_self_ty: ity={:?}", ity);
2636 let substs = self.fresh_substs_for_item(span, did);
2637 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2639 TypeAndSubsts { substs: substs, ty: substd_ty }
2642 /// Unifies the output type with the expected type early, for more coercions
2643 /// and forward type information on the input expressions.
2644 fn expected_inputs_for_expected_output(&self,
2646 expected_ret: Expectation<'tcx>,
2647 formal_ret: Ty<'tcx>,
2648 formal_args: &[Ty<'tcx>])
2650 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2651 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2652 // Attempt to apply a subtyping relationship between the formal
2653 // return type (likely containing type variables if the function
2654 // is polymorphic) and the expected return type.
2655 // No argument expectations are produced if unification fails.
2656 let origin = self.misc(call_span);
2657 let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
2659 // FIXME(#15760) can't use try! here, FromError doesn't default
2660 // to identity so the resulting type is not constrained.
2663 // Process any obligations locally as much as
2664 // we can. We don't care if some things turn
2665 // out unconstrained or ambiguous, as we're
2666 // just trying to get hints here.
2667 let result = self.save_and_restore_in_snapshot_flag(|_| {
2668 let mut fulfill = FulfillmentContext::new();
2669 let ok = ok; // FIXME(#30046)
2670 for obligation in ok.obligations {
2671 fulfill.register_predicate_obligation(self, obligation);
2673 fulfill.select_where_possible(self)
2678 Err(_) => return Err(()),
2681 Err(_) => return Err(()),
2684 // Record all the argument types, with the substitutions
2685 // produced from the above subtyping unification.
2686 Ok(formal_args.iter().map(|ty| {
2687 self.resolve_type_vars_if_possible(ty)
2690 }).unwrap_or(vec![]);
2691 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2692 formal_args, formal_ret,
2693 expected_args, expected_ret);
2697 // Checks a method call.
2698 fn check_method_call(&self,
2699 expr: &'gcx hir::Expr,
2700 method_name: Spanned<ast::Name>,
2701 args: &'gcx [hir::Expr],
2703 expected: Expectation<'tcx>,
2704 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2705 let rcvr = &args[0];
2706 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2708 // no need to check for bot/err -- callee does that
2709 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2711 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2712 let fn_ty = match self.lookup_method(method_name.span,
2719 let method_ty = method.ty;
2720 let method_call = MethodCall::expr(expr.id);
2721 self.tables.borrow_mut().method_map.insert(method_call, method);
2725 if method_name.node != keywords::Invalid.name() {
2726 self.report_method_error(method_name.span,
2733 self.write_error(expr.id);
2738 // Call the generic checker.
2739 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2747 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2751 .unwrap_or_else(|| span_bug!(return_expr.span,
2752 "check_return_expr called outside fn body"));
2754 let ret_ty = ret_coercion.borrow().expected_ty();
2755 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
2756 ret_coercion.borrow_mut()
2758 &self.misc(return_expr.span),
2761 self.diverges.get());
2765 // A generic function for checking the then and else in an if
2767 fn check_then_else(&self,
2768 cond_expr: &'gcx hir::Expr,
2769 then_expr: &'gcx hir::Expr,
2770 opt_else_expr: Option<&'gcx hir::Expr>,
2772 expected: Expectation<'tcx>) -> Ty<'tcx> {
2773 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2774 let cond_diverges = self.diverges.get();
2775 self.diverges.set(Diverges::Maybe);
2777 let expected = expected.adjust_for_branches(self);
2778 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2779 let then_diverges = self.diverges.get();
2780 self.diverges.set(Diverges::Maybe);
2782 // We've already taken the expected type's preferences
2783 // into account when typing the `then` branch. To figure
2784 // out the initial shot at a LUB, we thus only consider
2785 // `expected` if it represents a *hard* constraint
2786 // (`only_has_type`); otherwise, we just go with a
2787 // fresh type variable.
2788 let coerce_to_ty = expected.coercion_target_type(self, sp);
2789 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2791 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2792 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2794 if let Some(else_expr) = opt_else_expr {
2795 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2796 let else_diverges = self.diverges.get();
2798 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
2800 // We won't diverge unless both branches do (or the condition does).
2801 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2803 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2804 coerce.coerce_forced_unit(self, &else_cause, &mut |_| ());
2806 // If the condition is false we can't diverge.
2807 self.diverges.set(cond_diverges);
2810 let result_ty = coerce.complete(self);
2811 if cond_ty.references_error() {
2818 // Check field access expressions
2819 fn check_field(&self,
2820 expr: &'gcx hir::Expr,
2821 lvalue_pref: LvaluePreference,
2822 base: &'gcx hir::Expr,
2823 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2824 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2825 let expr_t = self.structurally_resolved_type(expr.span,
2827 let mut private_candidate = None;
2828 let mut autoderef = self.autoderef(expr.span, expr_t);
2829 while let Some((base_t, autoderefs)) = autoderef.next() {
2831 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2832 debug!("struct named {:?}", base_t);
2833 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2834 let field_ty = self.field_ty(expr.span, field, substs);
2835 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2836 autoderef.finalize(lvalue_pref, base);
2837 self.apply_autoderef_adjustment(base.id, autoderefs, base_t);
2839 self.tcx.check_stability(field.did, expr.id, expr.span);
2843 private_candidate = Some((base_def.did, field_ty));
2849 autoderef.unambiguous_final_ty();
2851 if let Some((did, field_ty)) = private_candidate {
2852 let struct_path = self.tcx().item_path_str(did);
2853 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2854 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2855 // Also check if an accessible method exists, which is often what is meant.
2856 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2857 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2862 } else if field.node == keywords::Invalid.name() {
2863 self.tcx().types.err
2864 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2865 self.type_error_struct(field.span, |actual| {
2866 format!("attempted to take value of method `{}` on type \
2867 `{}`", field.node, actual)
2869 .help("maybe a `()` to call it is missing? \
2870 If not, try an anonymous function")
2872 self.tcx().types.err
2874 let mut err = self.type_error_struct(field.span, |actual| {
2875 format!("no field `{}` on type `{}`",
2879 ty::TyAdt(def, _) if !def.is_enum() => {
2880 if let Some(suggested_field_name) =
2881 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2882 err.span_label(field.span,
2883 &format!("did you mean `{}`?", suggested_field_name));
2885 err.span_label(field.span,
2886 &format!("unknown field"));
2889 ty::TyRawPtr(..) => {
2890 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2892 self.tcx.hir.node_to_pretty_string(base.id),
2898 self.tcx().types.err
2902 // Return an hint about the closest match in field names
2903 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2904 field: &Spanned<ast::Name>,
2905 skip : Vec<InternedString>)
2907 let name = field.node.as_str();
2908 let names = variant.fields.iter().filter_map(|field| {
2909 // ignore already set fields and private fields from non-local crates
2910 if skip.iter().any(|x| *x == field.name.as_str()) ||
2911 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2918 // only find fits with at least one matching letter
2919 find_best_match_for_name(names, &name, Some(name.len()))
2922 // Check tuple index expressions
2923 fn check_tup_field(&self,
2924 expr: &'gcx hir::Expr,
2925 lvalue_pref: LvaluePreference,
2926 base: &'gcx hir::Expr,
2927 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2928 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2929 let expr_t = self.structurally_resolved_type(expr.span,
2931 let mut private_candidate = None;
2932 let mut tuple_like = false;
2933 let mut autoderef = self.autoderef(expr.span, expr_t);
2934 while let Some((base_t, autoderefs)) = autoderef.next() {
2935 let field = match base_t.sty {
2936 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2937 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2938 if !tuple_like { continue }
2940 debug!("tuple struct named {:?}", base_t);
2941 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
2942 let field_ty = self.field_ty(expr.span, field, substs);
2943 private_candidate = Some((base_def.did, field_ty));
2944 if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
2945 self.tcx.check_stability(field.did, expr.id, expr.span);
2952 ty::TyTuple(ref v, _) => {
2954 v.get(idx.node).cloned()
2959 if let Some(field_ty) = field {
2960 autoderef.finalize(lvalue_pref, base);
2961 self.apply_autoderef_adjustment(base.id, autoderefs, base_t);
2965 autoderef.unambiguous_final_ty();
2967 if let Some((did, field_ty)) = private_candidate {
2968 let struct_path = self.tcx().item_path_str(did);
2969 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
2970 self.tcx().sess.span_err(expr.span, &msg);
2974 self.type_error_message(
2978 format!("attempted out-of-bounds tuple index `{}` on \
2983 format!("attempted tuple index `{}` on type `{}`, but the \
2984 type was not a tuple or tuple struct",
2991 self.tcx().types.err
2994 fn report_unknown_field(&self,
2996 variant: &'tcx ty::VariantDef,
2998 skip_fields: &[hir::Field],
3000 let mut err = self.type_error_struct_with_diag(
3002 |actual| match ty.sty {
3003 ty::TyAdt(adt, ..) if adt.is_enum() => {
3004 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3005 "{} `{}::{}` has no field named `{}`",
3006 kind_name, actual, variant.name, field.name.node)
3009 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3010 "{} `{}` has no field named `{}`",
3011 kind_name, actual, field.name.node)
3015 // prevent all specified fields from being suggested
3016 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3017 if let Some(field_name) = Self::suggest_field_name(variant,
3019 skip_fields.collect()) {
3020 err.span_label(field.name.span,
3021 &format!("field does not exist - did you mean `{}`?", field_name));
3024 ty::TyAdt(adt, ..) if adt.is_enum() => {
3025 err.span_label(field.name.span, &format!("`{}::{}` does not have this field",
3029 err.span_label(field.name.span, &format!("`{}` does not have this field", ty));
3036 fn check_expr_struct_fields(&self,
3038 expected: Expectation<'tcx>,
3039 expr_id: ast::NodeId,
3041 variant: &'tcx ty::VariantDef,
3042 ast_fields: &'gcx [hir::Field],
3043 check_completeness: bool) {
3047 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3048 .get(0).cloned().unwrap_or(adt_ty);
3050 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3051 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3052 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3054 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3057 let mut remaining_fields = FxHashMap();
3058 for field in &variant.fields {
3059 remaining_fields.insert(field.name, field);
3062 let mut seen_fields = FxHashMap();
3064 let mut error_happened = false;
3066 // Typecheck each field.
3067 for field in ast_fields {
3068 let final_field_type;
3069 let field_type_hint;
3071 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3072 final_field_type = self.field_ty(field.span, v_field, substs);
3073 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3075 seen_fields.insert(field.name.node, field.span);
3077 // we don't look at stability attributes on
3078 // struct-like enums (yet...), but it's definitely not
3079 // a bug to have construct one.
3080 if adt_kind != ty::AdtKind::Enum {
3081 tcx.check_stability(v_field.did, expr_id, field.span);
3084 error_happened = true;
3085 final_field_type = tcx.types.err;
3086 field_type_hint = tcx.types.err;
3087 if let Some(_) = variant.find_field_named(field.name.node) {
3088 let mut err = struct_span_err!(self.tcx.sess,
3091 "field `{}` specified more than once",
3094 err.span_label(field.name.span, &format!("used more than once"));
3096 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3097 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3102 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3106 // Make sure to give a type to the field even if there's
3107 // an error, so we can continue typechecking
3108 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3109 self.demand_coerce(&field.expr, ty, final_field_type);
3112 // Make sure the programmer specified correct number of fields.
3113 if kind_name == "union" {
3114 if ast_fields.len() != 1 {
3115 tcx.sess.span_err(span, "union expressions should have exactly one field");
3117 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3118 let len = remaining_fields.len();
3120 let mut displayable_field_names = remaining_fields
3122 .map(|x| x.as_str())
3123 .collect::<Vec<_>>();
3125 displayable_field_names.sort();
3127 let truncated_fields_error = if len <= 3 {
3130 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3133 let remaining_fields_names = displayable_field_names.iter().take(3)
3134 .map(|n| format!("`{}`", n))
3135 .collect::<Vec<_>>()
3138 struct_span_err!(tcx.sess, span, E0063,
3139 "missing field{} {}{} in initializer of `{}`",
3140 if remaining_fields.len() == 1 {""} else {"s"},
3141 remaining_fields_names,
3142 truncated_fields_error,
3144 .span_label(span, &format!("missing {}{}",
3145 remaining_fields_names,
3146 truncated_fields_error))
3151 fn check_struct_fields_on_error(&self,
3152 fields: &'gcx [hir::Field],
3153 base_expr: &'gcx Option<P<hir::Expr>>) {
3154 for field in fields {
3155 self.check_expr(&field.expr);
3159 self.check_expr(&base);
3165 pub fn check_struct_path(&self,
3167 node_id: ast::NodeId)
3168 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3169 let path_span = match *qpath {
3170 hir::QPath::Resolved(_, ref path) => path.span,
3171 hir::QPath::TypeRelative(ref qself, _) => qself.span
3173 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3174 let variant = match def {
3176 self.set_tainted_by_errors();
3179 Def::Variant(..) => {
3181 ty::TyAdt(adt, substs) => {
3182 Some((adt.variant_of_def(def), adt.did, substs))
3184 _ => bug!("unexpected type: {:?}", ty.sty)
3187 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3188 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3190 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3191 Some((adt.struct_variant(), adt.did, substs))
3196 _ => bug!("unexpected definition: {:?}", def)
3199 if let Some((variant, did, substs)) = variant {
3200 // Check bounds on type arguments used in the path.
3201 let bounds = self.instantiate_bounds(path_span, did, substs);
3202 let cause = traits::ObligationCause::new(path_span, self.body_id,
3203 traits::ItemObligation(did));
3204 self.add_obligations_for_parameters(cause, &bounds);
3208 struct_span_err!(self.tcx.sess, path_span, E0071,
3209 "expected struct, variant or union type, found {}",
3210 ty.sort_string(self.tcx))
3211 .span_label(path_span, &format!("not a struct"))
3217 fn check_expr_struct(&self,
3219 expected: Expectation<'tcx>,
3221 fields: &'gcx [hir::Field],
3222 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3224 // Find the relevant variant
3225 let (variant, struct_ty) =
3226 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3229 self.check_struct_fields_on_error(fields, base_expr);
3230 return self.tcx.types.err;
3233 let path_span = match *qpath {
3234 hir::QPath::Resolved(_, ref path) => path.span,
3235 hir::QPath::TypeRelative(ref qself, _) => qself.span
3238 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3239 base_expr.is_none());
3240 if let &Some(ref base_expr) = base_expr {
3241 self.check_expr_has_type(base_expr, struct_ty);
3242 match struct_ty.sty {
3243 ty::TyAdt(adt, substs) if adt.is_struct() => {
3244 self.tables.borrow_mut().fru_field_types.insert(
3246 adt.struct_variant().fields.iter().map(|f| {
3247 self.normalize_associated_types_in(
3248 expr.span, &f.ty(self.tcx, substs)
3254 span_err!(self.tcx.sess, base_expr.span, E0436,
3255 "functional record update syntax requires a struct");
3259 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3265 /// If an expression has any sub-expressions that result in a type error,
3266 /// inspecting that expression's type with `ty.references_error()` will return
3267 /// true. Likewise, if an expression is known to diverge, inspecting its
3268 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3269 /// strict, _|_ can appear in the type of an expression that does not,
3270 /// itself, diverge: for example, fn() -> _|_.)
3271 /// Note that inspecting a type's structure *directly* may expose the fact
3272 /// that there are actually multiple representations for `TyError`, so avoid
3273 /// that when err needs to be handled differently.
3274 fn check_expr_with_expectation_and_lvalue_pref(&self,
3275 expr: &'gcx hir::Expr,
3276 expected: Expectation<'tcx>,
3277 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3278 debug!(">> typechecking: expr={:?} expected={:?}",
3281 // Warn for expressions after diverging siblings.
3282 self.warn_if_unreachable(expr.id, expr.span, "expression");
3284 // Hide the outer diverging and has_errors flags.
3285 let old_diverges = self.diverges.get();
3286 let old_has_errors = self.has_errors.get();
3287 self.diverges.set(Diverges::Maybe);
3288 self.has_errors.set(false);
3290 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3292 // Warn for non-block expressions with diverging children.
3295 hir::ExprLoop(..) | hir::ExprWhile(..) |
3296 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3298 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3301 // Any expression that produces a value of type `!` must have diverged
3303 self.diverges.set(self.diverges.get() | Diverges::Always);
3306 // Record the type, which applies it effects.
3307 // We need to do this after the warning above, so that
3308 // we don't warn for the diverging expression itself.
3309 self.write_ty(expr.id, ty);
3311 // Combine the diverging and has_error flags.
3312 self.diverges.set(self.diverges.get() | old_diverges);
3313 self.has_errors.set(self.has_errors.get() | old_has_errors);
3315 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3316 debug!("... {:?}, expected is {:?}", ty, expected);
3321 fn check_expr_kind(&self,
3322 expr: &'gcx hir::Expr,
3323 expected: Expectation<'tcx>,
3324 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3328 hir::ExprBox(ref subexpr) => {
3329 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3331 ty::TyAdt(def, _) if def.is_box()
3332 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3336 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3337 tcx.mk_box(referent_ty)
3340 hir::ExprLit(ref lit) => {
3341 self.check_lit(&lit, expected)
3343 hir::ExprBinary(op, ref lhs, ref rhs) => {
3344 self.check_binop(expr, op, lhs, rhs)
3346 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3347 self.check_binop_assign(expr, op, lhs, rhs)
3349 hir::ExprUnary(unop, ref oprnd) => {
3350 let expected_inner = match unop {
3351 hir::UnNot | hir::UnNeg => {
3358 let lvalue_pref = match unop {
3359 hir::UnDeref => lvalue_pref,
3362 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3366 if !oprnd_t.references_error() {
3369 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3371 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3373 } else if let Some(ok) = self.try_overloaded_deref(
3374 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3375 let method = self.register_infer_ok_obligations(ok);
3376 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3377 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3380 self.type_error_message(expr.span, |actual| {
3381 format!("type `{}` cannot be \
3382 dereferenced", actual)
3384 oprnd_t = tcx.types.err;
3388 oprnd_t = self.structurally_resolved_type(oprnd.span,
3390 let result = self.check_user_unop("!", "not",
3391 tcx.lang_items.not_trait(),
3392 expr, &oprnd, oprnd_t, unop);
3393 // If it's builtin, we can reuse the type, this helps inference.
3394 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3399 oprnd_t = self.structurally_resolved_type(oprnd.span,
3401 let result = self.check_user_unop("-", "neg",
3402 tcx.lang_items.neg_trait(),
3403 expr, &oprnd, oprnd_t, unop);
3404 // If it's builtin, we can reuse the type, this helps inference.
3405 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3413 hir::ExprAddrOf(mutbl, ref oprnd) => {
3414 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3416 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3417 if self.tcx.expr_is_lval(&oprnd) {
3418 // Lvalues may legitimately have unsized types.
3419 // For example, dereferences of a fat pointer and
3420 // the last field of a struct can be unsized.
3421 ExpectHasType(mt.ty)
3423 Expectation::rvalue_hint(self, mt.ty)
3429 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3430 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3432 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3433 if tm.ty.references_error() {
3436 // Note: at this point, we cannot say what the best lifetime
3437 // is to use for resulting pointer. We want to use the
3438 // shortest lifetime possible so as to avoid spurious borrowck
3439 // errors. Moreover, the longest lifetime will depend on the
3440 // precise details of the value whose address is being taken
3441 // (and how long it is valid), which we don't know yet until type
3442 // inference is complete.
3444 // Therefore, here we simply generate a region variable. The
3445 // region inferencer will then select the ultimate value.
3446 // Finally, borrowck is charged with guaranteeing that the
3447 // value whose address was taken can actually be made to live
3448 // as long as it needs to live.
3449 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3450 tcx.mk_ref(region, tm)
3453 hir::ExprPath(ref qpath) => {
3454 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3455 expr.id, expr.span);
3456 let ty = if def != Def::Err {
3457 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3459 self.set_tainted_by_errors();
3463 // We always require that the type provided as the value for
3464 // a type parameter outlives the moment of instantiation.
3465 self.opt_node_ty_substs(expr.id, |item_substs| {
3466 self.add_wf_bounds(&item_substs.substs, expr);
3471 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3472 for output in outputs {
3473 self.check_expr(output);
3475 for input in inputs {
3476 self.check_expr(input);
3480 hir::ExprBreak(destination, ref expr_opt) => {
3481 if let Some(target_id) = destination.target_id.opt_id() {
3482 let (e_ty, e_diverges, cause);
3483 if let Some(ref e) = *expr_opt {
3484 // If this is a break with a value, we need to type-check
3485 // the expression. Get an expected type from the loop context.
3486 let opt_coerce_to = {
3487 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3488 enclosing_breakables.find_breakable(target_id)
3491 .map(|coerce| coerce.expected_ty())
3494 // If the loop context is not a `loop { }`, then break with
3495 // a value is illegal, and `opt_coerce_to` will be `None`.
3496 // Just set expectation to error in that case.
3497 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3499 // Recurse without `enclosing_breakables` borrowed.
3500 e_ty = self.check_expr_with_hint(e, coerce_to);
3501 e_diverges = self.diverges.get();
3502 cause = self.misc(e.span);
3504 // Otherwise, this is a break *without* a value. That's
3505 // always legal, and is equivalent to `break ()`.
3506 e_ty = tcx.mk_nil();
3507 e_diverges = Diverges::Maybe;
3508 cause = self.misc(expr.span);
3511 // Now that we have type-checked `expr_opt`, borrow
3512 // the `enclosing_loops` field and let's coerce the
3513 // type of `expr_opt` into what is expected.
3514 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3515 let ctxt = enclosing_breakables.find_breakable(target_id);
3516 if let Some(ref mut coerce) = ctxt.coerce {
3517 if let Some(ref e) = *expr_opt {
3518 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3520 assert!(e_ty.is_nil());
3521 coerce.coerce_forced_unit(self, &cause, &mut |_| ());
3524 // If `ctxt.coerce` is `None`, we can just ignore
3525 // the type of the expresison. This is because
3526 // either this was a break *without* a value, in
3527 // which case it is always a legal type (`()`), or
3528 // else an error would have been flagged by the
3529 // `loops` pass for using break with an expression
3530 // where you are not supposed to.
3531 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3534 ctxt.may_break = true;
3536 // Otherwise, we failed to find the enclosing loop;
3537 // this can only happen if the `break` was not
3538 // inside a loop at all, which is caught by the
3539 // loop-checking pass.
3540 assert!(self.tcx.sess.err_count() > 0);
3543 // the type of a `break` is always `!`, since it diverges
3546 hir::ExprAgain(_) => { tcx.types.never }
3547 hir::ExprRet(ref expr_opt) => {
3548 if self.ret_coercion.is_none() {
3549 struct_span_err!(self.tcx.sess, expr.span, E0572,
3550 "return statement outside of function body").emit();
3551 } else if let Some(ref e) = *expr_opt {
3552 self.check_return_expr(e);
3554 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3555 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3556 coercion.coerce_forced_unit(self, &cause, &mut |_| ());
3560 hir::ExprAssign(ref lhs, ref rhs) => {
3561 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3564 if !tcx.expr_is_lval(&lhs) {
3566 tcx.sess, expr.span, E0070,
3567 "invalid left-hand side expression")
3570 &format!("left-hand of expression not valid"))
3574 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3576 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3578 if lhs_ty.references_error() || rhs_ty.references_error() {
3584 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3585 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3586 expr.span, expected)
3588 hir::ExprWhile(ref cond, ref body, _) => {
3589 let ctxt = BreakableCtxt {
3590 // cannot use break with a value from a while loop
3595 self.with_breakable_ctxt(expr.id, ctxt, || {
3596 self.check_expr_has_type(&cond, tcx.types.bool);
3597 let cond_diverging = self.diverges.get();
3598 self.check_block_no_value(&body);
3600 // We may never reach the body so it diverging means nothing.
3601 self.diverges.set(cond_diverging);
3606 hir::ExprLoop(ref body, _, source) => {
3607 let coerce = match source {
3608 // you can only use break with a value from a normal `loop { }`
3609 hir::LoopSource::Loop => {
3610 let coerce_to = expected.coercion_target_type(self, body.span);
3611 Some(CoerceMany::new(coerce_to))
3614 hir::LoopSource::WhileLet |
3615 hir::LoopSource::ForLoop => {
3620 let ctxt = BreakableCtxt {
3622 may_break: false, // will get updated if/when we find a `break`
3625 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3626 self.check_block_no_value(&body);
3630 // No way to know whether it's diverging because
3631 // of a `break` or an outer `break` or `return.
3632 self.diverges.set(Diverges::Maybe);
3635 // If we permit break with a value, then result type is
3636 // the LUB of the breaks (possibly ! if none); else, it
3637 // is nil. This makes sense because infinite loops
3638 // (which would have type !) are only possible iff we
3639 // permit break with a value [1].
3640 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3641 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3643 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3644 self.check_match(expr, &discrim, arms, expected, match_src)
3646 hir::ExprClosure(capture, ref decl, body_id, _) => {
3647 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3649 hir::ExprBlock(ref body) => {
3650 self.check_block_with_expected(&body, expected)
3652 hir::ExprCall(ref callee, ref args) => {
3653 self.check_call(expr, &callee, args, expected)
3655 hir::ExprMethodCall(name, ref tps, ref args) => {
3656 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3658 hir::ExprCast(ref e, ref t) => {
3659 // Find the type of `e`. Supply hints based on the type we are casting to,
3661 let t_cast = self.to_ty(t);
3662 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3663 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3664 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3665 let diverges = self.diverges.get();
3667 // Eagerly check for some obvious errors.
3668 if t_expr.references_error() || t_cast.references_error() {
3671 // Defer other checks until we're done type checking.
3672 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3673 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3675 deferred_cast_checks.push(cast_check);
3678 Err(ErrorReported) => {
3684 hir::ExprType(ref e, ref t) => {
3685 let typ = self.to_ty(&t);
3686 self.check_expr_eq_type(&e, typ);
3689 hir::ExprArray(ref args) => {
3690 let uty = expected.to_option(self).and_then(|uty| {
3692 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3697 let element_ty = if !args.is_empty() {
3698 let coerce_to = uty.unwrap_or_else(
3699 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3700 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3701 assert_eq!(self.diverges.get(), Diverges::Maybe);
3703 let e_ty = self.check_expr_with_hint(e, coerce_to);
3704 let cause = self.misc(e.span);
3705 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3707 coerce.complete(self)
3709 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3711 tcx.mk_array(element_ty, args.len())
3713 hir::ExprRepeat(ref element, count) => {
3714 let count = eval_length(self.tcx, count, "repeat count")
3717 let uty = match expected {
3718 ExpectHasType(uty) => {
3720 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3727 let (element_ty, t) = match uty {
3729 self.check_expr_coercable_to_type(&element, uty);
3733 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3734 let element_ty = self.check_expr_has_type(&element, t);
3740 // For [foo, ..n] where n > 1, `foo` must have
3742 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3743 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3746 if element_ty.references_error() {
3749 tcx.mk_array(t, count)
3752 hir::ExprTup(ref elts) => {
3753 let flds = expected.only_has_type(self).and_then(|ty| {
3755 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3760 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3761 let t = match flds {
3762 Some(ref fs) if i < fs.len() => {
3764 self.check_expr_coercable_to_type(&e, ety);
3768 self.check_expr_with_expectation(&e, NoExpectation)
3773 let tuple = tcx.mk_tup(elt_ts_iter, false);
3774 if tuple.references_error() {
3780 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3781 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3783 hir::ExprField(ref base, ref field) => {
3784 self.check_field(expr, lvalue_pref, &base, field)
3786 hir::ExprTupField(ref base, idx) => {
3787 self.check_tup_field(expr, lvalue_pref, &base, idx)
3789 hir::ExprIndex(ref base, ref idx) => {
3790 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3791 let idx_t = self.check_expr(&idx);
3793 if base_t.references_error() {
3795 } else if idx_t.references_error() {
3798 let base_t = self.structurally_resolved_type(expr.span, base_t);
3799 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3800 Some((index_ty, element_ty)) => {
3801 self.demand_coerce(idx, idx_t, index_ty);
3805 let mut err = self.type_error_struct(
3808 format!("cannot index a value of type `{}`",
3812 // Try to give some advice about indexing tuples.
3813 if let ty::TyTuple(..) = base_t.sty {
3814 let mut needs_note = true;
3815 // If the index is an integer, we can show the actual
3816 // fixed expression:
3817 if let hir::ExprLit(ref lit) = idx.node {
3818 if let ast::LitKind::Int(i,
3819 ast::LitIntType::Unsuffixed) = lit.node {
3820 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3821 if let Ok(snip) = snip {
3822 err.span_suggestion(expr.span,
3823 "to access tuple elements, \
3824 use tuple indexing syntax \
3826 format!("{}.{}", snip, i));
3832 err.help("to access tuple elements, use tuple indexing \
3833 syntax (e.g. `tuple.0`)");
3845 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3846 // The newly resolved definition is written into `type_relative_path_defs`.
3847 fn finish_resolving_struct_path(&self,
3850 node_id: ast::NodeId)
3854 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3855 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3856 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3859 hir::QPath::TypeRelative(ref qself, ref segment) => {
3860 let ty = self.to_ty(qself);
3862 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3867 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3870 // Write back the new resolution.
3871 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3878 // Resolve associated value path into a base type and associated constant or method definition.
3879 // The newly resolved definition is written into `type_relative_path_defs`.
3880 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3881 qpath: &'b hir::QPath,
3882 node_id: ast::NodeId,
3884 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3886 let (ty, item_segment) = match *qpath {
3887 hir::QPath::Resolved(ref opt_qself, ref path) => {
3889 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3890 &path.segments[..]);
3892 hir::QPath::TypeRelative(ref qself, ref segment) => {
3893 (self.to_ty(qself), segment)
3896 let item_name = item_segment.name;
3897 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3900 let def = match error {
3901 method::MethodError::PrivateMatch(def) => def,
3904 if item_name != keywords::Invalid.name() {
3905 self.report_method_error(span, ty, item_name, None, error, None);
3911 // Write back the new resolution.
3912 self.tables.borrow_mut().type_relative_path_defs.insert(node_id, def);
3913 (def, Some(ty), slice::ref_slice(&**item_segment))
3916 pub fn check_decl_initializer(&self,
3917 local: &'gcx hir::Local,
3918 init: &'gcx hir::Expr) -> Ty<'tcx>
3920 let ref_bindings = local.pat.contains_ref_binding();
3922 let local_ty = self.local_ty(init.span, local.id);
3923 if let Some(m) = ref_bindings {
3924 // Somewhat subtle: if we have a `ref` binding in the pattern,
3925 // we want to avoid introducing coercions for the RHS. This is
3926 // both because it helps preserve sanity and, in the case of
3927 // ref mut, for soundness (issue #23116). In particular, in
3928 // the latter case, we need to be clear that the type of the
3929 // referent for the reference that results is *equal to* the
3930 // type of the lvalue it is referencing, and not some
3931 // supertype thereof.
3932 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3933 self.demand_eqtype(init.span, init_ty, local_ty);
3936 self.check_expr_coercable_to_type(init, local_ty)
3940 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3941 let t = self.local_ty(local.span, local.id);
3942 self.write_ty(local.id, t);
3944 if let Some(ref init) = local.init {
3945 let init_ty = self.check_decl_initializer(local, &init);
3946 if init_ty.references_error() {
3947 self.write_ty(local.id, init_ty);
3951 self.check_pat(&local.pat, t);
3952 let pat_ty = self.node_ty(local.pat.id);
3953 if pat_ty.references_error() {
3954 self.write_ty(local.id, pat_ty);
3958 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3959 // Don't do all the complex logic below for DeclItem.
3961 hir::StmtDecl(ref decl, id) => {
3963 hir::DeclLocal(_) => {}
3964 hir::DeclItem(_) => {
3970 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
3973 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
3975 // Hide the outer diverging and has_errors flags.
3976 let old_diverges = self.diverges.get();
3977 let old_has_errors = self.has_errors.get();
3978 self.diverges.set(Diverges::Maybe);
3979 self.has_errors.set(false);
3981 let (node_id, _span) = match stmt.node {
3982 hir::StmtDecl(ref decl, id) => {
3983 let span = match decl.node {
3984 hir::DeclLocal(ref l) => {
3985 self.check_decl_local(&l);
3988 hir::DeclItem(_) => {/* ignore for now */
3994 hir::StmtExpr(ref expr, id) => {
3995 // Check with expected type of ()
3996 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3999 hir::StmtSemi(ref expr, id) => {
4000 self.check_expr(&expr);
4005 if self.has_errors.get() {
4006 self.write_error(node_id);
4008 self.write_nil(node_id);
4011 // Combine the diverging and has_error flags.
4012 self.diverges.set(self.diverges.get() | old_diverges);
4013 self.has_errors.set(self.has_errors.get() | old_has_errors);
4016 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4017 let unit = self.tcx.mk_nil();
4018 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4020 // if the block produces a `!` value, that can always be
4021 // (effectively) coerced to unit.
4023 self.demand_suptype(blk.span, unit, ty);
4027 fn check_block_with_expected(&self,
4028 blk: &'gcx hir::Block,
4029 expected: Expectation<'tcx>) -> Ty<'tcx> {
4031 let mut fcx_ps = self.ps.borrow_mut();
4032 let unsafety_state = fcx_ps.recurse(blk);
4033 replace(&mut *fcx_ps, unsafety_state)
4036 // In some cases, blocks have just one exit, but other blocks
4037 // can be targeted by multiple breaks. This cannot happen in
4038 // normal Rust syntax today, but it can happen when we desugar
4039 // a `do catch { ... }` expression.
4043 // 'a: { if true { break 'a Err(()); } Ok(()) }
4045 // Here we would wind up with two coercions, one from
4046 // `Err(())` and the other from the tail expression
4047 // `Ok(())`. If the tail expression is omitted, that's a
4048 // "forced unit" -- unless the block diverges, in which
4049 // case we can ignore the tail expression (e.g., `'a: {
4050 // break 'a 22; }` would not force the type of the block
4052 let tail_expr = blk.expr.as_ref();
4053 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4054 let coerce = if blk.targeted_by_break {
4055 CoerceMany::new(coerce_to_ty)
4057 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4058 Some(e) => ref_slice(e),
4061 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4064 let ctxt = BreakableCtxt {
4065 coerce: Some(coerce),
4069 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4070 for s in &blk.stmts {
4074 // check the tail expression **without** holding the
4075 // `enclosing_breakables` lock below.
4076 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4078 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4079 let mut ctxt = enclosing_breakables.find_breakable(blk.id);
4080 let mut coerce = ctxt.coerce.as_mut().unwrap();
4081 if let Some(tail_expr_ty) = tail_expr_ty {
4082 let tail_expr = tail_expr.unwrap();
4084 &self.misc(tail_expr.span),
4087 self.diverges.get());
4089 // Subtle: if there is no explicit tail expression,
4090 // that is typically equivalent to a tail expression
4091 // of `()` -- except if the block diverges. In that
4092 // case, there is no value supplied from the tail
4093 // expression (assuming there are no other breaks,
4094 // this implies that the type of the block will be
4096 if !self.diverges.get().always() {
4097 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4098 if let Some(expected_ty) = expected.only_has_type(self) {
4099 self.consider_hint_about_removing_semicolon(blk,
4108 let mut ty = ctxt.coerce.unwrap().complete(self);
4110 if self.has_errors.get() || ty.references_error() {
4111 ty = self.tcx.types.err
4114 self.write_ty(blk.id, ty);
4116 *self.ps.borrow_mut() = prev;
4120 /// A common error is to add an extra semicolon:
4123 /// fn foo() -> usize {
4128 /// This routine checks if the final statement in a block is an
4129 /// expression with an explicit semicolon whose type is compatible
4130 /// with `expected_ty`. If so, it suggests removing the semicolon.
4131 fn consider_hint_about_removing_semicolon(&self,
4132 blk: &'gcx hir::Block,
4133 expected_ty: Ty<'tcx>,
4134 err: &mut DiagnosticBuilder) {
4135 // Be helpful when the user wrote `{... expr;}` and
4136 // taking the `;` off is enough to fix the error.
4137 let last_stmt = match blk.stmts.last() {
4141 let last_expr = match last_stmt.node {
4142 hir::StmtSemi(ref e, _) => e,
4145 let last_expr_ty = self.expr_ty(last_expr);
4146 if self.can_sub_types(last_expr_ty, expected_ty).is_err() {
4149 let original_span = original_sp(last_stmt.span, blk.span);
4150 let span_semi = Span {
4151 lo: original_span.hi - BytePos(1),
4152 hi: original_span.hi,
4153 ctxt: original_span.ctxt,
4155 err.span_help(span_semi, "consider removing this semicolon:");
4158 // Instantiates the given path, which must refer to an item with the given
4159 // number of type parameters and type.
4160 pub fn instantiate_value_path(&self,
4161 segments: &[hir::PathSegment],
4162 opt_self_ty: Option<Ty<'tcx>>,
4165 node_id: ast::NodeId)
4167 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4172 // We need to extract the type parameters supplied by the user in
4173 // the path `path`. Due to the current setup, this is a bit of a
4174 // tricky-process; the problem is that resolve only tells us the
4175 // end-point of the path resolution, and not the intermediate steps.
4176 // Luckily, we can (at least for now) deduce the intermediate steps
4177 // just from the end-point.
4179 // There are basically four cases to consider:
4181 // 1. Reference to a constructor of enum variant or struct:
4183 // struct Foo<T>(...)
4184 // enum E<T> { Foo(...) }
4186 // In these cases, the parameters are declared in the type
4189 // 2. Reference to a fn item or a free constant:
4193 // In this case, the path will again always have the form
4194 // `a::b::foo::<T>` where only the final segment should have
4195 // type parameters. However, in this case, those parameters are
4196 // declared on a value, and hence are in the `FnSpace`.
4198 // 3. Reference to a method or an associated constant:
4200 // impl<A> SomeStruct<A> {
4204 // Here we can have a path like
4205 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4206 // may appear in two places. The penultimate segment,
4207 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4208 // final segment, `foo::<B>` contains parameters in fn space.
4210 // 4. Reference to a local variable
4212 // Local variables can't have any type parameters.
4214 // The first step then is to categorize the segments appropriately.
4216 assert!(!segments.is_empty());
4218 let mut ufcs_associated = None;
4219 let mut type_segment = None;
4220 let mut fn_segment = None;
4222 // Case 1. Reference to a struct/variant constructor.
4223 Def::StructCtor(def_id, ..) |
4224 Def::VariantCtor(def_id, ..) => {
4225 // Everything but the final segment should have no
4226 // parameters at all.
4227 let mut generics = self.tcx.item_generics(def_id);
4228 if let Some(def_id) = generics.parent {
4229 // Variant and struct constructors use the
4230 // generics of their parent type definition.
4231 generics = self.tcx.item_generics(def_id);
4233 type_segment = Some((segments.last().unwrap(), generics));
4236 // Case 2. Reference to a top-level value.
4238 Def::Const(def_id) |
4239 Def::Static(def_id, _) => {
4240 fn_segment = Some((segments.last().unwrap(),
4241 self.tcx.item_generics(def_id)));
4244 // Case 3. Reference to a method or associated const.
4245 Def::Method(def_id) |
4246 Def::AssociatedConst(def_id) => {
4247 let container = self.tcx.associated_item(def_id).container;
4249 ty::TraitContainer(trait_did) => {
4250 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4252 ty::ImplContainer(_) => {}
4255 let generics = self.tcx.item_generics(def_id);
4256 if segments.len() >= 2 {
4257 let parent_generics = self.tcx.item_generics(generics.parent.unwrap());
4258 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4260 // `<T>::assoc` will end up here, and so can `T::assoc`.
4261 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4262 ufcs_associated = Some((container, self_ty));
4264 fn_segment = Some((segments.last().unwrap(), generics));
4267 // Case 4. Local variable, no generics.
4268 Def::Local(..) | Def::Upvar(..) => {}
4270 _ => bug!("unexpected definition: {:?}", def),
4273 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4275 // Now that we have categorized what space the parameters for each
4276 // segment belong to, let's sort out the parameters that the user
4277 // provided (if any) into their appropriate spaces. We'll also report
4278 // errors if type parameters are provided in an inappropriate place.
4279 let poly_segments = type_segment.is_some() as usize +
4280 fn_segment.is_some() as usize;
4281 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4284 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4285 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4286 let ty = self.local_ty(span, nid);
4287 let ty = self.normalize_associated_types_in(span, &ty);
4288 self.write_ty(node_id, ty);
4289 self.write_substs(node_id, ty::ItemSubsts {
4290 substs: self.tcx.intern_substs(&[])
4297 // Now we have to compare the types that the user *actually*
4298 // provided against the types that were *expected*. If the user
4299 // did not provide any types, then we want to substitute inference
4300 // variables. If the user provided some types, we may still need
4301 // to add defaults. If the user provided *too many* types, that's
4303 self.check_path_parameter_count(span, &mut type_segment);
4304 self.check_path_parameter_count(span, &mut fn_segment);
4306 let (fn_start, has_self) = match (type_segment, fn_segment) {
4307 (_, Some((_, generics))) => {
4308 (generics.parent_count(), generics.has_self)
4310 (Some((_, generics)), None) => {
4311 (generics.own_count(), generics.has_self)
4313 (None, None) => (0, false)
4315 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4316 let mut i = def.index as usize;
4318 let segment = if i < fn_start {
4319 i -= has_self as usize;
4325 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4326 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4327 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4331 if let Some(lifetime) = lifetimes.get(i) {
4332 AstConv::ast_region_to_region(self, lifetime, Some(def))
4334 self.re_infer(span, Some(def)).unwrap()
4337 let mut i = def.index as usize;
4339 let segment = if i < fn_start {
4340 // Handle Self first, so we can adjust the index to match the AST.
4341 if has_self && i == 0 {
4342 return opt_self_ty.unwrap_or_else(|| {
4343 self.type_var_for_def(span, def, substs)
4346 i -= has_self as usize;
4352 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4353 Some(&hir::AngleBracketedParameters(ref data)) => {
4354 (&data.types[..], data.infer_types)
4356 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4357 None => (&[][..], true)
4360 // Skip over the lifetimes in the same segment.
4361 if let Some((_, generics)) = segment {
4362 i -= generics.regions.len();
4365 if let Some(ast_ty) = types.get(i) {
4366 // A provided type parameter.
4368 } else if !infer_types && def.has_default {
4369 // No type parameter provided, but a default exists.
4370 let default = self.tcx.item_type(def.def_id);
4373 default.subst_spanned(self.tcx, substs, Some(span))
4376 // No type parameters were provided, we can infer all.
4377 // This can also be reached in some error cases:
4378 // We prefer to use inference variables instead of
4379 // TyError to let type inference recover somewhat.
4380 self.type_var_for_def(span, def, substs)
4384 // The things we are substituting into the type should not contain
4385 // escaping late-bound regions, and nor should the base type scheme.
4386 let ty = self.tcx.item_type(def.def_id());
4387 assert!(!substs.has_escaping_regions());
4388 assert!(!ty.has_escaping_regions());
4390 // Add all the obligations that are required, substituting and
4391 // normalized appropriately.
4392 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4393 self.add_obligations_for_parameters(
4394 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4397 // Substitute the values for the type parameters into the type of
4398 // the referenced item.
4399 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4401 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4402 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4403 // is inherent, there is no `Self` parameter, instead, the impl needs
4404 // type parameters, which we can infer by unifying the provided `Self`
4405 // with the substituted impl type.
4406 let ty = self.tcx.item_type(impl_def_id);
4408 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4409 match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
4410 Ok(ok) => self.register_infer_ok_obligations(ok),
4413 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4420 debug!("instantiate_value_path: type of {:?} is {:?}",
4423 self.write_substs(node_id, ty::ItemSubsts {
4429 /// Report errors if the provided parameters are too few or too many.
4430 fn check_path_parameter_count(&self,
4432 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4433 let (lifetimes, types, infer_types, bindings) = {
4434 match segment.map(|(s, _)| &s.parameters) {
4435 Some(&hir::AngleBracketedParameters(ref data)) => {
4436 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4438 Some(&hir::ParenthesizedParameters(_)) => {
4439 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4441 None => (&[][..], &[][..], true, &[][..])
4445 let count_lifetime_params = |n| {
4446 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4448 let count_type_params = |n| {
4449 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4452 // Check provided lifetime parameters.
4453 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4454 if lifetimes.len() > lifetime_defs.len() {
4455 let expected_text = count_lifetime_params(lifetime_defs.len());
4456 let actual_text = count_lifetime_params(lifetimes.len());
4457 struct_span_err!(self.tcx.sess, span, E0088,
4458 "too many lifetime parameters provided: \
4459 expected at most {}, found {}",
4460 expected_text, actual_text)
4461 .span_label(span, &format!("expected {}", expected_text))
4463 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4464 let expected_text = count_lifetime_params(lifetime_defs.len());
4465 let actual_text = count_lifetime_params(lifetimes.len());
4466 struct_span_err!(self.tcx.sess, span, E0090,
4467 "too few lifetime parameters provided: \
4468 expected {}, found {}",
4469 expected_text, actual_text)
4470 .span_label(span, &format!("expected {}", expected_text))
4474 // The case where there is not enough lifetime parameters is not checked,
4475 // because this is not possible - a function never takes lifetime parameters.
4476 // See discussion for Pull Request 36208.
4478 // Check provided type parameters.
4479 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4480 if generics.parent.is_none() {
4481 &generics.types[generics.has_self as usize..]
4486 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4487 if types.len() > type_defs.len() {
4488 let span = types[type_defs.len()].span;
4489 let expected_text = count_type_params(type_defs.len());
4490 let actual_text = count_type_params(types.len());
4491 struct_span_err!(self.tcx.sess, span, E0087,
4492 "too many type parameters provided: \
4493 expected at most {}, found {}",
4494 expected_text, actual_text)
4495 .span_label(span, &format!("expected {}", expected_text))
4498 // To prevent derived errors to accumulate due to extra
4499 // type parameters, we force instantiate_value_path to
4500 // use inference variables instead of the provided types.
4502 } else if !infer_types && types.len() < required_len {
4503 let expected_text = count_type_params(required_len);
4504 let actual_text = count_type_params(types.len());
4505 struct_span_err!(self.tcx.sess, span, E0089,
4506 "too few type parameters provided: \
4507 expected {}, found {}",
4508 expected_text, actual_text)
4509 .span_label(span, &format!("expected {}", expected_text))
4513 if !bindings.is_empty() {
4514 span_err!(self.tcx.sess, bindings[0].span, E0182,
4515 "unexpected binding of associated item in expression path \
4516 (only allowed in type paths)");
4520 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4522 where F: Fn() -> Ty<'tcx>
4524 let mut ty = self.resolve_type_vars_with_obligations(ty);
4527 let alternative = f();
4530 if alternative.is_ty_var() || alternative.references_error() {
4531 if !self.is_tainted_by_errors() {
4532 self.type_error_message(sp, |_actual| {
4533 "the type of this value must be known in this context".to_string()
4536 self.demand_suptype(sp, self.tcx.types.err, ty);
4537 ty = self.tcx.types.err;
4539 self.demand_suptype(sp, alternative, ty);
4547 // Resolves `typ` by a single level if `typ` is a type variable. If no
4548 // resolution is possible, then an error is reported.
4549 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4550 self.structurally_resolve_type_or_else(sp, ty, || {
4555 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4556 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4557 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4560 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4561 index = enclosing_breakables.stack.len();
4562 enclosing_breakables.by_id.insert(id, index);
4563 enclosing_breakables.stack.push(ctxt);
4567 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4568 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4569 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4570 enclosing_breakables.stack.pop().expect("missing breakable context")
4576 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4577 generics: &hir::Generics,
4579 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4580 generics.ty_params.len(), ty);
4582 // make a vector of booleans initially false, set to true when used
4583 if generics.ty_params.is_empty() { return; }
4584 let mut tps_used = vec![false; generics.ty_params.len()];
4586 for leaf_ty in ty.walk() {
4587 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4588 debug!("Found use of ty param num {}", idx);
4589 tps_used[idx as usize - generics.lifetimes.len()] = true;
4593 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4595 struct_span_err!(tcx.sess, param.span, E0091,
4596 "type parameter `{}` is unused",
4598 .span_label(param.span, &format!("unused type parameter"))