1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
84 mod generator_interior;
88 use crate::astconv::{AstConv, PathSeg};
89 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
90 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
91 use rustc::hir::def::{CtorOf, CtorKind, Def, DefKind};
92 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
93 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
94 use rustc::hir::itemlikevisit::ItemLikeVisitor;
95 use crate::middle::lang_items;
96 use crate::namespace::Namespace;
97 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
98 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
99 use rustc_data_structures::indexed_vec::Idx;
100 use rustc_data_structures::sync::Lrc;
101 use rustc_target::spec::abi::Abi;
102 use rustc::infer::opaque_types::OpaqueTypeDecl;
103 use rustc::infer::type_variable::{TypeVariableOrigin};
104 use rustc::middle::region;
105 use rustc::mir::interpret::{ConstValue, GlobalId};
106 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
108 self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
109 ToPolyTraitRef, ToPredicate, RegionKind, UserType
111 use rustc::ty::adjustment::{
112 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
114 use rustc::ty::fold::TypeFoldable;
115 use rustc::ty::query::Providers;
116 use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
117 use rustc::ty::util::{Representability, IntTypeExt, Discr};
118 use rustc::ty::layout::VariantIdx;
119 use syntax_pos::{self, BytePos, Span, MultiSpan};
122 use syntax::feature_gate::{GateIssue, emit_feature_err};
124 use syntax::source_map::{DUMMY_SP, original_sp};
125 use syntax::symbol::{Symbol, LocalInternedString, keywords};
126 use syntax::util::lev_distance::find_best_match_for_name;
128 use std::cell::{Cell, RefCell, Ref, RefMut};
129 use std::collections::hash_map::Entry;
131 use std::fmt::Display;
133 use std::mem::replace;
134 use std::ops::{self, Deref};
137 use crate::require_c_abi_if_c_variadic;
138 use crate::session::Session;
139 use crate::session::config::EntryFnType;
140 use crate::TypeAndSubsts;
142 use crate::util::captures::Captures;
143 use crate::util::common::{ErrorReported, indenter};
144 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, HirIdMap};
146 pub use self::Expectation::*;
147 use self::autoderef::Autoderef;
148 use self::callee::DeferredCallResolution;
149 use self::coercion::{CoerceMany, DynamicCoerceMany};
150 pub use self::compare_method::{compare_impl_method, compare_const_impl};
151 use self::method::{MethodCallee, SelfSource};
152 use self::TupleArgumentsFlag::*;
154 /// The type of a local binding, including the revealed type for anon types.
155 #[derive(Copy, Clone)]
156 pub struct LocalTy<'tcx> {
158 revealed_ty: Ty<'tcx>
161 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
162 #[derive(Copy, Clone)]
163 struct MaybeInProgressTables<'a, 'tcx: 'a> {
164 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
167 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
168 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
169 match self.maybe_tables {
170 Some(tables) => tables.borrow(),
172 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
177 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
178 match self.maybe_tables {
179 Some(tables) => tables.borrow_mut(),
181 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
187 /// Closures defined within the function. For example:
190 /// bar(move|| { ... })
193 /// Here, the function `foo()` and the closure passed to
194 /// `bar()` will each have their own `FnCtxt`, but they will
195 /// share the inherited fields.
196 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
197 infcx: InferCtxt<'a, 'gcx, 'tcx>,
199 tables: MaybeInProgressTables<'a, 'tcx>,
201 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
203 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
205 // Some additional `Sized` obligations badly affect type inference.
206 // These obligations are added in a later stage of typeck.
207 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
209 // When we process a call like `c()` where `c` is a closure type,
210 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
211 // `FnOnce` closure. In that case, we defer full resolution of the
212 // call until upvar inference can kick in and make the
213 // decision. We keep these deferred resolutions grouped by the
214 // def-id of the closure, so that once we decide, we can easily go
215 // back and process them.
216 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
218 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
220 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
222 // Opaque types found in explicit return types and their
223 // associated fresh inference variable. Writeback resolves these
224 // variables to get the concrete type, which can be used to
225 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
226 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
228 /// Each type parameter has an implicit region bound that
229 /// indicates it must outlive at least the function body (the user
230 /// may specify stronger requirements). This field indicates the
231 /// region of the callee. If it is `None`, then the parameter
232 /// environment is for an item or something where the "callee" is
234 implicit_region_bound: Option<ty::Region<'tcx>>,
236 body_id: Option<hir::BodyId>,
239 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
240 type Target = InferCtxt<'a, 'gcx, 'tcx>;
241 fn deref(&self) -> &Self::Target {
246 /// When type-checking an expression, we propagate downward
247 /// whatever type hint we are able in the form of an `Expectation`.
248 #[derive(Copy, Clone, Debug)]
249 pub enum Expectation<'tcx> {
250 /// We know nothing about what type this expression should have.
253 /// This expression should have the type given (or some subtype).
254 ExpectHasType(Ty<'tcx>),
256 /// This expression will be cast to the `Ty`.
257 ExpectCastableToType(Ty<'tcx>),
259 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
260 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
261 ExpectRvalueLikeUnsized(Ty<'tcx>),
264 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
265 // Disregard "castable to" expectations because they
266 // can lead us astray. Consider for example `if cond
267 // {22} else {c} as u8` -- if we propagate the
268 // "castable to u8" constraint to 22, it will pick the
269 // type 22u8, which is overly constrained (c might not
270 // be a u8). In effect, the problem is that the
271 // "castable to" expectation is not the tightest thing
272 // we can say, so we want to drop it in this case.
273 // The tightest thing we can say is "must unify with
274 // else branch". Note that in the case of a "has type"
275 // constraint, this limitation does not hold.
277 // If the expected type is just a type variable, then don't use
278 // an expected type. Otherwise, we might write parts of the type
279 // when checking the 'then' block which are incompatible with the
281 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
283 ExpectHasType(ety) => {
284 let ety = fcx.shallow_resolve(ety);
285 if !ety.is_ty_var() {
291 ExpectRvalueLikeUnsized(ety) => {
292 ExpectRvalueLikeUnsized(ety)
298 /// Provides an expectation for an rvalue expression given an *optional*
299 /// hint, which is not required for type safety (the resulting type might
300 /// be checked higher up, as is the case with `&expr` and `box expr`), but
301 /// is useful in determining the concrete type.
303 /// The primary use case is where the expected type is a fat pointer,
304 /// like `&[isize]`. For example, consider the following statement:
306 /// let x: &[isize] = &[1, 2, 3];
308 /// In this case, the expected type for the `&[1, 2, 3]` expression is
309 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
310 /// expectation `ExpectHasType([isize])`, that would be too strong --
311 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
312 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
313 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
314 /// which still is useful, because it informs integer literals and the like.
315 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
316 /// for examples of where this comes up,.
317 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
318 match fcx.tcx.struct_tail(ty).sty {
319 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
320 ExpectRvalueLikeUnsized(ty)
322 _ => ExpectHasType(ty)
326 // Resolves `expected` by a single level if it is a variable. If
327 // there is no expected type or resolution is not possible (e.g.,
328 // no constraints yet present), just returns `None`.
329 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
331 NoExpectation => NoExpectation,
332 ExpectCastableToType(t) => {
333 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
335 ExpectHasType(t) => {
336 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
338 ExpectRvalueLikeUnsized(t) => {
339 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
344 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
345 match self.resolve(fcx) {
346 NoExpectation => None,
347 ExpectCastableToType(ty) |
349 ExpectRvalueLikeUnsized(ty) => Some(ty),
353 /// It sometimes happens that we want to turn an expectation into
354 /// a **hard constraint** (i.e., something that must be satisfied
355 /// for the program to type-check). `only_has_type` will return
356 /// such a constraint, if it exists.
357 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
358 match self.resolve(fcx) {
359 ExpectHasType(ty) => Some(ty),
360 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
364 /// Like `only_has_type`, but instead of returning `None` if no
365 /// hard constraint exists, creates a fresh type variable.
366 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
367 self.only_has_type(fcx)
368 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
372 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
379 fn maybe_mut_place(m: hir::Mutability) -> Self {
381 hir::MutMutable => Needs::MutPlace,
382 hir::MutImmutable => Needs::None,
387 #[derive(Copy, Clone)]
388 pub struct UnsafetyState {
390 pub unsafety: hir::Unsafety,
391 pub unsafe_push_count: u32,
396 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
397 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
400 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
401 match self.unsafety {
402 // If this unsafe, then if the outer function was already marked as
403 // unsafe we shouldn't attribute the unsafe'ness to the block. This
404 // way the block can be warned about instead of ignoring this
405 // extraneous block (functions are never warned about).
406 hir::Unsafety::Unsafe if self.from_fn => *self,
409 let (unsafety, def, count) = match blk.rules {
410 hir::PushUnsafeBlock(..) =>
411 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
412 hir::PopUnsafeBlock(..) =>
413 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
414 hir::UnsafeBlock(..) =>
415 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
417 (unsafety, self.def, self.unsafe_push_count),
421 unsafe_push_count: count,
428 #[derive(Debug, Copy, Clone)]
434 /// Tracks whether executing a node may exit normally (versus
435 /// return/break/panic, which "diverge", leaving dead code in their
436 /// wake). Tracked semi-automatically (through type variables marked
437 /// as diverging), with some manual adjustments for control-flow
438 /// primitives (approximating a CFG).
439 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
441 /// Potentially unknown, some cases converge,
442 /// others require a CFG to determine them.
445 /// Definitely known to diverge and therefore
446 /// not reach the next sibling or its parent.
449 /// Same as `Always` but with a reachability
450 /// warning already emitted.
454 // Convenience impls for combinig `Diverges`.
456 impl ops::BitAnd for Diverges {
458 fn bitand(self, other: Self) -> Self {
459 cmp::min(self, other)
463 impl ops::BitOr for Diverges {
465 fn bitor(self, other: Self) -> Self {
466 cmp::max(self, other)
470 impl ops::BitAndAssign for Diverges {
471 fn bitand_assign(&mut self, other: Self) {
472 *self = *self & other;
476 impl ops::BitOrAssign for Diverges {
477 fn bitor_assign(&mut self, other: Self) {
478 *self = *self | other;
483 fn always(self) -> bool {
484 self >= Diverges::Always
488 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
491 // this is `null` for loops where break with a value is illegal,
492 // such as `while`, `for`, and `while let`
493 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
496 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
497 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
498 by_id: HirIdMap<usize>,
501 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
502 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'gcx, 'tcx> {
503 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
504 bug!("could not find enclosing breakable with id {}", target_id);
510 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
513 /// The parameter environment used for proving trait obligations
514 /// in this function. This can change when we descend into
515 /// closures (as they bring new things into scope), hence it is
516 /// not part of `Inherited` (as of the time of this writing,
517 /// closures do not yet change the environment, but they will
519 param_env: ty::ParamEnv<'tcx>,
521 // Number of errors that had been reported when we started
522 // checking this function. On exit, if we find that *more* errors
523 // have been reported, we will skip regionck and other work that
524 // expects the types within the function to be consistent.
525 err_count_on_creation: usize,
527 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
528 ret_coercion_span: RefCell<Option<Span>>,
530 yield_ty: Option<Ty<'tcx>>,
532 ps: RefCell<UnsafetyState>,
534 /// Whether the last checked node generates a divergence (e.g.,
535 /// `return` will set this to `Always`). In general, when entering
536 /// an expression or other node in the tree, the initial value
537 /// indicates whether prior parts of the containing expression may
538 /// have diverged. It is then typically set to `Maybe` (and the
539 /// old value remembered) for processing the subparts of the
540 /// current expression. As each subpart is processed, they may set
541 /// the flag to `Always`, etc. Finally, at the end, we take the
542 /// result and "union" it with the original value, so that when we
543 /// return the flag indicates if any subpart of the parent
544 /// expression (up to and including this part) has diverged. So,
545 /// if you read it after evaluating a subexpression `X`, the value
546 /// you get indicates whether any subexpression that was
547 /// evaluating up to and including `X` diverged.
549 /// We currently use this flag only for diagnostic purposes:
551 /// - To warn about unreachable code: if, after processing a
552 /// sub-expression but before we have applied the effects of the
553 /// current node, we see that the flag is set to `Always`, we
554 /// can issue a warning. This corresponds to something like
555 /// `foo(return)`; we warn on the `foo()` expression. (We then
556 /// update the flag to `WarnedAlways` to suppress duplicate
557 /// reports.) Similarly, if we traverse to a fresh statement (or
558 /// tail expression) from a `Always` setting, we will issue a
559 /// warning. This corresponds to something like `{return;
560 /// foo();}` or `{return; 22}`, where we would warn on the
563 /// An expression represents dead code if, after checking it,
564 /// the diverges flag is set to something other than `Maybe`.
565 diverges: Cell<Diverges>,
567 /// Whether any child nodes have any type errors.
568 has_errors: Cell<bool>,
570 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
572 inh: &'a Inherited<'a, 'gcx, 'tcx>,
575 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
576 type Target = Inherited<'a, 'gcx, 'tcx>;
577 fn deref(&self) -> &Self::Target {
582 /// Helper type of a temporary returned by `Inherited::build(...)`.
583 /// Necessary because we can't write the following bound:
584 /// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>)`.
585 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
586 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
590 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
591 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
592 -> InheritedBuilder<'a, 'gcx, 'tcx> {
593 let hir_id_root = if def_id.is_local() {
594 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
595 DefId::local(hir_id.owner)
601 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
607 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
608 fn enter<F, R>(&'tcx mut self, f: F) -> R
609 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
611 let def_id = self.def_id;
612 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
616 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
617 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
619 let item_id = tcx.hir().as_local_hir_id(def_id);
620 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by_by_hir_id(id));
621 let implicit_region_bound = body_id.map(|body_id| {
622 let body = tcx.hir().body(body_id);
623 tcx.mk_region(ty::ReScope(region::Scope {
624 id: body.value.hir_id.local_id,
625 data: region::ScopeData::CallSite
630 tables: MaybeInProgressTables {
631 maybe_tables: infcx.in_progress_tables,
634 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
635 locals: RefCell::new(Default::default()),
636 deferred_sized_obligations: RefCell::new(Vec::new()),
637 deferred_call_resolutions: RefCell::new(Default::default()),
638 deferred_cast_checks: RefCell::new(Vec::new()),
639 deferred_generator_interiors: RefCell::new(Vec::new()),
640 opaque_types: RefCell::new(Default::default()),
641 implicit_region_bound,
646 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
647 debug!("register_predicate({:?})", obligation);
648 if obligation.has_escaping_bound_vars() {
649 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
654 .register_predicate_obligation(self, obligation);
657 fn register_predicates<I>(&self, obligations: I)
658 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
660 for obligation in obligations {
661 self.register_predicate(obligation);
665 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
666 self.register_predicates(infer_ok.obligations);
670 fn normalize_associated_types_in<T>(&self,
673 param_env: ty::ParamEnv<'tcx>,
675 where T : TypeFoldable<'tcx>
677 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
678 self.register_infer_ok_obligations(ok)
682 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
684 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
685 fn visit_item(&mut self, i: &'tcx hir::Item) {
686 check_item_type(self.tcx, i);
688 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
689 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
692 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
693 tcx.sess.track_errors(|| {
694 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
695 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
699 fn check_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
700 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
703 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) {
704 debug_assert!(crate_num == LOCAL_CRATE);
705 tcx.par_body_owners(|body_owner_def_id| {
706 tcx.ensure().typeck_tables_of(body_owner_def_id);
710 fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
711 wfcheck::check_item_well_formed(tcx, def_id);
714 fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
715 wfcheck::check_trait_item(tcx, def_id);
718 fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
719 wfcheck::check_impl_item(tcx, def_id);
722 pub fn provide(providers: &mut Providers<'_>) {
723 method::provide(providers);
724 *providers = Providers {
730 check_item_well_formed,
731 check_trait_item_well_formed,
732 check_impl_item_well_formed,
733 check_mod_item_types,
738 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
740 -> Option<ty::Destructor> {
741 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
744 /// If this `DefId` is a "primary tables entry", returns `Some((body_id, decl))`
745 /// with information about it's body-id and fn-decl (if any). Otherwise,
748 /// If this function returns "some", then `typeck_tables(def_id)` will
749 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
750 /// may not succeed. In some cases where this function returns `None`
751 /// (notably closures), `typeck_tables(def_id)` would wind up
752 /// redirecting to the owning function.
753 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
755 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
757 match tcx.hir().get_by_hir_id(id) {
758 Node::Item(item) => {
760 hir::ItemKind::Const(_, body) |
761 hir::ItemKind::Static(_, _, body) =>
763 hir::ItemKind::Fn(ref decl, .., body) =>
764 Some((body, Some(decl))),
769 Node::TraitItem(item) => {
771 hir::TraitItemKind::Const(_, Some(body)) =>
773 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
774 Some((body, Some(&sig.decl))),
779 Node::ImplItem(item) => {
781 hir::ImplItemKind::Const(_, body) =>
783 hir::ImplItemKind::Method(ref sig, body) =>
784 Some((body, Some(&sig.decl))),
789 Node::AnonConst(constant) => Some((constant.body, None)),
794 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
797 // Closures' tables come from their outermost function,
798 // as they are part of the same "inference environment".
799 let outer_def_id = tcx.closure_base_def_id(def_id);
800 if outer_def_id != def_id {
801 return tcx.has_typeck_tables(outer_def_id);
804 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
805 primary_body_of(tcx, id).is_some()
808 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
811 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
814 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
816 -> &'tcx ty::TypeckTables<'tcx> {
817 // Closures' tables come from their outermost function,
818 // as they are part of the same "inference environment".
819 let outer_def_id = tcx.closure_base_def_id(def_id);
820 if outer_def_id != def_id {
821 return tcx.typeck_tables_of(outer_def_id);
824 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
825 let span = tcx.hir().span_by_hir_id(id);
827 // Figure out what primary body this item has.
828 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
829 span_bug!(span, "can't type-check body of {:?}", def_id);
831 let body = tcx.hir().body(body_id);
833 let tables = Inherited::build(tcx, def_id).enter(|inh| {
834 let param_env = tcx.param_env(def_id);
835 let fcx = if let Some(decl) = fn_decl {
836 let fn_sig = tcx.fn_sig(def_id);
838 check_abi(tcx, span, fn_sig.abi());
840 // Compute the fty from point of view of inside the fn.
842 tcx.liberate_late_bound_regions(def_id, &fn_sig);
844 inh.normalize_associated_types_in(body.value.span,
849 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
852 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
853 let expected_type = tcx.type_of(def_id);
854 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
855 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
857 let revealed_ty = if tcx.features().impl_trait_in_bindings {
858 fcx.instantiate_opaque_types_from_value(
866 // Gather locals in statics (because of block expressions).
867 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
869 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
871 fcx.write_ty(id, revealed_ty);
876 // All type checking constraints were added, try to fallback unsolved variables.
877 fcx.select_obligations_where_possible(false);
878 let mut fallback_has_occurred = false;
879 for ty in &fcx.unsolved_variables() {
880 fallback_has_occurred |= fcx.fallback_if_possible(ty);
882 fcx.select_obligations_where_possible(fallback_has_occurred);
884 // Even though coercion casts provide type hints, we check casts after fallback for
885 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
888 // Closure and generator analysis may run after fallback
889 // because they don't constrain other type variables.
890 fcx.closure_analyze(body);
891 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
892 fcx.resolve_generator_interiors(def_id);
894 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
895 let ty = fcx.normalize_ty(span, ty);
896 fcx.require_type_is_sized(ty, span, code);
898 fcx.select_all_obligations_or_error();
900 if fn_decl.is_some() {
901 fcx.regionck_fn(id, body);
903 fcx.regionck_expr(body);
906 fcx.resolve_type_vars_in_body(body)
909 // Consistency check our TypeckTables instance can hold all ItemLocalIds
910 // it will need to hold.
911 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
916 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
917 if !tcx.sess.target.target.is_abi_supported(abi) {
918 struct_span_err!(tcx.sess, span, E0570,
919 "The ABI `{}` is not supported for the current target", abi).emit()
923 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
924 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
925 parent_id: hir::HirId,
928 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
929 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
932 // infer the variable's type
933 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
934 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
941 // take type that the user specified
942 self.fcx.locals.borrow_mut().insert(nid, typ);
949 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
950 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
951 NestedVisitorMap::None
954 // Add explicitly-declared locals.
955 fn visit_local(&mut self, local: &'gcx hir::Local) {
956 let local_ty = match local.ty {
958 let o_ty = self.fcx.to_ty(&ty);
960 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
961 self.fcx.instantiate_opaque_types_from_value(
969 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
970 &UserType::Ty(revealed_ty)
972 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
973 ty.hir_id, o_ty, revealed_ty, c_ty);
974 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
976 Some(LocalTy { decl_ty: o_ty, revealed_ty })
980 self.assign(local.span, local.hir_id, local_ty);
982 debug!("Local variable {:?} is assigned type {}",
984 self.fcx.ty_to_string(
985 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
986 intravisit::walk_local(self, local);
989 // Add pattern bindings.
990 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
991 if let PatKind::Binding(_, _, ident, _) = p.node {
992 let var_ty = self.assign(p.span, p.hir_id, None);
994 let node_id = self.fcx.tcx.hir().hir_to_node_id(p.hir_id);
995 if !self.fcx.tcx.features().unsized_locals {
996 self.fcx.require_type_is_sized(var_ty, p.span,
997 traits::VariableType(node_id));
1000 debug!("Pattern binding {} is assigned to {} with type {:?}",
1002 self.fcx.ty_to_string(
1003 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1006 intravisit::walk_pat(self, p);
1009 // Don't descend into the bodies of nested closures
1010 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
1011 _: hir::BodyId, _: Span, _: hir::HirId) { }
1013 fn visit_argument_source(&mut self, s: &'gcx hir::ArgSource) {
1015 // Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has
1016 // a `NodeId` w/out a type, as it is only used for getting the name of the original
1017 // pattern for diagnostics where only an `hir::Arg` is present.
1018 hir::ArgSource::AsyncFn(..) => {},
1019 _ => intravisit::walk_argument_source(self, s),
1024 /// When `check_fn` is invoked on a generator (i.e., a body that
1025 /// includes yield), it returns back some information about the yield
1027 struct GeneratorTypes<'tcx> {
1028 /// Type of value that is yielded.
1031 /// Types that are captured (see `GeneratorInterior` for more).
1034 /// Indicates if the generator is movable or static (immovable).
1035 movability: hir::GeneratorMovability,
1038 /// Helper used for fns and closures. Does the grungy work of checking a function
1039 /// body and returns the function context used for that purpose, since in the case of a fn item
1040 /// there is still a bit more to do.
1043 /// * inherited: other fields inherited from the enclosing fn (if any)
1044 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1045 param_env: ty::ParamEnv<'tcx>,
1046 fn_sig: ty::FnSig<'tcx>,
1047 decl: &'gcx hir::FnDecl,
1049 body: &'gcx hir::Body,
1050 can_be_generator: Option<hir::GeneratorMovability>)
1051 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<GeneratorTypes<'tcx>>)
1053 let mut fn_sig = fn_sig.clone();
1055 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1057 // Create the function context. This is either derived from scratch or,
1058 // in the case of closures, based on the outer context.
1059 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1060 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1062 let declared_ret_ty = fn_sig.output();
1063 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1064 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty);
1065 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1066 fn_sig = fcx.tcx.mk_fn_sig(
1067 fn_sig.inputs().iter().cloned(),
1074 let span = body.value.span;
1076 if body.is_generator && can_be_generator.is_some() {
1077 let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
1078 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1079 fcx.yield_ty = Some(yield_ty);
1082 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id_from_hir_id(fn_id));
1083 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1084 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1086 // Add formal parameters.
1087 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1088 // Check the pattern.
1092 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
1096 // Check that argument is Sized.
1097 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1098 // for simple cases like `fn foo(x: Trait)`,
1099 // where we would error once on the parameter as a whole, and once on the binding `x`.
1100 if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1101 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
1104 fcx.write_ty(arg.hir_id, arg_ty);
1107 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1109 fcx.check_return_expr(&body.value);
1111 // We insert the deferred_generator_interiors entry after visiting the body.
1112 // This ensures that all nested generators appear before the entry of this generator.
1113 // resolve_generator_interiors relies on this property.
1114 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1115 let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
1116 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1117 Some(GeneratorTypes {
1118 yield_ty: fcx.yield_ty.unwrap(),
1120 movability: can_be_generator.unwrap(),
1126 // Finalize the return check by taking the LUB of the return types
1127 // we saw and assigning it to the expected return type. This isn't
1128 // really expected to fail, since the coercions would have failed
1129 // earlier when trying to find a LUB.
1131 // However, the behavior around `!` is sort of complex. In the
1132 // event that the `actual_return_ty` comes back as `!`, that
1133 // indicates that the fn either does not return or "returns" only
1134 // values of type `!`. In this case, if there is an expected
1135 // return type that is *not* `!`, that should be ok. But if the
1136 // return type is being inferred, we want to "fallback" to `!`:
1138 // let x = move || panic!();
1140 // To allow for that, I am creating a type variable with diverging
1141 // fallback. This was deemed ever so slightly better than unifying
1142 // the return value with `!` because it allows for the caller to
1143 // make more assumptions about the return type (e.g., they could do
1145 // let y: Option<u32> = Some(x());
1147 // which would then cause this return type to become `u32`, not
1149 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1150 let mut actual_return_ty = coercion.complete(&fcx);
1151 if actual_return_ty.is_never() {
1152 actual_return_ty = fcx.next_diverging_ty_var(
1153 TypeVariableOrigin::DivergingFn(span));
1155 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1157 // Check that the main return type implements the termination trait.
1158 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1159 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1160 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1161 if main_id == fn_id {
1162 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1163 let trait_ref = ty::TraitRef::new(term_id, substs);
1164 let return_ty_span = decl.output.span();
1165 let cause = traits::ObligationCause::new(
1166 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1168 inherited.register_predicate(
1169 traits::Obligation::new(
1170 cause, param_env, trait_ref.to_predicate()));
1175 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1176 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1177 if panic_impl_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1178 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1179 // at this point we don't care if there are duplicate handlers or if the handler has
1180 // the wrong signature as this value we'll be used when writing metadata and that
1181 // only happens if compilation succeeded
1182 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1184 if declared_ret_ty.sty != ty::Never {
1185 fcx.tcx.sess.span_err(
1187 "return type should be `!`",
1191 let inputs = fn_sig.inputs();
1192 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1193 if inputs.len() == 1 {
1194 let arg_is_panic_info = match inputs[0].sty {
1195 ty::Ref(region, ty, mutbl) => match ty.sty {
1196 ty::Adt(ref adt, _) => {
1197 adt.did == panic_info_did &&
1198 mutbl == hir::Mutability::MutImmutable &&
1199 *region != RegionKind::ReStatic
1206 if !arg_is_panic_info {
1207 fcx.tcx.sess.span_err(
1208 decl.inputs[0].span,
1209 "argument should be `&PanicInfo`",
1213 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1214 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1215 if !generics.params.is_empty() {
1216 fcx.tcx.sess.span_err(
1218 "should have no type parameters",
1224 let span = fcx.tcx.sess.source_map().def_span(span);
1225 fcx.tcx.sess.span_err(span, "function should have one argument");
1228 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1233 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1234 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1235 if alloc_error_handler_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1236 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1237 if declared_ret_ty.sty != ty::Never {
1238 fcx.tcx.sess.span_err(
1240 "return type should be `!`",
1244 let inputs = fn_sig.inputs();
1245 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1246 if inputs.len() == 1 {
1247 let arg_is_alloc_layout = match inputs[0].sty {
1248 ty::Adt(ref adt, _) => {
1249 adt.did == alloc_layout_did
1254 if !arg_is_alloc_layout {
1255 fcx.tcx.sess.span_err(
1256 decl.inputs[0].span,
1257 "argument should be `Layout`",
1261 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1262 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1263 if !generics.params.is_empty() {
1264 fcx.tcx.sess.span_err(
1266 "`#[alloc_error_handler]` function should have no type \
1273 let span = fcx.tcx.sess.source_map().def_span(span);
1274 fcx.tcx.sess.span_err(span, "function should have one argument");
1277 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1285 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1288 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1289 let def = tcx.adt_def(def_id);
1290 def.destructor(tcx); // force the destructor to be evaluated
1291 check_representable(tcx, span, def_id);
1293 if def.repr.simd() {
1294 check_simd(tcx, span, def_id);
1297 check_transparent(tcx, span, def_id);
1298 check_packed(tcx, span, def_id);
1301 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1304 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1305 let def = tcx.adt_def(def_id);
1306 def.destructor(tcx); // force the destructor to be evaluated
1307 check_representable(tcx, span, def_id);
1309 check_packed(tcx, span, def_id);
1312 fn check_opaque<'a, 'tcx>(
1313 tcx: TyCtxt<'a, 'tcx, 'tcx>,
1315 substs: SubstsRef<'tcx>,
1318 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1319 let mut err = struct_span_err!(
1320 tcx.sess, span, E0720,
1321 "opaque type expands to a recursive type",
1323 err.span_label(span, "expands to self-referential type");
1324 if let ty::Opaque(..) = partially_expanded_type.sty {
1325 err.note("type resolves to itself");
1327 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1333 pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1335 "check_item_type(it.hir_id={}, it.name={})",
1337 tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
1339 let _indenter = indenter();
1341 // Consts can play a role in type-checking, so they are included here.
1342 hir::ItemKind::Static(..) => {
1343 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1344 tcx.typeck_tables_of(def_id);
1345 maybe_check_static_with_link_section(tcx, def_id, it.span);
1347 hir::ItemKind::Const(..) => {
1348 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(it.hir_id));
1350 hir::ItemKind::Enum(ref enum_definition, _) => {
1351 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1353 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1354 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1355 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1356 let impl_def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1357 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1358 check_impl_items_against_trait(
1365 let trait_def_id = impl_trait_ref.def_id;
1366 check_on_unimplemented(tcx, trait_def_id, it);
1369 hir::ItemKind::Trait(..) => {
1370 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1371 check_on_unimplemented(tcx, def_id, it);
1373 hir::ItemKind::Struct(..) => {
1374 check_struct(tcx, it.hir_id, it.span);
1376 hir::ItemKind::Union(..) => {
1377 check_union(tcx, it.hir_id, it.span);
1379 hir::ItemKind::Existential(..) => {
1380 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1382 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1383 check_opaque(tcx, def_id, substs, it.span);
1385 hir::ItemKind::Ty(..) => {
1386 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1387 let pty_ty = tcx.type_of(def_id);
1388 let generics = tcx.generics_of(def_id);
1389 check_bounds_are_used(tcx, &generics, pty_ty);
1391 hir::ItemKind::ForeignMod(ref m) => {
1392 check_abi(tcx, it.span, m.abi);
1394 if m.abi == Abi::RustIntrinsic {
1395 for item in &m.items {
1396 intrinsic::check_intrinsic_type(tcx, item);
1398 } else if m.abi == Abi::PlatformIntrinsic {
1399 for item in &m.items {
1400 intrinsic::check_platform_intrinsic_type(tcx, item);
1403 for item in &m.items {
1404 let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
1405 if generics.params.len() - generics.own_counts().lifetimes != 0 {
1406 let mut err = struct_span_err!(
1410 "foreign items may not have type parameters"
1412 err.span_label(item.span, "can't have type parameters");
1413 // FIXME: once we start storing spans for type arguments, turn this into a
1416 "use specialization instead of type parameters by replacing them \
1417 with concrete types like `u32`",
1422 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1423 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1428 _ => { /* nothing to do */ }
1432 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_, '_, '_>, id: DefId, span: Span) {
1433 // Only restricted on wasm32 target for now
1434 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1438 // If `#[link_section]` is missing, then nothing to verify
1439 let attrs = tcx.codegen_fn_attrs(id);
1440 if attrs.link_section.is_none() {
1444 // For the wasm32 target statics with #[link_section] are placed into custom
1445 // sections of the final output file, but this isn't link custom sections of
1446 // other executable formats. Namely we can only embed a list of bytes,
1447 // nothing with pointers to anything else or relocations. If any relocation
1448 // show up, reject them here.
1449 let instance = ty::Instance::mono(tcx, id);
1450 let cid = GlobalId {
1454 let param_env = ty::ParamEnv::reveal_all();
1455 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1456 let alloc = if let ConstValue::ByRef(_, allocation) = static_.val {
1459 bug!("Matching on non-ByRef static")
1461 if alloc.relocations.len() != 0 {
1462 let msg = "statics with a custom `#[link_section]` must be a \
1463 simple list of bytes on the wasm target with no \
1464 extra levels of indirection such as references";
1465 tcx.sess.span_err(span, msg);
1470 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1471 trait_def_id: DefId,
1473 let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
1474 // an error would be reported if this fails.
1475 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1478 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1479 impl_item: &hir::ImplItem,
1482 let mut err = struct_span_err!(
1483 tcx.sess, impl_item.span, E0520,
1484 "`{}` specializes an item from a parent `impl`, but \
1485 that item is not marked `default`",
1487 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1490 match tcx.span_of_impl(parent_impl) {
1492 err.span_label(span, "parent `impl` is here");
1493 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1497 err.note(&format!("parent implementation is in crate `{}`", cname));
1504 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1505 trait_def: &ty::TraitDef,
1506 trait_item: &ty::AssociatedItem,
1508 impl_item: &hir::ImplItem)
1510 let ancestors = trait_def.ancestors(tcx, impl_id);
1512 let kind = match impl_item.node {
1513 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1514 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1515 hir::ImplItemKind::Existential(..) => ty::AssociatedKind::Existential,
1516 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1519 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1520 .map(|node_item| node_item.map(|parent| parent.defaultness));
1522 if let Some(parent) = parent {
1523 if tcx.impl_item_is_final(&parent) {
1524 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1530 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1533 impl_trait_ref: ty::TraitRef<'tcx>,
1534 impl_item_refs: &[hir::ImplItemRef]) {
1535 let impl_span = tcx.sess.source_map().def_span(impl_span);
1537 // If the trait reference itself is erroneous (so the compilation is going
1538 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1539 // isn't populated for such impls.
1540 if impl_trait_ref.references_error() { return; }
1542 // Locate trait definition and items
1543 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1544 let mut overridden_associated_type = None;
1546 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1548 // Check existing impl methods to see if they are both present in trait
1549 // and compatible with trait signature
1550 for impl_item in impl_items() {
1551 let ty_impl_item = tcx.associated_item(
1552 tcx.hir().local_def_id_from_hir_id(impl_item.hir_id));
1553 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1554 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1555 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1557 // Not compatible, but needed for the error message
1558 tcx.associated_items(impl_trait_ref.def_id)
1559 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1562 // Check that impl definition matches trait definition
1563 if let Some(ty_trait_item) = ty_trait_item {
1564 match impl_item.node {
1565 hir::ImplItemKind::Const(..) => {
1566 // Find associated const definition.
1567 if ty_trait_item.kind == ty::AssociatedKind::Const {
1568 compare_const_impl(tcx,
1574 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1575 "item `{}` is an associated const, \
1576 which doesn't match its trait `{}`",
1579 err.span_label(impl_item.span, "does not match trait");
1580 // We can only get the spans from local trait definition
1581 // Same for E0324 and E0325
1582 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1583 err.span_label(trait_span, "item in trait");
1588 hir::ImplItemKind::Method(..) => {
1589 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1590 if ty_trait_item.kind == ty::AssociatedKind::Method {
1591 compare_impl_method(tcx,
1598 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1599 "item `{}` is an associated method, \
1600 which doesn't match its trait `{}`",
1603 err.span_label(impl_item.span, "does not match trait");
1604 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1605 err.span_label(trait_span, "item in trait");
1610 hir::ImplItemKind::Existential(..) |
1611 hir::ImplItemKind::Type(_) => {
1612 if ty_trait_item.kind == ty::AssociatedKind::Type {
1613 if ty_trait_item.defaultness.has_value() {
1614 overridden_associated_type = Some(impl_item);
1617 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1618 "item `{}` is an associated type, \
1619 which doesn't match its trait `{}`",
1622 err.span_label(impl_item.span, "does not match trait");
1623 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1624 err.span_label(trait_span, "item in trait");
1631 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1635 // Check for missing items from trait
1636 let mut missing_items = Vec::new();
1637 let mut invalidated_items = Vec::new();
1638 let associated_type_overridden = overridden_associated_type.is_some();
1639 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1640 let is_implemented = trait_def.ancestors(tcx, impl_id)
1641 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1643 .map(|node_item| !node_item.node.is_from_trait())
1646 if !is_implemented && !tcx.impl_is_default(impl_id) {
1647 if !trait_item.defaultness.has_value() {
1648 missing_items.push(trait_item);
1649 } else if associated_type_overridden {
1650 invalidated_items.push(trait_item.ident);
1655 if !missing_items.is_empty() {
1656 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1657 "not all trait items implemented, missing: `{}`",
1658 missing_items.iter()
1659 .map(|trait_item| trait_item.ident.to_string())
1660 .collect::<Vec<_>>().join("`, `"));
1661 err.span_label(impl_span, format!("missing `{}` in implementation",
1662 missing_items.iter()
1663 .map(|trait_item| trait_item.ident.to_string())
1664 .collect::<Vec<_>>().join("`, `")));
1665 for trait_item in missing_items {
1666 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1667 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1669 err.note_trait_signature(trait_item.ident.to_string(),
1670 trait_item.signature(tcx));
1676 if !invalidated_items.is_empty() {
1677 let invalidator = overridden_associated_type.unwrap();
1678 span_err!(tcx.sess, invalidator.span, E0399,
1679 "the following trait items need to be reimplemented \
1680 as `{}` was overridden: `{}`",
1682 invalidated_items.iter()
1683 .map(|name| name.to_string())
1684 .collect::<Vec<_>>().join("`, `"))
1688 /// Checks whether a type can be represented in memory. In particular, it
1689 /// identifies types that contain themselves without indirection through a
1690 /// pointer, which would mean their size is unbounded.
1691 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1695 let rty = tcx.type_of(item_def_id);
1697 // Check that it is possible to represent this type. This call identifies
1698 // (1) types that contain themselves and (2) types that contain a different
1699 // recursive type. It is only necessary to throw an error on those that
1700 // contain themselves. For case 2, there must be an inner type that will be
1701 // caught by case 1.
1702 match rty.is_representable(tcx, sp) {
1703 Representability::SelfRecursive(spans) => {
1704 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1706 err.span_label(span, "recursive without indirection");
1711 Representability::Representable | Representability::ContainsRecursive => (),
1716 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1717 let t = tcx.type_of(def_id);
1718 if let ty::Adt(def, substs) = t.sty {
1719 if def.is_struct() {
1720 let fields = &def.non_enum_variant().fields;
1721 if fields.is_empty() {
1722 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1725 let e = fields[0].ty(tcx, substs);
1726 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1727 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1728 .span_label(sp, "SIMD elements must have the same type")
1733 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1734 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1736 span_err!(tcx.sess, sp, E0077,
1737 "SIMD vector element type should be machine type");
1745 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1746 let repr = tcx.adt_def(def_id).repr;
1748 for attr in tcx.get_attrs(def_id).iter() {
1749 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1750 if let attr::ReprPacked(pack) = r {
1751 if pack != repr.pack {
1752 struct_span_err!(tcx.sess, sp, E0634,
1753 "type has conflicting packed representation hints").emit();
1759 struct_span_err!(tcx.sess, sp, E0587,
1760 "type has conflicting packed and align representation hints").emit();
1762 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1763 struct_span_err!(tcx.sess, sp, E0588,
1764 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1769 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1771 stack: &mut Vec<DefId>) -> bool {
1772 let t = tcx.type_of(def_id);
1773 if stack.contains(&def_id) {
1774 debug!("check_packed_inner: {:?} is recursive", t);
1777 if let ty::Adt(def, substs) = t.sty {
1778 if def.is_struct() || def.is_union() {
1779 if tcx.adt_def(def.did).repr.align > 0 {
1782 // push struct def_id before checking fields
1784 for field in &def.non_enum_variant().fields {
1785 let f = field.ty(tcx, substs);
1786 if let ty::Adt(def, _) = f.sty {
1787 if check_packed_inner(tcx, def.did, stack) {
1792 // only need to pop if not early out
1799 fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1800 let adt = tcx.adt_def(def_id);
1801 if !adt.repr.transparent() {
1805 // For each field, figure out if it's known to be a ZST and align(1)
1806 let field_infos = adt.non_enum_variant().fields.iter().map(|field| {
1807 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
1808 let param_env = tcx.param_env(field.did);
1809 let layout = tcx.layout_of(param_env.and(ty));
1810 // We are currently checking the type this field came from, so it must be local
1811 let span = tcx.hir().span_if_local(field.did).unwrap();
1812 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1813 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
1817 let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
1818 let non_zst_count = non_zst_fields.clone().count();
1819 if non_zst_count != 1 {
1820 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
1821 struct_span_err!(tcx.sess, sp, E0690,
1822 "transparent struct needs exactly one non-zero-sized field, but has {}",
1824 .span_note(field_spans, "non-zero-sized field")
1827 for (span, zst, align1) in field_infos {
1829 span_err!(tcx.sess, span, E0691,
1830 "zero-sized field in transparent struct has alignment larger than 1");
1835 #[allow(trivial_numeric_casts)]
1836 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1838 vs: &'tcx [hir::Variant],
1840 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1841 let def = tcx.adt_def(def_id);
1842 def.destructor(tcx); // force the destructor to be evaluated
1845 let attributes = tcx.get_attrs(def_id);
1846 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1848 tcx.sess, attr.span, E0084,
1849 "unsupported representation for zero-variant enum")
1850 .span_label(sp, "zero-variant enum")
1855 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1856 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1857 if !tcx.features().repr128 {
1858 emit_feature_err(&tcx.sess.parse_sess,
1861 GateIssue::Language,
1862 "repr with 128-bit type is unstable");
1867 if let Some(ref e) = v.node.disr_expr {
1868 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(e.hir_id));
1872 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
1873 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
1874 // Check for duplicate discriminant values
1875 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1876 let variant_did = def.variants[VariantIdx::new(i)].def_id;
1877 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
1878 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
1879 let i_span = match variant_i.node.disr_expr {
1880 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1881 None => tcx.hir().span_by_hir_id(variant_i_hir_id)
1883 let span = match v.node.disr_expr {
1884 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1887 struct_span_err!(tcx.sess, span, E0081,
1888 "discriminant value `{}` already exists", disr_vals[i])
1889 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1890 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1893 disr_vals.push(discr);
1896 check_representable(tcx, sp, def_id);
1899 fn report_unexpected_variant_def<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1903 span_err!(tcx.sess, span, E0533,
1904 "expected unit struct/variant or constant, found {} `{}`",
1906 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1909 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1910 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1912 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1913 -> Lrc<ty::GenericPredicates<'tcx>>
1916 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
1917 let item_id = tcx.hir().ty_param_owner(hir_id);
1918 let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
1919 let generics = tcx.generics_of(item_def_id);
1920 let index = generics.param_def_id_to_index[&def_id];
1921 Lrc::new(ty::GenericPredicates {
1923 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
1925 ty::Predicate::Trait(ref data)
1926 if data.skip_binder().self_ty().is_param(index) => {
1927 // HACK(eddyb) should get the original `Span`.
1928 let span = tcx.def_span(def_id);
1929 Some((predicate, span))
1937 fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
1938 -> Option<ty::Region<'tcx>> {
1940 Some(def) => infer::EarlyBoundRegion(span, def.name),
1941 None => infer::MiscVariable(span)
1943 Some(self.next_region_var(v))
1946 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1947 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1950 fn ty_infer_for_def(&self,
1951 ty_param_def: &ty::GenericParamDef,
1952 span: Span) -> Ty<'tcx> {
1953 if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
1959 fn projected_ty_from_poly_trait_ref(&self,
1962 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1965 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
1967 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1971 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1974 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1975 if ty.has_escaping_bound_vars() {
1976 ty // FIXME: normalization and escaping regions
1978 self.normalize_associated_types_in(span, &ty)
1982 fn set_tainted_by_errors(&self) {
1983 self.infcx.set_tainted_by_errors()
1986 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1987 self.write_ty(hir_id, ty)
1991 /// Controls whether the arguments are tupled. This is used for the call
1994 /// Tupling means that all call-side arguments are packed into a tuple and
1995 /// passed as a single parameter. For example, if tupling is enabled, this
1998 /// fn f(x: (isize, isize))
2000 /// Can be called as:
2007 #[derive(Clone, Eq, PartialEq)]
2008 enum TupleArgumentsFlag {
2013 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2014 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
2015 param_env: ty::ParamEnv<'tcx>,
2016 body_id: hir::HirId)
2017 -> FnCtxt<'a, 'gcx, 'tcx> {
2021 err_count_on_creation: inh.tcx.sess.err_count(),
2023 ret_coercion_span: RefCell::new(None),
2025 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2026 hir::CRATE_HIR_ID)),
2027 diverges: Cell::new(Diverges::Maybe),
2028 has_errors: Cell::new(false),
2029 enclosing_breakables: RefCell::new(EnclosingBreakables {
2031 by_id: Default::default(),
2037 pub fn sess(&self) -> &Session {
2041 pub fn err_count_since_creation(&self) -> usize {
2042 self.tcx.sess.err_count() - self.err_count_on_creation
2045 /// Produces warning on the given node, if the current point in the
2046 /// function is unreachable, and there hasn't been another warning.
2047 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2048 if self.diverges.get() == Diverges::Always {
2049 self.diverges.set(Diverges::WarnedAlways);
2051 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2053 self.tcx().lint_hir(
2054 lint::builtin::UNREACHABLE_CODE,
2056 &format!("unreachable {}", kind));
2062 code: ObligationCauseCode<'tcx>)
2063 -> ObligationCause<'tcx> {
2064 ObligationCause::new(span, self.body_id, code)
2067 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2068 self.cause(span, ObligationCauseCode::MiscObligation)
2071 /// Resolves type variables in `ty` if possible. Unlike the infcx
2072 /// version (resolve_type_vars_if_possible), this version will
2073 /// also select obligations if it seems useful, in an effort
2074 /// to get more type information.
2075 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2076 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2078 // No Infer()? Nothing needs doing.
2079 if !ty.has_infer_types() {
2080 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2084 // If `ty` is a type variable, see whether we already know what it is.
2085 ty = self.resolve_type_vars_if_possible(&ty);
2086 if !ty.has_infer_types() {
2087 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2091 // If not, try resolving pending obligations as much as
2092 // possible. This can help substantially when there are
2093 // indirect dependencies that don't seem worth tracking
2095 self.select_obligations_where_possible(false);
2096 ty = self.resolve_type_vars_if_possible(&ty);
2098 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2102 fn record_deferred_call_resolution(&self,
2103 closure_def_id: DefId,
2104 r: DeferredCallResolution<'gcx, 'tcx>) {
2105 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2106 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2109 fn remove_deferred_call_resolutions(&self,
2110 closure_def_id: DefId)
2111 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
2113 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2114 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2117 pub fn tag(&self) -> String {
2118 let self_ptr: *const FnCtxt<'_, '_, '_> = self;
2119 format!("{:?}", self_ptr)
2122 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2123 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2124 span_bug!(span, "no type for local variable {}",
2125 self.tcx.hir().hir_to_string(nid))
2130 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2131 debug!("write_ty({:?}, {:?}) in fcx {}",
2132 id, self.resolve_type_vars_if_possible(&ty), self.tag());
2133 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2135 if ty.references_error() {
2136 self.has_errors.set(true);
2137 self.set_tainted_by_errors();
2141 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2142 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2145 pub fn write_method_call(&self,
2147 method: MethodCallee<'tcx>) {
2148 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2151 .type_dependent_defs_mut()
2152 .insert(hir_id, Ok((DefKind::Method, method.def_id)));
2154 self.write_substs(hir_id, method.substs);
2156 // When the method is confirmed, the `method.substs` includes
2157 // parameters from not just the method, but also the impl of
2158 // the method -- in particular, the `Self` type will be fully
2159 // resolved. However, those are not something that the "user
2160 // specified" -- i.e., those types come from the inferred type
2161 // of the receiver, not something the user wrote. So when we
2162 // create the user-substs, we want to replace those earlier
2163 // types with just the types that the user actually wrote --
2164 // that is, those that appear on the *method itself*.
2166 // As an example, if the user wrote something like
2167 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2168 // type of `foo` (possibly adjusted), but we don't want to
2169 // include that. We want just the `[_, u32]` part.
2170 if !method.substs.is_noop() {
2171 let method_generics = self.tcx.generics_of(method.def_id);
2172 if !method_generics.params.is_empty() {
2173 let user_type_annotation = self.infcx.probe(|_| {
2174 let user_substs = UserSubsts {
2175 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2176 let i = param.index as usize;
2177 if i < method_generics.parent_count {
2178 self.infcx.var_for_def(DUMMY_SP, param)
2183 user_self_ty: None, // not relevant here
2186 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2192 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2193 self.write_user_type_annotation(hir_id, user_type_annotation);
2198 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2199 if !substs.is_noop() {
2200 debug!("write_substs({:?}, {:?}) in fcx {}",
2205 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2209 /// Given the substs that we just converted from the HIR, try to
2210 /// canonicalize them and store them as user-given substitutions
2211 /// (i.e., substitutions that must be respected by the NLL check).
2213 /// This should be invoked **before any unifications have
2214 /// occurred**, so that annotations like `Vec<_>` are preserved
2216 pub fn write_user_type_annotation_from_substs(
2220 substs: SubstsRef<'tcx>,
2221 user_self_ty: Option<UserSelfTy<'tcx>>,
2224 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2225 user_self_ty={:?} in fcx {}",
2226 hir_id, def_id, substs, user_self_ty, self.tag(),
2229 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2230 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2231 &UserType::TypeOf(def_id, UserSubsts {
2236 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2237 self.write_user_type_annotation(hir_id, canonicalized);
2241 pub fn write_user_type_annotation(
2244 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2247 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2248 hir_id, canonical_user_type_annotation, self.tag(),
2251 if !canonical_user_type_annotation.is_identity() {
2252 self.tables.borrow_mut().user_provided_types_mut().insert(
2253 hir_id, canonical_user_type_annotation
2256 debug!("write_user_type_annotation: skipping identity substs");
2260 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2261 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2267 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2268 Entry::Vacant(entry) => { entry.insert(adj); },
2269 Entry::Occupied(mut entry) => {
2270 debug!(" - composing on top of {:?}", entry.get());
2271 match (&entry.get()[..], &adj[..]) {
2272 // Applying any adjustment on top of a NeverToAny
2273 // is a valid NeverToAny adjustment, because it can't
2275 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2277 Adjustment { kind: Adjust::Deref(_), .. },
2278 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2280 Adjustment { kind: Adjust::Deref(_), .. },
2281 .. // Any following adjustments are allowed.
2283 // A reborrow has no effect before a dereference.
2285 // FIXME: currently we never try to compose autoderefs
2286 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2288 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2289 expr, entry.get(), adj)
2291 *entry.get_mut() = adj;
2296 /// Basically whenever we are converting from a type scheme into
2297 /// the fn body space, we always want to normalize associated
2298 /// types as well. This function combines the two.
2299 fn instantiate_type_scheme<T>(&self,
2301 substs: SubstsRef<'tcx>,
2304 where T : TypeFoldable<'tcx>
2306 let value = value.subst(self.tcx, substs);
2307 let result = self.normalize_associated_types_in(span, &value);
2308 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2315 /// As `instantiate_type_scheme`, but for the bounds found in a
2316 /// generic type scheme.
2317 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: SubstsRef<'tcx>)
2318 -> ty::InstantiatedPredicates<'tcx> {
2319 let bounds = self.tcx.predicates_of(def_id);
2320 let result = bounds.instantiate(self.tcx, substs);
2321 let result = self.normalize_associated_types_in(span, &result);
2322 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2329 /// Replaces the opaque types from the given value with type variables,
2330 /// and records the `OpaqueTypeMap` for later use during writeback. See
2331 /// `InferCtxt::instantiate_opaque_types` for more details.
2332 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2334 parent_id: hir::HirId,
2337 let parent_def_id = self.tcx.hir().local_def_id_from_hir_id(parent_id);
2338 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2342 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2343 self.instantiate_opaque_types(
2351 let mut opaque_types = self.opaque_types.borrow_mut();
2352 for (ty, decl) in opaque_type_map {
2353 let old_value = opaque_types.insert(ty, decl);
2354 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2360 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2361 where T : TypeFoldable<'tcx>
2363 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2366 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2368 where T : TypeFoldable<'tcx>
2370 self.inh.partially_normalize_associated_types_in(span,
2376 pub fn require_type_meets(&self,
2379 code: traits::ObligationCauseCode<'tcx>,
2382 self.register_bound(
2385 traits::ObligationCause::new(span, self.body_id, code));
2388 pub fn require_type_is_sized(&self,
2391 code: traits::ObligationCauseCode<'tcx>)
2393 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2394 self.require_type_meets(ty, span, code, lang_item);
2397 pub fn require_type_is_sized_deferred(&self,
2400 code: traits::ObligationCauseCode<'tcx>)
2402 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2405 pub fn register_bound(&self,
2408 cause: traits::ObligationCause<'tcx>)
2410 self.fulfillment_cx.borrow_mut()
2411 .register_bound(self, self.param_env, ty, def_id, cause);
2414 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2415 let t = AstConv::ast_ty_to_ty(self, ast_t);
2416 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2420 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2421 let ty = self.to_ty(ast_ty);
2422 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2424 if Self::can_contain_user_lifetime_bounds(ty) {
2425 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2426 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2427 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2433 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2434 AstConv::ast_const_to_const(self, ast_c, ty)
2437 // If the type given by the user has free regions, save it for later, since
2438 // NLL would like to enforce those. Also pass in types that involve
2439 // projections, since those can resolve to `'static` bounds (modulo #54940,
2440 // which hopefully will be fixed by the time you see this comment, dear
2441 // reader, although I have my doubts). Also pass in types with inference
2442 // types, because they may be repeated. Other sorts of things are already
2443 // sufficiently enforced with erased regions. =)
2444 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2446 T: TypeFoldable<'tcx>
2448 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2451 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2452 match self.tables.borrow().node_types().get(id) {
2454 None if self.is_tainted_by_errors() => self.tcx.types.err,
2456 let node_id = self.tcx.hir().hir_to_node_id(id);
2457 bug!("no type for node {}: {} in fcx {}",
2458 node_id, self.tcx.hir().node_to_string(node_id),
2464 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2465 /// outlive the region `r`.
2466 pub fn register_wf_obligation(&self,
2469 code: traits::ObligationCauseCode<'tcx>)
2471 // WF obligations never themselves fail, so no real need to give a detailed cause:
2472 let cause = traits::ObligationCause::new(span, self.body_id, code);
2473 self.register_predicate(traits::Obligation::new(cause,
2475 ty::Predicate::WellFormed(ty)));
2478 /// Registers obligations that all types appearing in `substs` are well-formed.
2479 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2480 for ty in substs.types() {
2481 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2485 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2486 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2487 /// trait/region obligations.
2489 /// For example, if there is a function:
2492 /// fn foo<'a,T:'a>(...)
2495 /// and a reference:
2501 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2502 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2503 pub fn add_obligations_for_parameters(&self,
2504 cause: traits::ObligationCause<'tcx>,
2505 predicates: &ty::InstantiatedPredicates<'tcx>)
2507 assert!(!predicates.has_escaping_bound_vars());
2509 debug!("add_obligations_for_parameters(predicates={:?})",
2512 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2513 self.register_predicate(obligation);
2517 // FIXME(arielb1): use this instead of field.ty everywhere
2518 // Only for fields! Returns <none> for methods>
2519 // Indifferent to privacy flags
2520 pub fn field_ty(&self,
2522 field: &'tcx ty::FieldDef,
2523 substs: SubstsRef<'tcx>)
2526 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2529 fn check_casts(&self) {
2530 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2531 for cast in deferred_cast_checks.drain(..) {
2536 fn resolve_generator_interiors(&self, def_id: DefId) {
2537 let mut generators = self.deferred_generator_interiors.borrow_mut();
2538 for (body_id, interior) in generators.drain(..) {
2539 self.select_obligations_where_possible(false);
2540 generator_interior::resolve_interior(self, def_id, body_id, interior);
2544 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2545 // Non-numerics get replaced with ! or () (depending on whether
2546 // feature(never_type) is enabled, unconstrained ints with i32,
2547 // unconstrained floats with f64.
2548 // Fallback becomes very dubious if we have encountered type-checking errors.
2549 // In that case, fallback to Error.
2550 // The return value indicates whether fallback has occurred.
2551 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2552 use rustc::ty::error::UnconstrainedNumeric::Neither;
2553 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2555 assert!(ty.is_ty_infer());
2556 let fallback = match self.type_is_unconstrained_numeric(ty) {
2557 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2558 UnconstrainedInt => self.tcx.types.i32,
2559 UnconstrainedFloat => self.tcx.types.f64,
2560 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2561 Neither => return false,
2563 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2564 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2568 fn select_all_obligations_or_error(&self) {
2569 debug!("select_all_obligations_or_error");
2570 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2571 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2575 /// Select as many obligations as we can at present.
2576 fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2577 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2578 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2582 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2583 /// returns a type of `&T`, but the actual type we assign to the
2584 /// *expression* is `T`. So this function just peels off the return
2585 /// type by one layer to yield `T`.
2586 fn make_overloaded_place_return_type(&self,
2587 method: MethodCallee<'tcx>)
2588 -> ty::TypeAndMut<'tcx>
2590 // extract method return type, which will be &T;
2591 let ret_ty = method.sig.output();
2593 // method returns &T, but the type as visible to user is T, so deref
2594 ret_ty.builtin_deref(true).unwrap()
2597 fn lookup_indexing(&self,
2599 base_expr: &'gcx hir::Expr,
2603 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2605 // FIXME(#18741) -- this is almost but not quite the same as the
2606 // autoderef that normal method probing does. They could likely be
2609 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2610 let mut result = None;
2611 while result.is_none() && autoderef.next().is_some() {
2612 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2614 autoderef.finalize(self);
2618 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2619 /// (and otherwise adjust) `base_expr`, looking for a type which either
2620 /// supports builtin indexing or overloaded indexing.
2621 /// This loop implements one step in that search; the autoderef loop
2622 /// is implemented by `lookup_indexing`.
2623 fn try_index_step(&self,
2625 base_expr: &hir::Expr,
2626 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2629 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2631 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2632 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2639 for &unsize in &[false, true] {
2640 let mut self_ty = adjusted_ty;
2642 // We only unsize arrays here.
2643 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2644 self_ty = self.tcx.mk_slice(element_ty);
2650 // If some lookup succeeds, write callee into table and extract index/element
2651 // type from the method signature.
2652 // If some lookup succeeded, install method in table
2653 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2654 let method = self.try_overloaded_place_op(
2655 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2657 let result = method.map(|ok| {
2658 debug!("try_index_step: success, using overloaded indexing");
2659 let method = self.register_infer_ok_obligations(ok);
2661 let mut adjustments = autoderef.adjust_steps(self, needs);
2662 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2663 let mutbl = match r_mutbl {
2664 hir::MutImmutable => AutoBorrowMutability::Immutable,
2665 hir::MutMutable => AutoBorrowMutability::Mutable {
2666 // Indexing can be desugared to a method call,
2667 // so maybe we could use two-phase here.
2668 // See the documentation of AllowTwoPhase for why that's
2669 // not the case today.
2670 allow_two_phase_borrow: AllowTwoPhase::No,
2673 adjustments.push(Adjustment {
2674 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2675 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2682 adjustments.push(Adjustment {
2683 kind: Adjust::Pointer(PointerCast::Unsize),
2684 target: method.sig.inputs()[0]
2687 self.apply_adjustments(base_expr, adjustments);
2689 self.write_method_call(expr.hir_id, method);
2690 (input_ty, self.make_overloaded_place_return_type(method).ty)
2692 if result.is_some() {
2700 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
2701 let (tr, name) = match (op, is_mut) {
2702 (PlaceOp::Deref, false) =>
2703 (self.tcx.lang_items().deref_trait(), "deref"),
2704 (PlaceOp::Deref, true) =>
2705 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2706 (PlaceOp::Index, false) =>
2707 (self.tcx.lang_items().index_trait(), "index"),
2708 (PlaceOp::Index, true) =>
2709 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2711 (tr, ast::Ident::from_str(name))
2714 fn try_overloaded_place_op(&self,
2717 arg_tys: &[Ty<'tcx>],
2720 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2722 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2728 // Try Mut first, if needed.
2729 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2730 let method = match (needs, mut_tr) {
2731 (Needs::MutPlace, Some(trait_did)) => {
2732 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2737 // Otherwise, fall back to the immutable version.
2738 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2739 let method = match (method, imm_tr) {
2740 (None, Some(trait_did)) => {
2741 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2743 (method, _) => method,
2749 fn check_method_argument_types(&self,
2752 method: Result<MethodCallee<'tcx>, ()>,
2753 args_no_rcvr: &'gcx [hir::Expr],
2754 tuple_arguments: TupleArgumentsFlag,
2755 expected: Expectation<'tcx>)
2757 let has_error = match method {
2759 method.substs.references_error() || method.sig.references_error()
2764 let err_inputs = self.err_args(args_no_rcvr.len());
2766 let err_inputs = match tuple_arguments {
2767 DontTupleArguments => err_inputs,
2768 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
2771 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2772 false, tuple_arguments, None);
2773 return self.tcx.types.err;
2776 let method = method.unwrap();
2777 // HACK(eddyb) ignore self in the definition (see above).
2778 let expected_arg_tys = self.expected_inputs_for_expected_output(
2781 method.sig.output(),
2782 &method.sig.inputs()[1..]
2784 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2785 args_no_rcvr, method.sig.c_variadic, tuple_arguments,
2786 self.tcx.hir().span_if_local(method.def_id));
2790 fn self_type_matches_expected_vid(
2792 trait_ref: ty::PolyTraitRef<'tcx>,
2793 expected_vid: ty::TyVid,
2795 let self_ty = self.shallow_resolve(trait_ref.self_ty());
2797 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
2798 trait_ref, self_ty, expected_vid
2801 ty::Infer(ty::TyVar(found_vid)) => {
2802 // FIXME: consider using `sub_root_var` here so we
2803 // can see through subtyping.
2804 let found_vid = self.root_var(found_vid);
2805 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
2806 expected_vid == found_vid
2812 fn obligations_for_self_ty<'b>(&'b self, self_ty: ty::TyVid)
2813 -> impl Iterator<Item=(ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
2814 + Captures<'gcx> + 'b
2816 // FIXME: consider using `sub_root_var` here so we
2817 // can see through subtyping.
2818 let ty_var_root = self.root_var(self_ty);
2819 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
2820 self_ty, ty_var_root,
2821 self.fulfillment_cx.borrow().pending_obligations());
2825 .pending_obligations()
2827 .filter_map(move |obligation| match obligation.predicate {
2828 ty::Predicate::Projection(ref data) =>
2829 Some((data.to_poly_trait_ref(self.tcx), obligation)),
2830 ty::Predicate::Trait(ref data) =>
2831 Some((data.to_poly_trait_ref(), obligation)),
2832 ty::Predicate::Subtype(..) => None,
2833 ty::Predicate::RegionOutlives(..) => None,
2834 ty::Predicate::TypeOutlives(..) => None,
2835 ty::Predicate::WellFormed(..) => None,
2836 ty::Predicate::ObjectSafe(..) => None,
2837 ty::Predicate::ConstEvaluatable(..) => None,
2838 // N.B., this predicate is created by breaking down a
2839 // `ClosureType: FnFoo()` predicate, where
2840 // `ClosureType` represents some `Closure`. It can't
2841 // possibly be referring to the current closure,
2842 // because we haven't produced the `Closure` for
2843 // this closure yet; this is exactly why the other
2844 // code is looking for a self type of a unresolved
2845 // inference variable.
2846 ty::Predicate::ClosureKind(..) => None,
2847 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
2850 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
2851 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
2852 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
2856 /// Generic function that factors out common logic from function calls,
2857 /// method calls and overloaded operators.
2858 fn check_argument_types(&self,
2861 fn_inputs: &[Ty<'tcx>],
2862 expected_arg_tys: &[Ty<'tcx>],
2863 args: &'gcx [hir::Expr],
2865 tuple_arguments: TupleArgumentsFlag,
2866 def_span: Option<Span>) {
2869 // Grab the argument types, supplying fresh type variables
2870 // if the wrong number of arguments were supplied
2871 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2877 // All the input types from the fn signature must outlive the call
2878 // so as to validate implied bounds.
2879 for &fn_input_ty in fn_inputs {
2880 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2883 let expected_arg_count = fn_inputs.len();
2885 let param_count_error = |expected_count: usize,
2890 let mut err = tcx.sess.struct_span_err_with_code(sp,
2891 &format!("this function takes {}{} but {} {} supplied",
2892 if c_variadic { "at least " } else { "" },
2893 potentially_plural_count(expected_count, "parameter"),
2894 potentially_plural_count(arg_count, "parameter"),
2895 if arg_count == 1 {"was"} else {"were"}),
2896 DiagnosticId::Error(error_code.to_owned()));
2898 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
2899 err.span_label(def_s, "defined here");
2902 let sugg_span = tcx.sess.source_map().end_point(expr_sp);
2903 // remove closing `)` from the span
2904 let sugg_span = sugg_span.shrink_to_lo();
2905 err.span_suggestion(
2907 "expected the unit value `()`; create it with empty parentheses",
2909 Applicability::MachineApplicable);
2911 err.span_label(sp, format!("expected {}{}",
2912 if c_variadic { "at least " } else { "" },
2913 potentially_plural_count(expected_count, "parameter")));
2918 let mut expected_arg_tys = expected_arg_tys.to_vec();
2920 let formal_tys = if tuple_arguments == TupleArguments {
2921 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2922 match tuple_type.sty {
2923 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
2924 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
2925 expected_arg_tys = vec![];
2926 self.err_args(args.len())
2928 ty::Tuple(arg_types) => {
2929 expected_arg_tys = match expected_arg_tys.get(0) {
2930 Some(&ty) => match ty.sty {
2931 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
2936 arg_types.iter().map(|k| k.expect_ty()).collect()
2939 span_err!(tcx.sess, sp, E0059,
2940 "cannot use call notation; the first type parameter \
2941 for the function trait is neither a tuple nor unit");
2942 expected_arg_tys = vec![];
2943 self.err_args(args.len())
2946 } else if expected_arg_count == supplied_arg_count {
2948 } else if c_variadic {
2949 if supplied_arg_count >= expected_arg_count {
2952 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
2953 expected_arg_tys = vec![];
2954 self.err_args(supplied_arg_count)
2957 // is the missing argument of type `()`?
2958 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2959 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_unit()
2960 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2961 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_unit()
2965 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
2967 expected_arg_tys = vec![];
2968 self.err_args(supplied_arg_count)
2971 debug!("check_argument_types: formal_tys={:?}",
2972 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2974 // If there is no expectation, expect formal_tys.
2975 let expected_arg_tys = if !expected_arg_tys.is_empty() {
2981 // Check the arguments.
2982 // We do this in a pretty awful way: first we type-check any arguments
2983 // that are not closures, then we type-check the closures. This is so
2984 // that we have more information about the types of arguments when we
2985 // type-check the functions. This isn't really the right way to do this.
2986 for &check_closures in &[false, true] {
2987 debug!("check_closures={}", check_closures);
2989 // More awful hacks: before we check argument types, try to do
2990 // an "opportunistic" vtable resolution of any trait bounds on
2991 // the call. This helps coercions.
2993 self.select_obligations_where_possible(false);
2996 // For C-variadic functions, we don't have a declared type for all of
2997 // the arguments hence we only do our usual type checking with
2998 // the arguments who's types we do know.
2999 let t = if c_variadic {
3001 } else if tuple_arguments == TupleArguments {
3006 for (i, arg) in args.iter().take(t).enumerate() {
3007 // Warn only for the first loop (the "no closures" one).
3008 // Closure arguments themselves can't be diverging, but
3009 // a previous argument can, e.g., `foo(panic!(), || {})`.
3010 if !check_closures {
3011 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3014 let is_closure = match arg.node {
3015 ExprKind::Closure(..) => true,
3019 if is_closure != check_closures {
3023 debug!("checking the argument");
3024 let formal_ty = formal_tys[i];
3026 // The special-cased logic below has three functions:
3027 // 1. Provide as good of an expected type as possible.
3028 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3030 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3032 // 2. Coerce to the most detailed type that could be coerced
3033 // to, which is `expected_ty` if `rvalue_hint` returns an
3034 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3035 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3036 // We're processing function arguments so we definitely want to use
3037 // two-phase borrows.
3038 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3040 // 3. Relate the expected type and the formal one,
3041 // if the expected type was used for the coercion.
3042 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3046 // We also need to make sure we at least write the ty of the other
3047 // arguments which we skipped above.
3049 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3050 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3051 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3054 for arg in args.iter().skip(expected_arg_count) {
3055 let arg_ty = self.check_expr(&arg);
3057 // There are a few types which get autopromoted when passed via varargs
3058 // in C but we just error out instead and require explicit casts.
3059 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3061 ty::Float(ast::FloatTy::F32) => {
3062 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3064 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3065 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3067 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3068 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3071 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3072 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
3073 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3081 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3082 vec![self.tcx.types.err; len]
3085 // AST fragment checking
3088 expected: Expectation<'tcx>)
3094 ast::LitKind::Str(..) => tcx.mk_static_str(),
3095 ast::LitKind::ByteStr(ref v) => {
3096 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3097 tcx.mk_array(tcx.types.u8, v.len() as u64))
3099 ast::LitKind::Byte(_) => tcx.types.u8,
3100 ast::LitKind::Char(_) => tcx.types.char,
3101 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3102 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3103 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3104 let opt_ty = expected.to_option(self).and_then(|ty| {
3106 ty::Int(_) | ty::Uint(_) => Some(ty),
3107 ty::Char => Some(tcx.types.u8),
3108 ty::RawPtr(..) => Some(tcx.types.usize),
3109 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3113 opt_ty.unwrap_or_else(|| self.next_int_var())
3115 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3116 ast::LitKind::FloatUnsuffixed(_) => {
3117 let opt_ty = expected.to_option(self).and_then(|ty| {
3119 ty::Float(_) => Some(ty),
3123 opt_ty.unwrap_or_else(|| self.next_float_var())
3125 ast::LitKind::Bool(_) => tcx.types.bool,
3126 ast::LitKind::Err(_) => tcx.types.err,
3130 fn check_expr_eq_type(&self,
3131 expr: &'gcx hir::Expr,
3132 expected: Ty<'tcx>) {
3133 let ty = self.check_expr_with_hint(expr, expected);
3134 self.demand_eqtype(expr.span, expected, ty);
3137 pub fn check_expr_has_type_or_error(&self,
3138 expr: &'gcx hir::Expr,
3139 expected: Ty<'tcx>) -> Ty<'tcx> {
3140 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
3143 fn check_expr_meets_expectation_or_error(&self,
3144 expr: &'gcx hir::Expr,
3145 expected: Expectation<'tcx>) -> Ty<'tcx> {
3146 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
3147 let mut ty = self.check_expr_with_expectation(expr, expected);
3149 // While we don't allow *arbitrary* coercions here, we *do* allow
3150 // coercions from ! to `expected`.
3152 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
3153 "expression with never type wound up being adjusted");
3154 let adj_ty = self.next_diverging_ty_var(
3155 TypeVariableOrigin::AdjustmentType(expr.span));
3156 self.apply_adjustments(expr, vec![Adjustment {
3157 kind: Adjust::NeverToAny,
3163 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
3164 if self.is_assign_to_bool(expr, expected_ty) {
3165 // Error reported in `check_assign` so avoid emitting error again.
3166 // FIXME(centril): Consider removing if/when `if` desugars to `match`.
3175 fn check_expr_coercable_to_type(&self,
3176 expr: &'gcx hir::Expr,
3177 expected: Ty<'tcx>) -> Ty<'tcx> {
3178 let ty = self.check_expr_with_hint(expr, expected);
3179 // checks don't need two phase
3180 self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
3183 fn check_expr_with_hint(&self,
3184 expr: &'gcx hir::Expr,
3185 expected: Ty<'tcx>) -> Ty<'tcx> {
3186 self.check_expr_with_expectation(expr, ExpectHasType(expected))
3189 fn check_expr_with_expectation(&self,
3190 expr: &'gcx hir::Expr,
3191 expected: Expectation<'tcx>) -> Ty<'tcx> {
3192 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
3195 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
3196 self.check_expr_with_expectation(expr, NoExpectation)
3199 fn check_expr_with_needs(&self, expr: &'gcx hir::Expr, needs: Needs) -> Ty<'tcx> {
3200 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
3203 // Determine the `Self` type, using fresh variables for all variables
3204 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3205 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3207 pub fn impl_self_ty(&self,
3208 span: Span, // (potential) receiver for this impl
3210 -> TypeAndSubsts<'tcx> {
3211 let ity = self.tcx.type_of(did);
3212 debug!("impl_self_ty: ity={:?}", ity);
3214 let substs = self.fresh_substs_for_item(span, did);
3215 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3217 TypeAndSubsts { substs: substs, ty: substd_ty }
3220 /// Unifies the output type with the expected type early, for more coercions
3221 /// and forward type information on the input expressions.
3222 fn expected_inputs_for_expected_output(&self,
3224 expected_ret: Expectation<'tcx>,
3225 formal_ret: Ty<'tcx>,
3226 formal_args: &[Ty<'tcx>])
3228 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3229 let ret_ty = match expected_ret.only_has_type(self) {
3231 None => return Vec::new()
3233 let expect_args = self.fudge_inference_if_ok(|| {
3234 // Attempt to apply a subtyping relationship between the formal
3235 // return type (likely containing type variables if the function
3236 // is polymorphic) and the expected return type.
3237 // No argument expectations are produced if unification fails.
3238 let origin = self.misc(call_span);
3239 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3241 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3242 // to identity so the resulting type is not constrained.
3245 // Process any obligations locally as much as
3246 // we can. We don't care if some things turn
3247 // out unconstrained or ambiguous, as we're
3248 // just trying to get hints here.
3249 self.save_and_restore_in_snapshot_flag(|_| {
3250 let mut fulfill = TraitEngine::new(self.tcx);
3251 for obligation in ok.obligations {
3252 fulfill.register_predicate_obligation(self, obligation);
3254 fulfill.select_where_possible(self)
3255 }).map_err(|_| ())?;
3257 Err(_) => return Err(()),
3260 // Record all the argument types, with the substitutions
3261 // produced from the above subtyping unification.
3262 Ok(formal_args.iter().map(|ty| {
3263 self.resolve_type_vars_if_possible(ty)
3265 }).unwrap_or_default();
3266 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3267 formal_args, formal_ret,
3268 expect_args, expected_ret);
3272 // Checks a method call.
3273 fn check_method_call(&self,
3274 expr: &'gcx hir::Expr,
3275 segment: &hir::PathSegment,
3277 args: &'gcx [hir::Expr],
3278 expected: Expectation<'tcx>,
3279 needs: Needs) -> Ty<'tcx> {
3280 let rcvr = &args[0];
3281 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
3282 // no need to check for bot/err -- callee does that
3283 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
3285 let method = match self.lookup_method(rcvr_t,
3291 self.write_method_call(expr.hir_id, method);
3295 if segment.ident.name != keywords::Invalid.name() {
3296 self.report_method_error(span,
3299 SelfSource::MethodCall(rcvr),
3307 // Call the generic checker.
3308 self.check_method_argument_types(span,
3316 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
3320 .unwrap_or_else(|| span_bug!(return_expr.span,
3321 "check_return_expr called outside fn body"));
3323 let ret_ty = ret_coercion.borrow().expected_ty();
3324 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
3325 ret_coercion.borrow_mut()
3327 &self.cause(return_expr.span,
3328 ObligationCauseCode::ReturnType(return_expr.hir_id)),
3333 // A generic function for checking the 'then' and 'else' clauses in an 'if'
3334 // or 'if-else' expression.
3335 fn check_then_else(&self,
3336 cond_expr: &'gcx hir::Expr,
3337 then_expr: &'gcx hir::Expr,
3338 opt_else_expr: Option<&'gcx hir::Expr>,
3340 expected: Expectation<'tcx>) -> Ty<'tcx> {
3341 let cond_ty = self.check_expr_has_type_or_error(cond_expr, self.tcx.types.bool);
3342 let cond_diverges = self.diverges.get();
3343 self.diverges.set(Diverges::Maybe);
3345 let expected = expected.adjust_for_branches(self);
3346 let then_ty = self.check_expr_with_expectation(then_expr, expected);
3347 let then_diverges = self.diverges.get();
3348 self.diverges.set(Diverges::Maybe);
3350 // We've already taken the expected type's preferences
3351 // into account when typing the `then` branch. To figure
3352 // out the initial shot at a LUB, we thus only consider
3353 // `expected` if it represents a *hard* constraint
3354 // (`only_has_type`); otherwise, we just go with a
3355 // fresh type variable.
3356 let coerce_to_ty = expected.coercion_target_type(self, sp);
3357 let mut coerce: DynamicCoerceMany<'_, '_> = CoerceMany::new(coerce_to_ty);
3359 coerce.coerce(self, &self.misc(sp), then_expr, then_ty);
3361 if let Some(else_expr) = opt_else_expr {
3362 let else_ty = self.check_expr_with_expectation(else_expr, expected);
3363 let else_diverges = self.diverges.get();
3365 let mut outer_sp = if self.tcx.sess.source_map().is_multiline(sp) {
3366 // The `if`/`else` isn't in one line in the output, include some context to make it
3367 // clear it is an if/else expression:
3369 // LL | let x = if true {
3372 // || ----- expected because of this
3375 // || ^^^^^ expected i32, found u32
3377 // ||_____- if and else have incompatible types
3381 // The entire expression is in one line, only point at the arms
3383 // LL | let x = if true { 10i32 } else { 10u32 };
3384 // | ----- ^^^^^ expected i32, found u32
3386 // | expected because of this
3390 let mut remove_semicolon = None;
3391 let error_sp = if let ExprKind::Block(block, _) = &else_expr.node {
3392 if let Some(expr) = &block.expr {
3394 } else if let Some(stmt) = block.stmts.last() {
3395 // possibly incorrect trailing `;` in the else arm
3396 remove_semicolon = self.could_remove_semicolon(block, then_ty);
3398 } else { // empty block, point at its entirety
3399 // Avoid overlapping spans that aren't as readable:
3401 // 2 | let x = if true {
3404 // | | - expected because of this
3411 // | |______if and else have incompatible types
3412 // | expected integer, found ()
3414 // by not pointing at the entire expression:
3416 // 2 | let x = if true {
3417 // | ------- if and else have incompatible types
3419 // | - expected because of this
3424 // | |_____^ expected integer, found ()
3426 if outer_sp.is_some() {
3427 outer_sp = Some(self.tcx.sess.source_map().def_span(sp));
3431 } else { // shouldn't happen unless the parser has done something weird
3434 let then_sp = if let ExprKind::Block(block, _) = &then_expr.node {
3435 if let Some(expr) = &block.expr {
3437 } else if let Some(stmt) = block.stmts.last() {
3438 // possibly incorrect trailing `;` in the else arm
3439 remove_semicolon = remove_semicolon.or(
3440 self.could_remove_semicolon(block, else_ty));
3442 } else { // empty block, point at its entirety
3443 outer_sp = None; // same as in `error_sp`, cleanup output
3446 } else { // shouldn't happen unless the parser has done something weird
3450 let if_cause = self.cause(error_sp, ObligationCauseCode::IfExpression {
3453 semicolon: remove_semicolon,
3456 coerce.coerce(self, &if_cause, else_expr, else_ty);
3458 // We won't diverge unless both branches do (or the condition does).
3459 self.diverges.set(cond_diverges | then_diverges & else_diverges);
3461 // If this `if` expr is the parent's function return expr, the cause of the type
3462 // coercion is the return type, point at it. (#25228)
3463 let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, sp);
3465 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
3466 coerce.coerce_forced_unit(self, &else_cause, &mut |err| {
3467 if let Some((sp, msg)) = &ret_reason {
3468 err.span_label(*sp, msg.as_str());
3469 } else if let ExprKind::Block(block, _) = &then_expr.node {
3470 if let Some(expr) = &block.expr {
3471 err.span_label(expr.span, "found here".to_string());
3474 err.note("`if` expressions without `else` evaluate to `()`");
3475 err.help("consider adding an `else` block that evaluates to the expected type");
3476 }, ret_reason.is_none());
3478 // If the condition is false we can't diverge.
3479 self.diverges.set(cond_diverges);
3482 let result_ty = coerce.complete(self);
3483 if cond_ty.references_error() {
3490 fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
3491 let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(
3492 self.tcx.hir().get_parent_node_by_hir_id(hir_id),
3494 if let Node::Block(block) = node {
3495 // check that the body's parent is an fn
3496 let parent = self.tcx.hir().get_by_hir_id(
3497 self.tcx.hir().get_parent_node_by_hir_id(
3498 self.tcx.hir().get_parent_node_by_hir_id(block.hir_id),
3501 if let (Some(expr), Node::Item(hir::Item {
3502 node: hir::ItemKind::Fn(..), ..
3503 })) = (&block.expr, parent) {
3504 // check that the `if` expr without `else` is the fn body's expr
3505 if expr.span == sp {
3506 return self.get_fn_decl(hir_id).map(|(fn_decl, _)| (
3507 fn_decl.output.span(),
3508 format!("expected `{}` because of this return type", fn_decl.output),
3513 if let Node::Local(hir::Local {
3514 ty: Some(_), pat, ..
3516 return Some((pat.span, "expected because of this assignment".to_string()));
3521 // Check field access expressions
3522 fn check_field(&self,
3523 expr: &'gcx hir::Expr,
3525 base: &'gcx hir::Expr,
3526 field: ast::Ident) -> Ty<'tcx> {
3527 let expr_t = self.check_expr_with_needs(base, needs);
3528 let expr_t = self.structurally_resolved_type(base.span,
3530 let mut private_candidate = None;
3531 let mut autoderef = self.autoderef(expr.span, expr_t);
3532 while let Some((base_t, _)) = autoderef.next() {
3534 ty::Adt(base_def, substs) if !base_def.is_enum() => {
3535 debug!("struct named {:?}", base_t);
3536 let (ident, def_scope) =
3537 self.tcx.adjust_ident(field, base_def.did, self.body_id);
3538 let fields = &base_def.non_enum_variant().fields;
3539 if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
3540 let field = &fields[index];
3541 let field_ty = self.field_ty(expr.span, field, substs);
3542 // Save the index of all fields regardless of their visibility in case
3543 // of error recovery.
3544 self.write_field_index(expr.hir_id, index);
3545 if field.vis.is_accessible_from(def_scope, self.tcx) {
3546 let adjustments = autoderef.adjust_steps(self, needs);
3547 self.apply_adjustments(base, adjustments);
3548 autoderef.finalize(self);
3550 self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
3553 private_candidate = Some((base_def.did, field_ty));
3556 ty::Tuple(ref tys) => {
3557 let fstr = field.as_str();
3558 if let Ok(index) = fstr.parse::<usize>() {
3559 if fstr == index.to_string() {
3560 if let Some(field_ty) = tys.get(index) {
3561 let adjustments = autoderef.adjust_steps(self, needs);
3562 self.apply_adjustments(base, adjustments);
3563 autoderef.finalize(self);
3565 self.write_field_index(expr.hir_id, index);
3566 return field_ty.expect_ty();
3574 autoderef.unambiguous_final_ty(self);
3576 if let Some((did, field_ty)) = private_candidate {
3577 let struct_path = self.tcx().def_path_str(did);
3578 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3579 "field `{}` of struct `{}` is private",
3580 field, struct_path);
3581 // Also check if an accessible method exists, which is often what is meant.
3582 if self.method_exists(field, expr_t, expr.hir_id, false)
3583 && !self.expr_in_place(expr.hir_id)
3585 self.suggest_method_call(
3587 &format!("a method `{}` also exists, call it with parentheses", field),
3595 } else if field.name == keywords::Invalid.name() {
3596 self.tcx().types.err
3597 } else if self.method_exists(field, expr_t, expr.hir_id, true) {
3598 let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3599 "attempted to take value of method `{}` on type `{}`",
3602 if !self.expr_in_place(expr.hir_id) {
3603 self.suggest_method_call(
3605 "use parentheses to call the method",
3611 err.help("methods are immutable and cannot be assigned to");
3615 self.tcx().types.err
3617 if !expr_t.is_primitive_ty() {
3618 let mut err = self.no_such_field_err(field.span, field, expr_t);
3621 ty::Adt(def, _) if !def.is_enum() => {
3622 if let Some(suggested_field_name) =
3623 Self::suggest_field_name(def.non_enum_variant(),
3624 &field.as_str(), vec![]) {
3625 err.span_suggestion(
3627 "a field with a similar name exists",
3628 suggested_field_name.to_string(),
3629 Applicability::MaybeIncorrect,
3632 err.span_label(field.span, "unknown field");
3633 let struct_variant_def = def.non_enum_variant();
3634 let field_names = self.available_field_names(struct_variant_def);
3635 if !field_names.is_empty() {
3636 err.note(&format!("available fields are: {}",
3637 self.name_series_display(field_names)));
3641 ty::Array(_, len) => {
3642 if let (Some(len), Ok(user_index)) = (
3643 len.assert_usize(self.tcx),
3644 field.as_str().parse::<u64>()
3646 let base = self.tcx.sess.source_map()
3647 .span_to_snippet(base.span)
3649 self.tcx.hir().hir_to_pretty_string(base.hir_id));
3650 let help = "instead of using tuple indexing, use array indexing";
3651 let suggestion = format!("{}[{}]", base, field);
3652 let applicability = if len < user_index {
3653 Applicability::MachineApplicable
3655 Applicability::MaybeIncorrect
3657 err.span_suggestion(
3658 expr.span, help, suggestion, applicability
3663 let base = self.tcx.sess.source_map()
3664 .span_to_snippet(base.span)
3665 .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
3666 let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
3667 let suggestion = format!("(*{}).{}", base, field);
3668 err.span_suggestion(
3672 Applicability::MaybeIncorrect,
3679 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3680 "`{}` is a primitive type and therefore doesn't have fields",
3683 self.tcx().types.err
3687 // Return an hint about the closest match in field names
3688 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3690 skip: Vec<LocalInternedString>)
3692 let names = variant.fields.iter().filter_map(|field| {
3693 // ignore already set fields and private fields from non-local crates
3694 if skip.iter().any(|x| *x == field.ident.as_str()) ||
3695 (!variant.def_id.is_local() && field.vis != Visibility::Public)
3699 Some(&field.ident.name)
3703 find_best_match_for_name(names, field, None)
3706 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3707 variant.fields.iter().filter(|field| {
3708 let def_scope = self.tcx.adjust_ident(field.ident, variant.def_id, self.body_id).1;
3709 field.vis.is_accessible_from(def_scope, self.tcx)
3711 .map(|field| field.ident.name)
3715 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3716 // dynamic limit, to never omit just one field
3717 let limit = if names.len() == 6 { 6 } else { 5 };
3718 let mut display = names.iter().take(limit)
3719 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3720 if names.len() > limit {
3721 display = format!("{} ... and {} others", display, names.len() - limit);
3726 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
3727 -> DiagnosticBuilder<'_> {
3728 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3729 "no field `{}` on type `{}`",
3733 fn report_unknown_field(
3736 variant: &'tcx ty::VariantDef,
3738 skip_fields: &[hir::Field],
3741 if variant.recovered {
3744 let mut err = self.type_error_struct_with_diag(
3746 |actual| match ty.sty {
3747 ty::Adt(adt, ..) if adt.is_enum() => {
3748 struct_span_err!(self.tcx.sess, field.ident.span, E0559,
3749 "{} `{}::{}` has no field named `{}`",
3750 kind_name, actual, variant.ident, field.ident)
3753 struct_span_err!(self.tcx.sess, field.ident.span, E0560,
3754 "{} `{}` has no field named `{}`",
3755 kind_name, actual, field.ident)
3759 // prevent all specified fields from being suggested
3760 let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
3761 if let Some(field_name) = Self::suggest_field_name(variant,
3762 &field.ident.as_str(),
3763 skip_fields.collect()) {
3764 err.span_suggestion(
3766 "a field with a similar name exists",
3767 field_name.to_string(),
3768 Applicability::MaybeIncorrect,
3772 ty::Adt(adt, ..) => {
3774 err.span_label(field.ident.span,
3775 format!("`{}::{}` does not have this field",
3776 ty, variant.ident));
3778 err.span_label(field.ident.span,
3779 format!("`{}` does not have this field", ty));
3781 let available_field_names = self.available_field_names(variant);
3782 if !available_field_names.is_empty() {
3783 err.note(&format!("available fields are: {}",
3784 self.name_series_display(available_field_names)));
3787 _ => bug!("non-ADT passed to report_unknown_field")
3793 fn check_expr_struct_fields(&self,
3795 expected: Expectation<'tcx>,
3796 expr_id: hir::HirId,
3798 variant: &'tcx ty::VariantDef,
3799 ast_fields: &'gcx [hir::Field],
3800 check_completeness: bool) -> bool {
3804 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3805 .get(0).cloned().unwrap_or(adt_ty);
3806 // re-link the regions that EIfEO can erase.
3807 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3809 let (substs, adt_kind, kind_name) = match &adt_ty.sty {
3810 &ty::Adt(adt, substs) => {
3811 (substs, adt.adt_kind(), adt.variant_descr())
3813 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3816 let mut remaining_fields = variant.fields.iter().enumerate().map(|(i, field)|
3817 (field.ident.modern(), (i, field))
3818 ).collect::<FxHashMap<_, _>>();
3820 let mut seen_fields = FxHashMap::default();
3822 let mut error_happened = false;
3824 // Type-check each field.
3825 for field in ast_fields {
3826 let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0;
3827 let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
3828 seen_fields.insert(ident, field.span);
3829 self.write_field_index(field.hir_id, i);
3831 // We don't look at stability attributes on
3832 // struct-like enums (yet...), but it's definitely not
3833 // a bug to have constructed one.
3834 if adt_kind != AdtKind::Enum {
3835 tcx.check_stability(v_field.did, Some(expr_id), field.span);
3838 self.field_ty(field.span, v_field, substs)
3840 error_happened = true;
3841 if let Some(prev_span) = seen_fields.get(&ident) {
3842 let mut err = struct_span_err!(self.tcx.sess,
3845 "field `{}` specified more than once",
3848 err.span_label(field.ident.span, "used more than once");
3849 err.span_label(*prev_span, format!("first use of `{}`", ident));
3853 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3859 // Make sure to give a type to the field even if there's
3860 // an error, so we can continue type-checking.
3861 self.check_expr_coercable_to_type(&field.expr, field_type);
3864 // Make sure the programmer specified correct number of fields.
3865 if kind_name == "union" {
3866 if ast_fields.len() != 1 {
3867 tcx.sess.span_err(span, "union expressions should have exactly one field");
3869 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3870 let len = remaining_fields.len();
3872 let mut displayable_field_names = remaining_fields
3874 .map(|ident| ident.as_str())
3875 .collect::<Vec<_>>();
3877 displayable_field_names.sort();
3879 let truncated_fields_error = if len <= 3 {
3882 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3885 let remaining_fields_names = displayable_field_names.iter().take(3)
3886 .map(|n| format!("`{}`", n))
3887 .collect::<Vec<_>>()
3890 struct_span_err!(tcx.sess, span, E0063,
3891 "missing field{} {}{} in initializer of `{}`",
3892 if remaining_fields.len() == 1 { "" } else { "s" },
3893 remaining_fields_names,
3894 truncated_fields_error,
3896 .span_label(span, format!("missing {}{}",
3897 remaining_fields_names,
3898 truncated_fields_error))
3904 fn check_struct_fields_on_error(&self,
3905 fields: &'gcx [hir::Field],
3906 base_expr: &'gcx Option<P<hir::Expr>>) {
3907 for field in fields {
3908 self.check_expr(&field.expr);
3910 if let Some(ref base) = *base_expr {
3911 self.check_expr(&base);
3915 pub fn check_struct_path(&self,
3918 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3919 let path_span = match *qpath {
3920 QPath::Resolved(_, ref path) => path.span,
3921 QPath::TypeRelative(ref qself, _) => qself.span
3923 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3924 let variant = match def {
3926 self.set_tainted_by_errors();
3929 Def::Def(DefKind::Variant, _) => {
3931 ty::Adt(adt, substs) => {
3932 Some((adt.variant_of_def(def), adt.did, substs))
3934 _ => bug!("unexpected type: {:?}", ty)
3937 Def::Def(DefKind::Struct, _)
3938 | Def::Def(DefKind::Union, _)
3939 | Def::Def(DefKind::TyAlias, _)
3940 | Def::Def(DefKind::AssociatedTy, _)
3941 | Def::SelfTy(..) => {
3943 ty::Adt(adt, substs) if !adt.is_enum() => {
3944 Some((adt.non_enum_variant(), adt.did, substs))
3949 _ => bug!("unexpected definition: {:?}", def)
3952 if let Some((variant, did, substs)) = variant {
3953 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3954 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3956 // Check bounds on type arguments used in the path.
3957 let bounds = self.instantiate_bounds(path_span, did, substs);
3958 let cause = traits::ObligationCause::new(path_span, self.body_id,
3959 traits::ItemObligation(did));
3960 self.add_obligations_for_parameters(cause, &bounds);
3964 struct_span_err!(self.tcx.sess, path_span, E0071,
3965 "expected struct, variant or union type, found {}",
3966 ty.sort_string(self.tcx))
3967 .span_label(path_span, "not a struct")
3973 fn check_expr_struct(&self,
3975 expected: Expectation<'tcx>,
3977 fields: &'gcx [hir::Field],
3978 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3980 // Find the relevant variant
3981 let (variant, adt_ty) =
3982 if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id) {
3985 self.check_struct_fields_on_error(fields, base_expr);
3986 return self.tcx.types.err;
3989 let path_span = match *qpath {
3990 QPath::Resolved(_, ref path) => path.span,
3991 QPath::TypeRelative(ref qself, _) => qself.span
3994 // Prohibit struct expressions when non-exhaustive flag is set.
3995 let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
3996 if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
3997 span_err!(self.tcx.sess, expr.span, E0639,
3998 "cannot create non-exhaustive {} using struct expression",
3999 adt.variant_descr());
4002 let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.hir_id, path_span,
4003 variant, fields, base_expr.is_none());
4004 if let &Some(ref base_expr) = base_expr {
4005 // If check_expr_struct_fields hit an error, do not attempt to populate
4006 // the fields with the base_expr. This could cause us to hit errors later
4007 // when certain fields are assumed to exist that in fact do not.
4008 if !error_happened {
4009 self.check_expr_has_type_or_error(base_expr, adt_ty);
4011 ty::Adt(adt, substs) if adt.is_struct() => {
4012 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
4013 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
4018 .fru_field_types_mut()
4019 .insert(expr.hir_id, fru_field_types);
4022 span_err!(self.tcx.sess, base_expr.span, E0436,
4023 "functional record update syntax requires a struct");
4028 self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
4034 /// If an expression has any sub-expressions that result in a type error,
4035 /// inspecting that expression's type with `ty.references_error()` will return
4036 /// true. Likewise, if an expression is known to diverge, inspecting its
4037 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
4038 /// strict, _|_ can appear in the type of an expression that does not,
4039 /// itself, diverge: for example, fn() -> _|_.)
4040 /// Note that inspecting a type's structure *directly* may expose the fact
4041 /// that there are actually multiple representations for `Error`, so avoid
4042 /// that when err needs to be handled differently.
4043 fn check_expr_with_expectation_and_needs(&self,
4044 expr: &'gcx hir::Expr,
4045 expected: Expectation<'tcx>,
4046 needs: Needs) -> Ty<'tcx> {
4047 debug!(">> type-checking: expr={:?} expected={:?}",
4050 // Warn for expressions after diverging siblings.
4051 self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
4053 // Hide the outer diverging and has_errors flags.
4054 let old_diverges = self.diverges.get();
4055 let old_has_errors = self.has_errors.get();
4056 self.diverges.set(Diverges::Maybe);
4057 self.has_errors.set(false);
4059 let ty = self.check_expr_kind(expr, expected, needs);
4061 // Warn for non-block expressions with diverging children.
4063 ExprKind::Block(..) |
4064 ExprKind::Loop(..) | ExprKind::While(..) |
4065 ExprKind::If(..) | ExprKind::Match(..) => {}
4067 _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression")
4070 // Any expression that produces a value of type `!` must have diverged
4072 self.diverges.set(self.diverges.get() | Diverges::Always);
4075 // Record the type, which applies it effects.
4076 // We need to do this after the warning above, so that
4077 // we don't warn for the diverging expression itself.
4078 self.write_ty(expr.hir_id, ty);
4080 // Combine the diverging and has_error flags.
4081 self.diverges.set(self.diverges.get() | old_diverges);
4082 self.has_errors.set(self.has_errors.get() | old_has_errors);
4084 debug!("type of {} is...", self.tcx.hir().hir_to_string(expr.hir_id));
4085 debug!("... {:?}, expected is {:?}", ty, expected);
4092 expr: &'gcx hir::Expr,
4093 expected: Expectation<'tcx>,
4097 "check_expr_kind(expr={:?}, expected={:?}, needs={:?})",
4104 let id = expr.hir_id;
4106 ExprKind::Box(ref subexpr) => {
4107 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
4109 ty::Adt(def, _) if def.is_box()
4110 => Expectation::rvalue_hint(self, ty.boxed_ty()),
4114 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
4115 tcx.mk_box(referent_ty)
4118 ExprKind::Lit(ref lit) => {
4119 self.check_lit(&lit, expected)
4121 ExprKind::Binary(op, ref lhs, ref rhs) => {
4122 self.check_binop(expr, op, lhs, rhs)
4124 ExprKind::AssignOp(op, ref lhs, ref rhs) => {
4125 self.check_binop_assign(expr, op, lhs, rhs)
4127 ExprKind::Unary(unop, ref oprnd) => {
4128 let expected_inner = match unop {
4129 hir::UnNot | hir::UnNeg => {
4136 let needs = match unop {
4137 hir::UnDeref => needs,
4140 let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
4144 if !oprnd_t.references_error() {
4145 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
4148 if let Some(mt) = oprnd_t.builtin_deref(true) {
4150 } else if let Some(ok) = self.try_overloaded_deref(
4151 expr.span, oprnd_t, needs) {
4152 let method = self.register_infer_ok_obligations(ok);
4153 if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
4154 let mutbl = match mutbl {
4155 hir::MutImmutable => AutoBorrowMutability::Immutable,
4156 hir::MutMutable => AutoBorrowMutability::Mutable {
4157 // (It shouldn't actually matter for unary ops whether
4158 // we enable two-phase borrows or not, since a unary
4159 // op has no additional operands.)
4160 allow_two_phase_borrow: AllowTwoPhase::No,
4163 self.apply_adjustments(oprnd, vec![Adjustment {
4164 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
4165 target: method.sig.inputs()[0]
4168 oprnd_t = self.make_overloaded_place_return_type(method).ty;
4169 self.write_method_call(expr.hir_id, method);
4171 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
4172 "type `{}` cannot be dereferenced",
4174 oprnd_t = tcx.types.err;
4178 let result = self.check_user_unop(expr, oprnd_t, unop);
4179 // If it's builtin, we can reuse the type, this helps inference.
4180 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::Bool) {
4185 let result = self.check_user_unop(expr, oprnd_t, unop);
4186 // If it's builtin, we can reuse the type, this helps inference.
4187 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
4195 ExprKind::AddrOf(mutbl, ref oprnd) => {
4196 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
4198 ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
4199 if oprnd.is_place_expr() {
4200 // Places may legitimately have unsized types.
4201 // For example, dereferences of a fat pointer and
4202 // the last field of a struct can be unsized.
4205 Expectation::rvalue_hint(self, ty)
4211 let needs = Needs::maybe_mut_place(mutbl);
4212 let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
4214 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
4215 if tm.ty.references_error() {
4218 // Note: at this point, we cannot say what the best lifetime
4219 // is to use for resulting pointer. We want to use the
4220 // shortest lifetime possible so as to avoid spurious borrowck
4221 // errors. Moreover, the longest lifetime will depend on the
4222 // precise details of the value whose address is being taken
4223 // (and how long it is valid), which we don't know yet until type
4224 // inference is complete.
4226 // Therefore, here we simply generate a region variable. The
4227 // region inferencer will then select the ultimate value.
4228 // Finally, borrowck is charged with guaranteeing that the
4229 // value whose address was taken can actually be made to live
4230 // as long as it needs to live.
4231 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
4232 tcx.mk_ref(region, tm)
4235 ExprKind::Path(ref qpath) => {
4236 let (def, opt_ty, segs) = self.resolve_ty_and_def_ufcs(qpath, expr.hir_id,
4238 let ty = match def {
4240 self.set_tainted_by_errors();
4243 Def::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
4244 report_unexpected_variant_def(tcx, &def, expr.span, qpath);
4247 _ => self.instantiate_value_path(segs, opt_ty, def, expr.span, id).0,
4250 if let ty::FnDef(..) = ty.sty {
4251 let fn_sig = ty.fn_sig(tcx);
4252 if !tcx.features().unsized_locals {
4253 // We want to remove some Sized bounds from std functions,
4254 // but don't want to expose the removal to stable Rust.
4255 // i.e., we don't want to allow
4261 // to work in stable even if the Sized bound on `drop` is relaxed.
4262 for i in 0..fn_sig.inputs().skip_binder().len() {
4263 // We just want to check sizedness, so instead of introducing
4264 // placeholder lifetimes with probing, we just replace higher lifetimes
4266 let input = self.replace_bound_vars_with_fresh_vars(
4268 infer::LateBoundRegionConversionTime::FnCall,
4269 &fn_sig.input(i)).0;
4270 self.require_type_is_sized_deferred(input, expr.span,
4271 traits::SizedArgumentType);
4274 // Here we want to prevent struct constructors from returning unsized types.
4275 // There were two cases this happened: fn pointer coercion in stable
4276 // and usual function call in presense of unsized_locals.
4277 // Also, as we just want to check sizedness, instead of introducing
4278 // placeholder lifetimes with probing, we just replace higher lifetimes
4280 let output = self.replace_bound_vars_with_fresh_vars(
4282 infer::LateBoundRegionConversionTime::FnCall,
4283 &fn_sig.output()).0;
4284 self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
4287 // We always require that the type provided as the value for
4288 // a type parameter outlives the moment of instantiation.
4289 let substs = self.tables.borrow().node_substs(expr.hir_id);
4290 self.add_wf_bounds(substs, expr);
4294 ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
4295 for expr in outputs.iter().chain(inputs.iter()) {
4296 self.check_expr(expr);
4300 ExprKind::Break(destination, ref expr_opt) => {
4301 if let Ok(target_id) = destination.target_id {
4303 if let Some(ref e) = *expr_opt {
4304 // If this is a break with a value, we need to type-check
4305 // the expression. Get an expected type from the loop context.
4306 let opt_coerce_to = {
4307 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4308 enclosing_breakables.find_breakable(target_id)
4311 .map(|coerce| coerce.expected_ty())
4314 // If the loop context is not a `loop { }`, then break with
4315 // a value is illegal, and `opt_coerce_to` will be `None`.
4316 // Just set expectation to error in that case.
4317 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
4319 // Recurse without `enclosing_breakables` borrowed.
4320 e_ty = self.check_expr_with_hint(e, coerce_to);
4321 cause = self.misc(e.span);
4323 // Otherwise, this is a break *without* a value. That's
4324 // always legal, and is equivalent to `break ()`.
4325 e_ty = tcx.mk_unit();
4326 cause = self.misc(expr.span);
4329 // Now that we have type-checked `expr_opt`, borrow
4330 // the `enclosing_loops` field and let's coerce the
4331 // type of `expr_opt` into what is expected.
4332 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4333 let ctxt = enclosing_breakables.find_breakable(target_id);
4334 if let Some(ref mut coerce) = ctxt.coerce {
4335 if let Some(ref e) = *expr_opt {
4336 coerce.coerce(self, &cause, e, e_ty);
4338 assert!(e_ty.is_unit());
4339 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
4342 // If `ctxt.coerce` is `None`, we can just ignore
4343 // the type of the expresison. This is because
4344 // either this was a break *without* a value, in
4345 // which case it is always a legal type (`()`), or
4346 // else an error would have been flagged by the
4347 // `loops` pass for using break with an expression
4348 // where you are not supposed to.
4349 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
4352 ctxt.may_break = true;
4354 // the type of a `break` is always `!`, since it diverges
4357 // Otherwise, we failed to find the enclosing loop;
4358 // this can only happen if the `break` was not
4359 // inside a loop at all, which is caught by the
4360 // loop-checking pass.
4361 if self.tcx.sess.err_count() == 0 {
4362 self.tcx.sess.delay_span_bug(expr.span,
4363 "break was outside loop, but no error was emitted");
4366 // We still need to assign a type to the inner expression to
4367 // prevent the ICE in #43162.
4368 if let Some(ref e) = *expr_opt {
4369 self.check_expr_with_hint(e, tcx.types.err);
4371 // ... except when we try to 'break rust;'.
4372 // ICE this expression in particular (see #43162).
4373 if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
4374 if path.segments.len() == 1 && path.segments[0].ident.name == "rust" {
4375 fatally_break_rust(self.tcx.sess);
4379 // There was an error; make type-check fail.
4384 ExprKind::Continue(destination) => {
4385 if destination.target_id.is_ok() {
4388 // There was an error; make type-check fail.
4392 ExprKind::Ret(ref expr_opt) => {
4393 if self.ret_coercion.is_none() {
4394 struct_span_err!(self.tcx.sess, expr.span, E0572,
4395 "return statement outside of function body").emit();
4396 } else if let Some(ref e) = *expr_opt {
4397 if self.ret_coercion_span.borrow().is_none() {
4398 *self.ret_coercion_span.borrow_mut() = Some(e.span);
4400 self.check_return_expr(e);
4402 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
4403 if self.ret_coercion_span.borrow().is_none() {
4404 *self.ret_coercion_span.borrow_mut() = Some(expr.span);
4406 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
4407 if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
4408 coercion.coerce_forced_unit(
4413 fn_decl.output.span(),
4415 "expected `{}` because of this return type",
4423 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
4428 ExprKind::Assign(ref lhs, ref rhs) => {
4429 self.check_assign(expr, expected, lhs, rhs)
4431 ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => {
4432 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
4433 expr.span, expected)
4435 ExprKind::While(ref cond, ref body, _) => {
4436 let ctxt = BreakableCtxt {
4437 // cannot use break with a value from a while loop
4439 may_break: false, // Will get updated if/when we find a `break`.
4442 let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
4443 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
4444 let cond_diverging = self.diverges.get();
4445 self.check_block_no_value(&body);
4447 // We may never reach the body so it diverging means nothing.
4448 self.diverges.set(cond_diverging);
4452 // No way to know whether it's diverging because
4453 // of a `break` or an outer `break` or `return`.
4454 self.diverges.set(Diverges::Maybe);
4459 ExprKind::Loop(ref body, _, source) => {
4460 let coerce = match source {
4461 // you can only use break with a value from a normal `loop { }`
4462 hir::LoopSource::Loop => {
4463 let coerce_to = expected.coercion_target_type(self, body.span);
4464 Some(CoerceMany::new(coerce_to))
4467 hir::LoopSource::WhileLet |
4468 hir::LoopSource::ForLoop => {
4473 let ctxt = BreakableCtxt {
4475 may_break: false, // Will get updated if/when we find a `break`.
4478 let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
4479 self.check_block_no_value(&body);
4483 // No way to know whether it's diverging because
4484 // of a `break` or an outer `break` or `return`.
4485 self.diverges.set(Diverges::Maybe);
4488 // If we permit break with a value, then result type is
4489 // the LUB of the breaks (possibly ! if none); else, it
4490 // is nil. This makes sense because infinite loops
4491 // (which would have type !) are only possible iff we
4492 // permit break with a value [1].
4493 if ctxt.coerce.is_none() && !ctxt.may_break {
4495 self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
4497 ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
4499 ExprKind::Match(ref discrim, ref arms, match_src) => {
4500 self.check_match(expr, &discrim, arms, expected, match_src)
4502 ExprKind::Closure(capture, ref decl, body_id, _, gen) => {
4503 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
4505 ExprKind::Block(ref body, _) => {
4506 self.check_block_with_expected(&body, expected)
4508 ExprKind::Call(ref callee, ref args) => {
4509 self.check_call(expr, &callee, args, expected)
4511 ExprKind::MethodCall(ref segment, span, ref args) => {
4512 self.check_method_call(expr, segment, span, args, expected, needs)
4514 ExprKind::Cast(ref e, ref t) => {
4515 // Find the type of `e`. Supply hints based on the type we are casting to,
4517 let t_cast = self.to_ty_saving_user_provided_ty(t);
4518 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
4519 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
4520 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
4522 // Eagerly check for some obvious errors.
4523 if t_expr.references_error() || t_cast.references_error() {
4526 // Defer other checks until we're done type checking.
4527 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
4528 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
4530 deferred_cast_checks.push(cast_check);
4533 Err(ErrorReported) => {
4539 ExprKind::Type(ref e, ref t) => {
4540 let ty = self.to_ty_saving_user_provided_ty(&t);
4541 self.check_expr_eq_type(&e, ty);
4544 ExprKind::DropTemps(ref e) => {
4545 self.check_expr_with_expectation(e, expected)
4547 ExprKind::Array(ref args) => {
4548 let uty = expected.to_option(self).and_then(|uty| {
4550 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4555 let element_ty = if !args.is_empty() {
4556 let coerce_to = uty.unwrap_or_else(
4557 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
4558 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
4559 assert_eq!(self.diverges.get(), Diverges::Maybe);
4561 let e_ty = self.check_expr_with_hint(e, coerce_to);
4562 let cause = self.misc(e.span);
4563 coerce.coerce(self, &cause, e, e_ty);
4565 coerce.complete(self)
4567 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
4569 tcx.mk_array(element_ty, args.len() as u64)
4571 ExprKind::Repeat(ref element, ref count) => {
4572 let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
4573 let param_env = ty::ParamEnv::empty();
4574 let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
4575 let instance = ty::Instance::resolve(
4581 let global_id = GlobalId {
4585 let count = tcx.const_eval(param_env.and(global_id));
4587 let uty = match expected {
4588 ExpectHasType(uty) => {
4590 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4597 let (element_ty, t) = match uty {
4599 self.check_expr_coercable_to_type(&element, uty);
4603 let ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
4604 let element_ty = self.check_expr_has_type_or_error(&element, ty);
4609 if let Ok(count) = count {
4610 let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
4612 // For [foo, ..n] where n > 1, `foo` must have
4614 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4615 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4619 if element_ty.references_error() {
4621 } else if let Ok(count) = count {
4622 tcx.mk_ty(ty::Array(t, tcx.mk_const(count)))
4627 ExprKind::Tup(ref elts) => {
4628 let flds = expected.only_has_type(self).and_then(|ty| {
4629 let ty = self.resolve_type_vars_with_obligations(ty);
4631 ty::Tuple(ref flds) => Some(&flds[..]),
4636 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4637 let t = match flds {
4638 Some(ref fs) if i < fs.len() => {
4639 let ety = fs[i].expect_ty();
4640 self.check_expr_coercable_to_type(&e, ety);
4644 self.check_expr_with_expectation(&e, NoExpectation)
4649 let tuple = tcx.mk_tup(elt_ts_iter);
4650 if tuple.references_error() {
4653 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4657 ExprKind::Struct(ref qpath, ref fields, ref base_expr) => {
4658 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4660 ExprKind::Field(ref base, field) => {
4661 self.check_field(expr, needs, &base, field)
4663 ExprKind::Index(ref base, ref idx) => {
4664 let base_t = self.check_expr_with_needs(&base, needs);
4665 let idx_t = self.check_expr(&idx);
4667 if base_t.references_error() {
4669 } else if idx_t.references_error() {
4672 let base_t = self.structurally_resolved_type(base.span, base_t);
4673 match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
4674 Some((index_ty, element_ty)) => {
4675 // two-phase not needed because index_ty is never mutable
4676 self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
4681 type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4682 "cannot index into a value of type `{}`",
4684 // Try to give some advice about indexing tuples.
4685 if let ty::Tuple(..) = base_t.sty {
4686 let mut needs_note = true;
4687 // If the index is an integer, we can show the actual
4688 // fixed expression:
4689 if let ExprKind::Lit(ref lit) = idx.node {
4690 if let ast::LitKind::Int(i,
4691 ast::LitIntType::Unsuffixed) = lit.node {
4692 let snip = tcx.sess.source_map().span_to_snippet(base.span);
4693 if let Ok(snip) = snip {
4694 err.span_suggestion(
4696 "to access tuple elements, use",
4697 format!("{}.{}", snip, i),
4698 Applicability::MachineApplicable,
4705 err.help("to access tuple elements, use tuple indexing \
4706 syntax (e.g., `tuple.0`)");
4715 ExprKind::Yield(ref value) => {
4716 match self.yield_ty {
4718 self.check_expr_coercable_to_type(&value, ty);
4721 struct_span_err!(self.tcx.sess, expr.span, E0627,
4722 "yield statement outside of generator literal").emit();
4727 hir::ExprKind::Err => {
4733 /// Type check assignment expression `expr` of form `lhs = rhs`.
4734 /// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
4737 expr: &'gcx hir::Expr,
4738 expected: Expectation<'tcx>,
4739 lhs: &'gcx hir::Expr,
4740 rhs: &'gcx hir::Expr,
4742 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
4743 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
4745 let expected_ty = expected.coercion_target_type(self, expr.span);
4746 if expected_ty == self.tcx.types.bool {
4747 // The expected type is `bool` but this will result in `()` so we can reasonably
4748 // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
4749 // The likely cause of this is `if foo = bar { .. }`.
4750 let actual_ty = self.tcx.mk_unit();
4751 let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
4752 let msg = "try comparing for equality";
4753 let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
4754 let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
4755 if let (Ok(left), Ok(right)) = (left, right) {
4756 let help = format!("{} == {}", left, right);
4757 err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
4762 } else if !lhs.is_place_expr() {
4763 struct_span_err!(self.tcx.sess, expr.span, E0070,
4764 "invalid left-hand side expression")
4765 .span_label(expr.span, "left-hand of expression not valid")
4769 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
4771 if lhs_ty.references_error() || rhs_ty.references_error() {
4778 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4779 // The newly resolved definition is written into `type_dependent_defs`.
4780 fn finish_resolving_struct_path(&self,
4787 QPath::Resolved(ref maybe_qself, ref path) => {
4788 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4789 let ty = AstConv::def_to_ty(self, self_ty, path, true);
4792 QPath::TypeRelative(ref qself, ref segment) => {
4793 let ty = self.to_ty(qself);
4795 let def = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
4800 let result = AstConv::associated_path_to_ty(
4809 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4810 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4812 // Write back the new resolution.
4813 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
4815 (result.map(|(kind, def_id)| Def::Def(kind, def_id)).unwrap_or(Def::Err), ty)
4820 /// Resolves associated value path into a base type and associated constant or method
4821 /// definition. The newly resolved definition is written into `type_dependent_defs`.
4822 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4826 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4828 debug!("resolve_ty_and_def_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4829 let (ty, qself, item_segment) = match *qpath {
4830 QPath::Resolved(ref opt_qself, ref path) => {
4832 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4833 &path.segments[..]);
4835 QPath::TypeRelative(ref qself, ref segment) => {
4836 (self.to_ty(qself), qself, segment)
4839 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4840 // Return directly on cache hit. This is useful to avoid doubly reporting
4841 // errors with default match binding modes. See #44614.
4842 let def = cached_result.map(|(kind, def_id)| Def::Def(kind, def_id))
4843 .unwrap_or(Def::Err);
4844 return (def, Some(ty), slice::from_ref(&**item_segment));
4846 let item_name = item_segment.ident;
4847 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4848 let result = match error {
4849 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4850 _ => Err(ErrorReported),
4852 if item_name.name != keywords::Invalid.name() {
4853 self.report_method_error(
4857 SelfSource::QPath(qself),
4865 // Write back the new resolution.
4866 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
4868 result.map(|(kind, def_id)| Def::Def(kind, def_id)).unwrap_or(Def::Err),
4870 slice::from_ref(&**item_segment),
4874 pub fn check_decl_initializer(&self,
4875 local: &'gcx hir::Local,
4876 init: &'gcx hir::Expr) -> Ty<'tcx>
4878 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4879 // for #42640 (default match binding modes).
4882 let ref_bindings = local.pat.contains_explicit_ref_binding();
4884 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4885 if let Some(m) = ref_bindings {
4886 // Somewhat subtle: if we have a `ref` binding in the pattern,
4887 // we want to avoid introducing coercions for the RHS. This is
4888 // both because it helps preserve sanity and, in the case of
4889 // ref mut, for soundness (issue #23116). In particular, in
4890 // the latter case, we need to be clear that the type of the
4891 // referent for the reference that results is *equal to* the
4892 // type of the place it is referencing, and not some
4893 // supertype thereof.
4894 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4895 self.demand_eqtype(init.span, local_ty, init_ty);
4898 self.check_expr_coercable_to_type(init, local_ty)
4902 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4903 let t = self.local_ty(local.span, local.hir_id).decl_ty;
4904 self.write_ty(local.hir_id, t);
4906 if let Some(ref init) = local.init {
4907 let init_ty = self.check_decl_initializer(local, &init);
4908 if init_ty.references_error() {
4909 self.write_ty(local.hir_id, init_ty);
4913 self.check_pat_walk(
4916 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4919 let pat_ty = self.node_ty(local.pat.hir_id);
4920 if pat_ty.references_error() {
4921 self.write_ty(local.hir_id, pat_ty);
4925 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4926 // Don't do all the complex logic below for `DeclItem`.
4928 hir::StmtKind::Item(..) => return,
4929 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4932 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4934 // Hide the outer diverging and `has_errors` flags.
4935 let old_diverges = self.diverges.get();
4936 let old_has_errors = self.has_errors.get();
4937 self.diverges.set(Diverges::Maybe);
4938 self.has_errors.set(false);
4941 hir::StmtKind::Local(ref l) => {
4942 self.check_decl_local(&l);
4945 hir::StmtKind::Item(_) => {}
4946 hir::StmtKind::Expr(ref expr) => {
4947 // Check with expected type of `()`.
4948 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
4950 hir::StmtKind::Semi(ref expr) => {
4951 self.check_expr(&expr);
4955 // Combine the diverging and `has_error` flags.
4956 self.diverges.set(self.diverges.get() | old_diverges);
4957 self.has_errors.set(self.has_errors.get() | old_has_errors);
4960 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4961 let unit = self.tcx.mk_unit();
4962 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4964 // if the block produces a `!` value, that can always be
4965 // (effectively) coerced to unit.
4967 self.demand_suptype(blk.span, unit, ty);
4971 fn check_block_with_expected(&self,
4972 blk: &'gcx hir::Block,
4973 expected: Expectation<'tcx>) -> Ty<'tcx> {
4975 let mut fcx_ps = self.ps.borrow_mut();
4976 let unsafety_state = fcx_ps.recurse(blk);
4977 replace(&mut *fcx_ps, unsafety_state)
4980 // In some cases, blocks have just one exit, but other blocks
4981 // can be targeted by multiple breaks. This can happen both
4982 // with labeled blocks as well as when we desugar
4983 // a `try { ... }` expression.
4987 // 'a: { if true { break 'a Err(()); } Ok(()) }
4989 // Here we would wind up with two coercions, one from
4990 // `Err(())` and the other from the tail expression
4991 // `Ok(())`. If the tail expression is omitted, that's a
4992 // "forced unit" -- unless the block diverges, in which
4993 // case we can ignore the tail expression (e.g., `'a: {
4994 // break 'a 22; }` would not force the type of the block
4996 let tail_expr = blk.expr.as_ref();
4997 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4998 let coerce = if blk.targeted_by_break {
4999 CoerceMany::new(coerce_to_ty)
5001 let tail_expr: &[P<hir::Expr>] = match tail_expr {
5002 Some(e) => slice::from_ref(e),
5005 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
5008 let prev_diverges = self.diverges.get();
5009 let ctxt = BreakableCtxt {
5010 coerce: Some(coerce),
5014 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
5015 for s in &blk.stmts {
5019 // check the tail expression **without** holding the
5020 // `enclosing_breakables` lock below.
5021 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
5023 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5024 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
5025 let coerce = ctxt.coerce.as_mut().unwrap();
5026 if let Some(tail_expr_ty) = tail_expr_ty {
5027 let tail_expr = tail_expr.unwrap();
5028 let cause = self.cause(tail_expr.span,
5029 ObligationCauseCode::BlockTailExpression(blk.hir_id));
5035 // Subtle: if there is no explicit tail expression,
5036 // that is typically equivalent to a tail expression
5037 // of `()` -- except if the block diverges. In that
5038 // case, there is no value supplied from the tail
5039 // expression (assuming there are no other breaks,
5040 // this implies that the type of the block will be
5043 // #41425 -- label the implicit `()` as being the
5044 // "found type" here, rather than the "expected type".
5045 if !self.diverges.get().always() {
5046 // #50009 -- Do not point at the entire fn block span, point at the return type
5047 // span, as it is the cause of the requirement, and
5048 // `consider_hint_about_removing_semicolon` will point at the last expression
5049 // if it were a relevant part of the error. This improves usability in editors
5050 // that highlight errors inline.
5051 let mut sp = blk.span;
5052 let mut fn_span = None;
5053 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
5054 let ret_sp = decl.output.span();
5055 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
5056 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
5057 // output would otherwise be incorrect and even misleading. Make sure
5058 // the span we're aiming at correspond to a `fn` body.
5059 if block_sp == blk.span {
5061 fn_span = Some(ident.span);
5065 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
5066 if let Some(expected_ty) = expected.only_has_type(self) {
5067 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
5069 if let Some(fn_span) = fn_span {
5070 err.span_label(fn_span, "this function's body doesn't return");
5078 // If we can break from the block, then the block's exit is always reachable
5079 // (... as long as the entry is reachable) - regardless of the tail of the block.
5080 self.diverges.set(prev_diverges);
5083 let mut ty = ctxt.coerce.unwrap().complete(self);
5085 if self.has_errors.get() || ty.references_error() {
5086 ty = self.tcx.types.err
5089 self.write_ty(blk.hir_id, ty);
5091 *self.ps.borrow_mut() = prev;
5095 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
5096 let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(id));
5098 Node::Item(&hir::Item {
5099 node: hir::ItemKind::Fn(_, _, _, body_id), ..
5101 Node::ImplItem(&hir::ImplItem {
5102 node: hir::ImplItemKind::Method(_, body_id), ..
5104 let body = self.tcx.hir().body(body_id);
5105 if let ExprKind::Block(block, _) = &body.value.node {
5106 return Some(block.span);
5114 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
5115 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> {
5116 let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id));
5117 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
5120 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
5121 fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> {
5123 Node::Item(&hir::Item {
5124 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
5125 }) => decl.clone().and_then(|decl| {
5126 // This is less than ideal, it will not suggest a return type span on any
5127 // method called `main`, regardless of whether it is actually the entry point,
5128 // but it will still present it as the reason for the expected type.
5129 Some((decl, ident, ident.name != Symbol::intern("main")))
5131 Node::TraitItem(&hir::TraitItem {
5132 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
5135 }) => decl.clone().and_then(|decl| Some((decl, ident, true))),
5136 Node::ImplItem(&hir::ImplItem {
5137 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
5140 }) => decl.clone().and_then(|decl| Some((decl, ident, false))),
5145 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
5146 /// suggestion can be made, `None` otherwise.
5147 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> {
5148 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
5149 // `while` before reaching it, as block tail returns are not available in them.
5150 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
5151 let parent = self.tcx.hir().get_by_hir_id(blk_id);
5152 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
5156 /// On implicit return expressions with mismatched types, provides the following suggestions:
5158 /// - Points out the method's return type as the reason for the expected type.
5159 /// - Possible missing semicolon.
5160 /// - Possible missing return type if the return type is the default, and not `fn main()`.
5161 pub fn suggest_mismatched_types_on_tail(
5163 err: &mut DiagnosticBuilder<'tcx>,
5164 expression: &'gcx hir::Expr,
5170 self.suggest_missing_semicolon(err, expression, expected, cause_span);
5171 let mut pointing_at_return_type = false;
5172 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
5173 pointing_at_return_type = self.suggest_missing_return_type(
5174 err, &fn_decl, expected, found, can_suggest);
5176 self.suggest_ref_or_into(err, expression, expected, found);
5177 pointing_at_return_type
5180 pub fn suggest_ref_or_into(
5182 err: &mut DiagnosticBuilder<'tcx>,
5187 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
5188 err.span_suggestion(
5192 Applicability::MachineApplicable,
5194 } else if !self.check_for_cast(err, expr, found, expected) {
5195 let methods = self.get_conversion_methods(expr.span, expected, found);
5196 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5197 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
5198 .filter_map(|(receiver, method)| {
5199 let method_call = format!(".{}()", method.ident);
5200 if receiver.ends_with(&method_call) {
5201 None // do not suggest code that is already there (#53348)
5203 let method_call_list = [".to_vec()", ".to_string()"];
5204 if receiver.ends_with(".clone()")
5205 && method_call_list.contains(&method_call.as_str()) {
5206 let max_len = receiver.rfind(".").unwrap();
5207 Some(format!("{}{}", &receiver[..max_len], method_call))
5210 Some(format!("{}{}", receiver, method_call))
5214 if suggestions.peek().is_some() {
5215 err.span_suggestions(
5217 "try using a conversion method",
5219 Applicability::MaybeIncorrect,
5226 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5230 /// bar_that_returns_u32()
5234 /// This routine checks if the return expression in a block would make sense on its own as a
5235 /// statement and the return type has been left as default or has been specified as `()`. If so,
5236 /// it suggests adding a semicolon.
5237 fn suggest_missing_semicolon(&self,
5238 err: &mut DiagnosticBuilder<'tcx>,
5239 expression: &'gcx hir::Expr,
5242 if expected.is_unit() {
5243 // `BlockTailExpression` only relevant if the tail expr would be
5244 // useful on its own.
5245 match expression.node {
5246 ExprKind::Call(..) |
5247 ExprKind::MethodCall(..) |
5249 ExprKind::While(..) |
5250 ExprKind::Loop(..) |
5251 ExprKind::Match(..) |
5252 ExprKind::Block(..) => {
5253 let sp = self.tcx.sess.source_map().next_point(cause_span);
5254 err.span_suggestion(
5256 "try adding a semicolon",
5258 Applicability::MachineApplicable);
5265 /// A possible error is to forget to add a return type that is needed:
5269 /// bar_that_returns_u32()
5273 /// This routine checks if the return type is left as default, the method is not part of an
5274 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5276 fn suggest_missing_return_type(
5278 err: &mut DiagnosticBuilder<'tcx>,
5279 fn_decl: &hir::FnDecl,
5284 // Only suggest changing the return type for methods that
5285 // haven't set a return type at all (and aren't `fn main()` or an impl).
5286 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5287 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
5288 err.span_suggestion(
5290 "try adding a return type",
5291 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
5292 Applicability::MachineApplicable);
5295 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
5296 err.span_label(span, "possibly return type missing here?");
5299 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
5300 // `fn main()` must return `()`, do not suggest changing return type
5301 err.span_label(span, "expected `()` because of default return type");
5304 // expectation was caused by something else, not the default return
5305 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
5306 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
5307 // Only point to return type if the expected type is the return type, as if they
5308 // are not, the expectation must have been caused by something else.
5309 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
5311 let ty = AstConv::ast_ty_to_ty(self, ty);
5312 debug!("suggest_missing_return_type: return type {:?}", ty);
5313 debug!("suggest_missing_return_type: expected type {:?}", ty);
5314 if ty.sty == expected.sty {
5315 err.span_label(sp, format!("expected `{}` because of return type",
5324 /// A common error is to add an extra semicolon:
5327 /// fn foo() -> usize {
5332 /// This routine checks if the final statement in a block is an
5333 /// expression with an explicit semicolon whose type is compatible
5334 /// with `expected_ty`. If so, it suggests removing the semicolon.
5335 fn consider_hint_about_removing_semicolon(
5337 blk: &'gcx hir::Block,
5338 expected_ty: Ty<'tcx>,
5339 err: &mut DiagnosticBuilder<'_>,
5341 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5342 err.span_suggestion(
5344 "consider removing this semicolon",
5346 Applicability::MachineApplicable,
5351 fn could_remove_semicolon(
5353 blk: &'gcx hir::Block,
5354 expected_ty: Ty<'tcx>,
5356 // Be helpful when the user wrote `{... expr;}` and
5357 // taking the `;` off is enough to fix the error.
5358 let last_stmt = blk.stmts.last()?;
5359 let last_expr = match last_stmt.node {
5360 hir::StmtKind::Semi(ref e) => e,
5363 let last_expr_ty = self.node_ty(last_expr.hir_id);
5364 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5367 let original_span = original_sp(last_stmt.span, blk.span);
5368 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5371 // Rewrite `SelfCtor` to `Ctor`
5372 pub fn rewrite_self_ctor(
5376 ) -> Result<(DefKind, DefId, Ty<'tcx>), ErrorReported> {
5378 if let Def::SelfCtor(impl_def_id) = def {
5379 let ty = self.impl_self_ty(span, impl_def_id).ty;
5380 let adt_def = ty.ty_adt_def();
5383 Some(adt_def) if adt_def.has_ctor() => {
5384 let variant = adt_def.non_enum_variant();
5385 let ctor_def_id = variant.ctor_def_id.unwrap();
5387 DefKind::Ctor(CtorOf::Struct, variant.ctor_kind),
5389 tcx.type_of(ctor_def_id),
5393 let mut err = tcx.sess.struct_span_err(span,
5394 "the `Self` constructor can only be used with tuple or unit structs");
5395 if let Some(adt_def) = adt_def {
5396 match adt_def.adt_kind() {
5398 err.help("did you mean to use one of the enum's variants?");
5402 err.span_suggestion(
5404 "use curly brackets",
5405 String::from("Self { /* fields */ }"),
5406 Applicability::HasPlaceholders,
5418 Def::Def(kind, def_id) => {
5419 // The things we are substituting into the type should not contain
5420 // escaping late-bound regions, and nor should the base type scheme.
5421 let ty = tcx.type_of(def_id);
5422 Ok((kind, def_id, ty))
5424 _ => span_bug!(span, "unexpected def in rewrite_self_ctor: {:?}", def),
5429 // Instantiates the given path, which must refer to an item with the given
5430 // number of type parameters and type.
5431 pub fn instantiate_value_path(&self,
5432 segments: &[hir::PathSegment],
5433 self_ty: Option<Ty<'tcx>>,
5437 -> (Ty<'tcx>, Def) {
5439 "instantiate_value_path(segments={:?}, self_ty={:?}, def={:?}, hir_id={})",
5449 Def::Local(hid) | Def::Upvar(hid, ..) => {
5450 let ty = self.local_ty(span, hid).decl_ty;
5451 let ty = self.normalize_associated_types_in(span, &ty);
5452 self.write_ty(hir_id, ty);
5458 let (kind, def_id, ty) = match self.rewrite_self_ctor(def, span) {
5459 Ok(result) => result,
5460 Err(ErrorReported) => return (tcx.types.err, def),
5463 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id);
5465 let mut user_self_ty = None;
5466 let mut is_alias_variant_ctor = false;
5468 DefKind::Ctor(CtorOf::Variant, _) => {
5469 if let Some(self_ty) = self_ty {
5470 let adt_def = self_ty.ty_adt_def().unwrap();
5471 user_self_ty = Some(UserSelfTy {
5472 impl_def_id: adt_def.did,
5475 is_alias_variant_ctor = true;
5479 | DefKind::AssociatedConst => {
5480 let container = tcx.associated_item(def_id).container;
5481 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5483 ty::TraitContainer(trait_did) => {
5484 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5486 ty::ImplContainer(impl_def_id) => {
5487 if segments.len() == 1 {
5488 // `<T>::assoc` will end up here, and so
5489 // can `T::assoc`. It this came from an
5490 // inherent impl, we need to record the
5491 // `T` for posterity (see `UserSelfTy` for
5493 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5494 user_self_ty = Some(UserSelfTy {
5505 // Now that we have categorized what space the parameters for each
5506 // segment belong to, let's sort out the parameters that the user
5507 // provided (if any) into their appropriate spaces. We'll also report
5508 // errors if type parameters are provided in an inappropriate place.
5510 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5511 let generics_has_err = AstConv::prohibit_generics(
5512 self, segments.iter().enumerate().filter_map(|(index, seg)| {
5513 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5519 if generics_has_err {
5520 // Don't try to infer type parameters when prohibited generic arguments were given.
5521 user_self_ty = None;
5524 // Now we have to compare the types that the user *actually*
5525 // provided against the types that were *expected*. If the user
5526 // did not provide any types, then we want to substitute inference
5527 // variables. If the user provided some types, we may still need
5528 // to add defaults. If the user provided *too many* types, that's
5531 let mut infer_args_for_err = FxHashSet::default();
5532 for &PathSeg(def_id, index) in &path_segs {
5533 let seg = &segments[index];
5534 let generics = tcx.generics_of(def_id);
5535 // Argument-position `impl Trait` is treated as a normal generic
5536 // parameter internally, but we don't allow users to specify the
5537 // parameter's value explicitly, so we have to do some error-
5539 let suppress_errors = AstConv::check_generic_arg_count_for_call(
5544 false, // `is_method_call`
5546 if suppress_errors {
5547 infer_args_for_err.insert(index);
5548 self.set_tainted_by_errors(); // See issue #53251.
5552 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
5553 tcx.generics_of(*def_id).has_self
5554 }).unwrap_or(false);
5556 let substs = AstConv::create_substs_for_generic_args(
5562 // Provide the generic args, and whether types should be inferred.
5564 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
5567 // If we've encountered an `impl Trait`-related error, we're just
5568 // going to infer the arguments for better error messages.
5569 if !infer_args_for_err.contains(&index) {
5570 // Check whether the user has provided generic arguments.
5571 if let Some(ref data) = segments[index].args {
5572 return (Some(data), segments[index].infer_types);
5575 return (None, segments[index].infer_types);
5580 // Provide substitutions for parameters for which (valid) arguments have been provided.
5582 match (¶m.kind, arg) {
5583 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5584 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5586 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5587 self.to_ty(ty).into()
5589 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5590 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
5592 _ => unreachable!(),
5595 // Provide substitutions for parameters for which arguments are inferred.
5596 |substs, param, infer_types| {
5598 GenericParamDefKind::Lifetime => {
5599 self.re_infer(span, Some(param)).unwrap().into()
5601 GenericParamDefKind::Type { has_default, .. } => {
5602 if !infer_types && has_default {
5603 // If we have a default, then we it doesn't matter that we're not
5604 // inferring the type arguments: we provide the default where any
5606 let default = tcx.type_of(param.def_id);
5609 default.subst_spanned(tcx, substs.unwrap(), Some(span))
5612 // If no type arguments were provided, we have to infer them.
5613 // This case also occurs as a result of some malformed input, e.g.
5614 // a lifetime argument being given instead of a type parameter.
5615 // Using inference instead of `Error` gives better error messages.
5616 self.var_for_def(span, param)
5619 GenericParamDefKind::Const => {
5620 // FIXME(const_generics:defaults)
5621 // No const parameters were provided, we have to infer them.
5622 self.var_for_def(span, param)
5627 assert!(!substs.has_escaping_bound_vars());
5628 assert!(!ty.has_escaping_bound_vars());
5630 // First, store the "user substs" for later.
5631 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5633 // Add all the obligations that are required, substituting and
5634 // normalized appropriately.
5635 let bounds = self.instantiate_bounds(span, def_id, &substs);
5636 self.add_obligations_for_parameters(
5637 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5640 // Substitute the values for the type parameters into the type of
5641 // the referenced item.
5642 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5644 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5645 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5646 // is inherent, there is no `Self` parameter; instead, the impl needs
5647 // type parameters, which we can infer by unifying the provided `Self`
5648 // with the substituted impl type.
5649 // This also occurs for an enum variant on a type alias.
5650 let ty = tcx.type_of(impl_def_id);
5652 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5653 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5654 Ok(ok) => self.register_infer_ok_obligations(ok),
5657 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5664 self.check_rustc_args_require_const(def_id, hir_id, span);
5666 debug!("instantiate_value_path: type of {:?} is {:?}",
5669 self.write_substs(hir_id, substs);
5671 (ty_substituted, Def::Def(kind, def_id))
5674 fn check_rustc_args_require_const(&self,
5678 // We're only interested in functions tagged with
5679 // #[rustc_args_required_const], so ignore anything that's not.
5680 if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
5684 // If our calling expression is indeed the function itself, we're good!
5685 // If not, generate an error that this can only be called directly.
5686 if let Node::Expr(expr) = self.tcx.hir().get_by_hir_id(
5687 self.tcx.hir().get_parent_node_by_hir_id(hir_id))
5689 if let ExprKind::Call(ref callee, ..) = expr.node {
5690 if callee.hir_id == hir_id {
5696 self.tcx.sess.span_err(span, "this function can only be invoked \
5697 directly, not through a function pointer");
5700 // Resolves `typ` by a single level if `typ` is a type variable.
5701 // If no resolution is possible, then an error is reported.
5702 // Numeric inference variables may be left unresolved.
5703 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5704 let ty = self.resolve_type_vars_with_obligations(ty);
5705 if !ty.is_ty_var() {
5708 if !self.is_tainted_by_errors() {
5709 self.need_type_info_err((**self).body_id, sp, ty)
5710 .note("type must be known at this point")
5713 self.demand_suptype(sp, self.tcx.types.err, ty);
5718 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: hir::HirId,
5719 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5720 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5723 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5724 index = enclosing_breakables.stack.len();
5725 enclosing_breakables.by_id.insert(id, index);
5726 enclosing_breakables.stack.push(ctxt);
5730 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5731 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5732 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5733 enclosing_breakables.stack.pop().expect("missing breakable context")
5738 /// Instantiate a QueryResponse in a probe context, without a
5739 /// good ObligationCause.
5740 fn probe_instantiate_query_response(
5743 original_values: &OriginalQueryValues<'tcx>,
5744 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5745 ) -> InferResult<'tcx, Ty<'tcx>>
5747 self.instantiate_query_response_and_region_obligations(
5748 &traits::ObligationCause::misc(span, self.body_id),
5754 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5755 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5756 let mut contained_in_place = false;
5758 while let hir::Node::Expr(parent_expr) =
5759 self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(expr_id))
5761 match &parent_expr.node {
5762 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5763 if lhs.hir_id == expr_id {
5764 contained_in_place = true;
5770 expr_id = parent_expr.hir_id;
5777 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5778 generics: &ty::Generics,
5780 let own_counts = generics.own_counts();
5782 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5788 // FIXME(const_generics): we probably want to check the bounds for const parameters too.
5790 if own_counts.types == 0 {
5794 // Make a vector of booleans initially false, set to true when used.
5795 let mut types_used = vec![false; own_counts.types];
5797 for leaf_ty in ty.walk() {
5798 if let ty::Param(ty::ParamTy { idx, .. }) = leaf_ty.sty {
5799 debug!("Found use of ty param num {}", idx);
5800 types_used[idx as usize - own_counts.lifetimes] = true;
5801 } else if let ty::Error = leaf_ty.sty {
5802 // If there is already another error, do not emit
5803 // an error for not using a type Parameter.
5804 assert!(tcx.sess.err_count() > 0);
5809 let types = generics.params.iter().filter(|param| match param.kind {
5810 ty::GenericParamDefKind::Type { .. } => true,
5813 for (&used, param) in types_used.iter().zip(types) {
5815 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5816 let span = tcx.hir().span_by_hir_id(id);
5817 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5818 .span_label(span, "unused type parameter")
5824 fn fatally_break_rust(sess: &Session) {
5825 let handler = sess.diagnostic();
5826 handler.span_bug_no_panic(
5828 "It looks like you're trying to break rust; would you like some ICE?",
5830 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5831 handler.note_without_error(
5832 "we would appreciate a joke overview: \
5833 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5835 handler.note_without_error(&format!("rustc {} running on {}",
5836 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5837 crate::session::config::host_triple(),
5841 fn potentially_plural_count(count: usize, word: &str) -> String {
5842 format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })