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.node_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::autoderef::Autoderef;
81 use self::callee::DeferredCallResolution;
82 use self::coercion::{CoerceMany, DynamicCoerceMany};
83 pub use self::compare_method::{compare_impl_method, compare_const_impl};
84 use self::method::MethodCallee;
85 use self::TupleArgumentsFlag::*;
88 use hir::def::{Def, CtorKind};
89 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
90 use rustc_back::slice::ref_slice;
91 use namespace::Namespace;
92 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
93 use rustc::infer::type_variable::{TypeVariableOrigin};
94 use rustc::middle::region;
95 use rustc::ty::subst::{Kind, Subst, Substs};
96 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
97 use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
98 use rustc::ty::{self, Ty, TyCtxt, Visibility};
99 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
100 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
101 use rustc::ty::maps::Providers;
102 use rustc::ty::util::{Representability, IntTypeExt};
103 use errors::{DiagnosticBuilder, DiagnosticId};
104 use require_c_abi_if_variadic;
105 use session::{CompileIncomplete, Session};
108 use util::common::{ErrorReported, indenter};
109 use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, NodeMap};
111 use std::cell::{Cell, RefCell, Ref, RefMut};
113 use std::collections::hash_map::Entry;
115 use std::fmt::Display;
116 use std::mem::replace;
117 use std::ops::{self, Deref};
118 use syntax::abi::Abi;
121 use syntax::codemap::{self, original_sp, Spanned};
122 use syntax::feature_gate::{GateIssue, emit_feature_err};
124 use syntax::symbol::{Symbol, InternedString, keywords};
125 use syntax::util::lev_distance::find_best_match_for_name;
126 use syntax_pos::{self, BytePos, Span, MultiSpan};
128 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
129 use rustc::hir::itemlikevisit::ItemLikeVisitor;
130 use rustc::hir::map::Node;
131 use rustc::hir::{self, PatKind};
132 use rustc::middle::lang_items;
133 use rustc_back::slice;
134 use rustc_const_math::ConstInt;
150 mod generator_interior;
154 /// A wrapper for InferCtxt's `in_progress_tables` field.
155 #[derive(Copy, Clone)]
156 struct MaybeInProgressTables<'a, 'tcx: 'a> {
157 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
160 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
161 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
162 match self.maybe_tables {
163 Some(tables) => tables.borrow(),
165 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
170 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
171 match self.maybe_tables {
172 Some(tables) => tables.borrow_mut(),
174 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
181 /// closures defined within the function. For example:
184 /// bar(move|| { ... })
187 /// Here, the function `foo()` and the closure passed to
188 /// `bar()` will each have their own `FnCtxt`, but they will
189 /// share the inherited fields.
190 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
191 infcx: InferCtxt<'a, 'gcx, 'tcx>,
193 tables: MaybeInProgressTables<'a, 'tcx>,
195 locals: RefCell<NodeMap<Ty<'tcx>>>,
197 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
199 // When we process a call like `c()` where `c` is a closure type,
200 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
201 // `FnOnce` closure. In that case, we defer full resolution of the
202 // call until upvar inference can kick in and make the
203 // decision. We keep these deferred resolutions grouped by the
204 // def-id of the closure, so that once we decide, we can easily go
205 // back and process them.
206 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
208 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
210 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
212 // Anonymized types found in explicit return types and their
213 // associated fresh inference variable. Writeback resolves these
214 // variables to get the concrete type, which can be used to
215 // deanonymize TyAnon, after typeck is done with all functions.
216 anon_types: RefCell<NodeMap<Ty<'tcx>>>,
218 /// Each type parameter has an implicit region bound that
219 /// indicates it must outlive at least the function body (the user
220 /// may specify stronger requirements). This field indicates the
221 /// region of the callee. If it is `None`, then the parameter
222 /// environment is for an item or something where the "callee" is
224 implicit_region_bound: Option<ty::Region<'tcx>>,
226 body_id: Option<hir::BodyId>,
229 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
230 type Target = InferCtxt<'a, 'gcx, 'tcx>;
231 fn deref(&self) -> &Self::Target {
236 /// When type-checking an expression, we propagate downward
237 /// whatever type hint we are able in the form of an `Expectation`.
238 #[derive(Copy, Clone, Debug)]
239 pub enum Expectation<'tcx> {
240 /// We know nothing about what type this expression should have.
243 /// This expression is an `if` condition, it must resolve to `bool`.
246 /// This expression should have the type given (or some subtype)
247 ExpectHasType(Ty<'tcx>),
249 /// This expression will be cast to the `Ty`
250 ExpectCastableToType(Ty<'tcx>),
252 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
253 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
254 ExpectRvalueLikeUnsized(Ty<'tcx>),
257 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
258 // Disregard "castable to" expectations because they
259 // can lead us astray. Consider for example `if cond
260 // {22} else {c} as u8` -- if we propagate the
261 // "castable to u8" constraint to 22, it will pick the
262 // type 22u8, which is overly constrained (c might not
263 // be a u8). In effect, the problem is that the
264 // "castable to" expectation is not the tightest thing
265 // we can say, so we want to drop it in this case.
266 // The tightest thing we can say is "must unify with
267 // else branch". Note that in the case of a "has type"
268 // constraint, this limitation does not hold.
270 // If the expected type is just a type variable, then don't use
271 // an expected type. Otherwise, we might write parts of the type
272 // when checking the 'then' block which are incompatible with the
274 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
276 ExpectHasType(ety) => {
277 let ety = fcx.shallow_resolve(ety);
278 if !ety.is_ty_var() {
284 ExpectRvalueLikeUnsized(ety) => {
285 ExpectRvalueLikeUnsized(ety)
291 /// Provide an expectation for an rvalue expression given an *optional*
292 /// hint, which is not required for type safety (the resulting type might
293 /// be checked higher up, as is the case with `&expr` and `box expr`), but
294 /// is useful in determining the concrete type.
296 /// The primary use case is where the expected type is a fat pointer,
297 /// like `&[isize]`. For example, consider the following statement:
299 /// let x: &[isize] = &[1, 2, 3];
301 /// In this case, the expected type for the `&[1, 2, 3]` expression is
302 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
303 /// expectation `ExpectHasType([isize])`, that would be too strong --
304 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
305 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
306 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
307 /// which still is useful, because it informs integer literals and the like.
308 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
309 /// for examples of where this comes up,.
310 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
311 match fcx.tcx.struct_tail(ty).sty {
312 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
313 ExpectRvalueLikeUnsized(ty)
315 _ => ExpectHasType(ty)
319 // Resolves `expected` by a single level if it is a variable. If
320 // there is no expected type or resolution is not possible (e.g.,
321 // no constraints yet present), just returns `None`.
322 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
324 NoExpectation => NoExpectation,
325 ExpectIfCondition => ExpectIfCondition,
326 ExpectCastableToType(t) => {
327 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
329 ExpectHasType(t) => {
330 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
332 ExpectRvalueLikeUnsized(t) => {
333 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
338 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
339 match self.resolve(fcx) {
340 NoExpectation => None,
341 ExpectIfCondition => Some(fcx.tcx.types.bool),
342 ExpectCastableToType(ty) |
344 ExpectRvalueLikeUnsized(ty) => Some(ty),
348 /// It sometimes happens that we want to turn an expectation into
349 /// a **hard constraint** (i.e., something that must be satisfied
350 /// for the program to type-check). `only_has_type` will return
351 /// such a constraint, if it exists.
352 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
353 match self.resolve(fcx) {
354 ExpectHasType(ty) => Some(ty),
355 ExpectIfCondition => Some(fcx.tcx.types.bool),
356 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
360 /// Like `only_has_type`, but instead of returning `None` if no
361 /// hard constraint exists, creates a fresh type variable.
362 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
363 self.only_has_type(fcx)
364 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
368 #[derive(Copy, Clone)]
369 pub struct UnsafetyState {
370 pub def: ast::NodeId,
371 pub unsafety: hir::Unsafety,
372 pub unsafe_push_count: u32,
377 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
378 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
381 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
382 match self.unsafety {
383 // If this unsafe, then if the outer function was already marked as
384 // unsafe we shouldn't attribute the unsafe'ness to the block. This
385 // way the block can be warned about instead of ignoring this
386 // extraneous block (functions are never warned about).
387 hir::Unsafety::Unsafe if self.from_fn => *self,
390 let (unsafety, def, count) = match blk.rules {
391 hir::PushUnsafeBlock(..) =>
392 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
393 hir::PopUnsafeBlock(..) =>
394 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
395 hir::UnsafeBlock(..) =>
396 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
398 (unsafety, self.def, self.unsafe_push_count),
402 unsafe_push_count: count,
409 #[derive(Debug, Copy, Clone)]
415 /// Tracks whether executing a node may exit normally (versus
416 /// return/break/panic, which "diverge", leaving dead code in their
417 /// wake). Tracked semi-automatically (through type variables marked
418 /// as diverging), with some manual adjustments for control-flow
419 /// primitives (approximating a CFG).
420 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
422 /// Potentially unknown, some cases converge,
423 /// others require a CFG to determine them.
426 /// Definitely known to diverge and therefore
427 /// not reach the next sibling or its parent.
430 /// Same as `Always` but with a reachability
431 /// warning already emitted
435 // Convenience impls for combinig `Diverges`.
437 impl ops::BitAnd for Diverges {
439 fn bitand(self, other: Self) -> Self {
440 cmp::min(self, other)
444 impl ops::BitOr for Diverges {
446 fn bitor(self, other: Self) -> Self {
447 cmp::max(self, other)
451 impl ops::BitAndAssign for Diverges {
452 fn bitand_assign(&mut self, other: Self) {
453 *self = *self & other;
457 impl ops::BitOrAssign for Diverges {
458 fn bitor_assign(&mut self, other: Self) {
459 *self = *self | other;
464 fn always(self) -> bool {
465 self >= Diverges::Always
469 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
472 // this is `null` for loops where break with a value is illegal,
473 // such as `while`, `for`, and `while let`
474 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
477 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
478 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
479 by_id: NodeMap<usize>,
482 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
483 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
484 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
485 bug!("could not find enclosing breakable with id {}", target_id);
491 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
492 body_id: ast::NodeId,
494 /// The parameter environment used for proving trait obligations
495 /// in this function. This can change when we descend into
496 /// closures (as they bring new things into scope), hence it is
497 /// not part of `Inherited` (as of the time of this writing,
498 /// closures do not yet change the environment, but they will
500 param_env: ty::ParamEnv<'tcx>,
502 // Number of errors that had been reported when we started
503 // checking this function. On exit, if we find that *more* errors
504 // have been reported, we will skip regionck and other work that
505 // expects the types within the function to be consistent.
506 err_count_on_creation: usize,
508 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
510 yield_ty: Option<Ty<'tcx>>,
512 ps: RefCell<UnsafetyState>,
514 /// Whether the last checked node generates a divergence (e.g.,
515 /// `return` will set this to Always). In general, when entering
516 /// an expression or other node in the tree, the initial value
517 /// indicates whether prior parts of the containing expression may
518 /// have diverged. It is then typically set to `Maybe` (and the
519 /// old value remembered) for processing the subparts of the
520 /// current expression. As each subpart is processed, they may set
521 /// the flag to `Always` etc. Finally, at the end, we take the
522 /// result and "union" it with the original value, so that when we
523 /// return the flag indicates if any subpart of the the parent
524 /// expression (up to and including this part) has diverged. So,
525 /// if you read it after evaluating a subexpression `X`, the value
526 /// you get indicates whether any subexpression that was
527 /// evaluating up to and including `X` diverged.
529 /// We use this flag for two purposes:
531 /// - To warn about unreachable code: if, after processing a
532 /// sub-expression but before we have applied the effects of the
533 /// current node, we see that the flag is set to `Always`, we
534 /// can issue a warning. This corresponds to something like
535 /// `foo(return)`; we warn on the `foo()` expression. (We then
536 /// update the flag to `WarnedAlways` to suppress duplicate
537 /// reports.) Similarly, if we traverse to a fresh statement (or
538 /// tail expression) from a `Always` setting, we will issue a
539 /// warning. This corresponds to something like `{return;
540 /// foo();}` or `{return; 22}`, where we would warn on the
543 /// - To permit assignment into a local variable or other lvalue
544 /// (including the "return slot") of type `!`. This is allowed
545 /// if **either** the type of value being assigned is `!`, which
546 /// means the current code is dead, **or** the expression's
547 /// diverging flag is true, which means that a diverging value was
548 /// wrapped (e.g., `let x: ! = foo(return)`).
550 /// To repeat the last point: an expression represents dead-code
551 /// if, after checking it, **either** its type is `!` OR the
552 /// diverges flag is set to something other than `Maybe`.
553 diverges: Cell<Diverges>,
555 /// Whether any child nodes have any type errors.
556 has_errors: Cell<bool>,
558 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
560 inh: &'a Inherited<'a, 'gcx, 'tcx>,
563 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
564 type Target = Inherited<'a, 'gcx, 'tcx>;
565 fn deref(&self) -> &Self::Target {
570 /// Helper type of a temporary returned by Inherited::build(...).
571 /// Necessary because we can't write the following bound:
572 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
573 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
574 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
578 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
579 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
580 -> InheritedBuilder<'a, 'gcx, 'tcx> {
581 let hir_id_root = if def_id.is_local() {
582 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
583 let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
584 DefId::local(hir_id.owner)
590 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
596 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
597 fn enter<F, R>(&'tcx mut self, f: F) -> R
598 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
600 let def_id = self.def_id;
601 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
605 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
606 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
608 let item_id = tcx.hir.as_local_node_id(def_id);
609 let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
610 let implicit_region_bound = body_id.map(|body_id| {
611 let body = tcx.hir.body(body_id);
612 tcx.mk_region(ty::ReScope(region::Scope::CallSite(body.value.hir_id.local_id)))
616 tables: MaybeInProgressTables {
617 maybe_tables: infcx.in_progress_tables,
620 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
621 locals: RefCell::new(NodeMap()),
622 deferred_call_resolutions: RefCell::new(DefIdMap()),
623 deferred_cast_checks: RefCell::new(Vec::new()),
624 deferred_generator_interiors: RefCell::new(Vec::new()),
625 anon_types: RefCell::new(NodeMap()),
626 implicit_region_bound,
631 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
632 debug!("register_predicate({:?})", obligation);
633 if obligation.has_escaping_regions() {
634 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
639 .register_predicate_obligation(self, obligation);
642 fn register_predicates<I>(&self, obligations: I)
643 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>> {
644 for obligation in obligations {
645 self.register_predicate(obligation);
649 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
650 self.register_predicates(infer_ok.obligations);
654 fn normalize_associated_types_in<T>(&self,
656 body_id: ast::NodeId,
657 param_env: ty::ParamEnv<'tcx>,
659 where T : TypeFoldable<'tcx>
661 let ok = self.normalize_associated_types_in_as_infer_ok(span, body_id, param_env, value);
662 self.register_infer_ok_obligations(ok)
665 fn normalize_associated_types_in_as_infer_ok<T>(&self,
667 body_id: ast::NodeId,
668 param_env: ty::ParamEnv<'tcx>,
671 where T : TypeFoldable<'tcx>
673 debug!("normalize_associated_types_in(value={:?})", value);
674 let mut selcx = traits::SelectionContext::new(self);
675 let cause = ObligationCause::misc(span, body_id);
676 let traits::Normalized { value, obligations } =
677 traits::normalize(&mut selcx, param_env, cause, value);
678 debug!("normalize_associated_types_in: result={:?} predicates={:?}",
681 InferOk { value, obligations }
684 /// Replace any late-bound regions bound in `value` with
685 /// free variants attached to `all_outlive_scope`.
686 fn liberate_late_bound_regions<T>(&self,
687 all_outlive_scope: DefId,
688 value: &ty::Binder<T>)
690 where T: TypeFoldable<'tcx>
692 self.tcx.replace_late_bound_regions(value, |br| {
693 self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
694 scope: all_outlive_scope,
701 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
703 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
704 fn visit_item(&mut self, i: &'tcx hir::Item) {
705 check_item_type(self.tcx, i);
707 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
708 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
711 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
712 tcx.sess.track_errors(|| {
713 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
714 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
718 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
719 tcx.sess.track_errors(|| {
720 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
724 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
725 tcx.typeck_item_bodies(LOCAL_CRATE)
728 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
729 -> Result<(), CompileIncomplete>
731 debug_assert!(crate_num == LOCAL_CRATE);
732 Ok(tcx.sess.track_errors(|| {
733 for body_owner_def_id in tcx.body_owners() {
734 ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
739 pub fn provide(providers: &mut Providers) {
740 *providers = Providers {
752 fn generator_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
754 -> Option<ty::PolyGenSig<'tcx>> {
755 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
756 let hir_id = tcx.hir.node_to_hir_id(node_id);
757 tcx.typeck_tables_of(def_id).generator_sigs()[hir_id].map(|s| ty::Binder(s))
760 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
763 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
764 let hir_id = tcx.hir.node_to_hir_id(node_id);
765 tcx.typeck_tables_of(def_id).closure_kinds()[hir_id].0
768 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
770 -> Option<ty::Destructor> {
771 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
774 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
775 /// with information about it's body-id and fn-decl (if any). Otherwise,
778 /// If this function returns "some", then `typeck_tables(def_id)` will
779 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
780 /// may not succeed. In some cases where this function returns `None`
781 /// (notably closures), `typeck_tables(def_id)` would wind up
782 /// redirecting to the owning function.
783 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
785 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
787 match tcx.hir.get(id) {
788 hir::map::NodeItem(item) => {
790 hir::ItemConst(_, body) |
791 hir::ItemStatic(_, _, body) =>
793 hir::ItemFn(ref decl, .., body) =>
794 Some((body, Some(decl))),
799 hir::map::NodeTraitItem(item) => {
801 hir::TraitItemKind::Const(_, Some(body)) =>
803 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
804 Some((body, Some(&sig.decl))),
809 hir::map::NodeImplItem(item) => {
811 hir::ImplItemKind::Const(_, body) =>
813 hir::ImplItemKind::Method(ref sig, body) =>
814 Some((body, Some(&sig.decl))),
819 hir::map::NodeExpr(expr) => {
820 // FIXME(eddyb) Closures should have separate
821 // function definition IDs and expression IDs.
822 // Type-checking should not let closures get
823 // this far in a constant position.
824 // Assume that everything other than closures
825 // is a constant "initializer" expression.
827 hir::ExprClosure(..) =>
830 Some((hir::BodyId { node_id: expr.id }, None)),
837 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
840 // Closures' tables come from their outermost function,
841 // as they are part of the same "inference environment".
842 let outer_def_id = tcx.closure_base_def_id(def_id);
843 if outer_def_id != def_id {
844 return tcx.has_typeck_tables(outer_def_id);
847 let id = tcx.hir.as_local_node_id(def_id).unwrap();
848 primary_body_of(tcx, id).is_some()
851 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
854 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
857 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
859 -> &'tcx ty::TypeckTables<'tcx> {
860 // Closures' tables come from their outermost function,
861 // as they are part of the same "inference environment".
862 let outer_def_id = tcx.closure_base_def_id(def_id);
863 if outer_def_id != def_id {
864 return tcx.typeck_tables_of(outer_def_id);
867 let id = tcx.hir.as_local_node_id(def_id).unwrap();
868 let span = tcx.hir.span(id);
870 // Figure out what primary body this item has.
871 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
872 span_bug!(span, "can't type-check body of {:?}", def_id);
874 let body = tcx.hir.body(body_id);
876 let tables = Inherited::build(tcx, def_id).enter(|inh| {
877 let param_env = tcx.param_env(def_id);
878 let fcx = if let Some(decl) = fn_decl {
879 let fn_sig = tcx.fn_sig(def_id);
881 check_abi(tcx, span, fn_sig.abi());
883 // Compute the fty from point of view of inside fn.
885 inh.liberate_late_bound_regions(def_id, &fn_sig);
887 inh.normalize_associated_types_in(body.value.span,
892 check_fn(&inh, param_env, fn_sig, decl, id, body, false).0
894 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
895 let expected_type = tcx.type_of(def_id);
896 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
897 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
899 // Gather locals in statics (because of block expressions).
900 // This is technically unnecessary because locals in static items are forbidden,
901 // but prevents type checking from blowing up before const checking can properly
903 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
905 fcx.check_expr_coercable_to_type(&body.value, expected_type);
910 fcx.select_all_obligations_and_apply_defaults();
911 fcx.closure_analyze(body);
912 fcx.select_obligations_where_possible();
914 fcx.resolve_generator_interiors(def_id);
915 fcx.select_all_obligations_or_error();
917 if fn_decl.is_some() {
918 fcx.regionck_fn(id, body);
920 fcx.regionck_expr(body);
923 fcx.resolve_type_vars_in_body(body)
926 // Consistency check our TypeckTables instance can hold all ItemLocalIds
927 // it will need to hold.
928 assert_eq!(tables.local_id_root,
929 Some(DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner)));
933 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
934 if !tcx.sess.target.target.is_abi_supported(abi) {
935 struct_span_err!(tcx.sess, span, E0570,
936 "The ABI `{}` is not supported for the current target", abi).emit()
940 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
941 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
944 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
945 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
948 // infer the variable's type
949 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
950 self.fcx.locals.borrow_mut().insert(nid, var_ty);
954 // take type that the user specified
955 self.fcx.locals.borrow_mut().insert(nid, typ);
962 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
963 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
964 NestedVisitorMap::None
967 // Add explicitly-declared locals.
968 fn visit_local(&mut self, local: &'gcx hir::Local) {
969 let o_ty = match local.ty {
970 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
973 self.assign(local.span, local.id, o_ty);
974 debug!("Local variable {:?} is assigned type {}",
976 self.fcx.ty_to_string(
977 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
978 intravisit::walk_local(self, local);
981 // Add pattern bindings.
982 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
983 if let PatKind::Binding(_, _, ref path1, _) = p.node {
984 let var_ty = self.assign(p.span, p.id, None);
986 self.fcx.require_type_is_sized(var_ty, p.span,
987 traits::VariableType(p.id));
989 debug!("Pattern binding {} is assigned to {} with type {:?}",
991 self.fcx.ty_to_string(
992 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
995 intravisit::walk_pat(self, p);
998 // Don't descend into the bodies of nested closures
999 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
1000 _: hir::BodyId, _: Span, _: ast::NodeId) { }
1003 /// Helper used for fns and closures. Does the grungy work of checking a function
1004 /// body and returns the function context used for that purpose, since in the case of a fn item
1005 /// there is still a bit more to do.
1008 /// * inherited: other fields inherited from the enclosing fn (if any)
1009 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1010 param_env: ty::ParamEnv<'tcx>,
1011 fn_sig: ty::FnSig<'tcx>,
1012 decl: &'gcx hir::FnDecl,
1014 body: &'gcx hir::Body,
1015 can_be_generator: bool)
1016 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<ty::GeneratorInterior<'tcx>>)
1018 let mut fn_sig = fn_sig.clone();
1020 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1022 // Create the function context. This is either derived from scratch or,
1023 // in the case of function expressions, based on the outer context.
1024 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
1025 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1027 let ret_ty = fn_sig.output();
1028 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType);
1029 let ret_ty = fcx.instantiate_anon_types(&ret_ty);
1030 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
1031 fn_sig = fcx.tcx.mk_fn_sig(
1032 fn_sig.inputs().iter().cloned(),
1039 let span = body.value.span;
1041 if body.is_generator && can_be_generator {
1042 fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
1045 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
1047 // Add formal parameters.
1048 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1049 // Check the pattern.
1050 fcx.check_pat_walk(&arg.pat, arg_ty,
1051 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
1053 // Check that argument is Sized.
1054 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1055 // for simple cases like `fn foo(x: Trait)`,
1056 // where we would error once on the parameter as a whole, and once on the binding `x`.
1057 if arg.pat.simple_name().is_none() {
1058 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
1061 fcx.write_ty(arg.hir_id, arg_ty);
1064 let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
1065 let gen_ty = if can_be_generator && body.is_generator {
1066 let gen_sig = ty::GenSig {
1067 yield_ty: fcx.yield_ty.unwrap(),
1070 inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, Some(gen_sig));
1072 let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
1073 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), witness));
1074 let interior = ty::GeneratorInterior::new(witness);
1076 inherited.tables.borrow_mut().generator_interiors_mut().insert(fn_hir_id, interior);
1080 inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, None);
1083 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
1085 fcx.check_return_expr(&body.value);
1087 // Finalize the return check by taking the LUB of the return types
1088 // we saw and assigning it to the expected return type. This isn't
1089 // really expected to fail, since the coercions would have failed
1090 // earlier when trying to find a LUB.
1092 // However, the behavior around `!` is sort of complex. In the
1093 // event that the `actual_return_ty` comes back as `!`, that
1094 // indicates that the fn either does not return or "returns" only
1095 // values of type `!`. In this case, if there is an expected
1096 // return type that is *not* `!`, that should be ok. But if the
1097 // return type is being inferred, we want to "fallback" to `!`:
1099 // let x = move || panic!();
1101 // To allow for that, I am creating a type variable with diverging
1102 // fallback. This was deemed ever so slightly better than unifying
1103 // the return value with `!` because it allows for the caller to
1104 // make more assumptions about the return type (e.g., they could do
1106 // let y: Option<u32> = Some(x());
1108 // which would then cause this return type to become `u32`, not
1110 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1111 let mut actual_return_ty = coercion.complete(&fcx);
1112 if actual_return_ty.is_never() {
1113 actual_return_ty = fcx.next_diverging_ty_var(
1114 TypeVariableOrigin::DivergingFn(span));
1116 fcx.demand_suptype(span, ret_ty, actual_return_ty);
1121 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1124 let def_id = tcx.hir.local_def_id(id);
1125 let def = tcx.adt_def(def_id);
1126 def.destructor(tcx); // force the destructor to be evaluated
1127 check_representable(tcx, span, def_id);
1129 if def.repr.simd() {
1130 check_simd(tcx, span, def_id);
1133 check_packed(tcx, span, def_id);
1136 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1139 let def_id = tcx.hir.local_def_id(id);
1140 let def = tcx.adt_def(def_id);
1141 def.destructor(tcx); // force the destructor to be evaluated
1142 check_representable(tcx, span, def_id);
1144 check_packed(tcx, span, def_id);
1147 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1148 debug!("check_item_type(it.id={}, it.name={})",
1150 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
1151 let _indenter = indenter();
1153 // Consts can play a role in type-checking, so they are included here.
1154 hir::ItemStatic(..) |
1155 hir::ItemConst(..) => {
1156 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1158 hir::ItemEnum(ref enum_definition, _) => {
1161 &enum_definition.variants,
1164 hir::ItemFn(..) => {} // entirely within check_item_body
1165 hir::ItemImpl(.., ref impl_item_refs) => {
1166 debug!("ItemImpl {} with id {}", it.name, it.id);
1167 let impl_def_id = tcx.hir.local_def_id(it.id);
1168 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1169 check_impl_items_against_trait(tcx,
1174 let trait_def_id = impl_trait_ref.def_id;
1175 check_on_unimplemented(tcx, trait_def_id, it);
1178 hir::ItemTrait(..) => {
1179 let def_id = tcx.hir.local_def_id(it.id);
1180 check_on_unimplemented(tcx, def_id, it);
1182 hir::ItemStruct(..) => {
1183 check_struct(tcx, it.id, it.span);
1185 hir::ItemUnion(..) => {
1186 check_union(tcx, it.id, it.span);
1188 hir::ItemTy(_, ref generics) => {
1189 let def_id = tcx.hir.local_def_id(it.id);
1190 let pty_ty = tcx.type_of(def_id);
1191 check_bounds_are_used(tcx, generics, pty_ty);
1193 hir::ItemForeignMod(ref m) => {
1194 check_abi(tcx, it.span, m.abi);
1196 if m.abi == Abi::RustIntrinsic {
1197 for item in &m.items {
1198 intrinsic::check_intrinsic_type(tcx, item);
1200 } else if m.abi == Abi::PlatformIntrinsic {
1201 for item in &m.items {
1202 intrinsic::check_platform_intrinsic_type(tcx, item);
1205 for item in &m.items {
1206 let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
1207 if !generics.types.is_empty() {
1208 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1209 "foreign items may not have type parameters");
1210 span_help!(&mut err, item.span,
1211 "consider using specialization instead of \
1216 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1217 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1222 _ => {/* nothing to do */ }
1226 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1227 trait_def_id: DefId,
1229 let item_def_id = tcx.hir.local_def_id(item.id);
1230 // an error would be reported if this fails.
1231 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1234 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1235 impl_item: &hir::ImplItem,
1238 let mut err = struct_span_err!(
1239 tcx.sess, impl_item.span, E0520,
1240 "`{}` specializes an item from a parent `impl`, but \
1241 that item is not marked `default`",
1243 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1246 match tcx.span_of_impl(parent_impl) {
1248 err.span_label(span, "parent `impl` is here");
1249 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1253 err.note(&format!("parent implementation is in crate `{}`", cname));
1260 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1261 trait_def: &ty::TraitDef,
1262 trait_item: &ty::AssociatedItem,
1264 impl_item: &hir::ImplItem)
1266 let ancestors = trait_def.ancestors(tcx, impl_id);
1268 let kind = match impl_item.node {
1269 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1270 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1271 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1274 let parent = ancestors.defs(tcx, trait_item.name, kind, trait_def.def_id).skip(1).next()
1275 .map(|node_item| node_item.map(|parent| parent.defaultness));
1277 if let Some(parent) = parent {
1278 if tcx.impl_item_is_final(&parent) {
1279 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1285 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1288 impl_trait_ref: ty::TraitRef<'tcx>,
1289 impl_item_refs: &[hir::ImplItemRef]) {
1290 // If the trait reference itself is erroneous (so the compilation is going
1291 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1292 // isn't populated for such impls.
1293 if impl_trait_ref.references_error() { return; }
1295 // Locate trait definition and items
1296 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1297 let mut overridden_associated_type = None;
1299 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1301 // Check existing impl methods to see if they are both present in trait
1302 // and compatible with trait signature
1303 for impl_item in impl_items() {
1304 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1305 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1306 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1307 tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1309 // Not compatible, but needed for the error message
1310 tcx.associated_items(impl_trait_ref.def_id)
1311 .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1314 // Check that impl definition matches trait definition
1315 if let Some(ty_trait_item) = ty_trait_item {
1316 match impl_item.node {
1317 hir::ImplItemKind::Const(..) => {
1318 // Find associated const definition.
1319 if ty_trait_item.kind == ty::AssociatedKind::Const {
1320 compare_const_impl(tcx,
1326 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1327 "item `{}` is an associated const, \
1328 which doesn't match its trait `{}`",
1331 err.span_label(impl_item.span, "does not match trait");
1332 // We can only get the spans from local trait definition
1333 // Same for E0324 and E0325
1334 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1335 err.span_label(trait_span, "item in trait");
1340 hir::ImplItemKind::Method(..) => {
1341 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1342 if ty_trait_item.kind == ty::AssociatedKind::Method {
1343 let err_count = tcx.sess.err_count();
1344 compare_impl_method(tcx,
1350 true); // start with old-broken-mode
1351 if err_count == tcx.sess.err_count() {
1352 // old broken mode did not report an error. Try with the new mode.
1353 compare_impl_method(tcx,
1359 false); // use the new mode
1362 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1363 "item `{}` is an associated method, \
1364 which doesn't match its trait `{}`",
1367 err.span_label(impl_item.span, "does not match trait");
1368 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1369 err.span_label(trait_span, "item in trait");
1374 hir::ImplItemKind::Type(_) => {
1375 if ty_trait_item.kind == ty::AssociatedKind::Type {
1376 if ty_trait_item.defaultness.has_value() {
1377 overridden_associated_type = Some(impl_item);
1380 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1381 "item `{}` is an associated type, \
1382 which doesn't match its trait `{}`",
1385 err.span_label(impl_item.span, "does not match trait");
1386 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1387 err.span_label(trait_span, "item in trait");
1394 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1398 // Check for missing items from trait
1399 let mut missing_items = Vec::new();
1400 let mut invalidated_items = Vec::new();
1401 let associated_type_overridden = overridden_associated_type.is_some();
1402 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1403 let is_implemented = trait_def.ancestors(tcx, impl_id)
1404 .defs(tcx, trait_item.name, trait_item.kind, impl_trait_ref.def_id)
1406 .map(|node_item| !node_item.node.is_from_trait())
1409 if !is_implemented {
1410 if !trait_item.defaultness.has_value() {
1411 missing_items.push(trait_item);
1412 } else if associated_type_overridden {
1413 invalidated_items.push(trait_item.name);
1418 if !missing_items.is_empty() {
1419 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1420 "not all trait items implemented, missing: `{}`",
1421 missing_items.iter()
1422 .map(|trait_item| trait_item.name.to_string())
1423 .collect::<Vec<_>>().join("`, `"));
1424 err.span_label(impl_span, format!("missing `{}` in implementation",
1425 missing_items.iter()
1426 .map(|trait_item| trait_item.name.to_string())
1427 .collect::<Vec<_>>().join("`, `")));
1428 for trait_item in missing_items {
1429 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1430 err.span_label(span, format!("`{}` from trait", trait_item.name));
1432 err.note_trait_signature(trait_item.name.to_string(),
1433 trait_item.signature(&tcx));
1439 if !invalidated_items.is_empty() {
1440 let invalidator = overridden_associated_type.unwrap();
1441 span_err!(tcx.sess, invalidator.span, E0399,
1442 "the following trait items need to be reimplemented \
1443 as `{}` was overridden: `{}`",
1445 invalidated_items.iter()
1446 .map(|name| name.to_string())
1447 .collect::<Vec<_>>().join("`, `"))
1451 /// Checks whether a type can be represented in memory. In particular, it
1452 /// identifies types that contain themselves without indirection through a
1453 /// pointer, which would mean their size is unbounded.
1454 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1458 let rty = tcx.type_of(item_def_id);
1460 // Check that it is possible to represent this type. This call identifies
1461 // (1) types that contain themselves and (2) types that contain a different
1462 // recursive type. It is only necessary to throw an error on those that
1463 // contain themselves. For case 2, there must be an inner type that will be
1464 // caught by case 1.
1465 match rty.is_representable(tcx, sp) {
1466 Representability::SelfRecursive(spans) => {
1467 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1469 err.span_label(span, "recursive without indirection");
1474 Representability::Representable | Representability::ContainsRecursive => (),
1479 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1480 let t = tcx.type_of(def_id);
1482 ty::TyAdt(def, substs) if def.is_struct() => {
1483 let fields = &def.struct_variant().fields;
1484 if fields.is_empty() {
1485 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1488 let e = fields[0].ty(tcx, substs);
1489 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1490 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1491 .span_label(sp, "SIMD elements must have the same type")
1496 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1497 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1499 span_err!(tcx.sess, sp, E0077,
1500 "SIMD vector element type should be machine type");
1509 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1510 if tcx.adt_def(def_id).repr.packed() {
1511 if tcx.adt_def(def_id).repr.align > 0 {
1512 struct_span_err!(tcx.sess, sp, E0587,
1513 "type has conflicting packed and align representation hints").emit();
1515 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1516 struct_span_err!(tcx.sess, sp, E0588,
1517 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1522 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1524 stack: &mut Vec<DefId>) -> bool {
1525 let t = tcx.type_of(def_id);
1526 if stack.contains(&def_id) {
1527 debug!("check_packed_inner: {:?} is recursive", t);
1531 ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
1532 if tcx.adt_def(def.did).repr.align > 0 {
1535 // push struct def_id before checking fields
1537 for field in &def.struct_variant().fields {
1538 let f = field.ty(tcx, substs);
1540 ty::TyAdt(def, _) => {
1541 if check_packed_inner(tcx, def.did, stack) {
1548 // only need to pop if not early out
1556 #[allow(trivial_numeric_casts)]
1557 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1559 vs: &'tcx [hir::Variant],
1561 let def_id = tcx.hir.local_def_id(id);
1562 let def = tcx.adt_def(def_id);
1563 def.destructor(tcx); // force the destructor to be evaluated
1566 let attributes = tcx.get_attrs(def_id);
1567 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1569 tcx.sess, attr.span, E0084,
1570 "unsupported representation for zero-variant enum")
1571 .span_label(sp, "zero-variant enum")
1576 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1577 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1578 if !tcx.sess.features.borrow().repr128 {
1579 emit_feature_err(&tcx.sess.parse_sess,
1582 GateIssue::Language,
1583 "repr with 128-bit type is unstable");
1588 if let Some(e) = v.node.disr_expr {
1589 tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
1593 let mut disr_vals: Vec<ConstInt> = Vec::new();
1594 for (discr, v) in def.discriminants(tcx).zip(vs) {
1595 // Check for duplicate discriminant values
1596 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1597 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1598 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1599 let i_span = match variant_i.node.disr_expr {
1600 Some(expr) => tcx.hir.span(expr.node_id),
1601 None => tcx.hir.span(variant_i_node_id)
1603 let span = match v.node.disr_expr {
1604 Some(expr) => tcx.hir.span(expr.node_id),
1607 struct_span_err!(tcx.sess, span, E0081,
1608 "discriminant value `{}` already exists", disr_vals[i])
1609 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1610 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1613 disr_vals.push(discr);
1616 check_representable(tcx, sp, def_id);
1619 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1620 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1622 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1623 -> ty::GenericPredicates<'tcx>
1626 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1627 let item_id = tcx.hir.ty_param_owner(node_id);
1628 let item_def_id = tcx.hir.local_def_id(item_id);
1629 let generics = tcx.generics_of(item_def_id);
1630 let index = generics.type_param_to_index[&def_id.index];
1631 ty::GenericPredicates {
1633 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1635 ty::Predicate::Trait(ref data) => {
1636 data.0.self_ty().is_param(index)
1640 }).cloned().collect()
1644 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1645 -> Option<ty::Region<'tcx>> {
1647 Some(def) => infer::EarlyBoundRegion(span, def.name),
1648 None => infer::MiscVariable(span)
1650 Some(self.next_region_var(v))
1653 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1654 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1657 fn ty_infer_for_def(&self,
1658 ty_param_def: &ty::TypeParameterDef,
1659 substs: &[Kind<'tcx>],
1660 span: Span) -> Ty<'tcx> {
1661 self.type_var_for_def(span, ty_param_def, substs)
1664 fn projected_ty_from_poly_trait_ref(&self,
1667 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1670 let (trait_ref, _) =
1671 self.replace_late_bound_regions_with_fresh_var(
1673 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1676 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1679 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1680 if ty.has_escaping_regions() {
1681 ty // FIXME: normalization and escaping regions
1683 self.normalize_associated_types_in(span, &ty)
1687 fn set_tainted_by_errors(&self) {
1688 self.infcx.set_tainted_by_errors()
1691 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1692 self.write_ty(hir_id, ty)
1696 /// Controls whether the arguments are tupled. This is used for the call
1699 /// Tupling means that all call-side arguments are packed into a tuple and
1700 /// passed as a single parameter. For example, if tupling is enabled, this
1703 /// fn f(x: (isize, isize))
1705 /// Can be called as:
1712 #[derive(Clone, Eq, PartialEq)]
1713 enum TupleArgumentsFlag {
1718 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1719 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1720 param_env: ty::ParamEnv<'tcx>,
1721 body_id: ast::NodeId)
1722 -> FnCtxt<'a, 'gcx, 'tcx> {
1726 err_count_on_creation: inh.tcx.sess.err_count(),
1729 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1730 ast::CRATE_NODE_ID)),
1731 diverges: Cell::new(Diverges::Maybe),
1732 has_errors: Cell::new(false),
1733 enclosing_breakables: RefCell::new(EnclosingBreakables {
1741 pub fn sess(&self) -> &Session {
1745 pub fn err_count_since_creation(&self) -> usize {
1746 self.tcx.sess.err_count() - self.err_count_on_creation
1749 /// Produce warning on the given node, if the current point in the
1750 /// function is unreachable, and there hasn't been another warning.
1751 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1752 if self.diverges.get() == Diverges::Always {
1753 self.diverges.set(Diverges::WarnedAlways);
1755 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1757 self.tcx().lint_node(
1758 lint::builtin::UNREACHABLE_CODE,
1760 &format!("unreachable {}", kind));
1766 code: ObligationCauseCode<'tcx>)
1767 -> ObligationCause<'tcx> {
1768 ObligationCause::new(span, self.body_id, code)
1771 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1772 self.cause(span, ObligationCauseCode::MiscObligation)
1775 /// Resolves type variables in `ty` if possible. Unlike the infcx
1776 /// version (resolve_type_vars_if_possible), this version will
1777 /// also select obligations if it seems useful, in an effort
1778 /// to get more type information.
1779 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1780 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1782 // No TyInfer()? Nothing needs doing.
1783 if !ty.has_infer_types() {
1784 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1788 // If `ty` is a type variable, see whether we already know what it is.
1789 ty = self.resolve_type_vars_if_possible(&ty);
1790 if !ty.has_infer_types() {
1791 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1795 // If not, try resolving pending obligations as much as
1796 // possible. This can help substantially when there are
1797 // indirect dependencies that don't seem worth tracking
1799 self.select_obligations_where_possible();
1800 ty = self.resolve_type_vars_if_possible(&ty);
1802 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1806 fn record_deferred_call_resolution(&self,
1807 closure_def_id: DefId,
1808 r: DeferredCallResolution<'gcx, 'tcx>) {
1809 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1810 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1813 fn remove_deferred_call_resolutions(&self,
1814 closure_def_id: DefId)
1815 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1817 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1818 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1821 pub fn tag(&self) -> String {
1822 let self_ptr: *const FnCtxt = self;
1823 format!("{:?}", self_ptr)
1826 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1827 match self.locals.borrow().get(&nid) {
1830 span_bug!(span, "no type for local variable {}",
1831 self.tcx.hir.node_to_string(nid));
1837 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
1838 debug!("write_ty({:?}, {:?}) in fcx {}",
1839 id, self.resolve_type_vars_if_possible(&ty), self.tag());
1840 self.tables.borrow_mut().node_types_mut().insert(id, ty);
1842 if ty.references_error() {
1843 self.has_errors.set(true);
1844 self.set_tainted_by_errors();
1848 // The NodeId and the ItemLocalId must identify the same item. We just pass
1849 // both of them for consistency checking.
1850 pub fn write_method_call(&self,
1852 method: MethodCallee<'tcx>) {
1855 .type_dependent_defs_mut()
1856 .insert(hir_id, Def::Method(method.def_id));
1857 self.write_substs(hir_id, method.substs);
1860 pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
1861 if !substs.is_noop() {
1862 debug!("write_substs({:?}, {:?}) in fcx {}",
1867 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
1871 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1872 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1878 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
1879 Entry::Vacant(entry) => { entry.insert(adj); },
1880 Entry::Occupied(mut entry) => {
1881 debug!(" - composing on top of {:?}", entry.get());
1882 match (&entry.get()[..], &adj[..]) {
1883 // Applying any adjustment on top of a NeverToAny
1884 // is a valid NeverToAny adjustment, because it can't
1886 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1888 Adjustment { kind: Adjust::Deref(_), .. },
1889 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1891 Adjustment { kind: Adjust::Deref(_), .. },
1892 .. // Any following adjustments are allowed.
1894 // A reborrow has no effect before a dereference.
1896 // FIXME: currently we never try to compose autoderefs
1897 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1899 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1900 expr, entry.get(), adj)
1902 *entry.get_mut() = adj;
1907 /// Basically whenever we are converting from a type scheme into
1908 /// the fn body space, we always want to normalize associated
1909 /// types as well. This function combines the two.
1910 fn instantiate_type_scheme<T>(&self,
1912 substs: &Substs<'tcx>,
1915 where T : TypeFoldable<'tcx>
1917 let value = value.subst(self.tcx, substs);
1918 let result = self.normalize_associated_types_in(span, &value);
1919 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1926 /// As `instantiate_type_scheme`, but for the bounds found in a
1927 /// generic type scheme.
1928 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1929 -> ty::InstantiatedPredicates<'tcx> {
1930 let bounds = self.tcx.predicates_of(def_id);
1931 let result = bounds.instantiate(self.tcx, substs);
1932 let result = self.normalize_associated_types_in(span, &result);
1933 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1940 /// Replace all anonymized types with fresh inference variables
1941 /// and record them for writeback.
1942 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1943 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1944 if let ty::TyAnon(def_id, substs) = ty.sty {
1945 // Use the same type variable if the exact same TyAnon appears more
1946 // than once in the return type (e.g. if it's passed to a type alias).
1947 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1948 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1951 let span = self.tcx.def_span(def_id);
1952 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1953 self.anon_types.borrow_mut().insert(id, ty_var);
1955 let predicates_of = self.tcx.predicates_of(def_id);
1956 let bounds = predicates_of.instantiate(self.tcx, substs);
1958 for predicate in bounds.predicates {
1959 // Change the predicate to refer to the type variable,
1960 // which will be the concrete type, instead of the TyAnon.
1961 // This also instantiates nested `impl Trait`.
1962 let predicate = self.instantiate_anon_types(&predicate);
1964 // Require that the predicate holds for the concrete type.
1965 let cause = traits::ObligationCause::new(span, self.body_id,
1966 traits::SizedReturnType);
1967 self.register_predicate(traits::Obligation::new(cause,
1979 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1980 where T : TypeFoldable<'tcx>
1982 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
1985 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
1987 where T : TypeFoldable<'tcx>
1989 self.inh.normalize_associated_types_in_as_infer_ok(span,
1995 pub fn require_type_meets(&self,
1998 code: traits::ObligationCauseCode<'tcx>,
2001 self.register_bound(
2004 traits::ObligationCause::new(span, self.body_id, code));
2007 pub fn require_type_is_sized(&self,
2010 code: traits::ObligationCauseCode<'tcx>)
2012 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2013 self.require_type_meets(ty, span, code, lang_item);
2016 pub fn register_bound(&self,
2019 cause: traits::ObligationCause<'tcx>)
2021 self.fulfillment_cx.borrow_mut()
2022 .register_bound(self, self.param_env, ty, def_id, cause);
2025 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2026 let t = AstConv::ast_ty_to_ty(self, ast_t);
2027 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2031 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2032 match self.tables.borrow().node_types().get(id) {
2034 None if self.is_tainted_by_errors() => self.tcx.types.err,
2036 let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id);
2037 bug!("no type for node {}: {} in fcx {}",
2038 node_id, self.tcx.hir.node_to_string(node_id),
2044 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2045 /// outlive the region `r`.
2046 pub fn register_wf_obligation(&self,
2049 code: traits::ObligationCauseCode<'tcx>)
2051 // WF obligations never themselves fail, so no real need to give a detailed cause:
2052 let cause = traits::ObligationCause::new(span, self.body_id, code);
2053 self.register_predicate(traits::Obligation::new(cause,
2055 ty::Predicate::WellFormed(ty)));
2058 /// Registers obligations that all types appearing in `substs` are well-formed.
2059 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
2061 for ty in substs.types() {
2062 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2066 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2067 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2068 /// trait/region obligations.
2070 /// For example, if there is a function:
2073 /// fn foo<'a,T:'a>(...)
2076 /// and a reference:
2082 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2083 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2084 pub fn add_obligations_for_parameters(&self,
2085 cause: traits::ObligationCause<'tcx>,
2086 predicates: &ty::InstantiatedPredicates<'tcx>)
2088 assert!(!predicates.has_escaping_regions());
2090 debug!("add_obligations_for_parameters(predicates={:?})",
2093 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2094 self.register_predicate(obligation);
2098 // FIXME(arielb1): use this instead of field.ty everywhere
2099 // Only for fields! Returns <none> for methods>
2100 // Indifferent to privacy flags
2101 pub fn field_ty(&self,
2103 field: &'tcx ty::FieldDef,
2104 substs: &Substs<'tcx>)
2107 self.normalize_associated_types_in(span,
2108 &field.ty(self.tcx, substs))
2111 fn check_casts(&self) {
2112 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2113 for cast in deferred_cast_checks.drain(..) {
2118 fn resolve_generator_interiors(&self, def_id: DefId) {
2119 let mut deferred_generator_interiors = self.deferred_generator_interiors.borrow_mut();
2120 for (body_id, witness) in deferred_generator_interiors.drain(..) {
2121 generator_interior::resolve_interior(self, def_id, body_id, witness);
2125 /// Apply "fallbacks" to some types
2126 /// unconstrained types get replaced with ! or () (depending on whether
2127 /// feature(never_type) is enabled), unconstrained ints with i32, and
2128 /// unconstrained floats with f64.
2129 fn default_type_parameters(&self) {
2130 use rustc::ty::error::UnconstrainedNumeric::Neither;
2131 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2133 // Defaulting inference variables becomes very dubious if we have
2134 // encountered type-checking errors. Therefore, if we think we saw
2135 // some errors in this function, just resolve all uninstanted type
2136 // varibles to TyError.
2137 if self.is_tainted_by_errors() {
2138 for ty in &self.unsolved_variables() {
2139 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
2140 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2141 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2147 for ty in &self.unsolved_variables() {
2148 let resolved = self.resolve_type_vars_if_possible(ty);
2149 if self.type_var_diverges(resolved) {
2150 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
2152 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2153 self.tcx.mk_diverging_default());
2155 match self.type_is_unconstrained_numeric(resolved) {
2156 UnconstrainedInt => {
2157 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
2159 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2161 UnconstrainedFloat => {
2162 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
2164 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2172 // Implements type inference fallback algorithm
2173 fn select_all_obligations_and_apply_defaults(&self) {
2174 self.select_obligations_where_possible();
2175 self.default_type_parameters();
2176 self.select_obligations_where_possible();
2179 fn select_all_obligations_or_error(&self) {
2180 debug!("select_all_obligations_or_error");
2182 // upvar inference should have ensured that all deferred call
2183 // resolutions are handled by now.
2184 assert!(self.deferred_call_resolutions.borrow().is_empty());
2186 self.select_all_obligations_and_apply_defaults();
2188 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2190 match fulfillment_cx.select_all_or_error(self) {
2192 Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2196 /// Select as many obligations as we can at present.
2197 fn select_obligations_where_possible(&self) {
2198 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2200 Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2204 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2205 /// returns a type of `&T`, but the actual type we assign to the
2206 /// *expression* is `T`. So this function just peels off the return
2207 /// type by one layer to yield `T`.
2208 fn make_overloaded_lvalue_return_type(&self,
2209 method: MethodCallee<'tcx>)
2210 -> ty::TypeAndMut<'tcx>
2212 // extract method return type, which will be &T;
2213 let ret_ty = method.sig.output();
2215 // method returns &T, but the type as visible to user is T, so deref
2216 ret_ty.builtin_deref(true, NoPreference).unwrap()
2219 fn lookup_indexing(&self,
2221 base_expr: &'gcx hir::Expr,
2224 lvalue_pref: LvaluePreference)
2225 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2227 // FIXME(#18741) -- this is almost but not quite the same as the
2228 // autoderef that normal method probing does. They could likely be
2231 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2232 let mut result = None;
2233 while result.is_none() && autoderef.next().is_some() {
2234 result = self.try_index_step(expr, base_expr, &autoderef, lvalue_pref, idx_ty);
2236 autoderef.finalize();
2240 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2241 /// (and otherwise adjust) `base_expr`, looking for a type which either
2242 /// supports builtin indexing or overloaded indexing.
2243 /// This loop implements one step in that search; the autoderef loop
2244 /// is implemented by `lookup_indexing`.
2245 fn try_index_step(&self,
2247 base_expr: &hir::Expr,
2248 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2249 lvalue_pref: LvaluePreference,
2251 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2253 let adjusted_ty = autoderef.unambiguous_final_ty();
2254 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2261 // First, try built-in indexing.
2262 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2263 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2264 debug!("try_index_step: success, using built-in indexing");
2265 let adjustments = autoderef.adjust_steps(lvalue_pref);
2266 self.apply_adjustments(base_expr, adjustments);
2267 return Some((self.tcx.types.usize, ty));
2272 for &unsize in &[false, true] {
2273 let mut self_ty = adjusted_ty;
2275 // We only unsize arrays here.
2276 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2277 self_ty = self.tcx.mk_slice(element_ty);
2283 // If some lookup succeeds, write callee into table and extract index/element
2284 // type from the method signature.
2285 // If some lookup succeeded, install method in table
2286 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2287 let method = self.try_overloaded_lvalue_op(
2288 expr.span, self_ty, &[input_ty], lvalue_pref, LvalueOp::Index);
2290 let result = method.map(|ok| {
2291 debug!("try_index_step: success, using overloaded indexing");
2292 let method = self.register_infer_ok_obligations(ok);
2294 let mut adjustments = autoderef.adjust_steps(lvalue_pref);
2295 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
2296 adjustments.push(Adjustment {
2297 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
2298 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2305 adjustments.push(Adjustment {
2306 kind: Adjust::Unsize,
2307 target: method.sig.inputs()[0]
2310 self.apply_adjustments(base_expr, adjustments);
2312 self.write_method_call(expr.hir_id, method);
2313 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2315 if result.is_some() {
2323 fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2324 let (tr, name) = match (op, is_mut) {
2325 (LvalueOp::Deref, false) =>
2326 (self.tcx.lang_items().deref_trait(), "deref"),
2327 (LvalueOp::Deref, true) =>
2328 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2329 (LvalueOp::Index, false) =>
2330 (self.tcx.lang_items().index_trait(), "index"),
2331 (LvalueOp::Index, true) =>
2332 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2334 (tr, Symbol::intern(name))
2337 fn try_overloaded_lvalue_op(&self,
2340 arg_tys: &[Ty<'tcx>],
2341 lvalue_pref: LvaluePreference,
2343 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2345 debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
2351 // Try Mut first, if preferred.
2352 let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
2353 let method = match (lvalue_pref, mut_tr) {
2354 (PreferMutLvalue, Some(trait_did)) => {
2355 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2360 // Otherwise, fall back to the immutable version.
2361 let (imm_tr, imm_op) = self.resolve_lvalue_op(op, false);
2362 let method = match (method, imm_tr) {
2363 (None, Some(trait_did)) => {
2364 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2366 (method, _) => method,
2372 fn check_method_argument_types(&self,
2375 method: Result<MethodCallee<'tcx>, ()>,
2376 args_no_rcvr: &'gcx [hir::Expr],
2377 tuple_arguments: TupleArgumentsFlag,
2378 expected: Expectation<'tcx>)
2380 let has_error = match method {
2382 method.substs.references_error() || method.sig.references_error()
2387 let err_inputs = self.err_args(args_no_rcvr.len());
2389 let err_inputs = match tuple_arguments {
2390 DontTupleArguments => err_inputs,
2391 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2394 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2395 false, tuple_arguments, None);
2396 return self.tcx.types.err;
2399 let method = method.unwrap();
2400 // HACK(eddyb) ignore self in the definition (see above).
2401 let expected_arg_tys = self.expected_inputs_for_expected_output(
2404 method.sig.output(),
2405 &method.sig.inputs()[1..]
2407 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2408 args_no_rcvr, method.sig.variadic, tuple_arguments,
2409 self.tcx.hir.span_if_local(method.def_id));
2413 /// Generic function that factors out common logic from function calls,
2414 /// method calls and overloaded operators.
2415 fn check_argument_types(&self,
2418 fn_inputs: &[Ty<'tcx>],
2419 expected_arg_tys: &[Ty<'tcx>],
2420 args: &'gcx [hir::Expr],
2422 tuple_arguments: TupleArgumentsFlag,
2423 def_span: Option<Span>) {
2426 // Grab the argument types, supplying fresh type variables
2427 // if the wrong number of arguments were supplied
2428 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2434 // All the input types from the fn signature must outlive the call
2435 // so as to validate implied bounds.
2436 for &fn_input_ty in fn_inputs {
2437 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2440 let mut expected_arg_tys = expected_arg_tys;
2441 let expected_arg_count = fn_inputs.len();
2443 let sp_args = if args.len() > 0 {
2444 let (first, args) = args.split_at(1);
2445 let mut sp_tmp = first[0].span;
2447 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2448 if ! sp_opt.is_some() {
2451 sp_tmp = sp_opt.unwrap();
2458 fn parameter_count_error<'tcx>(sess: &Session,
2461 expected_count: usize,
2465 def_span: Option<Span>,
2467 let mut err = sess.struct_span_err_with_code(sp,
2468 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2469 if variadic {"at least "} else {""},
2471 if expected_count == 1 {""} else {"s"},
2473 if arg_count == 1 {" was"} else {"s were"}),
2474 DiagnosticId::Error(error_code.to_owned()));
2476 if let Some(def_s) = def_span {
2477 err.span_label(def_s, "defined here");
2480 let sugg_span = expr_sp.end_point();
2481 // remove closing `)` from the span
2482 let sugg_span = sugg_span.with_hi(sugg_span.lo());
2483 err.span_suggestion(
2485 "expected the unit value `()`; create it with empty parentheses",
2486 String::from("()"));
2488 err.span_label(sp, format!("expected {}{} parameter{}",
2489 if variadic {"at least "} else {""},
2491 if expected_count == 1 {""} else {"s"}));
2496 let formal_tys = if tuple_arguments == TupleArguments {
2497 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2498 match tuple_type.sty {
2499 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2500 parameter_count_error(tcx.sess, sp_args, expr_sp, arg_types.len(), args.len(),
2501 "E0057", false, def_span, false);
2502 expected_arg_tys = &[];
2503 self.err_args(args.len())
2505 ty::TyTuple(arg_types, _) => {
2506 expected_arg_tys = match expected_arg_tys.get(0) {
2507 Some(&ty) => match ty.sty {
2508 ty::TyTuple(ref tys, _) => &tys,
2516 span_err!(tcx.sess, sp, E0059,
2517 "cannot use call notation; the first type parameter \
2518 for the function trait is neither a tuple nor unit");
2519 expected_arg_tys = &[];
2520 self.err_args(args.len())
2523 } else if expected_arg_count == supplied_arg_count {
2525 } else if variadic {
2526 if supplied_arg_count >= expected_arg_count {
2529 parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2530 supplied_arg_count, "E0060", true, def_span, false);
2531 expected_arg_tys = &[];
2532 self.err_args(supplied_arg_count)
2535 // is the missing argument of type `()`?
2536 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2537 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
2538 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2539 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
2543 parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2544 supplied_arg_count, "E0061", false, def_span, sugg_unit);
2545 expected_arg_tys = &[];
2546 self.err_args(supplied_arg_count)
2549 debug!("check_argument_types: formal_tys={:?}",
2550 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2552 // Check the arguments.
2553 // We do this in a pretty awful way: first we typecheck any arguments
2554 // that are not closures, then we typecheck the closures. This is so
2555 // that we have more information about the types of arguments when we
2556 // typecheck the functions. This isn't really the right way to do this.
2557 for &check_closures in &[false, true] {
2558 debug!("check_closures={}", check_closures);
2560 // More awful hacks: before we check argument types, try to do
2561 // an "opportunistic" vtable resolution of any trait bounds on
2562 // the call. This helps coercions.
2564 self.select_obligations_where_possible();
2567 // For variadic functions, we don't have a declared type for all of
2568 // the arguments hence we only do our usual type checking with
2569 // the arguments who's types we do know.
2570 let t = if variadic {
2572 } else if tuple_arguments == TupleArguments {
2577 for (i, arg) in args.iter().take(t).enumerate() {
2578 // Warn only for the first loop (the "no closures" one).
2579 // Closure arguments themselves can't be diverging, but
2580 // a previous argument can, e.g. `foo(panic!(), || {})`.
2581 if !check_closures {
2582 self.warn_if_unreachable(arg.id, arg.span, "expression");
2585 let is_closure = match arg.node {
2586 hir::ExprClosure(..) => true,
2590 if is_closure != check_closures {
2594 debug!("checking the argument");
2595 let formal_ty = formal_tys[i];
2597 // The special-cased logic below has three functions:
2598 // 1. Provide as good of an expected type as possible.
2599 let expected = expected_arg_tys.get(i).map(|&ty| {
2600 Expectation::rvalue_hint(self, ty)
2603 let checked_ty = self.check_expr_with_expectation(
2605 expected.unwrap_or(ExpectHasType(formal_ty)));
2607 // 2. Coerce to the most detailed type that could be coerced
2608 // to, which is `expected_ty` if `rvalue_hint` returns an
2609 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2610 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2611 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2613 // 3. Relate the expected type and the formal one,
2614 // if the expected type was used for the coercion.
2615 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2619 // We also need to make sure we at least write the ty of the other
2620 // arguments which we skipped above.
2622 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
2623 type_error_struct!(s, span, t, E0617,
2624 "can't pass `{}` to variadic function, cast to `{}`",
2628 for arg in args.iter().skip(expected_arg_count) {
2629 let arg_ty = self.check_expr(&arg);
2631 // There are a few types which get autopromoted when passed via varargs
2632 // in C but we just error out instead and require explicit casts.
2633 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
2635 ty::TyFloat(ast::FloatTy::F32) => {
2636 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
2638 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2639 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
2641 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2642 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
2644 ty::TyFnDef(..) => {
2645 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
2646 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2647 variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
2655 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2656 (0..len).map(|_| self.tcx.types.err).collect()
2659 // AST fragment checking
2662 expected: Expectation<'tcx>)
2668 ast::LitKind::Str(..) => tcx.mk_static_str(),
2669 ast::LitKind::ByteStr(ref v) => {
2670 tcx.mk_imm_ref(tcx.types.re_static,
2671 tcx.mk_array(tcx.types.u8, v.len() as u64))
2673 ast::LitKind::Byte(_) => tcx.types.u8,
2674 ast::LitKind::Char(_) => tcx.types.char,
2675 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2676 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2677 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2678 let opt_ty = expected.to_option(self).and_then(|ty| {
2680 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2681 ty::TyChar => Some(tcx.types.u8),
2682 ty::TyRawPtr(..) => Some(tcx.types.usize),
2683 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2687 opt_ty.unwrap_or_else(
2688 || tcx.mk_int_var(self.next_int_var_id()))
2690 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2691 ast::LitKind::FloatUnsuffixed(_) => {
2692 let opt_ty = expected.to_option(self).and_then(|ty| {
2694 ty::TyFloat(_) => Some(ty),
2698 opt_ty.unwrap_or_else(
2699 || tcx.mk_float_var(self.next_float_var_id()))
2701 ast::LitKind::Bool(_) => tcx.types.bool
2705 fn check_expr_eq_type(&self,
2706 expr: &'gcx hir::Expr,
2707 expected: Ty<'tcx>) {
2708 let ty = self.check_expr_with_hint(expr, expected);
2709 self.demand_eqtype(expr.span, expected, ty);
2712 pub fn check_expr_has_type_or_error(&self,
2713 expr: &'gcx hir::Expr,
2714 expected: Ty<'tcx>) -> Ty<'tcx> {
2715 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
2718 fn check_expr_meets_expectation_or_error(&self,
2719 expr: &'gcx hir::Expr,
2720 expected: Expectation<'tcx>) -> Ty<'tcx> {
2721 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
2722 let mut ty = self.check_expr_with_expectation(expr, expected);
2724 // While we don't allow *arbitrary* coercions here, we *do* allow
2725 // coercions from ! to `expected`.
2727 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
2728 "expression with never type wound up being adjusted");
2729 let adj_ty = self.next_diverging_ty_var(
2730 TypeVariableOrigin::AdjustmentType(expr.span));
2731 self.apply_adjustments(expr, vec![Adjustment {
2732 kind: Adjust::NeverToAny,
2738 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
2739 // Add help to type error if this is an `if` condition with an assignment
2740 match (expected, &expr.node) {
2741 (ExpectIfCondition, &hir::ExprAssign(ref lhs, ref rhs)) => {
2742 let msg = "try comparing for equality";
2743 if let (Ok(left), Ok(right)) = (
2744 self.tcx.sess.codemap().span_to_snippet(lhs.span),
2745 self.tcx.sess.codemap().span_to_snippet(rhs.span))
2747 err.span_suggestion(expr.span, msg, format!("{} == {}", left, right));
2759 fn check_expr_coercable_to_type(&self,
2760 expr: &'gcx hir::Expr,
2761 expected: Ty<'tcx>) -> Ty<'tcx> {
2762 self.check_expr_coercable_to_type_with_lvalue_pref(expr, expected, NoPreference)
2765 fn check_expr_coercable_to_type_with_lvalue_pref(&self,
2766 expr: &'gcx hir::Expr,
2768 lvalue_pref: LvaluePreference)
2770 let ty = self.check_expr_with_expectation_and_lvalue_pref(
2772 ExpectHasType(expected),
2774 self.demand_coerce(expr, ty, expected)
2777 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2778 expected: Ty<'tcx>) -> Ty<'tcx> {
2779 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2782 fn check_expr_with_expectation(&self,
2783 expr: &'gcx hir::Expr,
2784 expected: Expectation<'tcx>) -> Ty<'tcx> {
2785 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2788 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2789 self.check_expr_with_expectation(expr, NoExpectation)
2792 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2793 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2794 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2797 // determine the `self` type, using fresh variables for all variables
2798 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2799 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2801 pub fn impl_self_ty(&self,
2802 span: Span, // (potential) receiver for this impl
2804 -> TypeAndSubsts<'tcx> {
2805 let ity = self.tcx.type_of(did);
2806 debug!("impl_self_ty: ity={:?}", ity);
2808 let substs = self.fresh_substs_for_item(span, did);
2809 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2811 TypeAndSubsts { substs: substs, ty: substd_ty }
2814 /// Unifies the output type with the expected type early, for more coercions
2815 /// and forward type information on the input expressions.
2816 fn expected_inputs_for_expected_output(&self,
2818 expected_ret: Expectation<'tcx>,
2819 formal_ret: Ty<'tcx>,
2820 formal_args: &[Ty<'tcx>])
2822 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
2823 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2824 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2825 // Attempt to apply a subtyping relationship between the formal
2826 // return type (likely containing type variables if the function
2827 // is polymorphic) and the expected return type.
2828 // No argument expectations are produced if unification fails.
2829 let origin = self.misc(call_span);
2830 let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
2832 // FIXME(#15760) can't use try! here, FromError doesn't default
2833 // to identity so the resulting type is not constrained.
2836 // Process any obligations locally as much as
2837 // we can. We don't care if some things turn
2838 // out unconstrained or ambiguous, as we're
2839 // just trying to get hints here.
2840 let result = self.save_and_restore_in_snapshot_flag(|_| {
2841 let mut fulfill = FulfillmentContext::new();
2842 let ok = ok; // FIXME(#30046)
2843 for obligation in ok.obligations {
2844 fulfill.register_predicate_obligation(self, obligation);
2846 fulfill.select_where_possible(self)
2851 Err(_) => return Err(()),
2854 Err(_) => return Err(()),
2857 // Record all the argument types, with the substitutions
2858 // produced from the above subtyping unification.
2859 Ok(formal_args.iter().map(|ty| {
2860 self.resolve_type_vars_if_possible(ty)
2863 }).unwrap_or(vec![]);
2864 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2865 formal_args, formal_ret,
2866 expected_args, expected_ret);
2870 // Checks a method call.
2871 fn check_method_call(&self,
2872 expr: &'gcx hir::Expr,
2873 segment: &hir::PathSegment,
2875 args: &'gcx [hir::Expr],
2876 expected: Expectation<'tcx>,
2877 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2878 let rcvr = &args[0];
2879 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2880 // no need to check for bot/err -- callee does that
2881 let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2883 let method = match self.lookup_method(rcvr_t,
2889 self.write_method_call(expr.hir_id, method);
2893 if segment.name != keywords::Invalid.name() {
2894 self.report_method_error(span,
2905 // Call the generic checker.
2906 self.check_method_argument_types(span,
2914 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2918 .unwrap_or_else(|| span_bug!(return_expr.span,
2919 "check_return_expr called outside fn body"));
2921 let ret_ty = ret_coercion.borrow().expected_ty();
2922 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
2923 ret_coercion.borrow_mut()
2925 &self.cause(return_expr.span,
2926 ObligationCauseCode::ReturnType(return_expr.id)),
2929 self.diverges.get());
2933 // A generic function for checking the then and else in an if
2935 fn check_then_else(&self,
2936 cond_expr: &'gcx hir::Expr,
2937 then_expr: &'gcx hir::Expr,
2938 opt_else_expr: Option<&'gcx hir::Expr>,
2940 expected: Expectation<'tcx>) -> Ty<'tcx> {
2941 let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
2942 let cond_diverges = self.diverges.get();
2943 self.diverges.set(Diverges::Maybe);
2945 let expected = expected.adjust_for_branches(self);
2946 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2947 let then_diverges = self.diverges.get();
2948 self.diverges.set(Diverges::Maybe);
2950 // We've already taken the expected type's preferences
2951 // into account when typing the `then` branch. To figure
2952 // out the initial shot at a LUB, we thus only consider
2953 // `expected` if it represents a *hard* constraint
2954 // (`only_has_type`); otherwise, we just go with a
2955 // fresh type variable.
2956 let coerce_to_ty = expected.coercion_target_type(self, sp);
2957 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2959 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2960 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2962 if let Some(else_expr) = opt_else_expr {
2963 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2964 let else_diverges = self.diverges.get();
2966 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
2968 // We won't diverge unless both branches do (or the condition does).
2969 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2971 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2972 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
2974 // If the condition is false we can't diverge.
2975 self.diverges.set(cond_diverges);
2978 let result_ty = coerce.complete(self);
2979 if cond_ty.references_error() {
2986 // Check field access expressions
2987 fn check_field(&self,
2988 expr: &'gcx hir::Expr,
2989 lvalue_pref: LvaluePreference,
2990 base: &'gcx hir::Expr,
2991 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2992 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2993 let expr_t = self.structurally_resolved_type(expr.span,
2995 let mut private_candidate = None;
2996 let mut autoderef = self.autoderef(expr.span, expr_t);
2997 while let Some((base_t, _)) = autoderef.next() {
2999 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
3000 debug!("struct named {:?}", base_t);
3001 let (ident, def_scope) =
3002 self.tcx.adjust(field.node, base_def.did, self.body_id);
3003 let fields = &base_def.struct_variant().fields;
3004 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3005 let field_ty = self.field_ty(expr.span, field, substs);
3006 if field.vis.is_accessible_from(def_scope, self.tcx) {
3007 let adjustments = autoderef.adjust_steps(lvalue_pref);
3008 self.apply_adjustments(base, adjustments);
3009 autoderef.finalize();
3011 self.tcx.check_stability(field.did, expr.id, expr.span);
3015 private_candidate = Some((base_def.did, field_ty));
3021 autoderef.unambiguous_final_ty();
3023 if let Some((did, field_ty)) = private_candidate {
3024 let struct_path = self.tcx().item_path_str(did);
3025 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3026 "field `{}` of struct `{}` is private",
3027 field.node, struct_path);
3028 // Also check if an accessible method exists, which is often what is meant.
3029 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
3030 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
3035 } else if field.node == keywords::Invalid.name() {
3036 self.tcx().types.err
3037 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
3038 type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3039 "attempted to take value of method `{}` on type `{}`",
3041 .help("maybe a `()` to call it is missing?")
3043 self.tcx().types.err
3045 if !expr_t.is_primitive_ty() {
3046 let mut err = self.no_such_field_err(field.span, &field.node, expr_t);
3049 ty::TyAdt(def, _) if !def.is_enum() => {
3050 if let Some(suggested_field_name) =
3051 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
3052 err.span_label(field.span,
3053 format!("did you mean `{}`?", suggested_field_name));
3055 err.span_label(field.span, "unknown field");
3056 let struct_variant_def = def.struct_variant();
3057 let field_names = self.available_field_names(struct_variant_def);
3058 if !field_names.is_empty() {
3059 err.note(&format!("available fields are: {}",
3060 self.name_series_display(field_names)));
3064 ty::TyRawPtr(..) => {
3065 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \
3067 self.tcx.hir.node_to_pretty_string(base.id),
3074 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3075 "`{}` is a primitive type and therefore doesn't have fields",
3078 self.tcx().types.err
3082 // Return an hint about the closest match in field names
3083 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3084 field: &Spanned<ast::Name>,
3085 skip: Vec<InternedString>)
3087 let name = field.node.as_str();
3088 let names = variant.fields.iter().filter_map(|field| {
3089 // ignore already set fields and private fields from non-local crates
3090 if skip.iter().any(|x| *x == field.name.as_str()) ||
3091 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3098 find_best_match_for_name(names, &name, None)
3101 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3102 let mut available = Vec::new();
3103 for field in variant.fields.iter() {
3104 let (_, def_scope) = self.tcx.adjust(field.name, variant.did, self.body_id);
3105 if field.vis.is_accessible_from(def_scope, self.tcx) {
3106 available.push(field.name);
3112 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3113 // dynamic limit, to never omit just one field
3114 let limit = if names.len() == 6 { 6 } else { 5 };
3115 let mut display = names.iter().take(limit)
3116 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3117 if names.len() > limit {
3118 display = format!("{} ... and {} others", display, names.len() - limit);
3123 // Check tuple index expressions
3124 fn check_tup_field(&self,
3125 expr: &'gcx hir::Expr,
3126 lvalue_pref: LvaluePreference,
3127 base: &'gcx hir::Expr,
3128 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
3129 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
3130 let expr_t = self.structurally_resolved_type(expr.span,
3132 let mut private_candidate = None;
3133 let mut tuple_like = false;
3134 let mut autoderef = self.autoderef(expr.span, expr_t);
3135 while let Some((base_t, _)) = autoderef.next() {
3136 let field = match base_t.sty {
3137 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
3138 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
3139 if !tuple_like { continue }
3141 debug!("tuple struct named {:?}", base_t);
3142 let ident = ast::Ident {
3143 name: Symbol::intern(&idx.node.to_string()),
3144 ctxt: idx.span.ctxt().modern(),
3146 let (ident, def_scope) =
3147 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
3148 let fields = &base_def.struct_variant().fields;
3149 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3150 let field_ty = self.field_ty(expr.span, field, substs);
3151 if field.vis.is_accessible_from(def_scope, self.tcx) {
3152 self.tcx.check_stability(field.did, expr.id, expr.span);
3155 private_candidate = Some((base_def.did, field_ty));
3162 ty::TyTuple(ref v, _) => {
3164 v.get(idx.node).cloned()
3169 if let Some(field_ty) = field {
3170 let adjustments = autoderef.adjust_steps(lvalue_pref);
3171 self.apply_adjustments(base, adjustments);
3172 autoderef.finalize();
3176 autoderef.unambiguous_final_ty();
3178 if let Some((did, field_ty)) = private_candidate {
3179 let struct_path = self.tcx().item_path_str(did);
3180 struct_span_err!(self.tcx().sess, expr.span, E0611,
3181 "field `{}` of tuple-struct `{}` is private",
3182 idx.node, struct_path).emit();
3187 type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
3188 "attempted out-of-bounds tuple index `{}` on type `{}`",
3189 idx.node, expr_t).emit();
3191 self.no_such_field_err(expr.span, idx.node, expr_t).emit();
3194 self.tcx().types.err
3197 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
3198 -> DiagnosticBuilder {
3199 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3200 "no field `{}` on type `{}`",
3204 fn report_unknown_field(&self,
3206 variant: &'tcx ty::VariantDef,
3208 skip_fields: &[hir::Field],
3210 let mut err = self.type_error_struct_with_diag(
3212 |actual| match ty.sty {
3213 ty::TyAdt(adt, ..) if adt.is_enum() => {
3214 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3215 "{} `{}::{}` has no field named `{}`",
3216 kind_name, actual, variant.name, field.name.node)
3219 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3220 "{} `{}` has no field named `{}`",
3221 kind_name, actual, field.name.node)
3225 // prevent all specified fields from being suggested
3226 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3227 if let Some(field_name) = Self::suggest_field_name(variant,
3229 skip_fields.collect()) {
3230 err.span_label(field.name.span,
3231 format!("field does not exist - did you mean `{}`?", field_name));
3234 ty::TyAdt(adt, ..) => {
3236 err.span_label(field.name.span,
3237 format!("`{}::{}` does not have this field",
3240 err.span_label(field.name.span,
3241 format!("`{}` does not have this field", ty));
3243 let available_field_names = self.available_field_names(variant);
3244 if !available_field_names.is_empty() {
3245 err.note(&format!("available fields are: {}",
3246 self.name_series_display(available_field_names)));
3249 _ => bug!("non-ADT passed to report_unknown_field")
3255 fn check_expr_struct_fields(&self,
3257 expected: Expectation<'tcx>,
3258 expr_id: ast::NodeId,
3260 variant: &'tcx ty::VariantDef,
3261 ast_fields: &'gcx [hir::Field],
3262 check_completeness: bool) {
3266 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3267 .get(0).cloned().unwrap_or(adt_ty);
3268 // re-link the regions that EIfEO can erase.
3269 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3271 let (substs, adt_kind, kind_name) = match &adt_ty.sty{
3272 &ty::TyAdt(adt, substs) => {
3273 (substs, adt.adt_kind(), adt.variant_descr())
3275 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3278 let mut remaining_fields = FxHashMap();
3279 for field in &variant.fields {
3280 remaining_fields.insert(field.name.to_ident(), field);
3283 let mut seen_fields = FxHashMap();
3285 let mut error_happened = false;
3287 // Typecheck each field.
3288 for field in ast_fields {
3289 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3290 let field_type = if let Some(v_field) = remaining_fields.remove(&ident) {
3291 seen_fields.insert(field.name.node, field.span);
3293 // we don't look at stability attributes on
3294 // struct-like enums (yet...), but it's definitely not
3295 // a bug to have construct one.
3296 if adt_kind != ty::AdtKind::Enum {
3297 tcx.check_stability(v_field.did, expr_id, field.span);
3300 self.field_ty(field.span, v_field, substs)
3302 error_happened = true;
3303 if let Some(_) = variant.find_field_named(field.name.node) {
3304 let mut err = struct_span_err!(self.tcx.sess,
3307 "field `{}` specified more than once",
3310 err.span_label(field.name.span, "used more than once");
3312 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3313 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3318 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3324 // Make sure to give a type to the field even if there's
3325 // an error, so we can continue typechecking
3326 self.check_expr_coercable_to_type(&field.expr, field_type);
3329 // Make sure the programmer specified correct number of fields.
3330 if kind_name == "union" {
3331 if ast_fields.len() != 1 {
3332 tcx.sess.span_err(span, "union expressions should have exactly one field");
3334 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3335 let len = remaining_fields.len();
3337 let mut displayable_field_names = remaining_fields
3339 .map(|ident| ident.name.as_str())
3340 .collect::<Vec<_>>();
3342 displayable_field_names.sort();
3344 let truncated_fields_error = if len <= 3 {
3347 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3350 let remaining_fields_names = displayable_field_names.iter().take(3)
3351 .map(|n| format!("`{}`", n))
3352 .collect::<Vec<_>>()
3355 struct_span_err!(tcx.sess, span, E0063,
3356 "missing field{} {}{} in initializer of `{}`",
3357 if remaining_fields.len() == 1 { "" } else { "s" },
3358 remaining_fields_names,
3359 truncated_fields_error,
3361 .span_label(span, format!("missing {}{}",
3362 remaining_fields_names,
3363 truncated_fields_error))
3368 fn check_struct_fields_on_error(&self,
3369 fields: &'gcx [hir::Field],
3370 base_expr: &'gcx Option<P<hir::Expr>>) {
3371 for field in fields {
3372 self.check_expr(&field.expr);
3376 self.check_expr(&base);
3382 pub fn check_struct_path(&self,
3384 node_id: ast::NodeId)
3385 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3386 let path_span = match *qpath {
3387 hir::QPath::Resolved(_, ref path) => path.span,
3388 hir::QPath::TypeRelative(ref qself, _) => qself.span
3390 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3391 let variant = match def {
3393 self.set_tainted_by_errors();
3396 Def::Variant(..) => {
3398 ty::TyAdt(adt, substs) => {
3399 Some((adt.variant_of_def(def), adt.did, substs))
3401 _ => bug!("unexpected type: {:?}", ty.sty)
3404 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3405 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3407 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3408 Some((adt.struct_variant(), adt.did, substs))
3413 _ => bug!("unexpected definition: {:?}", def)
3416 if let Some((variant, did, substs)) = variant {
3417 // Check bounds on type arguments used in the path.
3418 let bounds = self.instantiate_bounds(path_span, did, substs);
3419 let cause = traits::ObligationCause::new(path_span, self.body_id,
3420 traits::ItemObligation(did));
3421 self.add_obligations_for_parameters(cause, &bounds);
3425 struct_span_err!(self.tcx.sess, path_span, E0071,
3426 "expected struct, variant or union type, found {}",
3427 ty.sort_string(self.tcx))
3428 .span_label(path_span, "not a struct")
3434 fn check_expr_struct(&self,
3436 expected: Expectation<'tcx>,
3438 fields: &'gcx [hir::Field],
3439 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3441 // Find the relevant variant
3442 let (variant, struct_ty) =
3443 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3446 self.check_struct_fields_on_error(fields, base_expr);
3447 return self.tcx.types.err;
3450 let path_span = match *qpath {
3451 hir::QPath::Resolved(_, ref path) => path.span,
3452 hir::QPath::TypeRelative(ref qself, _) => qself.span
3455 // Prohibit struct expressions when non exhaustive flag is set.
3456 if let ty::TyAdt(adt, _) = struct_ty.sty {
3457 if !adt.did.is_local() && adt.is_non_exhaustive() {
3458 span_err!(self.tcx.sess, expr.span, E0639,
3459 "cannot create non-exhaustive {} using struct expression",
3460 adt.variant_descr());
3464 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3465 base_expr.is_none());
3466 if let &Some(ref base_expr) = base_expr {
3467 self.check_expr_has_type_or_error(base_expr, struct_ty);
3468 match struct_ty.sty {
3469 ty::TyAdt(adt, substs) if adt.is_struct() => {
3470 let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
3471 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3476 .fru_field_types_mut()
3477 .insert(expr.hir_id, fru_field_types);
3480 span_err!(self.tcx.sess, base_expr.span, E0436,
3481 "functional record update syntax requires a struct");
3485 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3491 /// If an expression has any sub-expressions that result in a type error,
3492 /// inspecting that expression's type with `ty.references_error()` will return
3493 /// true. Likewise, if an expression is known to diverge, inspecting its
3494 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3495 /// strict, _|_ can appear in the type of an expression that does not,
3496 /// itself, diverge: for example, fn() -> _|_.)
3497 /// Note that inspecting a type's structure *directly* may expose the fact
3498 /// that there are actually multiple representations for `TyError`, so avoid
3499 /// that when err needs to be handled differently.
3500 fn check_expr_with_expectation_and_lvalue_pref(&self,
3501 expr: &'gcx hir::Expr,
3502 expected: Expectation<'tcx>,
3503 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3504 debug!(">> typechecking: expr={:?} expected={:?}",
3507 // Warn for expressions after diverging siblings.
3508 self.warn_if_unreachable(expr.id, expr.span, "expression");
3510 // Hide the outer diverging and has_errors flags.
3511 let old_diverges = self.diverges.get();
3512 let old_has_errors = self.has_errors.get();
3513 self.diverges.set(Diverges::Maybe);
3514 self.has_errors.set(false);
3516 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3518 // Warn for non-block expressions with diverging children.
3521 hir::ExprLoop(..) | hir::ExprWhile(..) |
3522 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3524 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3527 // Any expression that produces a value of type `!` must have diverged
3529 self.diverges.set(self.diverges.get() | Diverges::Always);
3532 // Record the type, which applies it effects.
3533 // We need to do this after the warning above, so that
3534 // we don't warn for the diverging expression itself.
3535 self.write_ty(expr.hir_id, ty);
3537 // Combine the diverging and has_error flags.
3538 self.diverges.set(self.diverges.get() | old_diverges);
3539 self.has_errors.set(self.has_errors.get() | old_has_errors);
3541 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3542 debug!("... {:?}, expected is {:?}", ty, expected);
3547 fn check_expr_kind(&self,
3548 expr: &'gcx hir::Expr,
3549 expected: Expectation<'tcx>,
3550 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3554 hir::ExprBox(ref subexpr) => {
3555 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3557 ty::TyAdt(def, _) if def.is_box()
3558 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3562 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3563 tcx.mk_box(referent_ty)
3566 hir::ExprLit(ref lit) => {
3567 self.check_lit(&lit, expected)
3569 hir::ExprBinary(op, ref lhs, ref rhs) => {
3570 self.check_binop(expr, op, lhs, rhs)
3572 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3573 self.check_binop_assign(expr, op, lhs, rhs)
3575 hir::ExprUnary(unop, ref oprnd) => {
3576 let expected_inner = match unop {
3577 hir::UnNot | hir::UnNeg => {
3584 let lvalue_pref = match unop {
3585 hir::UnDeref => lvalue_pref,
3588 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3592 if !oprnd_t.references_error() {
3593 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3596 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3598 } else if let Some(ok) = self.try_overloaded_deref(
3599 expr.span, oprnd_t, lvalue_pref) {
3600 let method = self.register_infer_ok_obligations(ok);
3601 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3602 self.apply_adjustments(oprnd, vec![Adjustment {
3603 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
3604 target: method.sig.inputs()[0]
3607 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3608 self.write_method_call(expr.hir_id, method);
3610 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3611 "type `{}` cannot be dereferenced",
3613 oprnd_t = tcx.types.err;
3617 let result = self.check_user_unop(expr, oprnd_t, unop);
3618 // If it's builtin, we can reuse the type, this helps inference.
3619 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3624 let result = self.check_user_unop(expr, oprnd_t, unop);
3625 // If it's builtin, we can reuse the type, this helps inference.
3626 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3634 hir::ExprAddrOf(mutbl, ref oprnd) => {
3635 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3637 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3638 if self.tcx.expr_is_lval(&oprnd) {
3639 // Lvalues may legitimately have unsized types.
3640 // For example, dereferences of a fat pointer and
3641 // the last field of a struct can be unsized.
3642 ExpectHasType(mt.ty)
3644 Expectation::rvalue_hint(self, mt.ty)
3650 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3651 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3653 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3654 if tm.ty.references_error() {
3657 // Note: at this point, we cannot say what the best lifetime
3658 // is to use for resulting pointer. We want to use the
3659 // shortest lifetime possible so as to avoid spurious borrowck
3660 // errors. Moreover, the longest lifetime will depend on the
3661 // precise details of the value whose address is being taken
3662 // (and how long it is valid), which we don't know yet until type
3663 // inference is complete.
3665 // Therefore, here we simply generate a region variable. The
3666 // region inferencer will then select the ultimate value.
3667 // Finally, borrowck is charged with guaranteeing that the
3668 // value whose address was taken can actually be made to live
3669 // as long as it needs to live.
3670 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3671 tcx.mk_ref(region, tm)
3674 hir::ExprPath(ref qpath) => {
3675 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3676 expr.id, expr.span);
3677 let ty = if def != Def::Err {
3678 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3680 self.set_tainted_by_errors();
3684 // We always require that the type provided as the value for
3685 // a type parameter outlives the moment of instantiation.
3686 let substs = self.tables.borrow().node_substs(expr.hir_id);
3687 self.add_wf_bounds(substs, expr);
3691 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3692 for output in outputs {
3693 self.check_expr(output);
3695 for input in inputs {
3696 self.check_expr(input);
3700 hir::ExprBreak(destination, ref expr_opt) => {
3701 if let Some(target_id) = destination.target_id.opt_id() {
3702 let (e_ty, e_diverges, cause);
3703 if let Some(ref e) = *expr_opt {
3704 // If this is a break with a value, we need to type-check
3705 // the expression. Get an expected type from the loop context.
3706 let opt_coerce_to = {
3707 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3708 enclosing_breakables.find_breakable(target_id)
3711 .map(|coerce| coerce.expected_ty())
3714 // If the loop context is not a `loop { }`, then break with
3715 // a value is illegal, and `opt_coerce_to` will be `None`.
3716 // Just set expectation to error in that case.
3717 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3719 // Recurse without `enclosing_breakables` borrowed.
3720 e_ty = self.check_expr_with_hint(e, coerce_to);
3721 e_diverges = self.diverges.get();
3722 cause = self.misc(e.span);
3724 // Otherwise, this is a break *without* a value. That's
3725 // always legal, and is equivalent to `break ()`.
3726 e_ty = tcx.mk_nil();
3727 e_diverges = Diverges::Maybe;
3728 cause = self.misc(expr.span);
3731 // Now that we have type-checked `expr_opt`, borrow
3732 // the `enclosing_loops` field and let's coerce the
3733 // type of `expr_opt` into what is expected.
3734 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3735 let ctxt = enclosing_breakables.find_breakable(target_id);
3736 if let Some(ref mut coerce) = ctxt.coerce {
3737 if let Some(ref e) = *expr_opt {
3738 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3740 assert!(e_ty.is_nil());
3741 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3744 // If `ctxt.coerce` is `None`, we can just ignore
3745 // the type of the expresison. This is because
3746 // either this was a break *without* a value, in
3747 // which case it is always a legal type (`()`), or
3748 // else an error would have been flagged by the
3749 // `loops` pass for using break with an expression
3750 // where you are not supposed to.
3751 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3754 ctxt.may_break = true;
3756 // Otherwise, we failed to find the enclosing loop;
3757 // this can only happen if the `break` was not
3758 // inside a loop at all, which is caught by the
3759 // loop-checking pass.
3760 assert!(self.tcx.sess.err_count() > 0);
3762 // We still need to assign a type to the inner expression to
3763 // prevent the ICE in #43162.
3764 if let Some(ref e) = *expr_opt {
3765 self.check_expr_with_hint(e, tcx.types.err);
3767 // ... except when we try to 'break rust;'.
3768 // ICE this expression in particular (see #43162).
3769 if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
3770 if path.segments.len() == 1 && path.segments[0].name == "rust" {
3771 fatally_break_rust(self.tcx.sess);
3777 // the type of a `break` is always `!`, since it diverges
3780 hir::ExprAgain(_) => { tcx.types.never }
3781 hir::ExprRet(ref expr_opt) => {
3782 if self.ret_coercion.is_none() {
3783 struct_span_err!(self.tcx.sess, expr.span, E0572,
3784 "return statement outside of function body").emit();
3785 } else if let Some(ref e) = *expr_opt {
3786 self.check_return_expr(e);
3788 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3789 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3790 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3794 hir::ExprAssign(ref lhs, ref rhs) => {
3795 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3797 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3800 ExpectIfCondition => {
3801 self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
3802 expected error elsehwere");
3805 // Only check this if not in an `if` condition, as the
3806 // mistyped comparison help is more appropriate.
3807 if !self.tcx.expr_is_lval(&lhs) {
3808 struct_span_err!(self.tcx.sess, expr.span, E0070,
3809 "invalid left-hand side expression")
3810 .span_label(expr.span, "left-hand of expression not valid")
3816 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3818 if lhs_ty.references_error() || rhs_ty.references_error() {
3824 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3825 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3826 expr.span, expected)
3828 hir::ExprWhile(ref cond, ref body, _) => {
3829 let ctxt = BreakableCtxt {
3830 // cannot use break with a value from a while loop
3835 self.with_breakable_ctxt(expr.id, ctxt, || {
3836 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
3837 let cond_diverging = self.diverges.get();
3838 self.check_block_no_value(&body);
3840 // We may never reach the body so it diverging means nothing.
3841 self.diverges.set(cond_diverging);
3846 hir::ExprLoop(ref body, _, source) => {
3847 let coerce = match source {
3848 // you can only use break with a value from a normal `loop { }`
3849 hir::LoopSource::Loop => {
3850 let coerce_to = expected.coercion_target_type(self, body.span);
3851 Some(CoerceMany::new(coerce_to))
3854 hir::LoopSource::WhileLet |
3855 hir::LoopSource::ForLoop => {
3860 let ctxt = BreakableCtxt {
3862 may_break: false, // will get updated if/when we find a `break`
3865 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3866 self.check_block_no_value(&body);
3870 // No way to know whether it's diverging because
3871 // of a `break` or an outer `break` or `return.
3872 self.diverges.set(Diverges::Maybe);
3875 // If we permit break with a value, then result type is
3876 // the LUB of the breaks (possibly ! if none); else, it
3877 // is nil. This makes sense because infinite loops
3878 // (which would have type !) are only possible iff we
3879 // permit break with a value [1].
3880 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3881 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3883 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3884 self.check_match(expr, &discrim, arms, expected, match_src)
3886 hir::ExprClosure(capture, ref decl, body_id, _, _) => {
3887 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3889 hir::ExprBlock(ref body) => {
3890 self.check_block_with_expected(&body, expected)
3892 hir::ExprCall(ref callee, ref args) => {
3893 self.check_call(expr, &callee, args, expected)
3895 hir::ExprMethodCall(ref segment, span, ref args) => {
3896 self.check_method_call(expr, segment, span, args, expected, lvalue_pref)
3898 hir::ExprCast(ref e, ref t) => {
3899 // Find the type of `e`. Supply hints based on the type we are casting to,
3901 let t_cast = self.to_ty(t);
3902 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3903 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3904 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3905 let diverges = self.diverges.get();
3907 // Eagerly check for some obvious errors.
3908 if t_expr.references_error() || t_cast.references_error() {
3911 // Defer other checks until we're done type checking.
3912 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3913 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3915 deferred_cast_checks.push(cast_check);
3918 Err(ErrorReported) => {
3924 hir::ExprType(ref e, ref t) => {
3925 let typ = self.to_ty(&t);
3926 self.check_expr_eq_type(&e, typ);
3929 hir::ExprArray(ref args) => {
3930 let uty = expected.to_option(self).and_then(|uty| {
3932 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3937 let element_ty = if !args.is_empty() {
3938 let coerce_to = uty.unwrap_or_else(
3939 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3940 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3941 assert_eq!(self.diverges.get(), Diverges::Maybe);
3943 let e_ty = self.check_expr_with_hint(e, coerce_to);
3944 let cause = self.misc(e.span);
3945 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3947 coerce.complete(self)
3949 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3951 tcx.mk_array(element_ty, args.len() as u64)
3953 hir::ExprRepeat(ref element, count) => {
3954 let count_def_id = tcx.hir.body_owner_def_id(count);
3955 let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing);
3956 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
3957 let count = tcx.const_eval(param_env.and((count_def_id, substs)));
3959 if let Err(ref err) = count {
3960 err.report(tcx, tcx.def_span(count_def_id), "constant expression");
3963 let uty = match expected {
3964 ExpectHasType(uty) => {
3966 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3973 let (element_ty, t) = match uty {
3975 self.check_expr_coercable_to_type(&element, uty);
3979 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3980 let element_ty = self.check_expr_has_type_or_error(&element, t);
3985 if let Ok(count) = count {
3986 let zero_or_one = count.val.to_const_int().and_then(|count| {
3987 count.to_u64().map(|count| count <= 1)
3988 }).unwrap_or(false);
3990 // For [foo, ..n] where n > 1, `foo` must have
3992 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3993 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3997 if element_ty.references_error() {
3999 } else if let Ok(count) = count {
4000 tcx.mk_ty(ty::TyArray(t, count))
4005 hir::ExprTup(ref elts) => {
4006 let flds = expected.only_has_type(self).and_then(|ty| {
4007 let ty = self.resolve_type_vars_with_obligations(ty);
4009 ty::TyTuple(ref flds, _) => Some(&flds[..]),
4014 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4015 let t = match flds {
4016 Some(ref fs) if i < fs.len() => {
4018 self.check_expr_coercable_to_type(&e, ety);
4022 self.check_expr_with_expectation(&e, NoExpectation)
4027 let tuple = tcx.mk_tup(elt_ts_iter, false);
4028 if tuple.references_error() {
4031 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4035 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
4036 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4038 hir::ExprField(ref base, ref field) => {
4039 self.check_field(expr, lvalue_pref, &base, field)
4041 hir::ExprTupField(ref base, idx) => {
4042 self.check_tup_field(expr, lvalue_pref, &base, idx)
4044 hir::ExprIndex(ref base, ref idx) => {
4045 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
4046 let idx_t = self.check_expr(&idx);
4048 if base_t.references_error() {
4050 } else if idx_t.references_error() {
4053 let base_t = self.structurally_resolved_type(expr.span, base_t);
4054 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
4055 Some((index_ty, element_ty)) => {
4056 self.demand_coerce(idx, idx_t, index_ty);
4060 let mut err = type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4061 "cannot index into a value of type `{}`",
4063 // Try to give some advice about indexing tuples.
4064 if let ty::TyTuple(..) = base_t.sty {
4065 let mut needs_note = true;
4066 // If the index is an integer, we can show the actual
4067 // fixed expression:
4068 if let hir::ExprLit(ref lit) = idx.node {
4069 if let ast::LitKind::Int(i,
4070 ast::LitIntType::Unsuffixed) = lit.node {
4071 let snip = tcx.sess.codemap().span_to_snippet(base.span);
4072 if let Ok(snip) = snip {
4073 err.span_suggestion(expr.span,
4074 "to access tuple elements, use",
4075 format!("{}.{}", snip, i));
4081 err.help("to access tuple elements, use tuple indexing \
4082 syntax (e.g. `tuple.0`)");
4091 hir::ExprYield(ref value) => {
4092 match self.yield_ty {
4094 self.check_expr_coercable_to_type(&value, ty);
4097 struct_span_err!(self.tcx.sess, expr.span, E0627,
4098 "yield statement outside of generator literal").emit();
4106 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4107 // The newly resolved definition is written into `type_dependent_defs`.
4108 fn finish_resolving_struct_path(&self,
4111 node_id: ast::NodeId)
4115 hir::QPath::Resolved(ref maybe_qself, ref path) => {
4116 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4117 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
4120 hir::QPath::TypeRelative(ref qself, ref segment) => {
4121 let ty = self.to_ty(qself);
4123 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
4128 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4131 // Write back the new resolution.
4132 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4133 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4140 // Resolve associated value path into a base type and associated constant or method definition.
4141 // The newly resolved definition is written into `type_dependent_defs`.
4142 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4143 qpath: &'b hir::QPath,
4144 node_id: ast::NodeId,
4146 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4148 let (ty, item_segment) = match *qpath {
4149 hir::QPath::Resolved(ref opt_qself, ref path) => {
4151 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4152 &path.segments[..]);
4154 hir::QPath::TypeRelative(ref qself, ref segment) => {
4155 (self.to_ty(qself), segment)
4158 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4159 if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4160 // Return directly on cache hit. This is useful to avoid doubly reporting
4161 // errors with default match binding modes. See #44614.
4162 return (*cached_def, Some(ty), slice::ref_slice(&**item_segment))
4164 let item_name = item_segment.name;
4165 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
4168 let def = match error {
4169 method::MethodError::PrivateMatch(def, _) => def,
4172 if item_name != keywords::Invalid.name() {
4173 self.report_method_error(span, ty, item_name, None, error, None);
4179 // Write back the new resolution.
4180 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4181 (def, Some(ty), slice::ref_slice(&**item_segment))
4184 pub fn check_decl_initializer(&self,
4185 local: &'gcx hir::Local,
4186 init: &'gcx hir::Expr) -> Ty<'tcx>
4188 // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed
4189 // for #42640 (default match binding modes).
4192 let ref_bindings = local.pat.contains_explicit_ref_binding();
4194 let local_ty = self.local_ty(init.span, local.id);
4195 if let Some(m) = ref_bindings {
4196 // Somewhat subtle: if we have a `ref` binding in the pattern,
4197 // we want to avoid introducing coercions for the RHS. This is
4198 // both because it helps preserve sanity and, in the case of
4199 // ref mut, for soundness (issue #23116). In particular, in
4200 // the latter case, we need to be clear that the type of the
4201 // referent for the reference that results is *equal to* the
4202 // type of the lvalue it is referencing, and not some
4203 // supertype thereof.
4204 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
4205 self.demand_eqtype(init.span, init_ty, local_ty);
4208 self.check_expr_coercable_to_type(init, local_ty)
4212 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4213 let t = self.local_ty(local.span, local.id);
4214 self.write_ty(local.hir_id, t);
4216 if let Some(ref init) = local.init {
4217 let init_ty = self.check_decl_initializer(local, &init);
4218 if init_ty.references_error() {
4219 self.write_ty(local.hir_id, init_ty);
4223 self.check_pat_walk(&local.pat, t,
4224 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4226 let pat_ty = self.node_ty(local.pat.hir_id);
4227 if pat_ty.references_error() {
4228 self.write_ty(local.hir_id, pat_ty);
4232 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4233 // Don't do all the complex logic below for DeclItem.
4235 hir::StmtDecl(ref decl, _) => {
4237 hir::DeclLocal(_) => {}
4238 hir::DeclItem(_) => {
4243 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4246 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4248 // Hide the outer diverging and has_errors flags.
4249 let old_diverges = self.diverges.get();
4250 let old_has_errors = self.has_errors.get();
4251 self.diverges.set(Diverges::Maybe);
4252 self.has_errors.set(false);
4255 hir::StmtDecl(ref decl, _) => {
4257 hir::DeclLocal(ref l) => {
4258 self.check_decl_local(&l);
4260 hir::DeclItem(_) => {/* ignore for now */}
4263 hir::StmtExpr(ref expr, _) => {
4264 // Check with expected type of ()
4265 self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
4267 hir::StmtSemi(ref expr, _) => {
4268 self.check_expr(&expr);
4272 // Combine the diverging and has_error flags.
4273 self.diverges.set(self.diverges.get() | old_diverges);
4274 self.has_errors.set(self.has_errors.get() | old_has_errors);
4277 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4278 let unit = self.tcx.mk_nil();
4279 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4281 // if the block produces a `!` value, that can always be
4282 // (effectively) coerced to unit.
4284 self.demand_suptype(blk.span, unit, ty);
4288 fn check_block_with_expected(&self,
4289 blk: &'gcx hir::Block,
4290 expected: Expectation<'tcx>) -> Ty<'tcx> {
4292 let mut fcx_ps = self.ps.borrow_mut();
4293 let unsafety_state = fcx_ps.recurse(blk);
4294 replace(&mut *fcx_ps, unsafety_state)
4297 // In some cases, blocks have just one exit, but other blocks
4298 // can be targeted by multiple breaks. This cannot happen in
4299 // normal Rust syntax today, but it can happen when we desugar
4300 // a `do catch { ... }` expression.
4304 // 'a: { if true { break 'a Err(()); } Ok(()) }
4306 // Here we would wind up with two coercions, one from
4307 // `Err(())` and the other from the tail expression
4308 // `Ok(())`. If the tail expression is omitted, that's a
4309 // "forced unit" -- unless the block diverges, in which
4310 // case we can ignore the tail expression (e.g., `'a: {
4311 // break 'a 22; }` would not force the type of the block
4313 let tail_expr = blk.expr.as_ref();
4314 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4315 let coerce = if blk.targeted_by_break {
4316 CoerceMany::new(coerce_to_ty)
4318 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4319 Some(e) => ref_slice(e),
4322 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4325 let prev_diverges = self.diverges.get();
4326 let ctxt = BreakableCtxt {
4327 coerce: Some(coerce),
4331 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4332 for s in &blk.stmts {
4336 // check the tail expression **without** holding the
4337 // `enclosing_breakables` lock below.
4338 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4340 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4341 let ctxt = enclosing_breakables.find_breakable(blk.id);
4342 let coerce = ctxt.coerce.as_mut().unwrap();
4343 if let Some(tail_expr_ty) = tail_expr_ty {
4344 let tail_expr = tail_expr.unwrap();
4345 let cause = self.cause(tail_expr.span,
4346 ObligationCauseCode::BlockTailExpression(blk.id));
4351 self.diverges.get());
4353 // Subtle: if there is no explicit tail expression,
4354 // that is typically equivalent to a tail expression
4355 // of `()` -- except if the block diverges. In that
4356 // case, there is no value supplied from the tail
4357 // expression (assuming there are no other breaks,
4358 // this implies that the type of the block will be
4361 // #41425 -- label the implicit `()` as being the
4362 // "found type" here, rather than the "expected type".
4363 if !self.diverges.get().always() {
4364 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4365 if let Some(expected_ty) = expected.only_has_type(self) {
4366 self.consider_hint_about_removing_semicolon(blk,
4376 // If we can break from the block, then the block's exit is always reachable
4377 // (... as long as the entry is reachable) - regardless of the tail of the block.
4378 self.diverges.set(prev_diverges);
4381 let mut ty = ctxt.coerce.unwrap().complete(self);
4383 if self.has_errors.get() || ty.references_error() {
4384 ty = self.tcx.types.err
4387 self.write_ty(blk.hir_id, ty);
4389 *self.ps.borrow_mut() = prev;
4393 /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
4394 /// suggestion can be made, `None` otherwise.
4395 pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
4396 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4397 // `while` before reaching it, as block tail returns are not available in them.
4398 if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
4399 let parent = self.tcx.hir.get(fn_id);
4401 if let Node::NodeItem(&hir::Item {
4402 name, node: hir::ItemFn(ref decl, ..), ..
4404 decl.clone().and_then(|decl| {
4405 // This is less than ideal, it will not suggest a return type span on any
4406 // method called `main`, regardless of whether it is actually the entry point,
4407 // but it will still present it as the reason for the expected type.
4408 Some((decl, name != Symbol::intern("main")))
4410 } else if let Node::NodeTraitItem(&hir::TraitItem {
4411 node: hir::TraitItemKind::Method(hir::MethodSig {
4415 decl.clone().and_then(|decl| {
4418 } else if let Node::NodeImplItem(&hir::ImplItem {
4419 node: hir::ImplItemKind::Method(hir::MethodSig {
4423 decl.clone().and_then(|decl| {
4434 /// On implicit return expressions with mismatched types, provide the following suggestions:
4436 /// - Point out the method's return type as the reason for the expected type
4437 /// - Possible missing semicolon
4438 /// - Possible missing return type if the return type is the default, and not `fn main()`
4439 pub fn suggest_mismatched_types_on_tail(&self,
4440 err: &mut DiagnosticBuilder<'tcx>,
4441 expression: &'gcx hir::Expr,
4445 blk_id: ast::NodeId) {
4446 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4448 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4449 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4453 /// A common error is to forget to add a semicolon at the end of a block:
4457 /// bar_that_returns_u32()
4461 /// This routine checks if the return expression in a block would make sense on its own as a
4462 /// statement and the return type has been left as default or has been specified as `()`. If so,
4463 /// it suggests adding a semicolon.
4464 fn suggest_missing_semicolon(&self,
4465 err: &mut DiagnosticBuilder<'tcx>,
4466 expression: &'gcx hir::Expr,
4469 if expected.is_nil() {
4470 // `BlockTailExpression` only relevant if the tail expr would be
4471 // useful on its own.
4472 match expression.node {
4474 hir::ExprMethodCall(..) |
4476 hir::ExprWhile(..) |
4478 hir::ExprMatch(..) |
4479 hir::ExprBlock(..) => {
4480 let sp = cause_span.next_point();
4481 err.span_suggestion(sp,
4482 "try adding a semicolon",
4491 /// A possible error is to forget to add a return type that is needed:
4495 /// bar_that_returns_u32()
4499 /// This routine checks if the return type is left as default, the method is not part of an
4500 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4502 fn suggest_missing_return_type(&self,
4503 err: &mut DiagnosticBuilder<'tcx>,
4504 fn_decl: &hir::FnDecl,
4507 can_suggest: bool) {
4508 // Only suggest changing the return type for methods that
4509 // haven't set a return type at all (and aren't `fn main()` or an impl).
4510 match (&fn_decl.output, found.is_suggestable(), can_suggest) {
4511 (&hir::FunctionRetTy::DefaultReturn(span), true, true) => {
4512 err.span_suggestion(span,
4513 "try adding a return type",
4514 format!("-> {} ", found));
4516 (&hir::FunctionRetTy::DefaultReturn(span), false, true) => {
4517 err.span_label(span, "possibly return type missing here?");
4519 (&hir::FunctionRetTy::DefaultReturn(span), _, _) => {
4520 // `fn main()` must return `()`, do not suggest changing return type
4521 err.span_label(span, "expected `()` because of default return type");
4523 (&hir::FunctionRetTy::Return(ref ty), _, _) => {
4524 // Only point to return type if the expected type is the return type, as if they
4525 // are not, the expectation must have been caused by something else.
4526 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4528 let ty = AstConv::ast_ty_to_ty(self, ty);
4529 debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
4530 debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
4531 if ty.sty == expected.sty {
4532 err.span_label(sp, format!("expected `{}` because of return type",
4540 /// A common error is to add an extra semicolon:
4543 /// fn foo() -> usize {
4548 /// This routine checks if the final statement in a block is an
4549 /// expression with an explicit semicolon whose type is compatible
4550 /// with `expected_ty`. If so, it suggests removing the semicolon.
4551 fn consider_hint_about_removing_semicolon(&self,
4552 blk: &'gcx hir::Block,
4553 expected_ty: Ty<'tcx>,
4554 err: &mut DiagnosticBuilder) {
4555 // Be helpful when the user wrote `{... expr;}` and
4556 // taking the `;` off is enough to fix the error.
4557 let last_stmt = match blk.stmts.last() {
4561 let last_expr = match last_stmt.node {
4562 hir::StmtSemi(ref e, _) => e,
4565 let last_expr_ty = self.node_ty(last_expr.hir_id);
4566 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4569 let original_span = original_sp(last_stmt.span, blk.span);
4570 let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
4571 err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
4574 // Instantiates the given path, which must refer to an item with the given
4575 // number of type parameters and type.
4576 pub fn instantiate_value_path(&self,
4577 segments: &[hir::PathSegment],
4578 opt_self_ty: Option<Ty<'tcx>>,
4581 node_id: ast::NodeId)
4583 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4588 // We need to extract the type parameters supplied by the user in
4589 // the path `path`. Due to the current setup, this is a bit of a
4590 // tricky-process; the problem is that resolve only tells us the
4591 // end-point of the path resolution, and not the intermediate steps.
4592 // Luckily, we can (at least for now) deduce the intermediate steps
4593 // just from the end-point.
4595 // There are basically four cases to consider:
4597 // 1. Reference to a constructor of enum variant or struct:
4599 // struct Foo<T>(...)
4600 // enum E<T> { Foo(...) }
4602 // In these cases, the parameters are declared in the type
4605 // 2. Reference to a fn item or a free constant:
4609 // In this case, the path will again always have the form
4610 // `a::b::foo::<T>` where only the final segment should have
4611 // type parameters. However, in this case, those parameters are
4612 // declared on a value, and hence are in the `FnSpace`.
4614 // 3. Reference to a method or an associated constant:
4616 // impl<A> SomeStruct<A> {
4620 // Here we can have a path like
4621 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4622 // may appear in two places. The penultimate segment,
4623 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4624 // final segment, `foo::<B>` contains parameters in fn space.
4626 // 4. Reference to a local variable
4628 // Local variables can't have any type parameters.
4630 // The first step then is to categorize the segments appropriately.
4632 assert!(!segments.is_empty());
4634 let mut ufcs_associated = None;
4635 let mut type_segment = None;
4636 let mut fn_segment = None;
4638 // Case 1. Reference to a struct/variant constructor.
4639 Def::StructCtor(def_id, ..) |
4640 Def::VariantCtor(def_id, ..) => {
4641 // Everything but the final segment should have no
4642 // parameters at all.
4643 let mut generics = self.tcx.generics_of(def_id);
4644 if let Some(def_id) = generics.parent {
4645 // Variant and struct constructors use the
4646 // generics of their parent type definition.
4647 generics = self.tcx.generics_of(def_id);
4649 type_segment = Some((segments.last().unwrap(), generics));
4652 // Case 2. Reference to a top-level value.
4654 Def::Const(def_id) |
4655 Def::Static(def_id, _) => {
4656 fn_segment = Some((segments.last().unwrap(),
4657 self.tcx.generics_of(def_id)));
4660 // Case 3. Reference to a method or associated const.
4661 Def::Method(def_id) |
4662 Def::AssociatedConst(def_id) => {
4663 let container = self.tcx.associated_item(def_id).container;
4665 ty::TraitContainer(trait_did) => {
4666 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4668 ty::ImplContainer(_) => {}
4671 let generics = self.tcx.generics_of(def_id);
4672 if segments.len() >= 2 {
4673 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4674 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4676 // `<T>::assoc` will end up here, and so can `T::assoc`.
4677 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4678 ufcs_associated = Some((container, self_ty));
4680 fn_segment = Some((segments.last().unwrap(), generics));
4683 // Case 4. Local variable, no generics.
4684 Def::Local(..) | Def::Upvar(..) => {}
4686 _ => bug!("unexpected definition: {:?}", def),
4689 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4691 // Now that we have categorized what space the parameters for each
4692 // segment belong to, let's sort out the parameters that the user
4693 // provided (if any) into their appropriate spaces. We'll also report
4694 // errors if type parameters are provided in an inappropriate place.
4695 let poly_segments = type_segment.is_some() as usize +
4696 fn_segment.is_some() as usize;
4697 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4700 Def::Local(nid) | Def::Upvar(nid, ..) => {
4701 let ty = self.local_ty(span, nid);
4702 let ty = self.normalize_associated_types_in(span, &ty);
4703 self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
4709 // Now we have to compare the types that the user *actually*
4710 // provided against the types that were *expected*. If the user
4711 // did not provide any types, then we want to substitute inference
4712 // variables. If the user provided some types, we may still need
4713 // to add defaults. If the user provided *too many* types, that's
4715 self.check_path_parameter_count(span, &mut type_segment, false);
4716 self.check_path_parameter_count(span, &mut fn_segment, false);
4717 self.check_impl_trait(span, &mut fn_segment);
4719 let (fn_start, has_self) = match (type_segment, fn_segment) {
4720 (_, Some((_, generics))) => {
4721 (generics.parent_count(), generics.has_self)
4723 (Some((_, generics)), None) => {
4724 (generics.own_count(), generics.has_self)
4726 (None, None) => (0, false)
4728 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4729 let mut i = def.index as usize;
4731 let segment = if i < fn_start {
4732 i -= has_self as usize;
4738 let lifetimes = segment.map_or(&[][..], |(s, _)| {
4739 s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
4742 if let Some(lifetime) = lifetimes.get(i) {
4743 AstConv::ast_region_to_region(self, lifetime, Some(def))
4745 self.re_infer(span, Some(def)).unwrap()
4748 let mut i = def.index as usize;
4750 let segment = if i < fn_start {
4751 // Handle Self first, so we can adjust the index to match the AST.
4752 if has_self && i == 0 {
4753 return opt_self_ty.unwrap_or_else(|| {
4754 self.type_var_for_def(span, def, substs)
4757 i -= has_self as usize;
4763 let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
4764 (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
4767 // Skip over the lifetimes in the same segment.
4768 if let Some((_, generics)) = segment {
4769 i -= generics.regions.len();
4772 if let Some(ast_ty) = types.get(i) {
4773 // A provided type parameter.
4775 } else if !infer_types && def.has_default {
4776 // No type parameter provided, but a default exists.
4777 let default = self.tcx.type_of(def.def_id);
4780 default.subst_spanned(self.tcx, substs, Some(span))
4783 // No type parameters were provided, we can infer all.
4784 // This can also be reached in some error cases:
4785 // We prefer to use inference variables instead of
4786 // TyError to let type inference recover somewhat.
4787 self.type_var_for_def(span, def, substs)
4791 // The things we are substituting into the type should not contain
4792 // escaping late-bound regions, and nor should the base type scheme.
4793 let ty = self.tcx.type_of(def.def_id());
4794 assert!(!substs.has_escaping_regions());
4795 assert!(!ty.has_escaping_regions());
4797 // Add all the obligations that are required, substituting and
4798 // normalized appropriately.
4799 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4800 self.add_obligations_for_parameters(
4801 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4804 // Substitute the values for the type parameters into the type of
4805 // the referenced item.
4806 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4808 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4809 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4810 // is inherent, there is no `Self` parameter, instead, the impl needs
4811 // type parameters, which we can infer by unifying the provided `Self`
4812 // with the substituted impl type.
4813 let ty = self.tcx.type_of(impl_def_id);
4815 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4816 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4817 Ok(ok) => self.register_infer_ok_obligations(ok),
4820 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4827 debug!("instantiate_value_path: type of {:?} is {:?}",
4830 self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
4834 /// Report errors if the provided parameters are too few or too many.
4835 fn check_path_parameter_count(&self,
4837 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
4838 is_method_call: bool) {
4839 let (lifetimes, types, infer_types, bindings) = segment.map_or(
4840 (&[][..], &[][..], true, &[][..]),
4841 |(s, _)| s.parameters.as_ref().map_or(
4842 (&[][..], &[][..], s.infer_types, &[][..]),
4843 |p| (&p.lifetimes[..], &p.types[..],
4844 s.infer_types, &p.bindings[..])));
4845 let infer_lifetimes = lifetimes.len() == 0;
4847 let count_lifetime_params = |n| {
4848 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4850 let count_type_params = |n| {
4851 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4854 // Check provided type parameters.
4855 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4856 if generics.parent.is_none() {
4857 &generics.types[generics.has_self as usize..]
4862 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4863 if types.len() > type_defs.len() {
4864 let span = types[type_defs.len()].span;
4865 let expected_text = count_type_params(type_defs.len());
4866 let actual_text = count_type_params(types.len());
4867 struct_span_err!(self.tcx.sess, span, E0087,
4868 "too many type parameters provided: \
4869 expected at most {}, found {}",
4870 expected_text, actual_text)
4871 .span_label(span, format!("expected {}", expected_text))
4874 // To prevent derived errors to accumulate due to extra
4875 // type parameters, we force instantiate_value_path to
4876 // use inference variables instead of the provided types.
4878 } else if types.len() < required_len && !infer_types {
4879 let expected_text = count_type_params(required_len);
4880 let actual_text = count_type_params(types.len());
4881 struct_span_err!(self.tcx.sess, span, E0089,
4882 "too few type parameters provided: \
4883 expected {}, found {}",
4884 expected_text, actual_text)
4885 .span_label(span, format!("expected {}", expected_text))
4889 if !bindings.is_empty() {
4890 AstConv::prohibit_projection(self, bindings[0].span);
4893 // Check provided lifetime parameters.
4894 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4895 let required_len = lifetime_defs.len();
4897 // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
4898 let has_late_bound_lifetime_defs =
4899 segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
4900 if let (Some(span_late), false) = (has_late_bound_lifetime_defs, lifetimes.is_empty()) {
4901 // Report this as a lint only if no error was reported previously.
4902 let primary_msg = "cannot specify lifetime arguments explicitly \
4903 if late bound lifetime parameters are present";
4904 let note_msg = "the late bound lifetime parameter is introduced here";
4905 if !is_method_call && (lifetimes.len() > lifetime_defs.len() ||
4906 lifetimes.len() < required_len && !infer_lifetimes) {
4907 let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
4908 err.span_note(span_late, note_msg);
4912 let mut multispan = MultiSpan::from_span(lifetimes[0].span);
4913 multispan.push_span_label(span_late, note_msg.to_string());
4914 self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
4915 lifetimes[0].id, multispan, primary_msg);
4920 if lifetimes.len() > lifetime_defs.len() {
4921 let span = lifetimes[lifetime_defs.len()].span;
4922 let expected_text = count_lifetime_params(lifetime_defs.len());
4923 let actual_text = count_lifetime_params(lifetimes.len());
4924 struct_span_err!(self.tcx.sess, span, E0088,
4925 "too many lifetime parameters provided: \
4926 expected at most {}, found {}",
4927 expected_text, actual_text)
4928 .span_label(span, format!("expected {}", expected_text))
4930 } else if lifetimes.len() < required_len && !infer_lifetimes {
4931 let expected_text = count_lifetime_params(lifetime_defs.len());
4932 let actual_text = count_lifetime_params(lifetimes.len());
4933 struct_span_err!(self.tcx.sess, span, E0090,
4934 "too few lifetime parameters provided: \
4935 expected {}, found {}",
4936 expected_text, actual_text)
4937 .span_label(span, format!("expected {}", expected_text))
4942 /// Report error if there is an explicit type parameter when using `impl Trait`.
4943 fn check_impl_trait(&self,
4945 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4946 use hir::SyntheticTyParamKind::*;
4948 segment.map(|(path_segment, generics)| {
4949 let explicit = !path_segment.infer_types;
4950 let impl_trait = generics.types.iter()
4952 match ty_param.synthetic {
4953 Some(ImplTrait) => true,
4958 if explicit && impl_trait {
4959 let mut err = struct_span_err! {
4963 "cannot provide explicit type parameters when `impl Trait` is \
4964 used in argument position."
4972 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4974 where F: Fn() -> Ty<'tcx>
4976 let mut ty = self.resolve_type_vars_with_obligations(ty);
4979 let alternative = f();
4982 if alternative.is_ty_var() || alternative.references_error() {
4983 if !self.is_tainted_by_errors() {
4984 type_error_struct!(self.tcx.sess, sp, ty, E0619,
4985 "the type of this value must be known in this context")
4988 self.demand_suptype(sp, self.tcx.types.err, ty);
4989 ty = self.tcx.types.err;
4991 self.demand_suptype(sp, alternative, ty);
4999 // Resolves `typ` by a single level if `typ` is a type variable. If no
5000 // resolution is possible, then an error is reported.
5001 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5002 self.structurally_resolve_type_or_else(sp, ty, || {
5007 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
5008 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5009 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5012 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5013 index = enclosing_breakables.stack.len();
5014 enclosing_breakables.by_id.insert(id, index);
5015 enclosing_breakables.stack.push(ctxt);
5019 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5020 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5021 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5022 enclosing_breakables.stack.pop().expect("missing breakable context")
5028 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5029 generics: &hir::Generics,
5031 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
5032 generics.ty_params.len(), ty);
5034 // make a vector of booleans initially false, set to true when used
5035 if generics.ty_params.is_empty() { return; }
5036 let mut tps_used = vec![false; generics.ty_params.len()];
5038 for leaf_ty in ty.walk() {
5039 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
5040 debug!("Found use of ty param num {}", idx);
5041 tps_used[idx as usize - generics.lifetimes.len()] = true;
5042 } else if let ty::TyError = leaf_ty.sty {
5043 // If there already another error, do not emit an error for not using a type Parameter
5044 assert!(tcx.sess.err_count() > 0);
5049 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
5051 struct_span_err!(tcx.sess, param.span, E0091,
5052 "type parameter `{}` is unused",
5054 .span_label(param.span, "unused type parameter")
5060 fn fatally_break_rust(sess: &Session) {
5061 let handler = sess.diagnostic();
5062 handler.span_bug_no_panic(
5064 "It looks like you're trying to break rust; would you like some ICE?",
5066 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5067 handler.note_without_error(
5068 "we would appreciate a joke overview: \
5069 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5071 handler.note_without_error(&format!("rustc {} running on {}",
5072 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5073 ::session::config::host_triple(),