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
80 mod generator_interior;
90 use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg};
91 use crate::middle::lang_items;
92 use rustc::hir::map::blocks::FnLikeNode;
93 use rustc::hir::map::Map;
94 use rustc::middle::region;
95 use rustc::mir::interpret::ConstValue;
96 use rustc::session::parse::feature_err;
97 use rustc::ty::adjustment::{
98 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
100 use rustc::ty::fold::{TypeFoldable, TypeFolder};
101 use rustc::ty::layout::VariantIdx;
102 use rustc::ty::query::Providers;
103 use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts};
104 use rustc::ty::util::{Discr, IntTypeExt, Representability};
106 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
107 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
109 use rustc_attr as attr;
110 use rustc_data_structures::captures::Captures;
111 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
112 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
113 use rustc_hir as hir;
114 use rustc_hir::def::{CtorOf, DefKind, Res};
115 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE};
116 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
117 use rustc_hir::itemlikevisit::ItemLikeVisitor;
118 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
119 use rustc_index::vec::Idx;
120 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
121 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
122 use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
123 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
124 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
125 use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
126 use rustc_infer::traits::error_reporting::recursive_type_with_infinite_size_error;
127 use rustc_infer::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
128 use rustc_span::hygiene::DesugaringKind;
129 use rustc_span::source_map::{original_sp, DUMMY_SP};
130 use rustc_span::symbol::{kw, sym, Ident};
131 use rustc_span::{self, BytePos, MultiSpan, Span};
132 use rustc_target::spec::abi::Abi;
134 use syntax::util::parser::ExprPrecedence;
136 use std::cell::{Cell, Ref, RefCell, RefMut};
138 use std::collections::hash_map::Entry;
140 use std::mem::replace;
141 use std::ops::{self, Deref};
145 use crate::require_c_abi_if_c_variadic;
146 use crate::session::config::EntryFnType;
147 use crate::session::Session;
148 use crate::util::common::{indenter, ErrorReported};
149 use crate::TypeAndSubsts;
151 use self::autoderef::Autoderef;
152 use self::callee::DeferredCallResolution;
153 use self::coercion::{CoerceMany, DynamicCoerceMany};
154 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
155 use self::method::{MethodCallee, SelfSource};
156 pub use self::Expectation::*;
157 use self::TupleArgumentsFlag::*;
160 macro_rules! type_error_struct {
161 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
162 if $typ.references_error() {
163 $session.diagnostic().struct_dummy()
165 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
170 /// The type of a local binding, including the revealed type for anon types.
171 #[derive(Copy, Clone, Debug)]
172 pub struct LocalTy<'tcx> {
174 revealed_ty: Ty<'tcx>,
177 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
178 #[derive(Copy, Clone)]
179 struct MaybeInProgressTables<'a, 'tcx> {
180 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
183 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
184 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
185 match self.maybe_tables {
186 Some(tables) => tables.borrow(),
187 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
191 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
192 match self.maybe_tables {
193 Some(tables) => tables.borrow_mut(),
194 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
199 /// Closures defined within the function. For example:
202 /// bar(move|| { ... })
205 /// Here, the function `foo()` and the closure passed to
206 /// `bar()` will each have their own `FnCtxt`, but they will
207 /// share the inherited fields.
208 pub struct Inherited<'a, 'tcx> {
209 infcx: InferCtxt<'a, 'tcx>,
211 tables: MaybeInProgressTables<'a, 'tcx>,
213 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
215 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
217 // Some additional `Sized` obligations badly affect type inference.
218 // These obligations are added in a later stage of typeck.
219 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
221 // When we process a call like `c()` where `c` is a closure type,
222 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
223 // `FnOnce` closure. In that case, we defer full resolution of the
224 // call until upvar inference can kick in and make the
225 // decision. We keep these deferred resolutions grouped by the
226 // def-id of the closure, so that once we decide, we can easily go
227 // back and process them.
228 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
230 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
232 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
234 // Opaque types found in explicit return types and their
235 // associated fresh inference variable. Writeback resolves these
236 // variables to get the concrete type, which can be used to
237 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
238 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
240 /// A map from inference variables created from opaque
241 /// type instantiations (`ty::Infer`) to the actual opaque
242 /// type (`ty::Opaque`). Used during fallback to map unconstrained
243 /// opaque type inference variables to their corresponding
245 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
247 /// Each type parameter has an implicit region bound that
248 /// indicates it must outlive at least the function body (the user
249 /// may specify stronger requirements). This field indicates the
250 /// region of the callee. If it is `None`, then the parameter
251 /// environment is for an item or something where the "callee" is
253 implicit_region_bound: Option<ty::Region<'tcx>>,
255 body_id: Option<hir::BodyId>,
258 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
259 type Target = InferCtxt<'a, 'tcx>;
260 fn deref(&self) -> &Self::Target {
265 /// When type-checking an expression, we propagate downward
266 /// whatever type hint we are able in the form of an `Expectation`.
267 #[derive(Copy, Clone, Debug)]
268 pub enum Expectation<'tcx> {
269 /// We know nothing about what type this expression should have.
272 /// This expression should have the type given (or some subtype).
273 ExpectHasType(Ty<'tcx>),
275 /// This expression will be cast to the `Ty`.
276 ExpectCastableToType(Ty<'tcx>),
278 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
279 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
280 ExpectRvalueLikeUnsized(Ty<'tcx>),
283 impl<'a, 'tcx> Expectation<'tcx> {
284 // Disregard "castable to" expectations because they
285 // can lead us astray. Consider for example `if cond
286 // {22} else {c} as u8` -- if we propagate the
287 // "castable to u8" constraint to 22, it will pick the
288 // type 22u8, which is overly constrained (c might not
289 // be a u8). In effect, the problem is that the
290 // "castable to" expectation is not the tightest thing
291 // we can say, so we want to drop it in this case.
292 // The tightest thing we can say is "must unify with
293 // else branch". Note that in the case of a "has type"
294 // constraint, this limitation does not hold.
296 // If the expected type is just a type variable, then don't use
297 // an expected type. Otherwise, we might write parts of the type
298 // when checking the 'then' block which are incompatible with the
300 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
302 ExpectHasType(ety) => {
303 let ety = fcx.shallow_resolve(ety);
304 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
306 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
311 /// Provides an expectation for an rvalue expression given an *optional*
312 /// hint, which is not required for type safety (the resulting type might
313 /// be checked higher up, as is the case with `&expr` and `box expr`), but
314 /// is useful in determining the concrete type.
316 /// The primary use case is where the expected type is a fat pointer,
317 /// like `&[isize]`. For example, consider the following statement:
319 /// let x: &[isize] = &[1, 2, 3];
321 /// In this case, the expected type for the `&[1, 2, 3]` expression is
322 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
323 /// expectation `ExpectHasType([isize])`, that would be too strong --
324 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
325 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
326 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
327 /// which still is useful, because it informs integer literals and the like.
328 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
329 /// for examples of where this comes up,.
330 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
331 match fcx.tcx.struct_tail_without_normalization(ty).kind {
332 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
333 _ => ExpectHasType(ty),
337 // Resolves `expected` by a single level if it is a variable. If
338 // there is no expected type or resolution is not possible (e.g.,
339 // no constraints yet present), just returns `None`.
340 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
342 NoExpectation => NoExpectation,
343 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
344 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
345 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
349 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
350 match self.resolve(fcx) {
351 NoExpectation => None,
352 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
356 /// It sometimes happens that we want to turn an expectation into
357 /// a **hard constraint** (i.e., something that must be satisfied
358 /// for the program to type-check). `only_has_type` will return
359 /// such a constraint, if it exists.
360 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
361 match self.resolve(fcx) {
362 ExpectHasType(ty) => Some(ty),
363 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
367 /// Like `only_has_type`, but instead of returning `None` if no
368 /// hard constraint exists, creates a fresh type variable.
369 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
370 self.only_has_type(fcx).unwrap_or_else(|| {
371 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
376 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
383 fn maybe_mut_place(m: hir::Mutability) -> Self {
385 hir::Mutability::Mut => Needs::MutPlace,
386 hir::Mutability::Not => Needs::None,
391 #[derive(Copy, Clone)]
392 pub struct UnsafetyState {
394 pub unsafety: hir::Unsafety,
395 pub unsafe_push_count: u32,
400 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
401 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
404 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
405 use hir::BlockCheckMode;
406 match self.unsafety {
407 // If this unsafe, then if the outer function was already marked as
408 // unsafe we shouldn't attribute the unsafe'ness to the block. This
409 // way the block can be warned about instead of ignoring this
410 // extraneous block (functions are never warned about).
411 hir::Unsafety::Unsafe if self.from_fn => *self,
414 let (unsafety, def, count) = match blk.rules {
415 BlockCheckMode::PushUnsafeBlock(..) => {
416 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
418 BlockCheckMode::PopUnsafeBlock(..) => {
419 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
421 BlockCheckMode::UnsafeBlock(..) => {
422 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
424 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
426 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
432 #[derive(Debug, Copy, Clone)]
438 /// Tracks whether executing a node may exit normally (versus
439 /// return/break/panic, which "diverge", leaving dead code in their
440 /// wake). Tracked semi-automatically (through type variables marked
441 /// as diverging), with some manual adjustments for control-flow
442 /// primitives (approximating a CFG).
443 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
445 /// Potentially unknown, some cases converge,
446 /// others require a CFG to determine them.
449 /// Definitely known to diverge and therefore
450 /// not reach the next sibling or its parent.
452 /// The `Span` points to the expression
453 /// that caused us to diverge
454 /// (e.g. `return`, `break`, etc).
456 /// In some cases (e.g. a `match` expression
457 /// where all arms diverge), we may be
458 /// able to provide a more informative
459 /// message to the user.
460 /// If this is `None`, a default messsage
461 /// will be generated, which is suitable
463 custom_note: Option<&'static str>,
466 /// Same as `Always` but with a reachability
467 /// warning already emitted.
471 // Convenience impls for combining `Diverges`.
473 impl ops::BitAnd for Diverges {
475 fn bitand(self, other: Self) -> Self {
476 cmp::min(self, other)
480 impl ops::BitOr for Diverges {
482 fn bitor(self, other: Self) -> Self {
483 cmp::max(self, other)
487 impl ops::BitAndAssign for Diverges {
488 fn bitand_assign(&mut self, other: Self) {
489 *self = *self & other;
493 impl ops::BitOrAssign for Diverges {
494 fn bitor_assign(&mut self, other: Self) {
495 *self = *self | other;
500 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
501 fn always(span: Span) -> Diverges {
502 Diverges::Always { span, custom_note: None }
505 fn is_always(self) -> bool {
506 // Enum comparison ignores the
507 // contents of fields, so we just
508 // fill them in with garbage here.
509 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
513 pub struct BreakableCtxt<'tcx> {
516 // this is `null` for loops where break with a value is illegal,
517 // such as `while`, `for`, and `while let`
518 coerce: Option<DynamicCoerceMany<'tcx>>,
521 pub struct EnclosingBreakables<'tcx> {
522 stack: Vec<BreakableCtxt<'tcx>>,
523 by_id: HirIdMap<usize>,
526 impl<'tcx> EnclosingBreakables<'tcx> {
527 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
528 self.opt_find_breakable(target_id).unwrap_or_else(|| {
529 bug!("could not find enclosing breakable with id {}", target_id);
533 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
534 match self.by_id.get(&target_id) {
535 Some(ix) => Some(&mut self.stack[*ix]),
541 pub struct FnCtxt<'a, 'tcx> {
544 /// The parameter environment used for proving trait obligations
545 /// in this function. This can change when we descend into
546 /// closures (as they bring new things into scope), hence it is
547 /// not part of `Inherited` (as of the time of this writing,
548 /// closures do not yet change the environment, but they will
550 param_env: ty::ParamEnv<'tcx>,
552 /// Number of errors that had been reported when we started
553 /// checking this function. On exit, if we find that *more* errors
554 /// have been reported, we will skip regionck and other work that
555 /// expects the types within the function to be consistent.
556 // FIXME(matthewjasper) This should not exist, and it's not correct
557 // if type checking is run in parallel.
558 err_count_on_creation: usize,
560 /// If `Some`, this stores coercion information for returned
561 /// expressions. If `None`, this is in a context where return is
562 /// inappropriate, such as a const expression.
564 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
565 /// can track all the return expressions and then use them to
566 /// compute a useful coercion from the set, similar to a match
567 /// expression or other branching context. You can use methods
568 /// like `expected_ty` to access the declared return type (if
570 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
572 /// First span of a return site that we find. Used in error messages.
573 ret_coercion_span: RefCell<Option<Span>>,
575 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
577 ps: RefCell<UnsafetyState>,
579 /// Whether the last checked node generates a divergence (e.g.,
580 /// `return` will set this to `Always`). In general, when entering
581 /// an expression or other node in the tree, the initial value
582 /// indicates whether prior parts of the containing expression may
583 /// have diverged. It is then typically set to `Maybe` (and the
584 /// old value remembered) for processing the subparts of the
585 /// current expression. As each subpart is processed, they may set
586 /// the flag to `Always`, etc. Finally, at the end, we take the
587 /// result and "union" it with the original value, so that when we
588 /// return the flag indicates if any subpart of the parent
589 /// expression (up to and including this part) has diverged. So,
590 /// if you read it after evaluating a subexpression `X`, the value
591 /// you get indicates whether any subexpression that was
592 /// evaluating up to and including `X` diverged.
594 /// We currently use this flag only for diagnostic purposes:
596 /// - To warn about unreachable code: if, after processing a
597 /// sub-expression but before we have applied the effects of the
598 /// current node, we see that the flag is set to `Always`, we
599 /// can issue a warning. This corresponds to something like
600 /// `foo(return)`; we warn on the `foo()` expression. (We then
601 /// update the flag to `WarnedAlways` to suppress duplicate
602 /// reports.) Similarly, if we traverse to a fresh statement (or
603 /// tail expression) from a `Always` setting, we will issue a
604 /// warning. This corresponds to something like `{return;
605 /// foo();}` or `{return; 22}`, where we would warn on the
608 /// An expression represents dead code if, after checking it,
609 /// the diverges flag is set to something other than `Maybe`.
610 diverges: Cell<Diverges>,
612 /// Whether any child nodes have any type errors.
613 has_errors: Cell<bool>,
615 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
617 inh: &'a Inherited<'a, 'tcx>,
620 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
621 type Target = Inherited<'a, 'tcx>;
622 fn deref(&self) -> &Self::Target {
627 /// Helper type of a temporary returned by `Inherited::build(...)`.
628 /// Necessary because we can't write the following bound:
629 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
630 pub struct InheritedBuilder<'tcx> {
631 infcx: infer::InferCtxtBuilder<'tcx>,
635 impl Inherited<'_, 'tcx> {
636 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
637 let hir_id_root = if def_id.is_local() {
638 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
639 DefId::local(hir_id.owner)
645 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
651 impl<'tcx> InheritedBuilder<'tcx> {
652 fn enter<F, R>(&mut self, f: F) -> R
654 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
656 let def_id = self.def_id;
657 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
661 impl Inherited<'a, 'tcx> {
662 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
664 let item_id = tcx.hir().as_local_hir_id(def_id);
665 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
666 let implicit_region_bound = body_id.map(|body_id| {
667 let body = tcx.hir().body(body_id);
668 tcx.mk_region(ty::ReScope(region::Scope {
669 id: body.value.hir_id.local_id,
670 data: region::ScopeData::CallSite,
675 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
677 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
678 locals: RefCell::new(Default::default()),
679 deferred_sized_obligations: RefCell::new(Vec::new()),
680 deferred_call_resolutions: RefCell::new(Default::default()),
681 deferred_cast_checks: RefCell::new(Vec::new()),
682 deferred_generator_interiors: RefCell::new(Vec::new()),
683 opaque_types: RefCell::new(Default::default()),
684 opaque_types_vars: RefCell::new(Default::default()),
685 implicit_region_bound,
690 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
691 debug!("register_predicate({:?})", obligation);
692 if obligation.has_escaping_bound_vars() {
693 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
695 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
698 fn register_predicates<I>(&self, obligations: I)
700 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
702 for obligation in obligations {
703 self.register_predicate(obligation);
707 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
708 self.register_predicates(infer_ok.obligations);
712 fn normalize_associated_types_in<T>(
716 param_env: ty::ParamEnv<'tcx>,
720 T: TypeFoldable<'tcx>,
722 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
723 self.register_infer_ok_obligations(ok)
727 struct CheckItemTypesVisitor<'tcx> {
731 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
732 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
733 check_item_type(self.tcx, i);
735 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
736 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
739 pub fn check_wf_new(tcx: TyCtxt<'_>) {
740 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
741 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
744 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
745 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
748 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
749 debug_assert!(crate_num == LOCAL_CRATE);
750 tcx.par_body_owners(|body_owner_def_id| {
751 tcx.ensure().typeck_tables_of(body_owner_def_id);
755 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
756 wfcheck::check_item_well_formed(tcx, def_id);
759 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
760 wfcheck::check_trait_item(tcx, def_id);
763 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
764 wfcheck::check_impl_item(tcx, def_id);
767 pub fn provide(providers: &mut Providers<'_>) {
768 method::provide(providers);
769 *providers = Providers {
772 diagnostic_only_typeck_tables_of,
776 check_item_well_formed,
777 check_trait_item_well_formed,
778 check_impl_item_well_formed,
779 check_mod_item_types,
784 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
785 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
788 /// If this `DefId` is a "primary tables entry", returns
789 /// `Some((body_id, header, decl))` with information about
790 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
793 /// If this function returns `Some`, then `typeck_tables(def_id)` will
794 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
795 /// may not succeed. In some cases where this function returns `None`
796 /// (notably closures), `typeck_tables(def_id)` would wind up
797 /// redirecting to the owning function.
801 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
802 match tcx.hir().get(id) {
803 Node::Item(item) => match item.kind {
804 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
805 Some((body, Some(ty), None, None))
807 hir::ItemKind::Fn(ref sig, .., body) => {
808 Some((body, None, Some(&sig.header), Some(&sig.decl)))
812 Node::TraitItem(item) => match item.kind {
813 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
814 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
815 Some((body, None, Some(&sig.header), Some(&sig.decl)))
819 Node::ImplItem(item) => match item.kind {
820 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
821 hir::ImplItemKind::Method(ref sig, body) => {
822 Some((body, None, Some(&sig.header), Some(&sig.decl)))
826 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
831 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
832 // Closures' tables come from their outermost function,
833 // as they are part of the same "inference environment".
834 let outer_def_id = tcx.closure_base_def_id(def_id);
835 if outer_def_id != def_id {
836 return tcx.has_typeck_tables(outer_def_id);
839 if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
840 primary_body_of(tcx, id).is_some()
846 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
847 &*tcx.typeck_tables_of(def_id).used_trait_imports
850 /// Inspects the substs of opaque types, replacing any inference variables
851 /// with proper generic parameter from the identity substs.
853 /// This is run after we normalize the function signature, to fix any inference
854 /// variables introduced by the projection of associated types. This ensures that
855 /// any opaque types used in the signature continue to refer to generic parameters,
856 /// allowing them to be considered for defining uses in the function body
858 /// For example, consider this code.
863 /// fn use_it(self) -> Self::MyItem
865 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
866 /// type MyItem = impl Iterator<Item = I>;
867 /// fn use_it(self) -> Self::MyItem {
873 /// When we normalize the signature of `use_it` from the impl block,
874 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
875 /// However, this projection result may contain inference variables, due
876 /// to the way that projection works. We didn't have any inference variables
877 /// in the signature to begin with - leaving them in will cause us to incorrectly
878 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
879 /// variables back to the actual generic parameters, we will correctly see that
880 /// we have a defining use of `MyItem`
881 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
883 T: TypeFoldable<'tcx>,
885 struct FixupFolder<'tcx> {
889 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
890 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
894 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
896 ty::Opaque(def_id, substs) => {
897 debug!("fixup_opaque_types: found type {:?}", ty);
898 // Here, we replace any inference variables that occur within
899 // the substs of an opaque type. By definition, any type occuring
900 // in the substs has a corresponding generic parameter, which is what
901 // we replace it with.
902 // This replacement is only run on the function signature, so any
903 // inference variables that we come across must be the rust of projection
904 // (there's no other way for a user to get inference variables into
905 // a function signature).
906 if ty.needs_infer() {
907 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
908 let old_param = substs[param.index as usize];
909 match old_param.unpack() {
910 GenericArgKind::Type(old_ty) => {
911 if let ty::Infer(_) = old_ty.kind {
912 // Replace inference type with a generic parameter
913 self.tcx.mk_param_from_def(param)
915 old_param.fold_with(self)
918 GenericArgKind::Const(old_const) => {
919 if let ty::ConstKind::Infer(_) = old_const.val {
920 // This should never happen - we currently do not support
921 // 'const projections', e.g.:
922 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
923 // which should be the only way for us to end up with a const inference
924 // variable after projection. If Rust ever gains support for this kind
925 // of projection, this should *probably* be changed to
926 // `self.tcx.mk_param_from_def(param)`
928 "Found infer const: `{:?}` in opaque type: {:?}",
933 old_param.fold_with(self)
936 GenericArgKind::Lifetime(old_region) => {
937 if let RegionKind::ReVar(_) = old_region {
938 self.tcx.mk_param_from_def(param)
940 old_param.fold_with(self)
945 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
946 debug!("fixup_opaque_types: new type: {:?}", new_ty);
952 _ => ty.super_fold_with(self),
957 debug!("fixup_opaque_types({:?})", val);
958 val.fold_with(&mut FixupFolder { tcx })
961 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &ty::TypeckTables<'tcx> {
962 let fallback = move || tcx.type_of(def_id);
963 typeck_tables_of_with_fallback(tcx, def_id, fallback)
966 /// Used only to get `TypeckTables` for type inference during error recovery.
967 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
968 fn diagnostic_only_typeck_tables_of<'tcx>(
971 ) -> &ty::TypeckTables<'tcx> {
972 assert!(def_id.is_local());
973 let fallback = move || {
974 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id).unwrap());
975 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
978 typeck_tables_of_with_fallback(tcx, def_id, fallback)
981 fn typeck_tables_of_with_fallback<'tcx>(
984 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
985 ) -> &'tcx ty::TypeckTables<'tcx> {
986 // Closures' tables come from their outermost function,
987 // as they are part of the same "inference environment".
988 let outer_def_id = tcx.closure_base_def_id(def_id);
989 if outer_def_id != def_id {
990 return tcx.typeck_tables_of(outer_def_id);
993 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
994 let span = tcx.hir().span(id);
996 // Figure out what primary body this item has.
997 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
998 span_bug!(span, "can't type-check body of {:?}", def_id);
1000 let body = tcx.hir().body(body_id);
1002 let tables = Inherited::build(tcx, def_id).enter(|inh| {
1003 let param_env = tcx.param_env(def_id);
1004 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1005 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1006 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1007 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl, &[], None)
1012 check_abi(tcx, span, fn_sig.abi());
1014 // Compute the fty from point of view of inside the fn.
1015 let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
1016 let fn_sig = inh.normalize_associated_types_in(
1023 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1025 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1028 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1029 let expected_type = body_ty
1030 .and_then(|ty| match ty.kind {
1031 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1034 .unwrap_or_else(fallback);
1035 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1036 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1038 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1039 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1044 // Gather locals in statics (because of block expressions).
1045 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1047 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1049 fcx.write_ty(id, revealed_ty);
1054 // All type checking constraints were added, try to fallback unsolved variables.
1055 fcx.select_obligations_where_possible(false, |_| {});
1056 let mut fallback_has_occurred = false;
1058 // We do fallback in two passes, to try to generate
1059 // better error messages.
1060 // The first time, we do *not* replace opaque types.
1061 for ty in &fcx.unsolved_variables() {
1062 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1064 // We now see if we can make progress. This might
1065 // cause us to unify inference variables for opaque types,
1066 // since we may have unified some other type variables
1067 // during the first phase of fallback.
1068 // This means that we only replace inference variables with their underlying
1069 // opaque types as a last resort.
1071 // In code like this:
1074 // type MyType = impl Copy;
1075 // fn produce() -> MyType { true }
1076 // fn bad_produce() -> MyType { panic!() }
1079 // we want to unify the opaque inference variable in `bad_produce`
1080 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1081 // This will produce a nice error message about conflicting concrete
1082 // types for `MyType`.
1084 // If we had tried to fallback the opaque inference variable to `MyType`,
1085 // we will generate a confusing type-check error that does not explicitly
1086 // refer to opaque types.
1087 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1089 // We now run fallback again, but this time we allow it to replace
1090 // unconstrained opaque type variables, in addition to performing
1091 // other kinds of fallback.
1092 for ty in &fcx.unsolved_variables() {
1093 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1096 // See if we can make any more progress.
1097 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1099 // Even though coercion casts provide type hints, we check casts after fallback for
1100 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1103 // Closure and generator analysis may run after fallback
1104 // because they don't constrain other type variables.
1105 fcx.closure_analyze(body);
1106 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1107 fcx.resolve_generator_interiors(def_id);
1109 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1110 let ty = fcx.normalize_ty(span, ty);
1111 fcx.require_type_is_sized(ty, span, code);
1114 fcx.select_all_obligations_or_error();
1116 if fn_decl.is_some() {
1117 fcx.regionck_fn(id, body);
1119 fcx.regionck_expr(body);
1122 fcx.resolve_type_vars_in_body(body)
1125 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1126 // it will need to hold.
1127 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
1132 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1133 if !tcx.sess.target.target.is_abi_supported(abi) {
1138 "The ABI `{}` is not supported for the current target",
1145 struct GatherLocalsVisitor<'a, 'tcx> {
1146 fcx: &'a FnCtxt<'a, 'tcx>,
1147 parent_id: hir::HirId,
1150 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1151 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1154 // infer the variable's type
1155 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1156 kind: TypeVariableOriginKind::TypeInference,
1162 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1166 // take type that the user specified
1167 self.fcx.locals.borrow_mut().insert(nid, typ);
1174 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1175 type Map = Map<'tcx>;
1177 fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> {
1178 NestedVisitorMap::None
1181 // Add explicitly-declared locals.
1182 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1183 let local_ty = match local.ty {
1185 let o_ty = self.fcx.to_ty(&ty);
1187 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1188 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1197 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1199 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1200 ty.hir_id, o_ty, revealed_ty, c_ty
1202 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1204 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1208 self.assign(local.span, local.hir_id, local_ty);
1211 "local variable {:?} is assigned type {}",
1213 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1215 intravisit::walk_local(self, local);
1218 // Add pattern bindings.
1219 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1220 if let PatKind::Binding(_, _, ident, _) = p.kind {
1221 let var_ty = self.assign(p.span, p.hir_id, None);
1223 if !self.fcx.tcx.features().unsized_locals {
1224 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1228 "pattern binding {} is assigned to {} with type {:?}",
1230 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1234 intravisit::walk_pat(self, p);
1237 // Don't descend into the bodies of nested closures
1240 _: intravisit::FnKind<'tcx>,
1241 _: &'tcx hir::FnDecl<'tcx>,
1249 /// When `check_fn` is invoked on a generator (i.e., a body that
1250 /// includes yield), it returns back some information about the yield
1252 struct GeneratorTypes<'tcx> {
1253 /// Type of generator argument / values returned by `yield`.
1254 resume_ty: Ty<'tcx>,
1256 /// Type of value that is yielded.
1259 /// Types that are captured (see `GeneratorInterior` for more).
1262 /// Indicates if the generator is movable or static (immovable).
1263 movability: hir::Movability,
1266 /// Helper used for fns and closures. Does the grungy work of checking a function
1267 /// body and returns the function context used for that purpose, since in the case of a fn item
1268 /// there is still a bit more to do.
1271 /// * inherited: other fields inherited from the enclosing fn (if any)
1272 fn check_fn<'a, 'tcx>(
1273 inherited: &'a Inherited<'a, 'tcx>,
1274 param_env: ty::ParamEnv<'tcx>,
1275 fn_sig: ty::FnSig<'tcx>,
1276 decl: &'tcx hir::FnDecl<'tcx>,
1278 body: &'tcx hir::Body<'tcx>,
1279 can_be_generator: Option<hir::Movability>,
1280 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1281 let mut fn_sig = fn_sig;
1283 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1285 // Create the function context. This is either derived from scratch or,
1286 // in the case of closures, based on the outer context.
1287 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1288 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1291 let sess = tcx.sess;
1292 let hir = tcx.hir();
1294 let declared_ret_ty = fn_sig.output();
1295 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1296 let revealed_ret_ty =
1297 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1298 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1299 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1300 fn_sig = tcx.mk_fn_sig(
1301 fn_sig.inputs().iter().cloned(),
1308 let span = body.value.span;
1310 fn_maybe_err(tcx, span, fn_sig.abi);
1312 if body.generator_kind.is_some() && can_be_generator.is_some() {
1314 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1315 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1317 // Resume type defaults to `()` if the generator has no argument.
1318 let resume_ty = fn_sig.inputs().get(0).map(|ty| *ty).unwrap_or_else(|| tcx.mk_unit());
1320 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1323 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
1324 let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap();
1325 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1327 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1328 // (as it's created inside the body itself, not passed in from outside).
1329 let maybe_va_list = if fn_sig.c_variadic {
1330 let va_list_did = tcx.require_lang_item(
1331 lang_items::VaListTypeLangItem,
1332 Some(body.params.last().unwrap().span),
1334 let region = tcx.mk_region(ty::ReScope(region::Scope {
1335 id: body.value.hir_id.local_id,
1336 data: region::ScopeData::CallSite,
1339 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1344 // Add formal parameters.
1345 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1346 let inputs_fn = fn_sig.inputs().iter().copied();
1347 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1348 // Check the pattern.
1349 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1351 // Check that argument is Sized.
1352 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1353 // for simple cases like `fn foo(x: Trait)`,
1354 // where we would error once on the parameter as a whole, and once on the binding `x`.
1355 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1356 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1359 fcx.write_ty(param.hir_id, param_ty);
1362 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1364 fcx.check_return_expr(&body.value);
1366 // We insert the deferred_generator_interiors entry after visiting the body.
1367 // This ensures that all nested generators appear before the entry of this generator.
1368 // resolve_generator_interiors relies on this property.
1369 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1371 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1372 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1374 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1375 Some(GeneratorTypes {
1379 movability: can_be_generator.unwrap(),
1385 // Finalize the return check by taking the LUB of the return types
1386 // we saw and assigning it to the expected return type. This isn't
1387 // really expected to fail, since the coercions would have failed
1388 // earlier when trying to find a LUB.
1390 // However, the behavior around `!` is sort of complex. In the
1391 // event that the `actual_return_ty` comes back as `!`, that
1392 // indicates that the fn either does not return or "returns" only
1393 // values of type `!`. In this case, if there is an expected
1394 // return type that is *not* `!`, that should be ok. But if the
1395 // return type is being inferred, we want to "fallback" to `!`:
1397 // let x = move || panic!();
1399 // To allow for that, I am creating a type variable with diverging
1400 // fallback. This was deemed ever so slightly better than unifying
1401 // the return value with `!` because it allows for the caller to
1402 // make more assumptions about the return type (e.g., they could do
1404 // let y: Option<u32> = Some(x());
1406 // which would then cause this return type to become `u32`, not
1408 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1409 let mut actual_return_ty = coercion.complete(&fcx);
1410 if actual_return_ty.is_never() {
1411 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1412 kind: TypeVariableOriginKind::DivergingFn,
1416 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1418 // Check that the main return type implements the termination trait.
1419 if let Some(term_id) = tcx.lang_items().termination() {
1420 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1421 let main_id = hir.as_local_hir_id(def_id).unwrap();
1422 if main_id == fn_id {
1423 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1424 let trait_ref = ty::TraitRef::new(term_id, substs);
1425 let return_ty_span = decl.output.span();
1426 let cause = traits::ObligationCause::new(
1429 ObligationCauseCode::MainFunctionType,
1432 inherited.register_predicate(traits::Obligation::new(
1435 trait_ref.without_const().to_predicate(),
1441 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1442 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1443 if panic_impl_did == hir.local_def_id(fn_id) {
1444 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1445 if declared_ret_ty.kind != ty::Never {
1446 sess.span_err(decl.output.span(), "return type should be `!`");
1449 let inputs = fn_sig.inputs();
1450 let span = hir.span(fn_id);
1451 if inputs.len() == 1 {
1452 let arg_is_panic_info = match inputs[0].kind {
1453 ty::Ref(region, ty, mutbl) => match ty.kind {
1454 ty::Adt(ref adt, _) => {
1455 adt.did == panic_info_did
1456 && mutbl == hir::Mutability::Not
1457 && *region != RegionKind::ReStatic
1464 if !arg_is_panic_info {
1465 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1468 if let Node::Item(item) = hir.get(fn_id) {
1469 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1470 if !generics.params.is_empty() {
1471 sess.span_err(span, "should have no type parameters");
1476 let span = sess.source_map().def_span(span);
1477 sess.span_err(span, "function should have one argument");
1480 sess.err("language item required, but not found: `panic_info`");
1485 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1486 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1487 if alloc_error_handler_did == hir.local_def_id(fn_id) {
1488 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1489 if declared_ret_ty.kind != ty::Never {
1490 sess.span_err(decl.output.span(), "return type should be `!`");
1493 let inputs = fn_sig.inputs();
1494 let span = hir.span(fn_id);
1495 if inputs.len() == 1 {
1496 let arg_is_alloc_layout = match inputs[0].kind {
1497 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1501 if !arg_is_alloc_layout {
1502 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1505 if let Node::Item(item) = hir.get(fn_id) {
1506 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1507 if !generics.params.is_empty() {
1510 "`#[alloc_error_handler]` function should have no type \
1517 let span = sess.source_map().def_span(span);
1518 sess.span_err(span, "function should have one argument");
1521 sess.err("language item required, but not found: `alloc_layout`");
1529 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1530 let def_id = tcx.hir().local_def_id(id);
1531 let def = tcx.adt_def(def_id);
1532 def.destructor(tcx); // force the destructor to be evaluated
1533 check_representable(tcx, span, def_id);
1535 if def.repr.simd() {
1536 check_simd(tcx, span, def_id);
1539 check_transparent(tcx, span, def_id);
1540 check_packed(tcx, span, def_id);
1543 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1544 let def_id = tcx.hir().local_def_id(id);
1545 let def = tcx.adt_def(def_id);
1546 def.destructor(tcx); // force the destructor to be evaluated
1547 check_representable(tcx, span, def_id);
1548 check_transparent(tcx, span, def_id);
1549 check_union_fields(tcx, span, def_id);
1550 check_packed(tcx, span, def_id);
1553 /// When the `#![feature(untagged_unions)]` gate is active,
1554 /// check that the fields of the `union` does not contain fields that need dropping.
1555 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1556 let item_type = tcx.type_of(item_def_id);
1557 if let ty::Adt(def, substs) = item_type.kind {
1558 assert!(def.is_union());
1559 let fields = &def.non_enum_variant().fields;
1560 let param_env = tcx.param_env(item_def_id);
1561 for field in fields {
1562 let field_ty = field.ty(tcx, substs);
1563 // We are currently checking the type this field came from, so it must be local.
1564 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1565 if field_ty.needs_drop(tcx, param_env) {
1570 "unions may not contain fields that need dropping"
1572 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1578 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1583 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1584 /// projections that would result in "inheriting lifetimes".
1585 fn check_opaque<'tcx>(
1588 substs: SubstsRef<'tcx>,
1590 origin: &hir::OpaqueTyOrigin,
1592 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1593 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1596 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1597 /// in "inheriting lifetimes".
1598 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span: Span) {
1600 tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1602 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1607 struct ProhibitOpaqueVisitor<'tcx> {
1608 opaque_identity_ty: Ty<'tcx>,
1609 generics: &'tcx ty::Generics,
1612 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1613 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1614 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1615 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1618 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1619 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1620 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1621 return *index < self.generics.parent_count as u32;
1624 r.super_visit_with(self)
1628 let prohibit_opaque = match item.kind {
1629 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. })
1630 | ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1631 let mut visitor = ProhibitOpaqueVisitor {
1632 opaque_identity_ty: tcx
1633 .mk_opaque(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1634 generics: tcx.generics_of(def_id),
1636 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1638 tcx.predicates_of(def_id)
1641 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1646 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1647 if prohibit_opaque {
1648 let is_async = match item.kind {
1649 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1650 hir::OpaqueTyOrigin::AsyncFn => true,
1653 _ => unreachable!(),
1656 tcx.sess.span_err(span, &format!(
1657 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1659 if is_async { "async fn" } else { "impl Trait" },
1664 /// Checks that an opaque type does not contain cycles.
1665 fn check_opaque_for_cycles<'tcx>(
1668 substs: SubstsRef<'tcx>,
1670 origin: &hir::OpaqueTyOrigin,
1672 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1673 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1674 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1675 .span_label(span, "recursive `async fn`")
1676 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1680 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1681 err.span_label(span, "expands to a recursive type");
1682 if let ty::Opaque(..) = partially_expanded_type.kind {
1683 err.note("type resolves to itself");
1685 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1692 // Forbid defining intrinsics in Rust code,
1693 // as they must always be defined by the compiler.
1694 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1695 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1696 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1700 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1702 "check_item_type(it.hir_id={}, it.name={})",
1704 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1706 let _indenter = indenter();
1708 // Consts can play a role in type-checking, so they are included here.
1709 hir::ItemKind::Static(..) => {
1710 let def_id = tcx.hir().local_def_id(it.hir_id);
1711 tcx.typeck_tables_of(def_id);
1712 maybe_check_static_with_link_section(tcx, def_id, it.span);
1714 hir::ItemKind::Const(..) => {
1715 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1717 hir::ItemKind::Enum(ref enum_definition, _) => {
1718 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1720 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1721 hir::ItemKind::Impl { ref items, .. } => {
1722 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1723 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1724 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1725 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1726 let trait_def_id = impl_trait_ref.def_id;
1727 check_on_unimplemented(tcx, trait_def_id, it);
1730 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1731 let def_id = tcx.hir().local_def_id(it.hir_id);
1732 check_on_unimplemented(tcx, def_id, it);
1734 for item in items.iter() {
1735 let item = tcx.hir().trait_item(item.id);
1736 if let hir::TraitItemKind::Method(sig, _) = &item.kind {
1737 let abi = sig.header.abi;
1738 fn_maybe_err(tcx, item.ident.span, abi);
1742 hir::ItemKind::Struct(..) => {
1743 check_struct(tcx, it.hir_id, it.span);
1745 hir::ItemKind::Union(..) => {
1746 check_union(tcx, it.hir_id, it.span);
1748 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1749 let def_id = tcx.hir().local_def_id(it.hir_id);
1751 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1752 check_opaque(tcx, def_id, substs, it.span, &origin);
1754 hir::ItemKind::TyAlias(..) => {
1755 let def_id = tcx.hir().local_def_id(it.hir_id);
1756 let pty_ty = tcx.type_of(def_id);
1757 let generics = tcx.generics_of(def_id);
1758 check_bounds_are_used(tcx, &generics, pty_ty);
1760 hir::ItemKind::ForeignMod(ref m) => {
1761 check_abi(tcx, it.span, m.abi);
1763 if m.abi == Abi::RustIntrinsic {
1764 for item in m.items {
1765 intrinsic::check_intrinsic_type(tcx, item);
1767 } else if m.abi == Abi::PlatformIntrinsic {
1768 for item in m.items {
1769 intrinsic::check_platform_intrinsic_type(tcx, item);
1772 for item in m.items {
1773 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1774 let own_counts = generics.own_counts();
1775 if generics.params.len() - own_counts.lifetimes != 0 {
1776 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1777 (_, 0) => ("type", "types", Some("u32")),
1778 // We don't specify an example value, because we can't generate
1779 // a valid value for any type.
1780 (0, _) => ("const", "consts", None),
1781 _ => ("type or const", "types or consts", None),
1787 "foreign items may not have {} parameters",
1790 .span_label(item.span, &format!("can't have {} parameters", kinds))
1792 // FIXME: once we start storing spans for type arguments, turn this
1793 // into a suggestion.
1795 "replace the {} parameters with concrete {}{}",
1798 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1804 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1805 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1810 _ => { /* nothing to do */ }
1814 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1815 // Only restricted on wasm32 target for now
1816 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1820 // If `#[link_section]` is missing, then nothing to verify
1821 let attrs = tcx.codegen_fn_attrs(id);
1822 if attrs.link_section.is_none() {
1826 // For the wasm32 target statics with `#[link_section]` are placed into custom
1827 // sections of the final output file, but this isn't link custom sections of
1828 // other executable formats. Namely we can only embed a list of bytes,
1829 // nothing with pointers to anything else or relocations. If any relocation
1830 // show up, reject them here.
1831 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1832 // the consumer's responsibility to ensure all bytes that have been read
1833 // have defined values.
1834 match tcx.const_eval_poly(id) {
1835 Ok(ConstValue::ByRef { alloc, .. }) => {
1836 if alloc.relocations().len() != 0 {
1837 let msg = "statics with a custom `#[link_section]` must be a \
1838 simple list of bytes on the wasm target with no \
1839 extra levels of indirection such as references";
1840 tcx.sess.span_err(span, msg);
1843 Ok(_) => bug!("Matching on non-ByRef static"),
1848 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1849 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1850 // an error would be reported if this fails.
1851 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1854 fn report_forbidden_specialization(
1856 impl_item: &hir::ImplItem<'_>,
1859 let mut err = struct_span_err!(
1863 "`{}` specializes an item from a parent `impl`, but \
1864 that item is not marked `default`",
1867 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1869 match tcx.span_of_impl(parent_impl) {
1871 err.span_label(span, "parent `impl` is here");
1873 "to specialize, `{}` in the parent `impl` must be marked `default`",
1878 err.note(&format!("parent implementation is in crate `{}`", cname));
1885 fn check_specialization_validity<'tcx>(
1887 trait_def: &ty::TraitDef,
1888 trait_item: &ty::AssocItem,
1890 impl_item: &hir::ImplItem<'_>,
1892 let kind = match impl_item.kind {
1893 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1894 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1895 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1896 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1899 let mut ancestor_impls = trait_def
1900 .ancestors(tcx, impl_id)
1902 .filter_map(|parent| {
1903 if parent.is_from_trait() {
1906 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1911 if ancestor_impls.peek().is_none() {
1912 // No parent, nothing to specialize.
1916 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1918 // Parent impl exists, and contains the parent item we're trying to specialize, but
1919 // doesn't mark it `default`.
1920 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1921 Some(Err(parent_impl.def_id()))
1924 // Parent impl contains item and makes it specializable.
1925 Some(_) => Some(Ok(())),
1927 // Parent impl doesn't mention the item. This means it's inherited from the
1928 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1929 // "defaultness" from the grandparent, else they are final.
1931 if traits::impl_is_default(tcx, parent_impl.def_id()) {
1934 Some(Err(parent_impl.def_id()))
1940 // If `opt_result` is `None`, we have only encoutered `default impl`s that don't contain the
1941 // item. This is allowed, the item isn't actually getting specialized here.
1942 let result = opt_result.unwrap_or(Ok(()));
1944 if let Err(parent_impl) = result {
1945 report_forbidden_specialization(tcx, impl_item, parent_impl);
1949 fn check_impl_items_against_trait<'tcx>(
1951 full_impl_span: Span,
1953 impl_trait_ref: ty::TraitRef<'tcx>,
1954 impl_item_refs: &[hir::ImplItemRef<'_>],
1956 let impl_span = tcx.sess.source_map().def_span(full_impl_span);
1958 // If the trait reference itself is erroneous (so the compilation is going
1959 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1960 // isn't populated for such impls.
1961 if impl_trait_ref.references_error() {
1965 // Locate trait definition and items
1966 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1967 let mut overridden_associated_type = None;
1969 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1971 // Check existing impl methods to see if they are both present in trait
1972 // and compatible with trait signature
1973 for impl_item in impl_items() {
1974 let namespace = impl_item.kind.namespace();
1975 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
1976 let ty_trait_item = tcx
1977 .associated_items(impl_trait_ref.def_id)
1978 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
1980 // Not compatible, but needed for the error message
1981 tcx.associated_items(impl_trait_ref.def_id)
1982 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
1986 // Check that impl definition matches trait definition
1987 if let Some(ty_trait_item) = ty_trait_item {
1988 match impl_item.kind {
1989 hir::ImplItemKind::Const(..) => {
1990 // Find associated const definition.
1991 if ty_trait_item.kind == ty::AssocKind::Const {
2000 let mut err = struct_span_err!(
2004 "item `{}` is an associated const, \
2005 which doesn't match its trait `{}`",
2007 impl_trait_ref.print_only_trait_path()
2009 err.span_label(impl_item.span, "does not match trait");
2010 // We can only get the spans from local trait definition
2011 // Same for E0324 and E0325
2012 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2013 err.span_label(trait_span, "item in trait");
2018 hir::ImplItemKind::Method(..) => {
2019 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2020 if ty_trait_item.kind == ty::AssocKind::Method {
2021 compare_impl_method(
2030 let mut err = struct_span_err!(
2034 "item `{}` is an associated method, \
2035 which doesn't match its trait `{}`",
2037 impl_trait_ref.print_only_trait_path()
2039 err.span_label(impl_item.span, "does not match trait");
2040 if let Some(trait_span) = opt_trait_span {
2041 err.span_label(trait_span, "item in trait");
2046 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2047 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2048 if ty_trait_item.kind == ty::AssocKind::Type {
2049 if ty_trait_item.defaultness.has_value() {
2050 overridden_associated_type = Some(impl_item);
2061 let mut err = struct_span_err!(
2065 "item `{}` is an associated type, \
2066 which doesn't match its trait `{}`",
2068 impl_trait_ref.print_only_trait_path()
2070 err.span_label(impl_item.span, "does not match trait");
2071 if let Some(trait_span) = opt_trait_span {
2072 err.span_label(trait_span, "item in trait");
2079 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
2083 // Check for missing items from trait
2084 let mut missing_items = Vec::new();
2085 let mut invalidated_items = Vec::new();
2086 let associated_type_overridden = overridden_associated_type.is_some();
2087 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2088 let is_implemented = trait_def
2089 .ancestors(tcx, impl_id)
2090 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2091 .map(|node_item| !node_item.node.is_from_trait())
2094 if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
2095 if !trait_item.defaultness.has_value() {
2096 missing_items.push(*trait_item);
2097 } else if associated_type_overridden {
2098 invalidated_items.push(trait_item.ident);
2103 if !missing_items.is_empty() {
2104 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2107 if !invalidated_items.is_empty() {
2108 let invalidator = overridden_associated_type.unwrap();
2113 "the following trait items need to be reimplemented as `{}` was overridden: `{}`",
2115 invalidated_items.iter().map(|name| name.to_string()).collect::<Vec<_>>().join("`, `")
2121 fn missing_items_err(
2124 missing_items: &[ty::AssocItem],
2125 full_impl_span: Span,
2127 let missing_items_msg = missing_items
2129 .map(|trait_item| trait_item.ident.to_string())
2130 .collect::<Vec<_>>()
2133 let mut err = struct_span_err!(
2137 "not all trait items implemented, missing: `{}`",
2140 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2142 // `Span` before impl block closing brace.
2143 let hi = full_impl_span.hi() - BytePos(1);
2144 // Point at the place right before the closing brace of the relevant `impl` to suggest
2145 // adding the associated item at the end of its body.
2146 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2147 // Obtain the level of indentation ending in `sugg_sp`.
2148 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2149 // Make the whitespace that will make the suggestion have the right indentation.
2150 let padding: String = (0..indentation).map(|_| " ").collect();
2152 for trait_item in missing_items {
2153 let snippet = suggestion_signature(&trait_item, tcx);
2154 let code = format!("{}{}\n{}", padding, snippet, padding);
2155 let msg = format!("implement the missing item: `{}`", snippet);
2156 let appl = Applicability::HasPlaceholders;
2157 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2158 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2159 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2161 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2167 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2168 fn bounds_from_generic_predicates(
2170 predicates: ty::GenericPredicates<'_>,
2171 ) -> (String, String) {
2172 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2173 let mut projections = vec![];
2174 for (predicate, _) in predicates.predicates {
2175 debug!("predicate {:?}", predicate);
2177 ty::Predicate::Trait(trait_predicate, _) => {
2178 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2179 let def_id = trait_predicate.skip_binder().def_id();
2180 if Some(def_id) != tcx.lang_items().sized_trait() {
2181 // Type params are `Sized` by default, do not add that restriction to the list
2182 // if it is a positive requirement.
2183 entry.push(trait_predicate.skip_binder().def_id());
2186 ty::Predicate::Projection(projection_pred) => {
2187 projections.push(projection_pred);
2192 let generics = if types.is_empty() {
2199 .filter_map(|t| match t.kind {
2200 ty::Param(_) => Some(t.to_string()),
2201 // Avoid suggesting the following:
2202 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2205 .collect::<Vec<_>>()
2209 let mut where_clauses = vec![];
2210 for (ty, bounds) in types {
2211 for bound in &bounds {
2212 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2215 for projection in &projections {
2216 let p = projection.skip_binder();
2217 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2218 // insert the associated types where they correspond, but for now let's be "lazy" and
2219 // propose this instead of the following valid resugaring:
2220 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2221 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2223 let where_clauses = if where_clauses.is_empty() {
2226 format!(" where {}", where_clauses.join(", "))
2228 (generics, where_clauses)
2231 /// Return placeholder code for the given function.
2232 fn fn_sig_suggestion(
2234 sig: &ty::FnSig<'_>,
2236 predicates: ty::GenericPredicates<'_>,
2242 Some(match ty.kind {
2243 ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
2244 ty::Ref(reg, ref_ty, mutability) => {
2245 let reg = match &format!("{}", reg)[..] {
2246 "'_" | "" => String::new(),
2247 reg => format!("{} ", reg),
2250 ty::Param(param) if param.name == kw::SelfUpper => {
2251 format!("&{}{}self", reg, mutability.prefix_str())
2253 _ => format!("_: {:?}", ty),
2256 _ => format!("_: {:?}", ty),
2259 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2260 .filter_map(|arg| arg)
2261 .collect::<Vec<String>>()
2263 let output = sig.output();
2264 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2266 let unsafety = sig.unsafety.prefix_str();
2267 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2269 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2270 // not be present in the `fn` definition, not will we account for renamed
2271 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2272 // fill in a significant portion of the missing code, and other subsequent
2273 // suggestions can help the user fix the code.
2275 "{}fn {}{}({}){}{} {{ todo!() }}",
2276 unsafety, ident, generics, args, output, where_clauses
2280 /// Return placeholder code for the given associated item.
2281 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2282 /// structured suggestion.
2283 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2285 ty::AssocKind::Method => {
2286 // We skip the binder here because the binder would deanonymize all
2287 // late-bound regions, and we don't want method signatures to show up
2288 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2289 // regions just fine, showing `fn(&MyType)`.
2292 tcx.fn_sig(assoc.def_id).skip_binder(),
2294 tcx.predicates_of(assoc.def_id),
2297 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2298 // FIXME(type_alias_impl_trait): we should print bounds here too.
2299 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2300 ty::AssocKind::Const => {
2301 let ty = tcx.type_of(assoc.def_id);
2302 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2303 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2308 /// Checks whether a type can be represented in memory. In particular, it
2309 /// identifies types that contain themselves without indirection through a
2310 /// pointer, which would mean their size is unbounded.
2311 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
2312 let rty = tcx.type_of(item_def_id);
2314 // Check that it is possible to represent this type. This call identifies
2315 // (1) types that contain themselves and (2) types that contain a different
2316 // recursive type. It is only necessary to throw an error on those that
2317 // contain themselves. For case 2, there must be an inner type that will be
2318 // caught by case 1.
2319 match rty.is_representable(tcx, sp) {
2320 Representability::SelfRecursive(spans) => {
2321 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id);
2323 err.span_label(span, "recursive without indirection");
2328 Representability::Representable | Representability::ContainsRecursive => (),
2333 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2334 let t = tcx.type_of(def_id);
2335 if let ty::Adt(def, substs) = t.kind {
2336 if def.is_struct() {
2337 let fields = &def.non_enum_variant().fields;
2338 if fields.is_empty() {
2339 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2342 let e = fields[0].ty(tcx, substs);
2343 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2344 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2345 .span_label(sp, "SIMD elements must have the same type")
2350 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2351 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2357 "SIMD vector element type should be machine type"
2367 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2368 let repr = tcx.adt_def(def_id).repr;
2370 for attr in tcx.get_attrs(def_id).iter() {
2371 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2372 if let attr::ReprPacked(pack) = r {
2373 if let Some(repr_pack) = repr.pack {
2374 if pack as u64 != repr_pack.bytes() {
2379 "type has conflicting packed representation hints"
2387 if repr.align.is_some() {
2392 "type has conflicting packed and align representation hints"
2396 if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) {
2397 let mut err = struct_span_err!(
2401 "packed type cannot transitively contain a `#[repr(align)]` type"
2404 let hir = tcx.hir();
2405 if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) {
2406 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2408 tcx.def_span(def_spans[0].0),
2409 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2414 if def_spans.len() > 2 {
2415 let mut first = true;
2416 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2417 if let Some(hir_id) = hir.as_local_hir_id(*adt_def) {
2418 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2423 "`{}` contains a field of type `{}`",
2424 tcx.type_of(def_id),
2428 format!("...which contains a field of type `{}`", ident)
2443 fn check_packed_inner(
2446 stack: &mut Vec<DefId>,
2447 ) -> Option<Vec<(DefId, Span)>> {
2448 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2449 if def.is_struct() || def.is_union() {
2450 if def.repr.align.is_some() {
2451 return Some(vec![(def.did, DUMMY_SP)]);
2455 for field in &def.non_enum_variant().fields {
2456 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2457 if !stack.contains(&def.did) {
2458 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2459 defs.push((def.did, field.ident.span));
2472 /// Emit an error when encountering more or less than one variant in a transparent enum.
2473 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2474 let variant_spans: Vec<_> = adt
2477 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2479 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2480 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2481 err.span_label(sp, &msg);
2482 if let [start @ .., end] = &*variant_spans {
2483 for variant_span in start {
2484 err.span_label(*variant_span, "");
2486 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2491 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2493 fn bad_non_zero_sized_fields<'tcx>(
2495 adt: &'tcx ty::AdtDef,
2497 field_spans: impl Iterator<Item = Span>,
2500 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2501 let mut err = struct_span_err!(
2505 "{}transparent {} {}",
2506 if adt.is_enum() { "the variant of a " } else { "" },
2510 err.span_label(sp, &msg);
2511 for sp in field_spans {
2512 err.span_label(sp, "this field is non-zero-sized");
2517 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2518 let adt = tcx.adt_def(def_id);
2519 if !adt.repr.transparent() {
2522 let sp = tcx.sess.source_map().def_span(sp);
2524 if adt.is_union() && !tcx.features().transparent_unions {
2526 &tcx.sess.parse_sess,
2527 sym::transparent_unions,
2529 "transparent unions are unstable",
2534 if adt.variants.len() != 1 {
2535 bad_variant_count(tcx, adt, sp, def_id);
2536 if adt.variants.is_empty() {
2537 // Don't bother checking the fields. No variants (and thus no fields) exist.
2542 // For each field, figure out if it's known to be a ZST and align(1)
2543 let field_infos = adt.all_fields().map(|field| {
2544 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2545 let param_env = tcx.param_env(field.did);
2546 let layout = tcx.layout_of(param_env.and(ty));
2547 // We are currently checking the type this field came from, so it must be local
2548 let span = tcx.hir().span_if_local(field.did).unwrap();
2549 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2550 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2554 let non_zst_fields =
2555 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2556 let non_zst_count = non_zst_fields.clone().count();
2557 if non_zst_count != 1 {
2558 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2560 for (span, zst, align1) in field_infos {
2566 "zero-sized field in transparent {} has alignment larger than 1",
2569 .span_label(span, "has alignment larger than 1")
2575 #[allow(trivial_numeric_casts)]
2576 pub fn check_enum<'tcx>(
2579 vs: &'tcx [hir::Variant<'tcx>],
2582 let def_id = tcx.hir().local_def_id(id);
2583 let def = tcx.adt_def(def_id);
2584 def.destructor(tcx); // force the destructor to be evaluated
2587 let attributes = tcx.get_attrs(def_id);
2588 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2593 "unsupported representation for zero-variant enum"
2595 .span_label(sp, "zero-variant enum")
2600 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2601 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2602 if !tcx.features().repr128 {
2604 &tcx.sess.parse_sess,
2607 "repr with 128-bit type is unstable",
2614 if let Some(ref e) = v.disr_expr {
2615 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2619 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2620 let is_unit = |var: &hir::Variant<'_>| match var.data {
2621 hir::VariantData::Unit(..) => true,
2625 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2626 let has_non_units = vs.iter().any(|var| !is_unit(var));
2627 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2628 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2630 if disr_non_unit || (disr_units && has_non_units) {
2632 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2637 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2638 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2639 // Check for duplicate discriminant values
2640 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2641 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2642 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2643 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2644 let i_span = match variant_i.disr_expr {
2645 Some(ref expr) => tcx.hir().span(expr.hir_id),
2646 None => tcx.hir().span(variant_i_hir_id),
2648 let span = match v.disr_expr {
2649 Some(ref expr) => tcx.hir().span(expr.hir_id),
2656 "discriminant value `{}` already exists",
2659 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2660 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2663 disr_vals.push(discr);
2666 check_representable(tcx, sp, def_id);
2667 check_transparent(tcx, sp, def_id);
2670 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath<'_>) {
2675 "expected unit struct, unit variant or constant, found {} `{}`",
2677 hir::print::to_string(&tcx.hir(), |s| s.print_qpath(qpath, false))
2682 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2683 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2687 fn item_def_id(&self) -> Option<DefId> {
2691 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2692 // FIXME: refactor this into a method
2693 let node = self.tcx.hir().get(self.body_id);
2694 if let Some(fn_like) = FnLikeNode::from_node(node) {
2697 hir::Constness::NotConst
2701 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2703 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2704 let item_id = tcx.hir().ty_param_owner(hir_id);
2705 let item_def_id = tcx.hir().local_def_id(item_id);
2706 let generics = tcx.generics_of(item_def_id);
2707 let index = generics.param_def_id_to_index[&def_id];
2708 ty::GenericPredicates {
2710 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2711 |&predicate| match predicate {
2712 ty::Predicate::Trait(ref data, _)
2713 if data.skip_binder().self_ty().is_param(index) =>
2715 // HACK(eddyb) should get the original `Span`.
2716 let span = tcx.def_span(def_id);
2717 Some((predicate, span))
2725 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2727 Some(def) => infer::EarlyBoundRegion(span, def.name),
2728 None => infer::MiscVariable(span),
2730 Some(self.next_region_var(v))
2733 fn allow_ty_infer(&self) -> bool {
2737 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2738 if let Some(param) = param {
2739 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2744 self.next_ty_var(TypeVariableOrigin {
2745 kind: TypeVariableOriginKind::TypeInference,
2754 param: Option<&ty::GenericParamDef>,
2756 ) -> &'tcx Const<'tcx> {
2757 if let Some(param) = param {
2758 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2763 self.next_const_var(
2765 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2770 fn projected_ty_from_poly_trait_ref(
2774 item_segment: &hir::PathSegment<'_>,
2775 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2777 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2779 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2783 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2792 self.tcx().mk_projection(item_def_id, item_substs)
2795 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2796 if ty.has_escaping_bound_vars() {
2797 ty // FIXME: normalization and escaping regions
2799 self.normalize_associated_types_in(span, &ty)
2803 fn set_tainted_by_errors(&self) {
2804 self.infcx.set_tainted_by_errors()
2807 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2808 self.write_ty(hir_id, ty)
2812 /// Controls whether the arguments are tupled. This is used for the call
2815 /// Tupling means that all call-side arguments are packed into a tuple and
2816 /// passed as a single parameter. For example, if tupling is enabled, this
2819 /// fn f(x: (isize, isize))
2821 /// Can be called as:
2828 #[derive(Clone, Eq, PartialEq)]
2829 enum TupleArgumentsFlag {
2834 /// Controls how we perform fallback for unconstrained
2837 /// Do not fallback type variables to opaque types.
2839 /// Perform all possible kinds of fallback, including
2840 /// turning type variables to opaque types.
2844 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2846 inh: &'a Inherited<'a, 'tcx>,
2847 param_env: ty::ParamEnv<'tcx>,
2848 body_id: hir::HirId,
2849 ) -> FnCtxt<'a, 'tcx> {
2853 err_count_on_creation: inh.tcx.sess.err_count(),
2855 ret_coercion_span: RefCell::new(None),
2856 resume_yield_tys: None,
2857 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2858 diverges: Cell::new(Diverges::Maybe),
2859 has_errors: Cell::new(false),
2860 enclosing_breakables: RefCell::new(EnclosingBreakables {
2862 by_id: Default::default(),
2868 pub fn sess(&self) -> &Session {
2872 pub fn errors_reported_since_creation(&self) -> bool {
2873 self.tcx.sess.err_count() > self.err_count_on_creation
2876 /// Produces warning on the given node, if the current point in the
2877 /// function is unreachable, and there hasn't been another warning.
2878 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2879 // FIXME: Combine these two 'if' expressions into one once
2880 // let chains are implemented
2881 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2882 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2883 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2884 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2885 if !span.is_desugaring(DesugaringKind::CondTemporary)
2886 && !span.is_desugaring(DesugaringKind::Async)
2887 && !orig_span.is_desugaring(DesugaringKind::Await)
2889 self.diverges.set(Diverges::WarnedAlways);
2891 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2893 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2894 let msg = format!("unreachable {}", kind);
2896 .span_label(span, &msg)
2900 .unwrap_or("any code following this expression is unreachable"),
2908 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2909 ObligationCause::new(span, self.body_id, code)
2912 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2913 self.cause(span, ObligationCauseCode::MiscObligation)
2916 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2917 /// version (resolve_vars_if_possible), this version will
2918 /// also select obligations if it seems useful, in an effort
2919 /// to get more type information.
2920 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2921 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2923 // No Infer()? Nothing needs doing.
2924 if !ty.has_infer_types() && !ty.has_infer_consts() {
2925 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2929 // If `ty` is a type variable, see whether we already know what it is.
2930 ty = self.resolve_vars_if_possible(&ty);
2931 if !ty.has_infer_types() && !ty.has_infer_consts() {
2932 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2936 // If not, try resolving pending obligations as much as
2937 // possible. This can help substantially when there are
2938 // indirect dependencies that don't seem worth tracking
2940 self.select_obligations_where_possible(false, |_| {});
2941 ty = self.resolve_vars_if_possible(&ty);
2943 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2947 fn record_deferred_call_resolution(
2949 closure_def_id: DefId,
2950 r: DeferredCallResolution<'tcx>,
2952 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2953 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2956 fn remove_deferred_call_resolutions(
2958 closure_def_id: DefId,
2959 ) -> Vec<DeferredCallResolution<'tcx>> {
2960 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2961 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2964 pub fn tag(&self) -> String {
2965 format!("{:p}", self)
2968 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2969 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
2970 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
2975 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2977 "write_ty({:?}, {:?}) in fcx {}",
2979 self.resolve_vars_if_possible(&ty),
2982 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2984 if ty.references_error() {
2985 self.has_errors.set(true);
2986 self.set_tainted_by_errors();
2990 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2991 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2994 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2995 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2998 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
2999 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3000 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
3001 self.write_substs(hir_id, method.substs);
3003 // When the method is confirmed, the `method.substs` includes
3004 // parameters from not just the method, but also the impl of
3005 // the method -- in particular, the `Self` type will be fully
3006 // resolved. However, those are not something that the "user
3007 // specified" -- i.e., those types come from the inferred type
3008 // of the receiver, not something the user wrote. So when we
3009 // create the user-substs, we want to replace those earlier
3010 // types with just the types that the user actually wrote --
3011 // that is, those that appear on the *method itself*.
3013 // As an example, if the user wrote something like
3014 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3015 // type of `foo` (possibly adjusted), but we don't want to
3016 // include that. We want just the `[_, u32]` part.
3017 if !method.substs.is_noop() {
3018 let method_generics = self.tcx.generics_of(method.def_id);
3019 if !method_generics.params.is_empty() {
3020 let user_type_annotation = self.infcx.probe(|_| {
3021 let user_substs = UserSubsts {
3022 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3023 let i = param.index as usize;
3024 if i < method_generics.parent_count {
3025 self.infcx.var_for_def(DUMMY_SP, param)
3030 user_self_ty: None, // not relevant here
3033 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3039 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3040 self.write_user_type_annotation(hir_id, user_type_annotation);
3045 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3046 if !substs.is_noop() {
3047 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3049 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3053 /// Given the substs that we just converted from the HIR, try to
3054 /// canonicalize them and store them as user-given substitutions
3055 /// (i.e., substitutions that must be respected by the NLL check).
3057 /// This should be invoked **before any unifications have
3058 /// occurred**, so that annotations like `Vec<_>` are preserved
3060 pub fn write_user_type_annotation_from_substs(
3064 substs: SubstsRef<'tcx>,
3065 user_self_ty: Option<UserSelfTy<'tcx>>,
3068 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3069 user_self_ty={:?} in fcx {}",
3077 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3078 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3080 UserSubsts { substs, user_self_ty },
3082 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3083 self.write_user_type_annotation(hir_id, canonicalized);
3087 pub fn write_user_type_annotation(
3090 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3093 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3095 canonical_user_type_annotation,
3099 if !canonical_user_type_annotation.is_identity() {
3102 .user_provided_types_mut()
3103 .insert(hir_id, canonical_user_type_annotation);
3105 debug!("write_user_type_annotation: skipping identity substs");
3109 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3110 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3116 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3117 Entry::Vacant(entry) => {
3120 Entry::Occupied(mut entry) => {
3121 debug!(" - composing on top of {:?}", entry.get());
3122 match (&entry.get()[..], &adj[..]) {
3123 // Applying any adjustment on top of a NeverToAny
3124 // is a valid NeverToAny adjustment, because it can't
3126 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3128 Adjustment { kind: Adjust::Deref(_), .. },
3129 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3131 Adjustment { kind: Adjust::Deref(_), .. },
3132 .. // Any following adjustments are allowed.
3134 // A reborrow has no effect before a dereference.
3136 // FIXME: currently we never try to compose autoderefs
3137 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3139 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3140 expr, entry.get(), adj)
3142 *entry.get_mut() = adj;
3147 /// Basically whenever we are converting from a type scheme into
3148 /// the fn body space, we always want to normalize associated
3149 /// types as well. This function combines the two.
3150 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3152 T: TypeFoldable<'tcx>,
3154 let value = value.subst(self.tcx, substs);
3155 let result = self.normalize_associated_types_in(span, &value);
3156 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3160 /// As `instantiate_type_scheme`, but for the bounds found in a
3161 /// generic type scheme.
3162 fn instantiate_bounds(
3166 substs: SubstsRef<'tcx>,
3167 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3168 let bounds = self.tcx.predicates_of(def_id);
3169 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3170 let result = bounds.instantiate(self.tcx, substs);
3171 let result = self.normalize_associated_types_in(span, &result);
3173 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3174 bounds, substs, result, spans,
3179 /// Replaces the opaque types from the given value with type variables,
3180 /// and records the `OpaqueTypeMap` for later use during writeback. See
3181 /// `InferCtxt::instantiate_opaque_types` for more details.
3182 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3184 parent_id: hir::HirId,
3188 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3190 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3191 parent_def_id, value
3194 let (value, opaque_type_map) =
3195 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3203 let mut opaque_types = self.opaque_types.borrow_mut();
3204 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3205 for (ty, decl) in opaque_type_map {
3206 let _ = opaque_types.insert(ty, decl);
3207 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3213 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3215 T: TypeFoldable<'tcx>,
3217 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3220 fn normalize_associated_types_in_as_infer_ok<T>(
3224 ) -> InferOk<'tcx, T>
3226 T: TypeFoldable<'tcx>,
3228 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3231 pub fn require_type_meets(
3235 code: traits::ObligationCauseCode<'tcx>,
3238 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3241 pub fn require_type_is_sized(
3245 code: traits::ObligationCauseCode<'tcx>,
3247 if !ty.references_error() {
3248 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
3249 self.require_type_meets(ty, span, code, lang_item);
3253 pub fn require_type_is_sized_deferred(
3257 code: traits::ObligationCauseCode<'tcx>,
3259 if !ty.references_error() {
3260 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3264 pub fn register_bound(
3268 cause: traits::ObligationCause<'tcx>,
3270 if !ty.references_error() {
3271 self.fulfillment_cx.borrow_mut().register_bound(
3281 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3282 let t = AstConv::ast_ty_to_ty(self, ast_t);
3283 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3287 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3288 let ty = self.to_ty(ast_ty);
3289 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3291 if Self::can_contain_user_lifetime_bounds(ty) {
3292 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3293 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3294 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3300 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
3301 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
3302 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
3305 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
3306 AstConv::ast_const_to_const(self, ast_c, ty)
3309 // If the type given by the user has free regions, save it for later, since
3310 // NLL would like to enforce those. Also pass in types that involve
3311 // projections, since those can resolve to `'static` bounds (modulo #54940,
3312 // which hopefully will be fixed by the time you see this comment, dear
3313 // reader, although I have my doubts). Also pass in types with inference
3314 // types, because they may be repeated. Other sorts of things are already
3315 // sufficiently enforced with erased regions. =)
3316 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3318 T: TypeFoldable<'tcx>,
3320 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3323 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3324 match self.tables.borrow().node_types().get(id) {
3326 None if self.is_tainted_by_errors() => self.tcx.types.err,
3329 "no type for node {}: {} in fcx {}",
3331 self.tcx.hir().node_to_string(id),
3338 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3339 /// outlive the region `r`.
3340 pub fn register_wf_obligation(
3344 code: traits::ObligationCauseCode<'tcx>,
3346 // WF obligations never themselves fail, so no real need to give a detailed cause:
3347 let cause = traits::ObligationCause::new(span, self.body_id, code);
3348 self.register_predicate(traits::Obligation::new(
3351 ty::Predicate::WellFormed(ty),
3355 /// Registers obligations that all types appearing in `substs` are well-formed.
3356 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3357 for ty in substs.types() {
3358 if !ty.references_error() {
3359 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3364 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3365 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3366 /// trait/region obligations.
3368 /// For example, if there is a function:
3371 /// fn foo<'a,T:'a>(...)
3374 /// and a reference:
3380 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3381 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3382 pub fn add_obligations_for_parameters(
3384 cause: traits::ObligationCause<'tcx>,
3385 predicates: &ty::InstantiatedPredicates<'tcx>,
3387 assert!(!predicates.has_escaping_bound_vars());
3389 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3391 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3392 self.register_predicate(obligation);
3396 // FIXME(arielb1): use this instead of field.ty everywhere
3397 // Only for fields! Returns <none> for methods>
3398 // Indifferent to privacy flags
3402 field: &'tcx ty::FieldDef,
3403 substs: SubstsRef<'tcx>,
3405 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3408 fn check_casts(&self) {
3409 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3410 for cast in deferred_cast_checks.drain(..) {
3415 fn resolve_generator_interiors(&self, def_id: DefId) {
3416 let mut generators = self.deferred_generator_interiors.borrow_mut();
3417 for (body_id, interior, kind) in generators.drain(..) {
3418 self.select_obligations_where_possible(false, |_| {});
3419 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3423 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3425 // - Unconstrained ints are replaced with `i32`.
3427 // - Unconstrained floats are replaced with with `f64`.
3429 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3430 // is enabled. Otherwise, they are replaced with `()`.
3432 // Fallback becomes very dubious if we have encountered type-checking errors.
3433 // In that case, fallback to Error.
3434 // The return value indicates whether fallback has occurred.
3435 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3436 use rustc::ty::error::UnconstrainedNumeric::Neither;
3437 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3439 assert!(ty.is_ty_infer());
3440 let fallback = match self.type_is_unconstrained_numeric(ty) {
3441 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3442 UnconstrainedInt => self.tcx.types.i32,
3443 UnconstrainedFloat => self.tcx.types.f64,
3444 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3446 // This type variable was created from the instantiation of an opaque
3447 // type. The fact that we're attempting to perform fallback for it
3448 // means that the function neither constrained it to a concrete
3449 // type, nor to the opaque type itself.
3451 // For example, in this code:
3454 // type MyType = impl Copy;
3455 // fn defining_use() -> MyType { true }
3456 // fn other_use() -> MyType { defining_use() }
3459 // `defining_use` will constrain the instantiated inference
3460 // variable to `bool`, while `other_use` will constrain
3461 // the instantiated inference variable to `MyType`.
3463 // When we process opaque types during writeback, we
3464 // will handle cases like `other_use`, and not count
3465 // them as defining usages
3467 // However, we also need to handle cases like this:
3470 // pub type Foo = impl Copy;
3471 // fn produce() -> Option<Foo> {
3476 // In the above snippet, the inference varaible created by
3477 // instantiating `Option<Foo>` will be completely unconstrained.
3478 // We treat this as a non-defining use by making the inference
3479 // variable fall back to the opaque type itself.
3480 if let FallbackMode::All = mode {
3481 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3483 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3495 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3496 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3500 fn select_all_obligations_or_error(&self) {
3501 debug!("select_all_obligations_or_error");
3502 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3503 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3507 /// Select as many obligations as we can at present.
3508 fn select_obligations_where_possible(
3510 fallback_has_occurred: bool,
3511 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3513 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3514 if let Err(mut errors) = result {
3515 mutate_fullfillment_errors(&mut errors);
3516 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3520 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3521 /// returns a type of `&T`, but the actual type we assign to the
3522 /// *expression* is `T`. So this function just peels off the return
3523 /// type by one layer to yield `T`.
3524 fn make_overloaded_place_return_type(
3526 method: MethodCallee<'tcx>,
3527 ) -> ty::TypeAndMut<'tcx> {
3528 // extract method return type, which will be &T;
3529 let ret_ty = method.sig.output();
3531 // method returns &T, but the type as visible to user is T, so deref
3532 ret_ty.builtin_deref(true).unwrap()
3537 expr: &hir::Expr<'_>,
3538 base_expr: &'tcx hir::Expr<'tcx>,
3542 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3543 // FIXME(#18741) -- this is almost but not quite the same as the
3544 // autoderef that normal method probing does. They could likely be
3547 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3548 let mut result = None;
3549 while result.is_none() && autoderef.next().is_some() {
3550 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3552 autoderef.finalize(self);
3556 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3557 /// (and otherwise adjust) `base_expr`, looking for a type which either
3558 /// supports builtin indexing or overloaded indexing.
3559 /// This loop implements one step in that search; the autoderef loop
3560 /// is implemented by `lookup_indexing`.
3563 expr: &hir::Expr<'_>,
3564 base_expr: &hir::Expr<'_>,
3565 autoderef: &Autoderef<'a, 'tcx>,
3568 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3569 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3571 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3573 expr, base_expr, adjusted_ty, index_ty
3576 for &unsize in &[false, true] {
3577 let mut self_ty = adjusted_ty;
3579 // We only unsize arrays here.
3580 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3581 self_ty = self.tcx.mk_slice(element_ty);
3587 // If some lookup succeeds, write callee into table and extract index/element
3588 // type from the method signature.
3589 // If some lookup succeeded, install method in table
3590 let input_ty = self.next_ty_var(TypeVariableOrigin {
3591 kind: TypeVariableOriginKind::AutoDeref,
3592 span: base_expr.span,
3594 let method = self.try_overloaded_place_op(
3602 let result = method.map(|ok| {
3603 debug!("try_index_step: success, using overloaded indexing");
3604 let method = self.register_infer_ok_obligations(ok);
3606 let mut adjustments = autoderef.adjust_steps(self, needs);
3607 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3608 let mutbl = match r_mutbl {
3609 hir::Mutability::Not => AutoBorrowMutability::Not,
3610 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3611 // Indexing can be desugared to a method call,
3612 // so maybe we could use two-phase here.
3613 // See the documentation of AllowTwoPhase for why that's
3614 // not the case today.
3615 allow_two_phase_borrow: AllowTwoPhase::No,
3618 adjustments.push(Adjustment {
3619 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3622 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3626 adjustments.push(Adjustment {
3627 kind: Adjust::Pointer(PointerCast::Unsize),
3628 target: method.sig.inputs()[0],
3631 self.apply_adjustments(base_expr, adjustments);
3633 self.write_method_call(expr.hir_id, method);
3634 (input_ty, self.make_overloaded_place_return_type(method).ty)
3636 if result.is_some() {
3644 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3645 let (tr, name) = match (op, is_mut) {
3646 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3647 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3648 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3649 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3651 (tr, ast::Ident::with_dummy_span(name))
3654 fn try_overloaded_place_op(
3658 arg_tys: &[Ty<'tcx>],
3661 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3662 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3664 // Try Mut first, if needed.
3665 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3666 let method = match (needs, mut_tr) {
3667 (Needs::MutPlace, Some(trait_did)) => {
3668 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3673 // Otherwise, fall back to the immutable version.
3674 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3675 let method = match (method, imm_tr) {
3676 (None, Some(trait_did)) => {
3677 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3679 (method, _) => method,
3685 fn check_method_argument_types(
3688 expr: &'tcx hir::Expr<'tcx>,
3689 method: Result<MethodCallee<'tcx>, ()>,
3690 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3691 tuple_arguments: TupleArgumentsFlag,
3692 expected: Expectation<'tcx>,
3694 let has_error = match method {
3695 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3699 let err_inputs = self.err_args(args_no_rcvr.len());
3701 let err_inputs = match tuple_arguments {
3702 DontTupleArguments => err_inputs,
3703 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3706 self.check_argument_types(
3716 return self.tcx.types.err;
3719 let method = method.unwrap();
3720 // HACK(eddyb) ignore self in the definition (see above).
3721 let expected_arg_tys = self.expected_inputs_for_expected_output(
3724 method.sig.output(),
3725 &method.sig.inputs()[1..],
3727 self.check_argument_types(
3730 &method.sig.inputs()[1..],
3731 &expected_arg_tys[..],
3733 method.sig.c_variadic,
3735 self.tcx.hir().span_if_local(method.def_id),
3740 fn self_type_matches_expected_vid(
3742 trait_ref: ty::PolyTraitRef<'tcx>,
3743 expected_vid: ty::TyVid,
3745 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3747 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3748 trait_ref, self_ty, expected_vid
3750 match self_ty.kind {
3751 ty::Infer(ty::TyVar(found_vid)) => {
3752 // FIXME: consider using `sub_root_var` here so we
3753 // can see through subtyping.
3754 let found_vid = self.root_var(found_vid);
3755 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3756 expected_vid == found_vid
3762 fn obligations_for_self_ty<'b>(
3765 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3768 // FIXME: consider using `sub_root_var` here so we
3769 // can see through subtyping.
3770 let ty_var_root = self.root_var(self_ty);
3772 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3775 self.fulfillment_cx.borrow().pending_obligations()
3780 .pending_obligations()
3782 .filter_map(move |obligation| match obligation.predicate {
3783 ty::Predicate::Projection(ref data) => {
3784 Some((data.to_poly_trait_ref(self.tcx), obligation))
3786 ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
3787 ty::Predicate::Subtype(..) => None,
3788 ty::Predicate::RegionOutlives(..) => None,
3789 ty::Predicate::TypeOutlives(..) => None,
3790 ty::Predicate::WellFormed(..) => None,
3791 ty::Predicate::ObjectSafe(..) => None,
3792 ty::Predicate::ConstEvaluatable(..) => None,
3793 // N.B., this predicate is created by breaking down a
3794 // `ClosureType: FnFoo()` predicate, where
3795 // `ClosureType` represents some `Closure`. It can't
3796 // possibly be referring to the current closure,
3797 // because we haven't produced the `Closure` for
3798 // this closure yet; this is exactly why the other
3799 // code is looking for a self type of a unresolved
3800 // inference variable.
3801 ty::Predicate::ClosureKind(..) => None,
3803 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3806 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3807 self.obligations_for_self_ty(self_ty)
3808 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3811 /// Generic function that factors out common logic from function calls,
3812 /// method calls and overloaded operators.
3813 fn check_argument_types(
3816 expr: &'tcx hir::Expr<'tcx>,
3817 fn_inputs: &[Ty<'tcx>],
3818 expected_arg_tys: &[Ty<'tcx>],
3819 args: &'tcx [hir::Expr<'tcx>],
3821 tuple_arguments: TupleArgumentsFlag,
3822 def_span: Option<Span>,
3825 // Grab the argument types, supplying fresh type variables
3826 // if the wrong number of arguments were supplied
3827 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3829 // All the input types from the fn signature must outlive the call
3830 // so as to validate implied bounds.
3831 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3832 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3835 let expected_arg_count = fn_inputs.len();
3837 let param_count_error = |expected_count: usize,
3842 let (span, start_span, args) = match &expr.kind {
3843 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3844 hir::ExprKind::MethodCall(path_segment, span, args) => (
3846 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3849 .and_then(|args| args.args.iter().last())
3850 // Account for `foo.bar::<T>()`.
3852 // Skip the closing `>`.
3855 .next_point(tcx.sess.source_map().next_point(arg.span()))
3858 &args[1..], // Skip the receiver.
3860 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3862 let arg_spans = if args.is_empty() {
3864 // ^^^-- supplied 0 arguments
3866 // expected 2 arguments
3867 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3870 // ^^^ - - - supplied 3 arguments
3872 // expected 2 arguments
3873 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3876 let mut err = tcx.sess.struct_span_err_with_code(
3879 "this function takes {}{} but {} {} supplied",
3880 if c_variadic { "at least " } else { "" },
3881 potentially_plural_count(expected_count, "argument"),
3882 potentially_plural_count(arg_count, "argument"),
3883 if arg_count == 1 { "was" } else { "were" }
3885 DiagnosticId::Error(error_code.to_owned()),
3887 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3888 for (i, span) in arg_spans.into_iter().enumerate() {
3891 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3895 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3896 err.span_label(def_s, "defined here");
3899 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3900 // remove closing `)` from the span
3901 let sugg_span = sugg_span.shrink_to_lo();
3902 err.span_suggestion(
3904 "expected the unit value `()`; create it with empty parentheses",
3906 Applicability::MachineApplicable,
3913 if c_variadic { "at least " } else { "" },
3914 potentially_plural_count(expected_count, "argument")
3921 let mut expected_arg_tys = expected_arg_tys.to_vec();
3923 let formal_tys = if tuple_arguments == TupleArguments {
3924 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3925 match tuple_type.kind {
3926 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3927 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3928 expected_arg_tys = vec![];
3929 self.err_args(args.len())
3931 ty::Tuple(arg_types) => {
3932 expected_arg_tys = match expected_arg_tys.get(0) {
3933 Some(&ty) => match ty.kind {
3934 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3939 arg_types.iter().map(|k| k.expect_ty()).collect()
3946 "cannot use call notation; the first type parameter \
3947 for the function trait is neither a tuple nor unit"
3950 expected_arg_tys = vec![];
3951 self.err_args(args.len())
3954 } else if expected_arg_count == supplied_arg_count {
3956 } else if c_variadic {
3957 if supplied_arg_count >= expected_arg_count {
3960 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3961 expected_arg_tys = vec![];
3962 self.err_args(supplied_arg_count)
3965 // is the missing argument of type `()`?
3966 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3967 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3968 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3969 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3973 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3975 expected_arg_tys = vec![];
3976 self.err_args(supplied_arg_count)
3980 "check_argument_types: formal_tys={:?}",
3981 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
3984 // If there is no expectation, expect formal_tys.
3985 let expected_arg_tys =
3986 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
3988 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
3990 // Check the arguments.
3991 // We do this in a pretty awful way: first we type-check any arguments
3992 // that are not closures, then we type-check the closures. This is so
3993 // that we have more information about the types of arguments when we
3994 // type-check the functions. This isn't really the right way to do this.
3995 for &check_closures in &[false, true] {
3996 debug!("check_closures={}", check_closures);
3998 // More awful hacks: before we check argument types, try to do
3999 // an "opportunistic" vtable resolution of any trait bounds on
4000 // the call. This helps coercions.
4002 self.select_obligations_where_possible(false, |errors| {
4003 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4004 self.point_at_arg_instead_of_call_if_possible(
4006 &final_arg_types[..],
4013 // For C-variadic functions, we don't have a declared type for all of
4014 // the arguments hence we only do our usual type checking with
4015 // the arguments who's types we do know.
4016 let t = if c_variadic {
4018 } else if tuple_arguments == TupleArguments {
4023 for (i, arg) in args.iter().take(t).enumerate() {
4024 // Warn only for the first loop (the "no closures" one).
4025 // Closure arguments themselves can't be diverging, but
4026 // a previous argument can, e.g., `foo(panic!(), || {})`.
4027 if !check_closures {
4028 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4031 let is_closure = match arg.kind {
4032 ExprKind::Closure(..) => true,
4036 if is_closure != check_closures {
4040 debug!("checking the argument");
4041 let formal_ty = formal_tys[i];
4043 // The special-cased logic below has three functions:
4044 // 1. Provide as good of an expected type as possible.
4045 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4047 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4049 // 2. Coerce to the most detailed type that could be coerced
4050 // to, which is `expected_ty` if `rvalue_hint` returns an
4051 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4052 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4053 // We're processing function arguments so we definitely want to use
4054 // two-phase borrows.
4055 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4056 final_arg_types.push((i, checked_ty, coerce_ty));
4058 // 3. Relate the expected type and the formal one,
4059 // if the expected type was used for the coercion.
4060 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4064 // We also need to make sure we at least write the ty of the other
4065 // arguments which we skipped above.
4067 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4068 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4069 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4072 for arg in args.iter().skip(expected_arg_count) {
4073 let arg_ty = self.check_expr(&arg);
4075 // There are a few types which get autopromoted when passed via varargs
4076 // in C but we just error out instead and require explicit casts.
4077 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4079 ty::Float(ast::FloatTy::F32) => {
4080 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4082 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
4083 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4085 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
4086 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4089 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4090 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4091 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4099 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4100 vec![self.tcx.types.err; len]
4103 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4104 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4105 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4106 /// can be not easily comparable with predicate type (because of coercion). If the types match
4107 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4108 /// the corresponding argument's expression span instead of the `fn` call path span.
4109 fn point_at_arg_instead_of_call_if_possible(
4111 errors: &mut Vec<traits::FulfillmentError<'_>>,
4112 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4114 args: &'tcx [hir::Expr<'tcx>],
4116 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4117 // the `?` operator.
4118 if call_sp.desugaring_kind().is_some() {
4122 for error in errors {
4123 // Only if the cause is somewhere inside the expression we want try to point at arg.
4124 // Otherwise, it means that the cause is somewhere else and we should not change
4125 // anything because we can break the correct span.
4126 if !call_sp.contains(error.obligation.cause.span) {
4130 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4131 // Collect the argument position for all arguments that could have caused this
4132 // `FulfillmentError`.
4133 let mut referenced_in = final_arg_types
4135 .map(|(i, checked_ty, _)| (i, checked_ty))
4136 .chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty)))
4137 .flat_map(|(i, ty)| {
4138 let ty = self.resolve_vars_if_possible(ty);
4139 // We walk the argument type because the argument's type could have
4140 // been `Option<T>`, but the `FulfillmentError` references `T`.
4142 .filter(|&ty| ty == predicate.skip_binder().self_ty())
4145 .collect::<Vec<_>>();
4147 // Both checked and coerced types could have matched, thus we need to remove
4149 referenced_in.dedup();
4151 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4152 // We make sure that only *one* argument matches the obligation failure
4153 // and we assign the obligation's span to its expression's.
4154 error.obligation.cause.span = args[ref_in].span;
4155 error.points_at_arg_span = true;
4161 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4162 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4163 /// were caused by them. If they were, we point at the corresponding type argument's span
4164 /// instead of the `fn` call path span.
4165 fn point_at_type_arg_instead_of_call_if_possible(
4167 errors: &mut Vec<traits::FulfillmentError<'_>>,
4168 call_expr: &'tcx hir::Expr<'tcx>,
4170 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4171 if let hir::ExprKind::Path(qpath) = &path.kind {
4172 if let hir::QPath::Resolved(_, path) = &qpath {
4173 for error in errors {
4174 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4175 // If any of the type arguments in this path segment caused the
4176 // `FullfillmentError`, point at its span (#61860).
4180 .filter_map(|seg| seg.args.as_ref())
4181 .flat_map(|a| a.args.iter())
4183 if let hir::GenericArg::Type(hir_ty) = &arg {
4184 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4187 // Avoid ICE with associated types. As this is best
4188 // effort only, it's ok to ignore the case. It
4189 // would trigger in `is_send::<T::AssocType>();`
4190 // from `typeck-default-trait-impl-assoc-type.rs`.
4192 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4193 let ty = self.resolve_vars_if_possible(&ty);
4194 if ty == predicate.skip_binder().self_ty() {
4195 error.obligation.cause.span = hir_ty.span;
4207 // AST fragment checking
4208 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4212 ast::LitKind::Str(..) => tcx.mk_static_str(),
4213 ast::LitKind::ByteStr(ref v) => {
4214 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4216 ast::LitKind::Byte(_) => tcx.types.u8,
4217 ast::LitKind::Char(_) => tcx.types.char,
4218 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4219 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4220 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4221 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4222 ty::Int(_) | ty::Uint(_) => Some(ty),
4223 ty::Char => Some(tcx.types.u8),
4224 ty::RawPtr(..) => Some(tcx.types.usize),
4225 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4228 opt_ty.unwrap_or_else(|| self.next_int_var())
4230 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4231 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4232 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4233 ty::Float(_) => Some(ty),
4236 opt_ty.unwrap_or_else(|| self.next_float_var())
4238 ast::LitKind::Bool(_) => tcx.types.bool,
4239 ast::LitKind::Err(_) => tcx.types.err,
4243 // Determine the `Self` type, using fresh variables for all variables
4244 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
4245 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
4247 pub fn impl_self_ty(
4249 span: Span, // (potential) receiver for this impl
4251 ) -> TypeAndSubsts<'tcx> {
4252 let ity = self.tcx.type_of(did);
4253 debug!("impl_self_ty: ity={:?}", ity);
4255 let substs = self.fresh_substs_for_item(span, did);
4256 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
4258 TypeAndSubsts { substs: substs, ty: substd_ty }
4261 /// Unifies the output type with the expected type early, for more coercions
4262 /// and forward type information on the input expressions.
4263 fn expected_inputs_for_expected_output(
4266 expected_ret: Expectation<'tcx>,
4267 formal_ret: Ty<'tcx>,
4268 formal_args: &[Ty<'tcx>],
4269 ) -> Vec<Ty<'tcx>> {
4270 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4271 let ret_ty = match expected_ret.only_has_type(self) {
4273 None => return Vec::new(),
4275 let expect_args = self
4276 .fudge_inference_if_ok(|| {
4277 // Attempt to apply a subtyping relationship between the formal
4278 // return type (likely containing type variables if the function
4279 // is polymorphic) and the expected return type.
4280 // No argument expectations are produced if unification fails.
4281 let origin = self.misc(call_span);
4282 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4284 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4285 // to identity so the resulting type is not constrained.
4288 // Process any obligations locally as much as
4289 // we can. We don't care if some things turn
4290 // out unconstrained or ambiguous, as we're
4291 // just trying to get hints here.
4292 self.save_and_restore_in_snapshot_flag(|_| {
4293 let mut fulfill = TraitEngine::new(self.tcx);
4294 for obligation in ok.obligations {
4295 fulfill.register_predicate_obligation(self, obligation);
4297 fulfill.select_where_possible(self)
4301 Err(_) => return Err(()),
4304 // Record all the argument types, with the substitutions
4305 // produced from the above subtyping unification.
4306 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4308 .unwrap_or_default();
4310 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4311 formal_args, formal_ret, expect_args, expected_ret
4316 pub fn check_struct_path(
4320 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4321 let path_span = match *qpath {
4322 QPath::Resolved(_, ref path) => path.span,
4323 QPath::TypeRelative(ref qself, _) => qself.span,
4325 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4326 let variant = match def {
4328 self.set_tainted_by_errors();
4331 Res::Def(DefKind::Variant, _) => match ty.kind {
4332 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4333 _ => bug!("unexpected type: {:?}", ty),
4335 Res::Def(DefKind::Struct, _)
4336 | Res::Def(DefKind::Union, _)
4337 | Res::Def(DefKind::TyAlias, _)
4338 | Res::Def(DefKind::AssocTy, _)
4339 | Res::SelfTy(..) => match ty.kind {
4340 ty::Adt(adt, substs) if !adt.is_enum() => {
4341 Some((adt.non_enum_variant(), adt.did, substs))
4345 _ => bug!("unexpected definition: {:?}", def),
4348 if let Some((variant, did, substs)) = variant {
4349 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4350 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4352 // Check bounds on type arguments used in the path.
4353 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4355 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4356 self.add_obligations_for_parameters(cause, &bounds);
4364 "expected struct, variant or union type, found {}",
4365 ty.sort_string(self.tcx)
4367 .span_label(path_span, "not a struct")
4373 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4374 // The newly resolved definition is written into `type_dependent_defs`.
4375 fn finish_resolving_struct_path(
4380 ) -> (Res, Ty<'tcx>) {
4382 QPath::Resolved(ref maybe_qself, ref path) => {
4383 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4384 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4387 QPath::TypeRelative(ref qself, ref segment) => {
4388 let ty = self.to_ty(qself);
4390 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4396 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4397 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4398 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4400 // Write back the new resolution.
4401 self.write_resolution(hir_id, result);
4403 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4408 /// Resolves an associated value path into a base type and associated constant, or method
4409 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4410 pub fn resolve_ty_and_res_ufcs<'b>(
4412 qpath: &'b QPath<'b>,
4415 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4416 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4417 let (ty, qself, item_segment) = match *qpath {
4418 QPath::Resolved(ref opt_qself, ref path) => {
4421 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4425 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4427 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4428 // Return directly on cache hit. This is useful to avoid doubly reporting
4429 // errors with default match binding modes. See #44614.
4431 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4432 return (def, Some(ty), slice::from_ref(&**item_segment));
4434 let item_name = item_segment.ident;
4435 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4436 let result = match error {
4437 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4438 _ => Err(ErrorReported),
4440 if item_name.name != kw::Invalid {
4441 self.report_method_error(
4445 SelfSource::QPath(qself),
4449 .map(|mut e| e.emit());
4454 // Write back the new resolution.
4455 self.write_resolution(hir_id, result);
4457 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4459 slice::from_ref(&**item_segment),
4463 pub fn check_decl_initializer(
4465 local: &'tcx hir::Local<'tcx>,
4466 init: &'tcx hir::Expr<'tcx>,
4468 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4469 // for #42640 (default match binding modes).
4472 let ref_bindings = local.pat.contains_explicit_ref_binding();
4474 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4475 if let Some(m) = ref_bindings {
4476 // Somewhat subtle: if we have a `ref` binding in the pattern,
4477 // we want to avoid introducing coercions for the RHS. This is
4478 // both because it helps preserve sanity and, in the case of
4479 // ref mut, for soundness (issue #23116). In particular, in
4480 // the latter case, we need to be clear that the type of the
4481 // referent for the reference that results is *equal to* the
4482 // type of the place it is referencing, and not some
4483 // supertype thereof.
4484 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4485 self.demand_eqtype(init.span, local_ty, init_ty);
4488 self.check_expr_coercable_to_type(init, local_ty)
4492 /// Type check a `let` statement.
4493 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4494 // Determine and write the type which we'll check the pattern against.
4495 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4496 self.write_ty(local.hir_id, ty);
4498 // Type check the initializer.
4499 if let Some(ref init) = local.init {
4500 let init_ty = self.check_decl_initializer(local, &init);
4501 self.overwrite_local_ty_if_err(local, ty, init_ty);
4504 // Does the expected pattern type originate from an expression and what is the span?
4505 let (origin_expr, ty_span) = match (local.ty, local.init) {
4506 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4507 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4508 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4511 // Type check the pattern. Override if necessary to avoid knock-on errors.
4512 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4513 let pat_ty = self.node_ty(local.pat.hir_id);
4514 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4517 fn overwrite_local_ty_if_err(
4519 local: &'tcx hir::Local<'tcx>,
4523 if ty.references_error() {
4524 // Override the types everywhere with `types.err` to avoid knock on errors.
4525 self.write_ty(local.hir_id, ty);
4526 self.write_ty(local.pat.hir_id, ty);
4527 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4528 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4529 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4533 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4534 err.span_suggestion_short(
4535 span.shrink_to_hi(),
4536 "consider using a semicolon here",
4538 Applicability::MachineApplicable,
4542 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4543 // Don't do all the complex logic below for `DeclItem`.
4545 hir::StmtKind::Item(..) => return,
4546 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4549 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4551 // Hide the outer diverging and `has_errors` flags.
4552 let old_diverges = self.diverges.replace(Diverges::Maybe);
4553 let old_has_errors = self.has_errors.replace(false);
4556 hir::StmtKind::Local(ref l) => {
4557 self.check_decl_local(&l);
4560 hir::StmtKind::Item(_) => {}
4561 hir::StmtKind::Expr(ref expr) => {
4562 // Check with expected type of `()`.
4563 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4564 self.suggest_semicolon_at_end(expr.span, err);
4567 hir::StmtKind::Semi(ref expr) => {
4568 self.check_expr(&expr);
4572 // Combine the diverging and `has_error` flags.
4573 self.diverges.set(self.diverges.get() | old_diverges);
4574 self.has_errors.set(self.has_errors.get() | old_has_errors);
4577 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4578 let unit = self.tcx.mk_unit();
4579 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4581 // if the block produces a `!` value, that can always be
4582 // (effectively) coerced to unit.
4584 self.demand_suptype(blk.span, unit, ty);
4588 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4589 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4590 /// when given code like the following:
4592 /// if false { return 0i32; } else { 1u32 }
4593 /// // ^^^^ point at this instead of the whole `if` expression
4595 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4596 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4597 let arm_spans: Vec<Span> = arms
4600 self.in_progress_tables
4601 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4602 .and_then(|arm_ty| {
4603 if arm_ty.is_never() {
4606 Some(match &arm.body.kind {
4607 // Point at the tail expression when possible.
4608 hir::ExprKind::Block(block, _) => {
4609 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4617 if arm_spans.len() == 1 {
4618 return arm_spans[0];
4624 fn check_block_with_expected(
4626 blk: &'tcx hir::Block<'tcx>,
4627 expected: Expectation<'tcx>,
4630 let mut fcx_ps = self.ps.borrow_mut();
4631 let unsafety_state = fcx_ps.recurse(blk);
4632 replace(&mut *fcx_ps, unsafety_state)
4635 // In some cases, blocks have just one exit, but other blocks
4636 // can be targeted by multiple breaks. This can happen both
4637 // with labeled blocks as well as when we desugar
4638 // a `try { ... }` expression.
4642 // 'a: { if true { break 'a Err(()); } Ok(()) }
4644 // Here we would wind up with two coercions, one from
4645 // `Err(())` and the other from the tail expression
4646 // `Ok(())`. If the tail expression is omitted, that's a
4647 // "forced unit" -- unless the block diverges, in which
4648 // case we can ignore the tail expression (e.g., `'a: {
4649 // break 'a 22; }` would not force the type of the block
4651 let tail_expr = blk.expr.as_ref();
4652 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4653 let coerce = if blk.targeted_by_break {
4654 CoerceMany::new(coerce_to_ty)
4656 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4657 Some(e) => slice::from_ref(e),
4660 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4663 let prev_diverges = self.diverges.get();
4664 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4666 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4667 for s in blk.stmts {
4671 // check the tail expression **without** holding the
4672 // `enclosing_breakables` lock below.
4673 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4675 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4676 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4677 let coerce = ctxt.coerce.as_mut().unwrap();
4678 if let Some(tail_expr_ty) = tail_expr_ty {
4679 let tail_expr = tail_expr.unwrap();
4680 let span = self.get_expr_coercion_span(tail_expr);
4681 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4682 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4684 // Subtle: if there is no explicit tail expression,
4685 // that is typically equivalent to a tail expression
4686 // of `()` -- except if the block diverges. In that
4687 // case, there is no value supplied from the tail
4688 // expression (assuming there are no other breaks,
4689 // this implies that the type of the block will be
4692 // #41425 -- label the implicit `()` as being the
4693 // "found type" here, rather than the "expected type".
4694 if !self.diverges.get().is_always() {
4695 // #50009 -- Do not point at the entire fn block span, point at the return type
4696 // span, as it is the cause of the requirement, and
4697 // `consider_hint_about_removing_semicolon` will point at the last expression
4698 // if it were a relevant part of the error. This improves usability in editors
4699 // that highlight errors inline.
4700 let mut sp = blk.span;
4701 let mut fn_span = None;
4702 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4703 let ret_sp = decl.output.span();
4704 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4705 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4706 // output would otherwise be incorrect and even misleading. Make sure
4707 // the span we're aiming at correspond to a `fn` body.
4708 if block_sp == blk.span {
4710 fn_span = Some(ident.span);
4714 coerce.coerce_forced_unit(
4718 if let Some(expected_ty) = expected.only_has_type(self) {
4719 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4721 if let Some(fn_span) = fn_span {
4724 "implicitly returns `()` as its body has no tail or `return` \
4736 // If we can break from the block, then the block's exit is always reachable
4737 // (... as long as the entry is reachable) - regardless of the tail of the block.
4738 self.diverges.set(prev_diverges);
4741 let mut ty = ctxt.coerce.unwrap().complete(self);
4743 if self.has_errors.get() || ty.references_error() {
4744 ty = self.tcx.types.err
4747 self.write_ty(blk.hir_id, ty);
4749 *self.ps.borrow_mut() = prev;
4753 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4754 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4756 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4757 | Node::ImplItem(&hir::ImplItem {
4758 kind: hir::ImplItemKind::Method(_, body_id), ..
4760 let body = self.tcx.hir().body(body_id);
4761 if let ExprKind::Block(block, _) = &body.value.kind {
4762 return Some(block.span);
4770 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4771 fn get_parent_fn_decl(
4774 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
4775 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4776 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4779 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4780 fn get_node_fn_decl(
4783 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
4785 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4786 // This is less than ideal, it will not suggest a return type span on any
4787 // method called `main`, regardless of whether it is actually the entry point,
4788 // but it will still present it as the reason for the expected type.
4789 Some((&sig.decl, ident, ident.name != sym::main))
4791 Node::TraitItem(&hir::TraitItem {
4793 kind: hir::TraitItemKind::Method(ref sig, ..),
4795 }) => Some((&sig.decl, ident, true)),
4796 Node::ImplItem(&hir::ImplItem {
4798 kind: hir::ImplItemKind::Method(ref sig, ..),
4800 }) => Some((&sig.decl, ident, false)),
4805 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4806 /// suggestion can be made, `None` otherwise.
4807 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4808 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4809 // `while` before reaching it, as block tail returns are not available in them.
4810 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4811 let parent = self.tcx.hir().get(blk_id);
4812 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4816 /// On implicit return expressions with mismatched types, provides the following suggestions:
4818 /// - Points out the method's return type as the reason for the expected type.
4819 /// - Possible missing semicolon.
4820 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4821 pub fn suggest_mismatched_types_on_tail(
4823 err: &mut DiagnosticBuilder<'_>,
4824 expr: &'tcx hir::Expr<'tcx>,
4830 let expr = expr.peel_drop_temps();
4831 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4832 let mut pointing_at_return_type = false;
4833 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4834 pointing_at_return_type =
4835 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4837 pointing_at_return_type
4840 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4841 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4843 /// fn foo(x: usize) -> usize { x }
4844 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4848 err: &mut DiagnosticBuilder<'_>,
4849 expr: &hir::Expr<'_>,
4853 let hir = self.tcx.hir();
4854 let (def_id, sig) = match found.kind {
4855 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4856 ty::Closure(def_id, substs) => {
4857 // We don't use `closure_sig` to account for malformed closures like
4858 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4859 let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4862 match closure_sig_ty.kind {
4863 ty::FnPtr(sig) => sig,
4871 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4872 let sig = self.normalize_associated_types_in(expr.span, &sig);
4873 if self.can_coerce(sig.output(), expected) {
4874 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4875 (String::new(), Applicability::MachineApplicable)
4877 ("...".to_string(), Applicability::HasPlaceholders)
4879 let mut msg = "call this function";
4880 match hir.get_if_local(def_id) {
4881 Some(Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. }))
4882 | Some(Node::ImplItem(hir::ImplItem {
4883 kind: hir::ImplItemKind::Method(_, body_id),
4886 | Some(Node::TraitItem(hir::TraitItem {
4887 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4890 let body = hir.body(*body_id);
4894 .map(|param| match ¶m.pat.kind {
4895 hir::PatKind::Binding(_, _, ident, None)
4896 if ident.name != kw::SelfLower =>
4900 _ => "_".to_string(),
4902 .collect::<Vec<_>>()
4905 Some(Node::Expr(hir::Expr {
4906 kind: ExprKind::Closure(_, _, body_id, _, _),
4907 span: full_closure_span,
4910 if *full_closure_span == expr.span {
4913 msg = "call this closure";
4914 let body = hir.body(*body_id);
4918 .map(|param| match ¶m.pat.kind {
4919 hir::PatKind::Binding(_, _, ident, None)
4920 if ident.name != kw::SelfLower =>
4924 _ => "_".to_string(),
4926 .collect::<Vec<_>>()
4929 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4930 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4931 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4932 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4933 msg = "instantiate this tuple variant";
4935 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4936 msg = "instantiate this tuple struct";
4941 Some(Node::ForeignItem(hir::ForeignItem {
4942 kind: hir::ForeignItemKind::Fn(_, idents, _),
4948 if ident.name != kw::SelfLower {
4954 .collect::<Vec<_>>()
4957 Some(Node::TraitItem(hir::TraitItem {
4958 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4964 if ident.name != kw::SelfLower {
4970 .collect::<Vec<_>>()
4975 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4976 err.span_suggestion(
4978 &format!("use parentheses to {}", msg),
4979 format!("{}({})", code, sugg_call),
4988 pub fn suggest_ref_or_into(
4990 err: &mut DiagnosticBuilder<'_>,
4991 expr: &hir::Expr<'_>,
4995 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4996 err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable);
4997 } else if let (ty::FnDef(def_id, ..), true) =
4998 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5000 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5001 let sp = self.sess().source_map().def_span(sp);
5002 err.span_label(sp, &format!("{} defined here", found));
5004 } else if !self.check_for_cast(err, expr, found, expected) {
5005 let is_struct_pat_shorthand_field =
5006 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5007 let methods = self.get_conversion_methods(expr.span, expected, found);
5008 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5009 let mut suggestions = iter::repeat(&expr_text)
5010 .zip(methods.iter())
5011 .filter_map(|(receiver, method)| {
5012 let method_call = format!(".{}()", method.ident);
5013 if receiver.ends_with(&method_call) {
5014 None // do not suggest code that is already there (#53348)
5016 let method_call_list = [".to_vec()", ".to_string()"];
5017 let sugg = if receiver.ends_with(".clone()")
5018 && method_call_list.contains(&method_call.as_str())
5020 let max_len = receiver.rfind(".").unwrap();
5021 format!("{}{}", &receiver[..max_len], method_call)
5023 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5024 format!("({}){}", receiver, method_call)
5026 format!("{}{}", receiver, method_call)
5029 Some(if is_struct_pat_shorthand_field {
5030 format!("{}: {}", receiver, sugg)
5037 if suggestions.peek().is_some() {
5038 err.span_suggestions(
5040 "try using a conversion method",
5042 Applicability::MaybeIncorrect,
5049 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5050 /// in the heap by calling `Box::new()`.
5051 fn suggest_boxing_when_appropriate(
5053 err: &mut DiagnosticBuilder<'_>,
5054 expr: &hir::Expr<'_>,
5058 if self.tcx.hir().is_const_context(expr.hir_id) {
5059 // Do not suggest `Box::new` in const context.
5062 if !expected.is_box() || found.is_box() {
5065 let boxed_found = self.tcx.mk_box(found);
5066 if let (true, Ok(snippet)) = (
5067 self.can_coerce(boxed_found, expected),
5068 self.sess().source_map().span_to_snippet(expr.span),
5070 err.span_suggestion(
5072 "store this in the heap by calling `Box::new`",
5073 format!("Box::new({})", snippet),
5074 Applicability::MachineApplicable,
5077 "for more on the distinction between the stack and the heap, read \
5078 https://doc.rust-lang.org/book/ch15-01-box.html, \
5079 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5080 https://doc.rust-lang.org/std/boxed/index.html",
5085 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5086 fn suggest_calling_boxed_future_when_appropriate(
5088 err: &mut DiagnosticBuilder<'_>,
5089 expr: &hir::Expr<'_>,
5095 if self.tcx.hir().is_const_context(expr.hir_id) {
5096 // Do not suggest `Box::new` in const context.
5099 let pin_did = self.tcx.lang_items().pin_type();
5100 match expected.kind {
5101 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5102 // This guards the `unwrap` and `mk_box` below.
5103 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5106 let boxed_found = self.tcx.mk_box(found);
5107 let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap();
5108 if let (true, Ok(snippet)) = (
5109 self.can_coerce(new_found, expected),
5110 self.sess().source_map().span_to_snippet(expr.span),
5113 ty::Adt(def, _) if def.is_box() => {
5114 err.help("use `Box::pin`");
5117 err.span_suggestion(
5119 "you need to pin and box this expression",
5120 format!("Box::pin({})", snippet),
5121 Applicability::MachineApplicable,
5131 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5135 /// bar_that_returns_u32()
5139 /// This routine checks if the return expression in a block would make sense on its own as a
5140 /// statement and the return type has been left as default or has been specified as `()`. If so,
5141 /// it suggests adding a semicolon.
5142 fn suggest_missing_semicolon(
5144 err: &mut DiagnosticBuilder<'_>,
5145 expression: &'tcx hir::Expr<'tcx>,
5149 if expected.is_unit() {
5150 // `BlockTailExpression` only relevant if the tail expr would be
5151 // useful on its own.
5152 match expression.kind {
5154 | ExprKind::MethodCall(..)
5155 | ExprKind::Loop(..)
5156 | ExprKind::Match(..)
5157 | ExprKind::Block(..) => {
5158 err.span_suggestion(
5159 cause_span.shrink_to_hi(),
5160 "try adding a semicolon",
5162 Applicability::MachineApplicable,
5170 /// A possible error is to forget to add a return type that is needed:
5174 /// bar_that_returns_u32()
5178 /// This routine checks if the return type is left as default, the method is not part of an
5179 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5181 fn suggest_missing_return_type(
5183 err: &mut DiagnosticBuilder<'_>,
5184 fn_decl: &hir::FnDecl<'_>,
5189 // Only suggest changing the return type for methods that
5190 // haven't set a return type at all (and aren't `fn main()` or an impl).
5191 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5192 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5193 err.span_suggestion(
5195 "try adding a return type",
5196 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5197 Applicability::MachineApplicable,
5201 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5202 err.span_label(span, "possibly return type missing here?");
5205 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5206 // `fn main()` must return `()`, do not suggest changing return type
5207 err.span_label(span, "expected `()` because of default return type");
5210 // expectation was caused by something else, not the default return
5211 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5212 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5213 // Only point to return type if the expected type is the return type, as if they
5214 // are not, the expectation must have been caused by something else.
5215 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5217 let ty = AstConv::ast_ty_to_ty(self, ty);
5218 debug!("suggest_missing_return_type: return type {:?}", ty);
5219 debug!("suggest_missing_return_type: expected type {:?}", ty);
5220 if ty.kind == expected.kind {
5221 err.span_label(sp, format!("expected `{}` because of return type", expected));
5229 /// A possible error is to forget to add `.await` when using futures:
5232 /// async fn make_u32() -> u32 {
5236 /// fn take_u32(x: u32) {}
5238 /// async fn foo() {
5239 /// let x = make_u32();
5244 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5245 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5246 /// `.await` to the tail of the expression.
5247 fn suggest_missing_await(
5249 err: &mut DiagnosticBuilder<'_>,
5250 expr: &hir::Expr<'_>,
5254 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5255 // body isn't `async`.
5256 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5257 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5258 let body = self.tcx().hir().body(body_id);
5259 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5261 // Check for `Future` implementations by constructing a predicate to
5262 // prove: `<T as Future>::Output == U`
5263 let future_trait = self.tcx.lang_items().future_trait().unwrap();
5264 let item_def_id = self
5266 .associated_items(future_trait)
5267 .in_definition_order()
5272 ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5273 // `<T as Future>::Output`
5274 projection_ty: ty::ProjectionTy {
5276 substs: self.tcx.mk_substs_trait(
5278 self.fresh_substs_for_item(sp, item_def_id),
5285 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5286 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5287 if self.infcx.predicate_may_hold(&obligation) {
5288 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5289 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5290 err.span_suggestion(
5292 "consider using `.await` here",
5293 format!("{}.await", code),
5294 Applicability::MaybeIncorrect,
5297 debug!("suggest_missing_await: no snippet for {:?}", sp);
5300 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5306 /// A common error is to add an extra semicolon:
5309 /// fn foo() -> usize {
5314 /// This routine checks if the final statement in a block is an
5315 /// expression with an explicit semicolon whose type is compatible
5316 /// with `expected_ty`. If so, it suggests removing the semicolon.
5317 fn consider_hint_about_removing_semicolon(
5319 blk: &'tcx hir::Block<'tcx>,
5320 expected_ty: Ty<'tcx>,
5321 err: &mut DiagnosticBuilder<'_>,
5323 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5324 err.span_suggestion(
5326 "consider removing this semicolon",
5328 Applicability::MachineApplicable,
5333 fn could_remove_semicolon(
5335 blk: &'tcx hir::Block<'tcx>,
5336 expected_ty: Ty<'tcx>,
5338 // Be helpful when the user wrote `{... expr;}` and
5339 // taking the `;` off is enough to fix the error.
5340 let last_stmt = blk.stmts.last()?;
5341 let last_expr = match last_stmt.kind {
5342 hir::StmtKind::Semi(ref e) => e,
5345 let last_expr_ty = self.node_ty(last_expr.hir_id);
5346 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5349 let original_span = original_sp(last_stmt.span, blk.span);
5350 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5353 // Instantiates the given path, which must refer to an item with the given
5354 // number of type parameters and type.
5355 pub fn instantiate_value_path(
5357 segments: &[hir::PathSegment<'_>],
5358 self_ty: Option<Ty<'tcx>>,
5362 ) -> (Ty<'tcx>, Res) {
5364 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5365 segments, self_ty, res, hir_id,
5370 let path_segs = match res {
5371 Res::Local(_) | Res::SelfCtor(_) => vec![],
5372 Res::Def(kind, def_id) => {
5373 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5375 _ => bug!("instantiate_value_path on {:?}", res),
5378 let mut user_self_ty = None;
5379 let mut is_alias_variant_ctor = false;
5381 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5382 if let Some(self_ty) = self_ty {
5383 let adt_def = self_ty.ty_adt_def().unwrap();
5384 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5385 is_alias_variant_ctor = true;
5388 Res::Def(DefKind::Method, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
5389 let container = tcx.associated_item(def_id).container;
5390 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5392 ty::TraitContainer(trait_did) => {
5393 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5395 ty::ImplContainer(impl_def_id) => {
5396 if segments.len() == 1 {
5397 // `<T>::assoc` will end up here, and so
5398 // can `T::assoc`. It this came from an
5399 // inherent impl, we need to record the
5400 // `T` for posterity (see `UserSelfTy` for
5402 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5403 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5411 // Now that we have categorized what space the parameters for each
5412 // segment belong to, let's sort out the parameters that the user
5413 // provided (if any) into their appropriate spaces. We'll also report
5414 // errors if type parameters are provided in an inappropriate place.
5416 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5417 let generics_has_err = AstConv::prohibit_generics(
5419 segments.iter().enumerate().filter_map(|(index, seg)| {
5420 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5428 if let Res::Local(hid) = res {
5429 let ty = self.local_ty(span, hid).decl_ty;
5430 let ty = self.normalize_associated_types_in(span, &ty);
5431 self.write_ty(hir_id, ty);
5435 if generics_has_err {
5436 // Don't try to infer type parameters when prohibited generic arguments were given.
5437 user_self_ty = None;
5440 // Now we have to compare the types that the user *actually*
5441 // provided against the types that were *expected*. If the user
5442 // did not provide any types, then we want to substitute inference
5443 // variables. If the user provided some types, we may still need
5444 // to add defaults. If the user provided *too many* types, that's
5447 let mut infer_args_for_err = FxHashSet::default();
5448 for &PathSeg(def_id, index) in &path_segs {
5449 let seg = &segments[index];
5450 let generics = tcx.generics_of(def_id);
5451 // Argument-position `impl Trait` is treated as a normal generic
5452 // parameter internally, but we don't allow users to specify the
5453 // parameter's value explicitly, so we have to do some error-
5455 let suppress_errors = AstConv::check_generic_arg_count_for_call(
5456 tcx, span, &generics, &seg, false, // `is_method_call`
5459 if suppress_errors {
5460 infer_args_for_err.insert(index);
5461 self.set_tainted_by_errors(); // See issue #53251.
5465 let has_self = path_segs
5467 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5470 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5471 let ty = self.impl_self_ty(span, impl_def_id).ty;
5472 let adt_def = ty.ty_adt_def();
5475 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5476 let variant = adt_def.non_enum_variant();
5477 let ctor_def_id = variant.ctor_def_id.unwrap();
5479 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5484 let mut err = tcx.sess.struct_span_err(
5486 "the `Self` constructor can only be used with tuple or unit structs",
5488 if let Some(adt_def) = adt_def {
5489 match adt_def.adt_kind() {
5491 err.help("did you mean to use one of the enum's variants?");
5493 AdtKind::Struct | AdtKind::Union => {
5494 err.span_suggestion(
5496 "use curly brackets",
5497 String::from("Self { /* fields */ }"),
5498 Applicability::HasPlaceholders,
5505 return (tcx.types.err, res);
5511 let def_id = res.def_id();
5513 // The things we are substituting into the type should not contain
5514 // escaping late-bound regions, and nor should the base type scheme.
5515 let ty = tcx.type_of(def_id);
5517 let substs = self_ctor_substs.unwrap_or_else(|| {
5518 AstConv::create_substs_for_generic_args(
5524 if infer_args_for_err.is_empty() { Ok(()) } else { Err(GenericArgCountMismatch) },
5525 // Provide the generic args, and whether types should be inferred.
5527 if let Some(&PathSeg(_, index)) =
5528 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5530 // If we've encountered an `impl Trait`-related error, we're just
5531 // going to infer the arguments for better error messages.
5532 if !infer_args_for_err.contains(&index) {
5533 // Check whether the user has provided generic arguments.
5534 if let Some(ref data) = segments[index].args {
5535 return (Some(data), segments[index].infer_args);
5538 return (None, segments[index].infer_args);
5543 // Provide substitutions for parameters for which (valid) arguments have been provided.
5544 |param, arg| match (¶m.kind, arg) {
5545 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5546 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5548 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5549 self.to_ty(ty).into()
5551 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5552 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
5554 _ => unreachable!(),
5556 // Provide substitutions for parameters for which arguments are inferred.
5557 |substs, param, infer_args| {
5559 GenericParamDefKind::Lifetime => {
5560 self.re_infer(Some(param), span).unwrap().into()
5562 GenericParamDefKind::Type { has_default, .. } => {
5563 if !infer_args && has_default {
5564 // If we have a default, then we it doesn't matter that we're not
5565 // inferring the type arguments: we provide the default where any
5567 let default = tcx.type_of(param.def_id);
5570 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5574 // If no type arguments were provided, we have to infer them.
5575 // This case also occurs as a result of some malformed input, e.g.
5576 // a lifetime argument being given instead of a type parameter.
5577 // Using inference instead of `Error` gives better error messages.
5578 self.var_for_def(span, param)
5581 GenericParamDefKind::Const => {
5582 // FIXME(const_generics:defaults)
5583 // No const parameters were provided, we have to infer them.
5584 self.var_for_def(span, param)
5590 assert!(!substs.has_escaping_bound_vars());
5591 assert!(!ty.has_escaping_bound_vars());
5593 // First, store the "user substs" for later.
5594 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5596 self.add_required_obligations(span, def_id, &substs);
5598 // Substitute the values for the type parameters into the type of
5599 // the referenced item.
5600 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5602 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5603 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5604 // is inherent, there is no `Self` parameter; instead, the impl needs
5605 // type parameters, which we can infer by unifying the provided `Self`
5606 // with the substituted impl type.
5607 // This also occurs for an enum variant on a type alias.
5608 let ty = tcx.type_of(impl_def_id);
5610 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5611 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5612 Ok(ok) => self.register_infer_ok_obligations(ok),
5614 self.tcx.sess.delay_span_bug(span, &format!(
5615 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5623 self.check_rustc_args_require_const(def_id, hir_id, span);
5625 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5626 self.write_substs(hir_id, substs);
5628 (ty_substituted, res)
5631 /// Add all the obligations that are required, substituting and normalized appropriately.
5632 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5633 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5635 for (i, mut obligation) in traits::predicates_for_generics(
5636 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5643 // This makes the error point at the bound, but we want to point at the argument
5644 if let Some(span) = spans.get(i) {
5645 obligation.cause.code = traits::BindingObligation(def_id, *span);
5647 self.register_predicate(obligation);
5651 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5652 // We're only interested in functions tagged with
5653 // #[rustc_args_required_const], so ignore anything that's not.
5654 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5658 // If our calling expression is indeed the function itself, we're good!
5659 // If not, generate an error that this can only be called directly.
5660 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5661 if let ExprKind::Call(ref callee, ..) = expr.kind {
5662 if callee.hir_id == hir_id {
5668 self.tcx.sess.span_err(
5670 "this function can only be invoked directly, not through a function pointer",
5674 /// Resolves `typ` by a single level if `typ` is a type variable.
5675 /// If no resolution is possible, then an error is reported.
5676 /// Numeric inference variables may be left unresolved.
5677 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5678 let ty = self.resolve_vars_with_obligations(ty);
5679 if !ty.is_ty_var() {
5682 if !self.is_tainted_by_errors() {
5683 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5684 .note("type must be known at this point")
5687 self.demand_suptype(sp, self.tcx.types.err, ty);
5692 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5695 ctxt: BreakableCtxt<'tcx>,
5697 ) -> (BreakableCtxt<'tcx>, R) {
5700 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5701 index = enclosing_breakables.stack.len();
5702 enclosing_breakables.by_id.insert(id, index);
5703 enclosing_breakables.stack.push(ctxt);
5707 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5708 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5709 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5710 enclosing_breakables.stack.pop().expect("missing breakable context")
5715 /// Instantiate a QueryResponse in a probe context, without a
5716 /// good ObligationCause.
5717 fn probe_instantiate_query_response(
5720 original_values: &OriginalQueryValues<'tcx>,
5721 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5722 ) -> InferResult<'tcx, Ty<'tcx>> {
5723 self.instantiate_query_response_and_region_obligations(
5724 &traits::ObligationCause::misc(span, self.body_id),
5731 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5732 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5733 let mut contained_in_place = false;
5735 while let hir::Node::Expr(parent_expr) =
5736 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5738 match &parent_expr.kind {
5739 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5740 if lhs.hir_id == expr_id {
5741 contained_in_place = true;
5747 expr_id = parent_expr.hir_id;
5754 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5755 let own_counts = generics.own_counts();
5757 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5758 own_counts.types, own_counts.consts, ty
5761 if own_counts.types == 0 {
5765 // Make a vector of booleans initially `false`; set to `true` when used.
5766 let mut types_used = vec![false; own_counts.types];
5768 for leaf_ty in ty.walk() {
5769 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.kind {
5770 debug!("found use of ty param num {}", index);
5771 types_used[index as usize - own_counts.lifetimes] = true;
5772 } else if let ty::Error = leaf_ty.kind {
5773 // If there is already another error, do not emit
5774 // an error for not using a type parameter.
5775 assert!(tcx.sess.has_errors());
5780 let types = generics.params.iter().filter(|param| match param.kind {
5781 ty::GenericParamDefKind::Type { .. } => true,
5784 for (&used, param) in types_used.iter().zip(types) {
5786 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5787 let span = tcx.hir().span(id);
5788 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5789 .span_label(span, "unused type parameter")
5795 fn fatally_break_rust(sess: &Session) {
5796 let handler = sess.diagnostic();
5797 handler.span_bug_no_panic(
5799 "It looks like you're trying to break rust; would you like some ICE?",
5801 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5802 handler.note_without_error(
5803 "we would appreciate a joke overview: \
5804 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5806 handler.note_without_error(&format!(
5807 "rustc {} running on {}",
5808 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5809 crate::session::config::host_triple(),
5813 fn potentially_plural_count(count: usize, word: &str) -> String {
5814 format!("{} {}{}", count, word, pluralize!(count))