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;
91 AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
94 use rustc_ast::util::parser::ExprPrecedence;
95 use rustc_attr as attr;
96 use rustc_data_structures::captures::Captures;
97 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
98 use rustc_errors::ErrorReported;
99 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
100 use rustc_hir as hir;
101 use rustc_hir::def::{CtorOf, DefKind, Res};
102 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
103 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
104 use rustc_hir::itemlikevisit::ItemLikeVisitor;
105 use rustc_hir::lang_items::{
106 FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem,
108 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
109 use rustc_index::bit_set::BitSet;
110 use rustc_index::vec::Idx;
111 use rustc_infer::infer;
112 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
113 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
114 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
115 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
116 use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
117 use rustc_middle::hir::map::blocks::FnLikeNode;
118 use rustc_middle::mir::interpret::ConstValue;
119 use rustc_middle::ty::adjustment::{
120 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
122 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
123 use rustc_middle::ty::query::Providers;
124 use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
125 use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts};
126 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
127 use rustc_middle::ty::{
128 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
129 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
131 use rustc_session::config::{self, EntryFnType};
132 use rustc_session::lint;
133 use rustc_session::parse::feature_err;
134 use rustc_session::Session;
135 use rustc_span::hygiene::DesugaringKind;
136 use rustc_span::source_map::{original_sp, DUMMY_SP};
137 use rustc_span::symbol::{kw, sym, Ident};
138 use rustc_span::{self, BytePos, MultiSpan, Span};
139 use rustc_target::abi::VariantIdx;
140 use rustc_target::spec::abi::Abi;
141 use rustc_trait_selection::infer::InferCtxtExt as _;
142 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
143 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
144 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
145 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
146 use rustc_trait_selection::traits::{
147 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
150 use std::cell::{Cell, Ref, RefCell, RefMut};
152 use std::collections::hash_map::Entry;
154 use std::mem::replace;
155 use std::ops::{self, Deref};
158 use crate::require_c_abi_if_c_variadic;
159 use crate::util::common::indenter;
161 use self::autoderef::Autoderef;
162 use self::callee::DeferredCallResolution;
163 use self::coercion::{CoerceMany, DynamicCoerceMany};
164 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
165 use self::method::{MethodCallee, SelfSource};
166 pub use self::Expectation::*;
167 use self::TupleArgumentsFlag::*;
170 macro_rules! type_error_struct {
171 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
172 if $typ.references_error() {
173 $session.diagnostic().struct_dummy()
175 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
180 /// The type of a local binding, including the revealed type for anon types.
181 #[derive(Copy, Clone, Debug)]
182 pub struct LocalTy<'tcx> {
184 revealed_ty: Ty<'tcx>,
187 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
188 #[derive(Copy, Clone)]
189 struct MaybeInProgressTables<'a, 'tcx> {
190 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
193 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
194 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
195 match self.maybe_tables {
196 Some(tables) => tables.borrow(),
197 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
201 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
202 match self.maybe_tables {
203 Some(tables) => tables.borrow_mut(),
204 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
209 /// Closures defined within the function. For example:
212 /// bar(move|| { ... })
215 /// Here, the function `foo()` and the closure passed to
216 /// `bar()` will each have their own `FnCtxt`, but they will
217 /// share the inherited fields.
218 pub struct Inherited<'a, 'tcx> {
219 infcx: InferCtxt<'a, 'tcx>,
221 tables: MaybeInProgressTables<'a, 'tcx>,
223 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
225 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
227 // Some additional `Sized` obligations badly affect type inference.
228 // These obligations are added in a later stage of typeck.
229 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
231 // When we process a call like `c()` where `c` is a closure type,
232 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
233 // `FnOnce` closure. In that case, we defer full resolution of the
234 // call until upvar inference can kick in and make the
235 // decision. We keep these deferred resolutions grouped by the
236 // def-id of the closure, so that once we decide, we can easily go
237 // back and process them.
238 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
240 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
242 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
244 // Opaque types found in explicit return types and their
245 // associated fresh inference variable. Writeback resolves these
246 // variables to get the concrete type, which can be used to
247 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
248 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
250 /// A map from inference variables created from opaque
251 /// type instantiations (`ty::Infer`) to the actual opaque
252 /// type (`ty::Opaque`). Used during fallback to map unconstrained
253 /// opaque type inference variables to their corresponding
255 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
257 /// Each type parameter has an implicit region bound that
258 /// indicates it must outlive at least the function body (the user
259 /// may specify stronger requirements). This field indicates the
260 /// region of the callee. If it is `None`, then the parameter
261 /// environment is for an item or something where the "callee" is
263 implicit_region_bound: Option<ty::Region<'tcx>>,
265 body_id: Option<hir::BodyId>,
268 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
269 type Target = InferCtxt<'a, 'tcx>;
270 fn deref(&self) -> &Self::Target {
275 /// When type-checking an expression, we propagate downward
276 /// whatever type hint we are able in the form of an `Expectation`.
277 #[derive(Copy, Clone, Debug)]
278 pub enum Expectation<'tcx> {
279 /// We know nothing about what type this expression should have.
282 /// This expression should have the type given (or some subtype).
283 ExpectHasType(Ty<'tcx>),
285 /// This expression will be cast to the `Ty`.
286 ExpectCastableToType(Ty<'tcx>),
288 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
289 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
290 ExpectRvalueLikeUnsized(Ty<'tcx>),
293 impl<'a, 'tcx> Expectation<'tcx> {
294 // Disregard "castable to" expectations because they
295 // can lead us astray. Consider for example `if cond
296 // {22} else {c} as u8` -- if we propagate the
297 // "castable to u8" constraint to 22, it will pick the
298 // type 22u8, which is overly constrained (c might not
299 // be a u8). In effect, the problem is that the
300 // "castable to" expectation is not the tightest thing
301 // we can say, so we want to drop it in this case.
302 // The tightest thing we can say is "must unify with
303 // else branch". Note that in the case of a "has type"
304 // constraint, this limitation does not hold.
306 // If the expected type is just a type variable, then don't use
307 // an expected type. Otherwise, we might write parts of the type
308 // when checking the 'then' block which are incompatible with the
310 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
312 ExpectHasType(ety) => {
313 let ety = fcx.shallow_resolve(ety);
314 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
316 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
321 /// Provides an expectation for an rvalue expression given an *optional*
322 /// hint, which is not required for type safety (the resulting type might
323 /// be checked higher up, as is the case with `&expr` and `box expr`), but
324 /// is useful in determining the concrete type.
326 /// The primary use case is where the expected type is a fat pointer,
327 /// like `&[isize]`. For example, consider the following statement:
329 /// let x: &[isize] = &[1, 2, 3];
331 /// In this case, the expected type for the `&[1, 2, 3]` expression is
332 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
333 /// expectation `ExpectHasType([isize])`, that would be too strong --
334 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
335 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
336 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
337 /// which still is useful, because it informs integer literals and the like.
338 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
339 /// for examples of where this comes up,.
340 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
341 match fcx.tcx.struct_tail_without_normalization(ty).kind {
342 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
343 _ => ExpectHasType(ty),
347 // Resolves `expected` by a single level if it is a variable. If
348 // there is no expected type or resolution is not possible (e.g.,
349 // no constraints yet present), just returns `None`.
350 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
352 NoExpectation => NoExpectation,
353 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
354 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
355 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
359 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
360 match self.resolve(fcx) {
361 NoExpectation => None,
362 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
366 /// It sometimes happens that we want to turn an expectation into
367 /// a **hard constraint** (i.e., something that must be satisfied
368 /// for the program to type-check). `only_has_type` will return
369 /// such a constraint, if it exists.
370 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
371 match self.resolve(fcx) {
372 ExpectHasType(ty) => Some(ty),
373 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
377 /// Like `only_has_type`, but instead of returning `None` if no
378 /// hard constraint exists, creates a fresh type variable.
379 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
380 self.only_has_type(fcx).unwrap_or_else(|| {
381 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
386 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
393 fn maybe_mut_place(m: hir::Mutability) -> Self {
395 hir::Mutability::Mut => Needs::MutPlace,
396 hir::Mutability::Not => Needs::None,
401 #[derive(Copy, Clone)]
402 pub struct UnsafetyState {
404 pub unsafety: hir::Unsafety,
405 pub unsafe_push_count: u32,
410 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
411 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
414 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
415 use hir::BlockCheckMode;
416 match self.unsafety {
417 // If this unsafe, then if the outer function was already marked as
418 // unsafe we shouldn't attribute the unsafe'ness to the block. This
419 // way the block can be warned about instead of ignoring this
420 // extraneous block (functions are never warned about).
421 hir::Unsafety::Unsafe if self.from_fn => *self,
424 let (unsafety, def, count) = match blk.rules {
425 BlockCheckMode::PushUnsafeBlock(..) => {
426 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
428 BlockCheckMode::PopUnsafeBlock(..) => {
429 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
431 BlockCheckMode::UnsafeBlock(..) => {
432 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
434 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
436 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
442 #[derive(Debug, Copy, Clone)]
448 /// Tracks whether executing a node may exit normally (versus
449 /// return/break/panic, which "diverge", leaving dead code in their
450 /// wake). Tracked semi-automatically (through type variables marked
451 /// as diverging), with some manual adjustments for control-flow
452 /// primitives (approximating a CFG).
453 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
455 /// Potentially unknown, some cases converge,
456 /// others require a CFG to determine them.
459 /// Definitely known to diverge and therefore
460 /// not reach the next sibling or its parent.
462 /// The `Span` points to the expression
463 /// that caused us to diverge
464 /// (e.g. `return`, `break`, etc).
466 /// In some cases (e.g. a `match` expression
467 /// where all arms diverge), we may be
468 /// able to provide a more informative
469 /// message to the user.
470 /// If this is `None`, a default message
471 /// will be generated, which is suitable
473 custom_note: Option<&'static str>,
476 /// Same as `Always` but with a reachability
477 /// warning already emitted.
481 // Convenience impls for combining `Diverges`.
483 impl ops::BitAnd for Diverges {
485 fn bitand(self, other: Self) -> Self {
486 cmp::min(self, other)
490 impl ops::BitOr for Diverges {
492 fn bitor(self, other: Self) -> Self {
493 cmp::max(self, other)
497 impl ops::BitAndAssign for Diverges {
498 fn bitand_assign(&mut self, other: Self) {
499 *self = *self & other;
503 impl ops::BitOrAssign for Diverges {
504 fn bitor_assign(&mut self, other: Self) {
505 *self = *self | other;
510 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
511 fn always(span: Span) -> Diverges {
512 Diverges::Always { span, custom_note: None }
515 fn is_always(self) -> bool {
516 // Enum comparison ignores the
517 // contents of fields, so we just
518 // fill them in with garbage here.
519 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
523 pub struct BreakableCtxt<'tcx> {
526 // this is `null` for loops where break with a value is illegal,
527 // such as `while`, `for`, and `while let`
528 coerce: Option<DynamicCoerceMany<'tcx>>,
531 pub struct EnclosingBreakables<'tcx> {
532 stack: Vec<BreakableCtxt<'tcx>>,
533 by_id: HirIdMap<usize>,
536 impl<'tcx> EnclosingBreakables<'tcx> {
537 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
538 self.opt_find_breakable(target_id).unwrap_or_else(|| {
539 bug!("could not find enclosing breakable with id {}", target_id);
543 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
544 match self.by_id.get(&target_id) {
545 Some(ix) => Some(&mut self.stack[*ix]),
551 pub struct FnCtxt<'a, 'tcx> {
554 /// The parameter environment used for proving trait obligations
555 /// in this function. This can change when we descend into
556 /// closures (as they bring new things into scope), hence it is
557 /// not part of `Inherited` (as of the time of this writing,
558 /// closures do not yet change the environment, but they will
560 param_env: ty::ParamEnv<'tcx>,
562 /// Number of errors that had been reported when we started
563 /// checking this function. On exit, if we find that *more* errors
564 /// have been reported, we will skip regionck and other work that
565 /// expects the types within the function to be consistent.
566 // FIXME(matthewjasper) This should not exist, and it's not correct
567 // if type checking is run in parallel.
568 err_count_on_creation: usize,
570 /// If `Some`, this stores coercion information for returned
571 /// expressions. If `None`, this is in a context where return is
572 /// inappropriate, such as a const expression.
574 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
575 /// can track all the return expressions and then use them to
576 /// compute a useful coercion from the set, similar to a match
577 /// expression or other branching context. You can use methods
578 /// like `expected_ty` to access the declared return type (if
580 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
582 /// First span of a return site that we find. Used in error messages.
583 ret_coercion_span: RefCell<Option<Span>>,
585 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
587 ps: RefCell<UnsafetyState>,
589 /// Whether the last checked node generates a divergence (e.g.,
590 /// `return` will set this to `Always`). In general, when entering
591 /// an expression or other node in the tree, the initial value
592 /// indicates whether prior parts of the containing expression may
593 /// have diverged. It is then typically set to `Maybe` (and the
594 /// old value remembered) for processing the subparts of the
595 /// current expression. As each subpart is processed, they may set
596 /// the flag to `Always`, etc. Finally, at the end, we take the
597 /// result and "union" it with the original value, so that when we
598 /// return the flag indicates if any subpart of the parent
599 /// expression (up to and including this part) has diverged. So,
600 /// if you read it after evaluating a subexpression `X`, the value
601 /// you get indicates whether any subexpression that was
602 /// evaluating up to and including `X` diverged.
604 /// We currently use this flag only for diagnostic purposes:
606 /// - To warn about unreachable code: if, after processing a
607 /// sub-expression but before we have applied the effects of the
608 /// current node, we see that the flag is set to `Always`, we
609 /// can issue a warning. This corresponds to something like
610 /// `foo(return)`; we warn on the `foo()` expression. (We then
611 /// update the flag to `WarnedAlways` to suppress duplicate
612 /// reports.) Similarly, if we traverse to a fresh statement (or
613 /// tail expression) from a `Always` setting, we will issue a
614 /// warning. This corresponds to something like `{return;
615 /// foo();}` or `{return; 22}`, where we would warn on the
618 /// An expression represents dead code if, after checking it,
619 /// the diverges flag is set to something other than `Maybe`.
620 diverges: Cell<Diverges>,
622 /// Whether any child nodes have any type errors.
623 has_errors: Cell<bool>,
625 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
627 inh: &'a Inherited<'a, 'tcx>,
630 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
631 type Target = Inherited<'a, 'tcx>;
632 fn deref(&self) -> &Self::Target {
637 /// Helper type of a temporary returned by `Inherited::build(...)`.
638 /// Necessary because we can't write the following bound:
639 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
640 pub struct InheritedBuilder<'tcx> {
641 infcx: infer::InferCtxtBuilder<'tcx>,
645 impl Inherited<'_, 'tcx> {
646 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
647 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
650 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_owner),
656 impl<'tcx> InheritedBuilder<'tcx> {
657 fn enter<F, R>(&mut self, f: F) -> R
659 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
661 let def_id = self.def_id;
662 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
666 impl Inherited<'a, 'tcx> {
667 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
669 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
670 let body_id = tcx.hir().maybe_body_owned_by(item_id);
673 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
675 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
676 locals: RefCell::new(Default::default()),
677 deferred_sized_obligations: RefCell::new(Vec::new()),
678 deferred_call_resolutions: RefCell::new(Default::default()),
679 deferred_cast_checks: RefCell::new(Vec::new()),
680 deferred_generator_interiors: RefCell::new(Vec::new()),
681 opaque_types: RefCell::new(Default::default()),
682 opaque_types_vars: RefCell::new(Default::default()),
683 implicit_region_bound: None,
688 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
689 debug!("register_predicate({:?})", obligation);
690 if obligation.has_escaping_bound_vars() {
691 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
693 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
696 fn register_predicates<I>(&self, obligations: I)
698 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
700 for obligation in obligations {
701 self.register_predicate(obligation);
705 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
706 self.register_predicates(infer_ok.obligations);
710 fn normalize_associated_types_in<T>(
714 param_env: ty::ParamEnv<'tcx>,
718 T: TypeFoldable<'tcx>,
720 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
721 self.register_infer_ok_obligations(ok)
725 struct CheckItemTypesVisitor<'tcx> {
729 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
730 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
731 check_item_type(self.tcx, i);
733 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
734 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
737 pub fn check_wf_new(tcx: TyCtxt<'_>) {
738 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
739 tcx.hir().krate().par_visit_all_item_likes(&visit);
742 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
743 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
746 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
747 debug_assert!(crate_num == LOCAL_CRATE);
748 tcx.par_body_owners(|body_owner_def_id| {
749 tcx.ensure().typeck_tables_of(body_owner_def_id);
753 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
754 wfcheck::check_item_well_formed(tcx, def_id);
757 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
758 wfcheck::check_trait_item(tcx, def_id);
761 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
762 wfcheck::check_impl_item(tcx, def_id);
765 pub fn provide(providers: &mut Providers<'_>) {
766 method::provide(providers);
767 *providers = Providers {
770 diagnostic_only_typeck_tables_of,
774 check_item_well_formed,
775 check_trait_item_well_formed,
776 check_impl_item_well_formed,
777 check_mod_item_types,
782 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
783 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
786 /// If this `DefId` is a "primary tables entry", returns
787 /// `Some((body_id, header, decl))` with information about
788 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
791 /// If this function returns `Some`, then `typeck_tables(def_id)` will
792 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
793 /// may not succeed. In some cases where this function returns `None`
794 /// (notably closures), `typeck_tables(def_id)` would wind up
795 /// redirecting to the owning function.
799 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
800 match tcx.hir().get(id) {
801 Node::Item(item) => match item.kind {
802 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
803 Some((body, Some(ty), None, None))
805 hir::ItemKind::Fn(ref sig, .., body) => {
806 Some((body, None, Some(&sig.header), Some(&sig.decl)))
810 Node::TraitItem(item) => match item.kind {
811 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
812 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
813 Some((body, None, Some(&sig.header), Some(&sig.decl)))
817 Node::ImplItem(item) => match item.kind {
818 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
819 hir::ImplItemKind::Fn(ref sig, body) => {
820 Some((body, None, Some(&sig.header), Some(&sig.decl)))
824 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
829 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
830 // Closures' tables come from their outermost function,
831 // as they are part of the same "inference environment".
832 let outer_def_id = tcx.closure_base_def_id(def_id);
833 if outer_def_id != def_id {
834 return tcx.has_typeck_tables(outer_def_id);
837 if let Some(def_id) = def_id.as_local() {
838 let id = tcx.hir().local_def_id_to_hir_id(def_id);
839 primary_body_of(tcx, id).is_some()
845 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &DefIdSet {
846 &*tcx.typeck_tables_of(def_id).used_trait_imports
849 /// Inspects the substs of opaque types, replacing any inference variables
850 /// with proper generic parameter from the identity substs.
852 /// This is run after we normalize the function signature, to fix any inference
853 /// variables introduced by the projection of associated types. This ensures that
854 /// any opaque types used in the signature continue to refer to generic parameters,
855 /// allowing them to be considered for defining uses in the function body
857 /// For example, consider this code.
862 /// fn use_it(self) -> Self::MyItem
864 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
865 /// type MyItem = impl Iterator<Item = I>;
866 /// fn use_it(self) -> Self::MyItem {
872 /// When we normalize the signature of `use_it` from the impl block,
873 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
874 /// However, this projection result may contain inference variables, due
875 /// to the way that projection works. We didn't have any inference variables
876 /// in the signature to begin with - leaving them in will cause us to incorrectly
877 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
878 /// variables back to the actual generic parameters, we will correctly see that
879 /// we have a defining use of `MyItem`
880 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
882 T: TypeFoldable<'tcx>,
884 struct FixupFolder<'tcx> {
888 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
889 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
893 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
895 ty::Opaque(def_id, substs) => {
896 debug!("fixup_opaque_types: found type {:?}", ty);
897 // Here, we replace any inference variables that occur within
898 // the substs of an opaque type. By definition, any type occurring
899 // in the substs has a corresponding generic parameter, which is what
900 // we replace it with.
901 // This replacement is only run on the function signature, so any
902 // inference variables that we come across must be the rust of projection
903 // (there's no other way for a user to get inference variables into
904 // a function signature).
905 if ty.needs_infer() {
906 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
907 let old_param = substs[param.index as usize];
908 match old_param.unpack() {
909 GenericArgKind::Type(old_ty) => {
910 if let ty::Infer(_) = old_ty.kind {
911 // Replace inference type with a generic parameter
912 self.tcx.mk_param_from_def(param)
914 old_param.fold_with(self)
917 GenericArgKind::Const(old_const) => {
918 if let ty::ConstKind::Infer(_) = old_const.val {
919 // This should never happen - we currently do not support
920 // 'const projections', e.g.:
921 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
922 // which should be the only way for us to end up with a const inference
923 // variable after projection. If Rust ever gains support for this kind
924 // of projection, this should *probably* be changed to
925 // `self.tcx.mk_param_from_def(param)`
927 "Found infer const: `{:?}` in opaque type: {:?}",
932 old_param.fold_with(self)
935 GenericArgKind::Lifetime(old_region) => {
936 if let RegionKind::ReVar(_) = old_region {
937 self.tcx.mk_param_from_def(param)
939 old_param.fold_with(self)
944 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
945 debug!("fixup_opaque_types: new type: {:?}", new_ty);
951 _ => ty.super_fold_with(self),
956 debug!("fixup_opaque_types({:?})", val);
957 val.fold_with(&mut FixupFolder { tcx })
960 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> {
961 let fallback = move || tcx.type_of(def_id.to_def_id());
962 typeck_tables_of_with_fallback(tcx, def_id, fallback)
965 /// Used only to get `TypeckTables` for type inference during error recovery.
966 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
967 fn diagnostic_only_typeck_tables_of<'tcx>(
970 ) -> &ty::TypeckTables<'tcx> {
971 let fallback = move || {
972 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
973 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
976 typeck_tables_of_with_fallback(tcx, def_id, fallback)
979 fn typeck_tables_of_with_fallback<'tcx>(
982 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
983 ) -> &'tcx ty::TypeckTables<'tcx> {
984 // Closures' tables come from their outermost function,
985 // as they are part of the same "inference environment".
986 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
987 if outer_def_id != def_id {
988 return tcx.typeck_tables_of(outer_def_id);
991 let id = tcx.hir().as_local_hir_id(def_id);
992 let span = tcx.hir().span(id);
994 // Figure out what primary body this item has.
995 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
996 span_bug!(span, "can't type-check body of {:?}", def_id);
998 let body = tcx.hir().body(body_id);
1000 let tables = Inherited::build(tcx, def_id).enter(|inh| {
1001 let param_env = tcx.param_env(def_id);
1002 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1003 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1004 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1010 &hir::Generics::empty(),
1017 check_abi(tcx, span, fn_sig.abi());
1019 // Compute the fty from point of view of inside the fn.
1020 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1021 let fn_sig = inh.normalize_associated_types_in(
1028 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1030 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1033 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1034 let expected_type = body_ty
1035 .and_then(|ty| match ty.kind {
1036 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1039 .unwrap_or_else(fallback);
1040 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1041 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1043 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1044 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1049 // Gather locals in statics (because of block expressions).
1050 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1052 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1054 fcx.write_ty(id, revealed_ty);
1059 // All type checking constraints were added, try to fallback unsolved variables.
1060 fcx.select_obligations_where_possible(false, |_| {});
1061 let mut fallback_has_occurred = false;
1063 // We do fallback in two passes, to try to generate
1064 // better error messages.
1065 // The first time, we do *not* replace opaque types.
1066 for ty in &fcx.unsolved_variables() {
1067 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1069 // We now see if we can make progress. This might
1070 // cause us to unify inference variables for opaque types,
1071 // since we may have unified some other type variables
1072 // during the first phase of fallback.
1073 // This means that we only replace inference variables with their underlying
1074 // opaque types as a last resort.
1076 // In code like this:
1079 // type MyType = impl Copy;
1080 // fn produce() -> MyType { true }
1081 // fn bad_produce() -> MyType { panic!() }
1084 // we want to unify the opaque inference variable in `bad_produce`
1085 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1086 // This will produce a nice error message about conflicting concrete
1087 // types for `MyType`.
1089 // If we had tried to fallback the opaque inference variable to `MyType`,
1090 // we will generate a confusing type-check error that does not explicitly
1091 // refer to opaque types.
1092 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1094 // We now run fallback again, but this time we allow it to replace
1095 // unconstrained opaque type variables, in addition to performing
1096 // other kinds of fallback.
1097 for ty in &fcx.unsolved_variables() {
1098 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1101 // See if we can make any more progress.
1102 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1104 // Even though coercion casts provide type hints, we check casts after fallback for
1105 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1108 // Closure and generator analysis may run after fallback
1109 // because they don't constrain other type variables.
1110 fcx.closure_analyze(body);
1111 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1112 fcx.resolve_generator_interiors(def_id.to_def_id());
1114 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1115 let ty = fcx.normalize_ty(span, ty);
1116 fcx.require_type_is_sized(ty, span, code);
1119 fcx.select_all_obligations_or_error();
1121 if fn_decl.is_some() {
1122 fcx.regionck_fn(id, body);
1124 fcx.regionck_expr(body);
1127 fcx.resolve_type_vars_in_body(body)
1130 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1131 // it will need to hold.
1132 assert_eq!(tables.hir_owner, Some(id.owner));
1137 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1138 if !tcx.sess.target.target.is_abi_supported(abi) {
1143 "The ABI `{}` is not supported for the current target",
1150 struct GatherLocalsVisitor<'a, 'tcx> {
1151 fcx: &'a FnCtxt<'a, 'tcx>,
1152 parent_id: hir::HirId,
1155 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1156 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1159 // Infer the variable's type.
1160 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1161 kind: TypeVariableOriginKind::TypeInference,
1167 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1171 // Take type that the user specified.
1172 self.fcx.locals.borrow_mut().insert(nid, typ);
1179 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1180 type Map = intravisit::ErasedMap<'tcx>;
1182 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1183 NestedVisitorMap::None
1186 // Add explicitly-declared locals.
1187 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1188 let local_ty = match local.ty {
1190 let o_ty = self.fcx.to_ty(&ty);
1192 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1193 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1202 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1204 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1205 ty.hir_id, o_ty, revealed_ty, c_ty
1207 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1209 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1213 self.assign(local.span, local.hir_id, local_ty);
1216 "local variable {:?} is assigned type {}",
1218 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1220 intravisit::walk_local(self, local);
1223 // Add pattern bindings.
1224 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1225 if let PatKind::Binding(_, _, ident, _) = p.kind {
1226 let var_ty = self.assign(p.span, p.hir_id, None);
1228 if !self.fcx.tcx.features().unsized_locals {
1229 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1233 "pattern binding {} is assigned to {} with type {:?}",
1235 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1239 intravisit::walk_pat(self, p);
1242 // Don't descend into the bodies of nested closures.
1245 _: intravisit::FnKind<'tcx>,
1246 _: &'tcx hir::FnDecl<'tcx>,
1254 /// When `check_fn` is invoked on a generator (i.e., a body that
1255 /// includes yield), it returns back some information about the yield
1257 struct GeneratorTypes<'tcx> {
1258 /// Type of generator argument / values returned by `yield`.
1259 resume_ty: Ty<'tcx>,
1261 /// Type of value that is yielded.
1264 /// Types that are captured (see `GeneratorInterior` for more).
1267 /// Indicates if the generator is movable or static (immovable).
1268 movability: hir::Movability,
1271 /// Helper used for fns and closures. Does the grungy work of checking a function
1272 /// body and returns the function context used for that purpose, since in the case of a fn item
1273 /// there is still a bit more to do.
1276 /// * inherited: other fields inherited from the enclosing fn (if any)
1277 fn check_fn<'a, 'tcx>(
1278 inherited: &'a Inherited<'a, 'tcx>,
1279 param_env: ty::ParamEnv<'tcx>,
1280 fn_sig: ty::FnSig<'tcx>,
1281 decl: &'tcx hir::FnDecl<'tcx>,
1283 body: &'tcx hir::Body<'tcx>,
1284 can_be_generator: Option<hir::Movability>,
1285 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1286 let mut fn_sig = fn_sig;
1288 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1290 // Create the function context. This is either derived from scratch or,
1291 // in the case of closures, based on the outer context.
1292 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1293 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1296 let sess = tcx.sess;
1297 let hir = tcx.hir();
1299 let declared_ret_ty = fn_sig.output();
1300 let revealed_ret_ty =
1301 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1302 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1303 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1304 fn_sig = tcx.mk_fn_sig(
1305 fn_sig.inputs().iter().cloned(),
1312 let span = body.value.span;
1314 fn_maybe_err(tcx, span, fn_sig.abi);
1316 if body.generator_kind.is_some() && can_be_generator.is_some() {
1318 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1319 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1321 // Resume type defaults to `()` if the generator has no argument.
1322 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1324 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1327 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
1328 let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1329 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1331 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1332 // (as it's created inside the body itself, not passed in from outside).
1333 let maybe_va_list = if fn_sig.c_variadic {
1334 let span = body.params.last().unwrap().span;
1335 let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
1336 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1338 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1343 // Add formal parameters.
1344 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1345 let inputs_fn = fn_sig.inputs().iter().copied();
1346 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1347 // Check the pattern.
1348 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1350 // Check that argument is Sized.
1351 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1352 // for simple cases like `fn foo(x: Trait)`,
1353 // where we would error once on the parameter as a whole, and once on the binding `x`.
1354 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1355 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1358 fcx.write_ty(param.hir_id, param_ty);
1361 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1363 if let ty::Dynamic(..) = declared_ret_ty.kind {
1364 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1365 // been evaluated so that we have types available for all the nodes being returned, but that
1366 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1367 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1368 // while keeping the current ordering we will ignore the tail expression's type because we
1369 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1370 // because we will trigger "unreachable expression" lints unconditionally.
1371 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1372 // case that a newcomer might make, returning a bare trait, and in that case we populate
1373 // the tail expression's type so that the suggestion will be correct, but ignore all other
1375 fcx.check_expr(&body.value);
1376 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1377 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1379 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1380 fcx.check_return_expr(&body.value);
1383 // We insert the deferred_generator_interiors entry after visiting the body.
1384 // This ensures that all nested generators appear before the entry of this generator.
1385 // resolve_generator_interiors relies on this property.
1386 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1388 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1389 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1391 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1392 Some(GeneratorTypes {
1396 movability: can_be_generator.unwrap(),
1402 // Finalize the return check by taking the LUB of the return types
1403 // we saw and assigning it to the expected return type. This isn't
1404 // really expected to fail, since the coercions would have failed
1405 // earlier when trying to find a LUB.
1407 // However, the behavior around `!` is sort of complex. In the
1408 // event that the `actual_return_ty` comes back as `!`, that
1409 // indicates that the fn either does not return or "returns" only
1410 // values of type `!`. In this case, if there is an expected
1411 // return type that is *not* `!`, that should be ok. But if the
1412 // return type is being inferred, we want to "fallback" to `!`:
1414 // let x = move || panic!();
1416 // To allow for that, I am creating a type variable with diverging
1417 // fallback. This was deemed ever so slightly better than unifying
1418 // the return value with `!` because it allows for the caller to
1419 // make more assumptions about the return type (e.g., they could do
1421 // let y: Option<u32> = Some(x());
1423 // which would then cause this return type to become `u32`, not
1425 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1426 let mut actual_return_ty = coercion.complete(&fcx);
1427 if actual_return_ty.is_never() {
1428 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1429 kind: TypeVariableOriginKind::DivergingFn,
1433 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1435 // Check that the main return type implements the termination trait.
1436 if let Some(term_id) = tcx.lang_items().termination() {
1437 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1438 let main_id = hir.as_local_hir_id(def_id);
1439 if main_id == fn_id {
1440 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1441 let trait_ref = ty::TraitRef::new(term_id, substs);
1442 let return_ty_span = decl.output.span();
1443 let cause = traits::ObligationCause::new(
1446 ObligationCauseCode::MainFunctionType,
1449 inherited.register_predicate(traits::Obligation::new(
1452 trait_ref.without_const().to_predicate(tcx),
1458 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1459 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1460 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1461 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1462 if declared_ret_ty.kind != ty::Never {
1463 sess.span_err(decl.output.span(), "return type should be `!`");
1466 let inputs = fn_sig.inputs();
1467 let span = hir.span(fn_id);
1468 if inputs.len() == 1 {
1469 let arg_is_panic_info = match inputs[0].kind {
1470 ty::Ref(region, ty, mutbl) => match ty.kind {
1471 ty::Adt(ref adt, _) => {
1472 adt.did == panic_info_did
1473 && mutbl == hir::Mutability::Not
1474 && *region != RegionKind::ReStatic
1481 if !arg_is_panic_info {
1482 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1485 if let Node::Item(item) = hir.get(fn_id) {
1486 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1487 if !generics.params.is_empty() {
1488 sess.span_err(span, "should have no type parameters");
1493 let span = sess.source_map().guess_head_span(span);
1494 sess.span_err(span, "function should have one argument");
1497 sess.err("language item required, but not found: `panic_info`");
1502 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1503 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1504 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1505 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1506 if declared_ret_ty.kind != ty::Never {
1507 sess.span_err(decl.output.span(), "return type should be `!`");
1510 let inputs = fn_sig.inputs();
1511 let span = hir.span(fn_id);
1512 if inputs.len() == 1 {
1513 let arg_is_alloc_layout = match inputs[0].kind {
1514 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1518 if !arg_is_alloc_layout {
1519 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1522 if let Node::Item(item) = hir.get(fn_id) {
1523 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1524 if !generics.params.is_empty() {
1527 "`#[alloc_error_handler]` function should have no type \
1534 let span = sess.source_map().guess_head_span(span);
1535 sess.span_err(span, "function should have one argument");
1538 sess.err("language item required, but not found: `alloc_layout`");
1546 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1547 let def_id = tcx.hir().local_def_id(id);
1548 let def = tcx.adt_def(def_id);
1549 def.destructor(tcx); // force the destructor to be evaluated
1550 check_representable(tcx, span, def_id);
1552 if def.repr.simd() {
1553 check_simd(tcx, span, def_id);
1556 check_transparent(tcx, span, def);
1557 check_packed(tcx, span, def);
1560 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1561 let def_id = tcx.hir().local_def_id(id);
1562 let def = tcx.adt_def(def_id);
1563 def.destructor(tcx); // force the destructor to be evaluated
1564 check_representable(tcx, span, def_id);
1565 check_transparent(tcx, span, def);
1566 check_union_fields(tcx, span, def_id);
1567 check_packed(tcx, span, def);
1570 /// When the `#![feature(untagged_unions)]` gate is active,
1571 /// check that the fields of the `union` does not contain fields that need dropping.
1572 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1573 let item_type = tcx.type_of(item_def_id);
1574 if let ty::Adt(def, substs) = item_type.kind {
1575 assert!(def.is_union());
1576 let fields = &def.non_enum_variant().fields;
1577 let param_env = tcx.param_env(item_def_id);
1578 for field in fields {
1579 let field_ty = field.ty(tcx, substs);
1580 // We are currently checking the type this field came from, so it must be local.
1581 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1582 if field_ty.needs_drop(tcx, param_env) {
1587 "unions may not contain fields that need dropping"
1589 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1595 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1600 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1601 /// projections that would result in "inheriting lifetimes".
1602 fn check_opaque<'tcx>(
1605 substs: SubstsRef<'tcx>,
1607 origin: &hir::OpaqueTyOrigin,
1609 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1610 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1613 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1614 /// in "inheriting lifetimes".
1615 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1616 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1618 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1623 struct ProhibitOpaqueVisitor<'tcx> {
1624 opaque_identity_ty: Ty<'tcx>,
1625 generics: &'tcx ty::Generics,
1628 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1629 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1630 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1631 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1634 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1635 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1636 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1637 return *index < self.generics.parent_count as u32;
1640 r.super_visit_with(self)
1643 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1644 if let ty::ConstKind::Unevaluated(..) = c.val {
1645 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1646 // which would violate this check. Even though the particular substitution is not used
1647 // within the const, this should still be fixed.
1650 c.super_visit_with(self)
1654 let prohibit_opaque = match item.kind {
1655 ItemKind::OpaqueTy(hir::OpaqueTy {
1656 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1659 let mut visitor = ProhibitOpaqueVisitor {
1660 opaque_identity_ty: tcx.mk_opaque(
1662 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1664 generics: tcx.generics_of(def_id),
1666 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1668 tcx.predicates_of(def_id)
1671 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1676 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1677 if prohibit_opaque {
1678 let is_async = match item.kind {
1679 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1680 hir::OpaqueTyOrigin::AsyncFn => true,
1683 _ => unreachable!(),
1689 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1691 if is_async { "async fn" } else { "impl Trait" },
1697 /// Checks that an opaque type does not contain cycles.
1698 fn check_opaque_for_cycles<'tcx>(
1701 substs: SubstsRef<'tcx>,
1703 origin: &hir::OpaqueTyOrigin,
1705 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1707 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1708 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1709 .span_label(span, "recursive `async fn`")
1710 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1714 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1715 err.span_label(span, "expands to a recursive type");
1716 if let ty::Opaque(..) = partially_expanded_type.kind {
1717 err.note("type resolves to itself");
1719 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1726 // Forbid defining intrinsics in Rust code,
1727 // as they must always be defined by the compiler.
1728 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1729 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1730 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1734 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1736 "check_item_type(it.hir_id={}, it.name={})",
1738 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1740 let _indenter = indenter();
1742 // Consts can play a role in type-checking, so they are included here.
1743 hir::ItemKind::Static(..) => {
1744 let def_id = tcx.hir().local_def_id(it.hir_id);
1745 tcx.ensure().typeck_tables_of(def_id);
1746 maybe_check_static_with_link_section(tcx, def_id, it.span);
1748 hir::ItemKind::Const(..) => {
1749 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1751 hir::ItemKind::Enum(ref enum_definition, _) => {
1752 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1754 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1755 hir::ItemKind::Impl { ref items, .. } => {
1756 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1757 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1758 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1759 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1760 let trait_def_id = impl_trait_ref.def_id;
1761 check_on_unimplemented(tcx, trait_def_id, it);
1764 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1765 let def_id = tcx.hir().local_def_id(it.hir_id);
1766 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1768 for item in items.iter() {
1769 let item = tcx.hir().trait_item(item.id);
1770 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1771 let abi = sig.header.abi;
1772 fn_maybe_err(tcx, item.ident.span, abi);
1776 hir::ItemKind::Struct(..) => {
1777 check_struct(tcx, it.hir_id, it.span);
1779 hir::ItemKind::Union(..) => {
1780 check_union(tcx, it.hir_id, it.span);
1782 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1783 let def_id = tcx.hir().local_def_id(it.hir_id);
1785 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1786 check_opaque(tcx, def_id, substs, it.span, &origin);
1788 hir::ItemKind::TyAlias(..) => {
1789 let def_id = tcx.hir().local_def_id(it.hir_id);
1790 let pty_ty = tcx.type_of(def_id);
1791 let generics = tcx.generics_of(def_id);
1792 check_type_params_are_used(tcx, &generics, pty_ty);
1794 hir::ItemKind::ForeignMod(ref m) => {
1795 check_abi(tcx, it.span, m.abi);
1797 if m.abi == Abi::RustIntrinsic {
1798 for item in m.items {
1799 intrinsic::check_intrinsic_type(tcx, item);
1801 } else if m.abi == Abi::PlatformIntrinsic {
1802 for item in m.items {
1803 intrinsic::check_platform_intrinsic_type(tcx, item);
1806 for item in m.items {
1807 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1808 let own_counts = generics.own_counts();
1809 if generics.params.len() - own_counts.lifetimes != 0 {
1810 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1811 (_, 0) => ("type", "types", Some("u32")),
1812 // We don't specify an example value, because we can't generate
1813 // a valid value for any type.
1814 (0, _) => ("const", "consts", None),
1815 _ => ("type or const", "types or consts", None),
1821 "foreign items may not have {} parameters",
1824 .span_label(item.span, &format!("can't have {} parameters", kinds))
1826 // FIXME: once we start storing spans for type arguments, turn this
1827 // into a suggestion.
1829 "replace the {} parameters with concrete {}{}",
1832 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1838 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1839 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1844 _ => { /* nothing to do */ }
1848 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1849 // Only restricted on wasm32 target for now
1850 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1854 // If `#[link_section]` is missing, then nothing to verify
1855 let attrs = tcx.codegen_fn_attrs(id);
1856 if attrs.link_section.is_none() {
1860 // For the wasm32 target statics with `#[link_section]` are placed into custom
1861 // sections of the final output file, but this isn't link custom sections of
1862 // other executable formats. Namely we can only embed a list of bytes,
1863 // nothing with pointers to anything else or relocations. If any relocation
1864 // show up, reject them here.
1865 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1866 // the consumer's responsibility to ensure all bytes that have been read
1867 // have defined values.
1868 match tcx.const_eval_poly(id.to_def_id()) {
1869 Ok(ConstValue::ByRef { alloc, .. }) => {
1870 if alloc.relocations().len() != 0 {
1871 let msg = "statics with a custom `#[link_section]` must be a \
1872 simple list of bytes on the wasm target with no \
1873 extra levels of indirection such as references";
1874 tcx.sess.span_err(span, msg);
1877 Ok(_) => bug!("Matching on non-ByRef static"),
1882 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1883 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1884 // an error would be reported if this fails.
1885 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1888 fn report_forbidden_specialization(
1890 impl_item: &hir::ImplItem<'_>,
1893 let mut err = struct_span_err!(
1897 "`{}` specializes an item from a parent `impl`, but \
1898 that item is not marked `default`",
1901 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1903 match tcx.span_of_impl(parent_impl) {
1905 err.span_label(span, "parent `impl` is here");
1907 "to specialize, `{}` in the parent `impl` must be marked `default`",
1912 err.note(&format!("parent implementation is in crate `{}`", cname));
1919 fn check_specialization_validity<'tcx>(
1921 trait_def: &ty::TraitDef,
1922 trait_item: &ty::AssocItem,
1924 impl_item: &hir::ImplItem<'_>,
1926 let kind = match impl_item.kind {
1927 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1928 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1929 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1930 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1933 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1934 Ok(ancestors) => ancestors,
1937 let mut ancestor_impls = ancestors
1939 .filter_map(|parent| {
1940 if parent.is_from_trait() {
1943 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1948 if ancestor_impls.peek().is_none() {
1949 // No parent, nothing to specialize.
1953 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1955 // Parent impl exists, and contains the parent item we're trying to specialize, but
1956 // doesn't mark it `default`.
1957 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1958 Some(Err(parent_impl.def_id()))
1961 // Parent impl contains item and makes it specializable.
1962 Some(_) => Some(Ok(())),
1964 // Parent impl doesn't mention the item. This means it's inherited from the
1965 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1966 // "defaultness" from the grandparent, else they are final.
1968 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1971 Some(Err(parent_impl.def_id()))
1977 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1978 // item. This is allowed, the item isn't actually getting specialized here.
1979 let result = opt_result.unwrap_or(Ok(()));
1981 if let Err(parent_impl) = result {
1982 report_forbidden_specialization(tcx, impl_item, parent_impl);
1986 fn check_impl_items_against_trait<'tcx>(
1988 full_impl_span: Span,
1989 impl_id: LocalDefId,
1990 impl_trait_ref: ty::TraitRef<'tcx>,
1991 impl_item_refs: &[hir::ImplItemRef<'_>],
1993 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1995 // If the trait reference itself is erroneous (so the compilation is going
1996 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1997 // isn't populated for such impls.
1998 if impl_trait_ref.references_error() {
2002 // Negative impls are not expected to have any items
2003 match tcx.impl_polarity(impl_id) {
2004 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2005 ty::ImplPolarity::Negative => {
2006 if let [first_item_ref, ..] = impl_item_refs {
2007 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2012 "negative impls cannot have any items"
2020 // Locate trait definition and items
2021 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2023 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2025 // Check existing impl methods to see if they are both present in trait
2026 // and compatible with trait signature
2027 for impl_item in impl_items() {
2028 let namespace = impl_item.kind.namespace();
2029 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2030 let ty_trait_item = tcx
2031 .associated_items(impl_trait_ref.def_id)
2032 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2034 // Not compatible, but needed for the error message
2035 tcx.associated_items(impl_trait_ref.def_id)
2036 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2040 // Check that impl definition matches trait definition
2041 if let Some(ty_trait_item) = ty_trait_item {
2042 match impl_item.kind {
2043 hir::ImplItemKind::Const(..) => {
2044 // Find associated const definition.
2045 if ty_trait_item.kind == ty::AssocKind::Const {
2054 let mut err = struct_span_err!(
2058 "item `{}` is an associated const, \
2059 which doesn't match its trait `{}`",
2061 impl_trait_ref.print_only_trait_path()
2063 err.span_label(impl_item.span, "does not match trait");
2064 // We can only get the spans from local trait definition
2065 // Same for E0324 and E0325
2066 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2067 err.span_label(trait_span, "item in trait");
2072 hir::ImplItemKind::Fn(..) => {
2073 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2074 if ty_trait_item.kind == ty::AssocKind::Fn {
2075 compare_impl_method(
2084 let mut err = struct_span_err!(
2088 "item `{}` is an associated method, \
2089 which doesn't match its trait `{}`",
2091 impl_trait_ref.print_only_trait_path()
2093 err.span_label(impl_item.span, "does not match trait");
2094 if let Some(trait_span) = opt_trait_span {
2095 err.span_label(trait_span, "item in trait");
2100 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2101 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2102 if ty_trait_item.kind == ty::AssocKind::Type {
2112 let mut err = struct_span_err!(
2116 "item `{}` is an associated type, \
2117 which doesn't match its trait `{}`",
2119 impl_trait_ref.print_only_trait_path()
2121 err.span_label(impl_item.span, "does not match trait");
2122 if let Some(trait_span) = opt_trait_span {
2123 err.span_label(trait_span, "item in trait");
2130 check_specialization_validity(
2134 impl_id.to_def_id(),
2140 // Check for missing items from trait
2141 let mut missing_items = Vec::new();
2142 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2143 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2144 let is_implemented = ancestors
2145 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2146 .map(|node_item| !node_item.defining_node.is_from_trait())
2149 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2150 if !trait_item.defaultness.has_value() {
2151 missing_items.push(*trait_item);
2157 if !missing_items.is_empty() {
2158 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2162 fn missing_items_err(
2165 missing_items: &[ty::AssocItem],
2166 full_impl_span: Span,
2168 let missing_items_msg = missing_items
2170 .map(|trait_item| trait_item.ident.to_string())
2171 .collect::<Vec<_>>()
2174 let mut err = struct_span_err!(
2178 "not all trait items implemented, missing: `{}`",
2181 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2183 // `Span` before impl block closing brace.
2184 let hi = full_impl_span.hi() - BytePos(1);
2185 // Point at the place right before the closing brace of the relevant `impl` to suggest
2186 // adding the associated item at the end of its body.
2187 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2188 // Obtain the level of indentation ending in `sugg_sp`.
2189 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2190 // Make the whitespace that will make the suggestion have the right indentation.
2191 let padding: String = (0..indentation).map(|_| " ").collect();
2193 for trait_item in missing_items {
2194 let snippet = suggestion_signature(&trait_item, tcx);
2195 let code = format!("{}{}\n{}", padding, snippet, padding);
2196 let msg = format!("implement the missing item: `{}`", snippet);
2197 let appl = Applicability::HasPlaceholders;
2198 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2199 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2200 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2202 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2208 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2209 fn bounds_from_generic_predicates(
2211 predicates: ty::GenericPredicates<'_>,
2212 ) -> (String, String) {
2213 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2214 let mut projections = vec![];
2215 for (predicate, _) in predicates.predicates {
2216 debug!("predicate {:?}", predicate);
2217 match predicate.kind() {
2218 ty::PredicateKind::Trait(trait_predicate, _) => {
2219 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2220 let def_id = trait_predicate.skip_binder().def_id();
2221 if Some(def_id) != tcx.lang_items().sized_trait() {
2222 // Type params are `Sized` by default, do not add that restriction to the list
2223 // if it is a positive requirement.
2224 entry.push(trait_predicate.skip_binder().def_id());
2227 ty::PredicateKind::Projection(projection_pred) => {
2228 projections.push(projection_pred);
2233 let generics = if types.is_empty() {
2240 .filter_map(|t| match t.kind {
2241 ty::Param(_) => Some(t.to_string()),
2242 // Avoid suggesting the following:
2243 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2246 .collect::<Vec<_>>()
2250 let mut where_clauses = vec![];
2251 for (ty, bounds) in types {
2252 for bound in &bounds {
2253 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2256 for projection in &projections {
2257 let p = projection.skip_binder();
2258 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2259 // insert the associated types where they correspond, but for now let's be "lazy" and
2260 // propose this instead of the following valid resugaring:
2261 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2262 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2264 let where_clauses = if where_clauses.is_empty() {
2267 format!(" where {}", where_clauses.join(", "))
2269 (generics, where_clauses)
2272 /// Return placeholder code for the given function.
2273 fn fn_sig_suggestion(
2275 sig: &ty::FnSig<'_>,
2277 predicates: ty::GenericPredicates<'_>,
2278 assoc: &ty::AssocItem,
2285 Some(match ty.kind {
2286 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2287 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2288 let reg = match &format!("{}", reg)[..] {
2289 "'_" | "" => String::new(),
2290 reg => format!("{} ", reg),
2292 if assoc.fn_has_self_parameter {
2294 ty::Param(param) if param.name == kw::SelfUpper => {
2295 format!("&{}{}self", reg, mutability.prefix_str())
2298 _ => format!("self: {}", ty),
2301 format!("_: {:?}", ty)
2305 if assoc.fn_has_self_parameter && i == 0 {
2306 format!("self: {:?}", ty)
2308 format!("_: {:?}", ty)
2313 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2314 .filter_map(|arg| arg)
2315 .collect::<Vec<String>>()
2317 let output = sig.output();
2318 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2320 let unsafety = sig.unsafety.prefix_str();
2321 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2323 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2324 // not be present in the `fn` definition, not will we account for renamed
2325 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2326 // fill in a significant portion of the missing code, and other subsequent
2327 // suggestions can help the user fix the code.
2329 "{}fn {}{}({}){}{} {{ todo!() }}",
2330 unsafety, ident, generics, args, output, where_clauses
2334 /// Return placeholder code for the given associated item.
2335 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2336 /// structured suggestion.
2337 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2339 ty::AssocKind::Fn => {
2340 // We skip the binder here because the binder would deanonymize all
2341 // late-bound regions, and we don't want method signatures to show up
2342 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2343 // regions just fine, showing `fn(&MyType)`.
2346 tcx.fn_sig(assoc.def_id).skip_binder(),
2348 tcx.predicates_of(assoc.def_id),
2352 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2353 // FIXME(type_alias_impl_trait): we should print bounds here too.
2354 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2355 ty::AssocKind::Const => {
2356 let ty = tcx.type_of(assoc.def_id);
2357 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2358 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2363 /// Checks whether a type can be represented in memory. In particular, it
2364 /// identifies types that contain themselves without indirection through a
2365 /// pointer, which would mean their size is unbounded.
2366 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2367 let rty = tcx.type_of(item_def_id);
2369 // Check that it is possible to represent this type. This call identifies
2370 // (1) types that contain themselves and (2) types that contain a different
2371 // recursive type. It is only necessary to throw an error on those that
2372 // contain themselves. For case 2, there must be an inner type that will be
2373 // caught by case 1.
2374 match rty.is_representable(tcx, sp) {
2375 Representability::SelfRecursive(spans) => {
2376 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2378 err.span_label(span, "recursive without indirection");
2383 Representability::Representable | Representability::ContainsRecursive => (),
2388 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2389 let t = tcx.type_of(def_id);
2390 if let ty::Adt(def, substs) = t.kind {
2391 if def.is_struct() {
2392 let fields = &def.non_enum_variant().fields;
2393 if fields.is_empty() {
2394 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2397 let e = fields[0].ty(tcx, substs);
2398 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2399 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2400 .span_label(sp, "SIMD elements must have the same type")
2405 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2406 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2412 "SIMD vector element type should be machine type"
2422 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2423 let repr = def.repr;
2425 for attr in tcx.get_attrs(def.did).iter() {
2426 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2427 if let attr::ReprPacked(pack) = r {
2428 if let Some(repr_pack) = repr.pack {
2429 if pack as u64 != repr_pack.bytes() {
2434 "type has conflicting packed representation hints"
2442 if repr.align.is_some() {
2447 "type has conflicting packed and align representation hints"
2451 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2452 let mut err = struct_span_err!(
2456 "packed type cannot transitively contain a `#[repr(align)]` type"
2459 let hir = tcx.hir();
2460 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2461 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2463 tcx.def_span(def_spans[0].0),
2464 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2468 if def_spans.len() > 2 {
2469 let mut first = true;
2470 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2471 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2472 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2477 "`{}` contains a field of type `{}`",
2478 tcx.type_of(def.did),
2482 format!("...which contains a field of type `{}`", ident)
2496 fn check_packed_inner(
2499 stack: &mut Vec<DefId>,
2500 ) -> Option<Vec<(DefId, Span)>> {
2501 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2502 if def.is_struct() || def.is_union() {
2503 if def.repr.align.is_some() {
2504 return Some(vec![(def.did, DUMMY_SP)]);
2508 for field in &def.non_enum_variant().fields {
2509 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2510 if !stack.contains(&def.did) {
2511 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2512 defs.push((def.did, field.ident.span));
2525 /// Emit an error when encountering more or less than one variant in a transparent enum.
2526 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2527 let variant_spans: Vec<_> = adt
2530 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2532 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2533 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2534 err.span_label(sp, &msg);
2535 if let [start @ .., end] = &*variant_spans {
2536 for variant_span in start {
2537 err.span_label(*variant_span, "");
2539 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2544 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2546 fn bad_non_zero_sized_fields<'tcx>(
2548 adt: &'tcx ty::AdtDef,
2550 field_spans: impl Iterator<Item = Span>,
2553 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2554 let mut err = struct_span_err!(
2558 "{}transparent {} {}",
2559 if adt.is_enum() { "the variant of a " } else { "" },
2563 err.span_label(sp, &msg);
2564 for sp in field_spans {
2565 err.span_label(sp, "this field is non-zero-sized");
2570 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2571 if !adt.repr.transparent() {
2574 let sp = tcx.sess.source_map().guess_head_span(sp);
2576 if adt.is_union() && !tcx.features().transparent_unions {
2578 &tcx.sess.parse_sess,
2579 sym::transparent_unions,
2581 "transparent unions are unstable",
2586 if adt.variants.len() != 1 {
2587 bad_variant_count(tcx, adt, sp, adt.did);
2588 if adt.variants.is_empty() {
2589 // Don't bother checking the fields. No variants (and thus no fields) exist.
2594 // For each field, figure out if it's known to be a ZST and align(1)
2595 let field_infos = adt.all_fields().map(|field| {
2596 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2597 let param_env = tcx.param_env(field.did);
2598 let layout = tcx.layout_of(param_env.and(ty));
2599 // We are currently checking the type this field came from, so it must be local
2600 let span = tcx.hir().span_if_local(field.did).unwrap();
2601 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2602 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2606 let non_zst_fields =
2607 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2608 let non_zst_count = non_zst_fields.clone().count();
2609 if non_zst_count != 1 {
2610 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2612 for (span, zst, align1) in field_infos {
2618 "zero-sized field in transparent {} has alignment larger than 1",
2621 .span_label(span, "has alignment larger than 1")
2627 #[allow(trivial_numeric_casts)]
2628 pub fn check_enum<'tcx>(
2631 vs: &'tcx [hir::Variant<'tcx>],
2634 let def_id = tcx.hir().local_def_id(id);
2635 let def = tcx.adt_def(def_id);
2636 def.destructor(tcx); // force the destructor to be evaluated
2639 let attributes = tcx.get_attrs(def_id.to_def_id());
2640 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2645 "unsupported representation for zero-variant enum"
2647 .span_label(sp, "zero-variant enum")
2652 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2653 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2654 if !tcx.features().repr128 {
2656 &tcx.sess.parse_sess,
2659 "repr with 128-bit type is unstable",
2666 if let Some(ref e) = v.disr_expr {
2667 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2671 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2672 let is_unit = |var: &hir::Variant<'_>| match var.data {
2673 hir::VariantData::Unit(..) => true,
2677 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2678 let has_non_units = vs.iter().any(|var| !is_unit(var));
2679 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2680 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2682 if disr_non_unit || (disr_units && has_non_units) {
2684 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2689 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2690 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2691 // Check for duplicate discriminant values
2692 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2693 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2694 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2695 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2696 let i_span = match variant_i.disr_expr {
2697 Some(ref expr) => tcx.hir().span(expr.hir_id),
2698 None => tcx.hir().span(variant_i_hir_id),
2700 let span = match v.disr_expr {
2701 Some(ref expr) => tcx.hir().span(expr.hir_id),
2708 "discriminant value `{}` already exists",
2711 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2712 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2715 disr_vals.push(discr);
2718 check_representable(tcx, sp, def_id);
2719 check_transparent(tcx, sp, def);
2722 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2727 "expected unit struct, unit variant or constant, found {}{}",
2729 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2734 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2735 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2739 fn item_def_id(&self) -> Option<DefId> {
2743 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2744 // FIXME: refactor this into a method
2745 let node = self.tcx.hir().get(self.body_id);
2746 if let Some(fn_like) = FnLikeNode::from_node(node) {
2749 hir::Constness::NotConst
2753 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2755 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2756 let item_id = tcx.hir().ty_param_owner(hir_id);
2757 let item_def_id = tcx.hir().local_def_id(item_id);
2758 let generics = tcx.generics_of(item_def_id);
2759 let index = generics.param_def_id_to_index[&def_id];
2760 ty::GenericPredicates {
2762 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2763 |predicate| match predicate.kind() {
2764 ty::PredicateKind::Trait(ref data, _)
2765 if data.skip_binder().self_ty().is_param(index) =>
2767 // HACK(eddyb) should get the original `Span`.
2768 let span = tcx.def_span(def_id);
2769 Some((predicate, span))
2777 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2779 Some(def) => infer::EarlyBoundRegion(span, def.name),
2780 None => infer::MiscVariable(span),
2782 Some(self.next_region_var(v))
2785 fn allow_ty_infer(&self) -> bool {
2789 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2790 if let Some(param) = param {
2791 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2796 self.next_ty_var(TypeVariableOrigin {
2797 kind: TypeVariableOriginKind::TypeInference,
2806 param: Option<&ty::GenericParamDef>,
2808 ) -> &'tcx Const<'tcx> {
2809 if let Some(param) = param {
2810 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2815 self.next_const_var(
2817 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2822 fn projected_ty_from_poly_trait_ref(
2826 item_segment: &hir::PathSegment<'_>,
2827 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2829 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2831 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2835 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2844 self.tcx().mk_projection(item_def_id, item_substs)
2847 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2848 if ty.has_escaping_bound_vars() {
2849 ty // FIXME: normalization and escaping regions
2851 self.normalize_associated_types_in(span, &ty)
2855 fn set_tainted_by_errors(&self) {
2856 self.infcx.set_tainted_by_errors()
2859 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2860 self.write_ty(hir_id, ty)
2864 /// Controls whether the arguments are tupled. This is used for the call
2867 /// Tupling means that all call-side arguments are packed into a tuple and
2868 /// passed as a single parameter. For example, if tupling is enabled, this
2871 /// fn f(x: (isize, isize))
2873 /// Can be called as:
2880 #[derive(Clone, Eq, PartialEq)]
2881 enum TupleArgumentsFlag {
2886 /// Controls how we perform fallback for unconstrained
2889 /// Do not fallback type variables to opaque types.
2891 /// Perform all possible kinds of fallback, including
2892 /// turning type variables to opaque types.
2896 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2898 inh: &'a Inherited<'a, 'tcx>,
2899 param_env: ty::ParamEnv<'tcx>,
2900 body_id: hir::HirId,
2901 ) -> FnCtxt<'a, 'tcx> {
2905 err_count_on_creation: inh.tcx.sess.err_count(),
2907 ret_coercion_span: RefCell::new(None),
2908 resume_yield_tys: None,
2909 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2910 diverges: Cell::new(Diverges::Maybe),
2911 has_errors: Cell::new(false),
2912 enclosing_breakables: RefCell::new(EnclosingBreakables {
2914 by_id: Default::default(),
2920 pub fn sess(&self) -> &Session {
2924 pub fn errors_reported_since_creation(&self) -> bool {
2925 self.tcx.sess.err_count() > self.err_count_on_creation
2928 /// Produces warning on the given node, if the current point in the
2929 /// function is unreachable, and there hasn't been another warning.
2930 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2931 // FIXME: Combine these two 'if' expressions into one once
2932 // let chains are implemented
2933 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2934 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2935 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2936 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2937 if !span.is_desugaring(DesugaringKind::CondTemporary)
2938 && !span.is_desugaring(DesugaringKind::Async)
2939 && !orig_span.is_desugaring(DesugaringKind::Await)
2941 self.diverges.set(Diverges::WarnedAlways);
2943 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2945 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2946 let msg = format!("unreachable {}", kind);
2948 .span_label(span, &msg)
2952 .unwrap_or("any code following this expression is unreachable"),
2960 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2961 ObligationCause::new(span, self.body_id, code)
2964 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2965 self.cause(span, ObligationCauseCode::MiscObligation)
2968 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2969 /// version (resolve_vars_if_possible), this version will
2970 /// also select obligations if it seems useful, in an effort
2971 /// to get more type information.
2972 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2973 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2975 // No Infer()? Nothing needs doing.
2976 if !ty.has_infer_types_or_consts() {
2977 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2981 // If `ty` is a type variable, see whether we already know what it is.
2982 ty = self.resolve_vars_if_possible(&ty);
2983 if !ty.has_infer_types_or_consts() {
2984 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2988 // If not, try resolving pending obligations as much as
2989 // possible. This can help substantially when there are
2990 // indirect dependencies that don't seem worth tracking
2992 self.select_obligations_where_possible(false, |_| {});
2993 ty = self.resolve_vars_if_possible(&ty);
2995 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2999 fn record_deferred_call_resolution(
3001 closure_def_id: DefId,
3002 r: DeferredCallResolution<'tcx>,
3004 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3005 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3008 fn remove_deferred_call_resolutions(
3010 closure_def_id: DefId,
3011 ) -> Vec<DeferredCallResolution<'tcx>> {
3012 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3013 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3016 pub fn tag(&self) -> String {
3017 format!("{:p}", self)
3020 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3021 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3022 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3027 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3029 "write_ty({:?}, {:?}) in fcx {}",
3031 self.resolve_vars_if_possible(&ty),
3034 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3036 if ty.references_error() {
3037 self.has_errors.set(true);
3038 self.set_tainted_by_errors();
3042 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3043 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3046 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3047 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3050 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3051 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3052 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3053 self.write_substs(hir_id, method.substs);
3055 // When the method is confirmed, the `method.substs` includes
3056 // parameters from not just the method, but also the impl of
3057 // the method -- in particular, the `Self` type will be fully
3058 // resolved. However, those are not something that the "user
3059 // specified" -- i.e., those types come from the inferred type
3060 // of the receiver, not something the user wrote. So when we
3061 // create the user-substs, we want to replace those earlier
3062 // types with just the types that the user actually wrote --
3063 // that is, those that appear on the *method itself*.
3065 // As an example, if the user wrote something like
3066 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3067 // type of `foo` (possibly adjusted), but we don't want to
3068 // include that. We want just the `[_, u32]` part.
3069 if !method.substs.is_noop() {
3070 let method_generics = self.tcx.generics_of(method.def_id);
3071 if !method_generics.params.is_empty() {
3072 let user_type_annotation = self.infcx.probe(|_| {
3073 let user_substs = UserSubsts {
3074 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3075 let i = param.index as usize;
3076 if i < method_generics.parent_count {
3077 self.infcx.var_for_def(DUMMY_SP, param)
3082 user_self_ty: None, // not relevant here
3085 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3091 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3092 self.write_user_type_annotation(hir_id, user_type_annotation);
3097 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3098 if !substs.is_noop() {
3099 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3101 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3105 /// Given the substs that we just converted from the HIR, try to
3106 /// canonicalize them and store them as user-given substitutions
3107 /// (i.e., substitutions that must be respected by the NLL check).
3109 /// This should be invoked **before any unifications have
3110 /// occurred**, so that annotations like `Vec<_>` are preserved
3112 pub fn write_user_type_annotation_from_substs(
3116 substs: SubstsRef<'tcx>,
3117 user_self_ty: Option<UserSelfTy<'tcx>>,
3120 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3121 user_self_ty={:?} in fcx {}",
3129 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3130 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3132 UserSubsts { substs, user_self_ty },
3134 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3135 self.write_user_type_annotation(hir_id, canonicalized);
3139 pub fn write_user_type_annotation(
3142 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3145 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3147 canonical_user_type_annotation,
3151 if !canonical_user_type_annotation.is_identity() {
3154 .user_provided_types_mut()
3155 .insert(hir_id, canonical_user_type_annotation);
3157 debug!("write_user_type_annotation: skipping identity substs");
3161 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3162 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3168 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3169 Entry::Vacant(entry) => {
3172 Entry::Occupied(mut entry) => {
3173 debug!(" - composing on top of {:?}", entry.get());
3174 match (&entry.get()[..], &adj[..]) {
3175 // Applying any adjustment on top of a NeverToAny
3176 // is a valid NeverToAny adjustment, because it can't
3178 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3180 Adjustment { kind: Adjust::Deref(_), .. },
3181 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3183 Adjustment { kind: Adjust::Deref(_), .. },
3184 .. // Any following adjustments are allowed.
3186 // A reborrow has no effect before a dereference.
3188 // FIXME: currently we never try to compose autoderefs
3189 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3191 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3192 expr, entry.get(), adj)
3194 *entry.get_mut() = adj;
3199 /// Basically whenever we are converting from a type scheme into
3200 /// the fn body space, we always want to normalize associated
3201 /// types as well. This function combines the two.
3202 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3204 T: TypeFoldable<'tcx>,
3206 let value = value.subst(self.tcx, substs);
3207 let result = self.normalize_associated_types_in(span, &value);
3208 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3212 /// As `instantiate_type_scheme`, but for the bounds found in a
3213 /// generic type scheme.
3214 fn instantiate_bounds(
3218 substs: SubstsRef<'tcx>,
3219 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3220 let bounds = self.tcx.predicates_of(def_id);
3221 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3222 let result = bounds.instantiate(self.tcx, substs);
3223 let result = self.normalize_associated_types_in(span, &result);
3225 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3226 bounds, substs, result, spans,
3231 /// Replaces the opaque types from the given value with type variables,
3232 /// and records the `OpaqueTypeMap` for later use during writeback. See
3233 /// `InferCtxt::instantiate_opaque_types` for more details.
3234 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3236 parent_id: hir::HirId,
3240 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3242 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3243 parent_def_id, value
3246 let (value, opaque_type_map) =
3247 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3248 parent_def_id.to_def_id(),
3255 let mut opaque_types = self.opaque_types.borrow_mut();
3256 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3257 for (ty, decl) in opaque_type_map {
3258 let _ = opaque_types.insert(ty, decl);
3259 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3265 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3267 T: TypeFoldable<'tcx>,
3269 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3272 fn normalize_associated_types_in_as_infer_ok<T>(
3276 ) -> InferOk<'tcx, T>
3278 T: TypeFoldable<'tcx>,
3280 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3283 pub fn require_type_meets(
3287 code: traits::ObligationCauseCode<'tcx>,
3290 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3293 pub fn require_type_is_sized(
3297 code: traits::ObligationCauseCode<'tcx>,
3299 if !ty.references_error() {
3300 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3301 self.require_type_meets(ty, span, code, lang_item);
3305 pub fn require_type_is_sized_deferred(
3309 code: traits::ObligationCauseCode<'tcx>,
3311 if !ty.references_error() {
3312 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3316 pub fn register_bound(
3320 cause: traits::ObligationCause<'tcx>,
3322 if !ty.references_error() {
3323 self.fulfillment_cx.borrow_mut().register_bound(
3333 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3334 let t = AstConv::ast_ty_to_ty(self, ast_t);
3335 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3339 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3340 let ty = self.to_ty(ast_ty);
3341 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3343 if Self::can_contain_user_lifetime_bounds(ty) {
3344 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3345 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3346 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3352 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3353 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3354 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3355 self.register_wf_obligation(
3357 self.tcx.hir().span(ast_c.hir_id),
3358 ObligationCauseCode::MiscObligation,
3363 // If the type given by the user has free regions, save it for later, since
3364 // NLL would like to enforce those. Also pass in types that involve
3365 // projections, since those can resolve to `'static` bounds (modulo #54940,
3366 // which hopefully will be fixed by the time you see this comment, dear
3367 // reader, although I have my doubts). Also pass in types with inference
3368 // types, because they may be repeated. Other sorts of things are already
3369 // sufficiently enforced with erased regions. =)
3370 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3372 T: TypeFoldable<'tcx>,
3374 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3377 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3378 match self.tables.borrow().node_types().get(id) {
3380 None if self.is_tainted_by_errors() => self.tcx.types.err,
3383 "no type for node {}: {} in fcx {}",
3385 self.tcx.hir().node_to_string(id),
3392 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3393 pub fn register_wf_obligation(
3395 arg: subst::GenericArg<'tcx>,
3397 code: traits::ObligationCauseCode<'tcx>,
3399 // WF obligations never themselves fail, so no real need to give a detailed cause:
3400 let cause = traits::ObligationCause::new(span, self.body_id, code);
3401 self.register_predicate(traits::Obligation::new(
3404 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3408 /// Registers obligations that all `substs` are well-formed.
3409 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3410 for arg in substs.iter().filter(|arg| {
3411 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3413 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3417 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3418 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3419 /// trait/region obligations.
3421 /// For example, if there is a function:
3424 /// fn foo<'a,T:'a>(...)
3427 /// and a reference:
3433 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3434 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3435 pub fn add_obligations_for_parameters(
3437 cause: traits::ObligationCause<'tcx>,
3438 predicates: ty::InstantiatedPredicates<'tcx>,
3440 assert!(!predicates.has_escaping_bound_vars());
3442 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3444 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3445 self.register_predicate(obligation);
3449 // FIXME(arielb1): use this instead of field.ty everywhere
3450 // Only for fields! Returns <none> for methods>
3451 // Indifferent to privacy flags
3455 field: &'tcx ty::FieldDef,
3456 substs: SubstsRef<'tcx>,
3458 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3461 fn check_casts(&self) {
3462 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3463 for cast in deferred_cast_checks.drain(..) {
3468 fn resolve_generator_interiors(&self, def_id: DefId) {
3469 let mut generators = self.deferred_generator_interiors.borrow_mut();
3470 for (body_id, interior, kind) in generators.drain(..) {
3471 self.select_obligations_where_possible(false, |_| {});
3472 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3476 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3478 // - Unconstrained ints are replaced with `i32`.
3480 // - Unconstrained floats are replaced with with `f64`.
3482 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3483 // is enabled. Otherwise, they are replaced with `()`.
3485 // Fallback becomes very dubious if we have encountered type-checking errors.
3486 // In that case, fallback to Error.
3487 // The return value indicates whether fallback has occurred.
3488 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3489 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3490 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3492 assert!(ty.is_ty_infer());
3493 let fallback = match self.type_is_unconstrained_numeric(ty) {
3494 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3495 UnconstrainedInt => self.tcx.types.i32,
3496 UnconstrainedFloat => self.tcx.types.f64,
3497 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3499 // This type variable was created from the instantiation of an opaque
3500 // type. The fact that we're attempting to perform fallback for it
3501 // means that the function neither constrained it to a concrete
3502 // type, nor to the opaque type itself.
3504 // For example, in this code:
3507 // type MyType = impl Copy;
3508 // fn defining_use() -> MyType { true }
3509 // fn other_use() -> MyType { defining_use() }
3512 // `defining_use` will constrain the instantiated inference
3513 // variable to `bool`, while `other_use` will constrain
3514 // the instantiated inference variable to `MyType`.
3516 // When we process opaque types during writeback, we
3517 // will handle cases like `other_use`, and not count
3518 // them as defining usages
3520 // However, we also need to handle cases like this:
3523 // pub type Foo = impl Copy;
3524 // fn produce() -> Option<Foo> {
3529 // In the above snippet, the inference variable created by
3530 // instantiating `Option<Foo>` will be completely unconstrained.
3531 // We treat this as a non-defining use by making the inference
3532 // variable fall back to the opaque type itself.
3533 if let FallbackMode::All = mode {
3534 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3536 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3548 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3549 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3553 fn select_all_obligations_or_error(&self) {
3554 debug!("select_all_obligations_or_error");
3555 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3556 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3560 /// Select as many obligations as we can at present.
3561 fn select_obligations_where_possible(
3563 fallback_has_occurred: bool,
3564 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3566 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3567 if let Err(mut errors) = result {
3568 mutate_fullfillment_errors(&mut errors);
3569 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3573 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3574 /// returns a type of `&T`, but the actual type we assign to the
3575 /// *expression* is `T`. So this function just peels off the return
3576 /// type by one layer to yield `T`.
3577 fn make_overloaded_place_return_type(
3579 method: MethodCallee<'tcx>,
3580 ) -> ty::TypeAndMut<'tcx> {
3581 // extract method return type, which will be &T;
3582 let ret_ty = method.sig.output();
3584 // method returns &T, but the type as visible to user is T, so deref
3585 ret_ty.builtin_deref(true).unwrap()
3590 expr: &hir::Expr<'_>,
3591 base_expr: &'tcx hir::Expr<'tcx>,
3595 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3596 // FIXME(#18741) -- this is almost but not quite the same as the
3597 // autoderef that normal method probing does. They could likely be
3600 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3601 let mut result = None;
3602 while result.is_none() && autoderef.next().is_some() {
3603 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3605 autoderef.finalize(self);
3609 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3610 /// (and otherwise adjust) `base_expr`, looking for a type which either
3611 /// supports builtin indexing or overloaded indexing.
3612 /// This loop implements one step in that search; the autoderef loop
3613 /// is implemented by `lookup_indexing`.
3616 expr: &hir::Expr<'_>,
3617 base_expr: &hir::Expr<'_>,
3618 autoderef: &Autoderef<'a, 'tcx>,
3621 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3622 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3624 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3626 expr, base_expr, adjusted_ty, index_ty
3629 for &unsize in &[false, true] {
3630 let mut self_ty = adjusted_ty;
3632 // We only unsize arrays here.
3633 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3634 self_ty = self.tcx.mk_slice(element_ty);
3640 // If some lookup succeeds, write callee into table and extract index/element
3641 // type from the method signature.
3642 // If some lookup succeeded, install method in table
3643 let input_ty = self.next_ty_var(TypeVariableOrigin {
3644 kind: TypeVariableOriginKind::AutoDeref,
3645 span: base_expr.span,
3647 let method = self.try_overloaded_place_op(
3655 let result = method.map(|ok| {
3656 debug!("try_index_step: success, using overloaded indexing");
3657 let method = self.register_infer_ok_obligations(ok);
3659 let mut adjustments = autoderef.adjust_steps(self, needs);
3660 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3661 let mutbl = match r_mutbl {
3662 hir::Mutability::Not => AutoBorrowMutability::Not,
3663 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3664 // Indexing can be desugared to a method call,
3665 // so maybe we could use two-phase here.
3666 // See the documentation of AllowTwoPhase for why that's
3667 // not the case today.
3668 allow_two_phase_borrow: AllowTwoPhase::No,
3671 adjustments.push(Adjustment {
3672 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3675 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3679 adjustments.push(Adjustment {
3680 kind: Adjust::Pointer(PointerCast::Unsize),
3681 target: method.sig.inputs()[0],
3684 self.apply_adjustments(base_expr, adjustments);
3686 self.write_method_call(expr.hir_id, method);
3687 (input_ty, self.make_overloaded_place_return_type(method).ty)
3689 if result.is_some() {
3697 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
3698 let (tr, name) = match (op, is_mut) {
3699 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3700 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3701 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3702 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3704 (tr, Ident::with_dummy_span(name))
3707 fn try_overloaded_place_op(
3711 arg_tys: &[Ty<'tcx>],
3714 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3715 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3717 // Try Mut first, if needed.
3718 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3719 let method = match (needs, mut_tr) {
3720 (Needs::MutPlace, Some(trait_did)) => {
3721 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3726 // Otherwise, fall back to the immutable version.
3727 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3728 match (method, imm_tr) {
3729 (None, Some(trait_did)) => {
3730 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3732 (method, _) => method,
3736 fn check_method_argument_types(
3739 expr: &'tcx hir::Expr<'tcx>,
3740 method: Result<MethodCallee<'tcx>, ()>,
3741 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3742 tuple_arguments: TupleArgumentsFlag,
3743 expected: Expectation<'tcx>,
3745 let has_error = match method {
3746 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3750 let err_inputs = self.err_args(args_no_rcvr.len());
3752 let err_inputs = match tuple_arguments {
3753 DontTupleArguments => err_inputs,
3754 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3757 self.check_argument_types(
3767 return self.tcx.types.err;
3770 let method = method.unwrap();
3771 // HACK(eddyb) ignore self in the definition (see above).
3772 let expected_arg_tys = self.expected_inputs_for_expected_output(
3775 method.sig.output(),
3776 &method.sig.inputs()[1..],
3778 self.check_argument_types(
3781 &method.sig.inputs()[1..],
3782 &expected_arg_tys[..],
3784 method.sig.c_variadic,
3786 self.tcx.hir().span_if_local(method.def_id),
3791 fn self_type_matches_expected_vid(
3793 trait_ref: ty::PolyTraitRef<'tcx>,
3794 expected_vid: ty::TyVid,
3796 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3798 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3799 trait_ref, self_ty, expected_vid
3801 match self_ty.kind {
3802 ty::Infer(ty::TyVar(found_vid)) => {
3803 // FIXME: consider using `sub_root_var` here so we
3804 // can see through subtyping.
3805 let found_vid = self.root_var(found_vid);
3806 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3807 expected_vid == found_vid
3813 fn obligations_for_self_ty<'b>(
3816 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3819 // FIXME: consider using `sub_root_var` here so we
3820 // can see through subtyping.
3821 let ty_var_root = self.root_var(self_ty);
3823 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3826 self.fulfillment_cx.borrow().pending_obligations()
3831 .pending_obligations()
3833 .filter_map(move |obligation| match obligation.predicate.kind() {
3834 ty::PredicateKind::Projection(ref data) => {
3835 Some((data.to_poly_trait_ref(self.tcx), obligation))
3837 ty::PredicateKind::Trait(ref data, _) => {
3838 Some((data.to_poly_trait_ref(), obligation))
3840 ty::PredicateKind::Subtype(..) => None,
3841 ty::PredicateKind::RegionOutlives(..) => None,
3842 ty::PredicateKind::TypeOutlives(..) => None,
3843 ty::PredicateKind::WellFormed(..) => None,
3844 ty::PredicateKind::ObjectSafe(..) => None,
3845 ty::PredicateKind::ConstEvaluatable(..) => None,
3846 ty::PredicateKind::ConstEquate(..) => None,
3847 // N.B., this predicate is created by breaking down a
3848 // `ClosureType: FnFoo()` predicate, where
3849 // `ClosureType` represents some `Closure`. It can't
3850 // possibly be referring to the current closure,
3851 // because we haven't produced the `Closure` for
3852 // this closure yet; this is exactly why the other
3853 // code is looking for a self type of a unresolved
3854 // inference variable.
3855 ty::PredicateKind::ClosureKind(..) => None,
3857 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3860 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3861 self.obligations_for_self_ty(self_ty)
3862 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3865 /// Generic function that factors out common logic from function calls,
3866 /// method calls and overloaded operators.
3867 fn check_argument_types(
3870 expr: &'tcx hir::Expr<'tcx>,
3871 fn_inputs: &[Ty<'tcx>],
3872 expected_arg_tys: &[Ty<'tcx>],
3873 args: &'tcx [hir::Expr<'tcx>],
3875 tuple_arguments: TupleArgumentsFlag,
3876 def_span: Option<Span>,
3879 // Grab the argument types, supplying fresh type variables
3880 // if the wrong number of arguments were supplied
3881 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3883 // All the input types from the fn signature must outlive the call
3884 // so as to validate implied bounds.
3885 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3886 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3889 let expected_arg_count = fn_inputs.len();
3891 let param_count_error = |expected_count: usize,
3896 let (span, start_span, args) = match &expr.kind {
3897 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3898 hir::ExprKind::MethodCall(path_segment, span, args) => (
3900 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3903 .and_then(|args| args.args.iter().last())
3904 // Account for `foo.bar::<T>()`.
3906 // Skip the closing `>`.
3909 .next_point(tcx.sess.source_map().next_point(arg.span()))
3912 &args[1..], // Skip the receiver.
3914 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3916 let arg_spans = if args.is_empty() {
3918 // ^^^-- supplied 0 arguments
3920 // expected 2 arguments
3921 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3924 // ^^^ - - - supplied 3 arguments
3926 // expected 2 arguments
3927 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3930 let mut err = tcx.sess.struct_span_err_with_code(
3933 "this function takes {}{} but {} {} supplied",
3934 if c_variadic { "at least " } else { "" },
3935 potentially_plural_count(expected_count, "argument"),
3936 potentially_plural_count(arg_count, "argument"),
3937 if arg_count == 1 { "was" } else { "were" }
3939 DiagnosticId::Error(error_code.to_owned()),
3941 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3942 for (i, span) in arg_spans.into_iter().enumerate() {
3945 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3949 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3950 err.span_label(def_s, "defined here");
3953 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3954 // remove closing `)` from the span
3955 let sugg_span = sugg_span.shrink_to_lo();
3956 err.span_suggestion(
3958 "expected the unit value `()`; create it with empty parentheses",
3960 Applicability::MachineApplicable,
3967 if c_variadic { "at least " } else { "" },
3968 potentially_plural_count(expected_count, "argument")
3975 let mut expected_arg_tys = expected_arg_tys.to_vec();
3977 let formal_tys = if tuple_arguments == TupleArguments {
3978 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3979 match tuple_type.kind {
3980 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3981 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3982 expected_arg_tys = vec![];
3983 self.err_args(args.len())
3985 ty::Tuple(arg_types) => {
3986 expected_arg_tys = match expected_arg_tys.get(0) {
3987 Some(&ty) => match ty.kind {
3988 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3993 arg_types.iter().map(|k| k.expect_ty()).collect()
4000 "cannot use call notation; the first type parameter \
4001 for the function trait is neither a tuple nor unit"
4004 expected_arg_tys = vec![];
4005 self.err_args(args.len())
4008 } else if expected_arg_count == supplied_arg_count {
4010 } else if c_variadic {
4011 if supplied_arg_count >= expected_arg_count {
4014 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4015 expected_arg_tys = vec![];
4016 self.err_args(supplied_arg_count)
4019 // is the missing argument of type `()`?
4020 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4021 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4022 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4023 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4027 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4029 expected_arg_tys = vec![];
4030 self.err_args(supplied_arg_count)
4034 "check_argument_types: formal_tys={:?}",
4035 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4038 // If there is no expectation, expect formal_tys.
4039 let expected_arg_tys =
4040 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4042 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4044 // Check the arguments.
4045 // We do this in a pretty awful way: first we type-check any arguments
4046 // that are not closures, then we type-check the closures. This is so
4047 // that we have more information about the types of arguments when we
4048 // type-check the functions. This isn't really the right way to do this.
4049 for &check_closures in &[false, true] {
4050 debug!("check_closures={}", check_closures);
4052 // More awful hacks: before we check argument types, try to do
4053 // an "opportunistic" vtable resolution of any trait bounds on
4054 // the call. This helps coercions.
4056 self.select_obligations_where_possible(false, |errors| {
4057 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4058 self.point_at_arg_instead_of_call_if_possible(
4060 &final_arg_types[..],
4067 // For C-variadic functions, we don't have a declared type for all of
4068 // the arguments hence we only do our usual type checking with
4069 // the arguments who's types we do know.
4070 let t = if c_variadic {
4072 } else if tuple_arguments == TupleArguments {
4077 for (i, arg) in args.iter().take(t).enumerate() {
4078 // Warn only for the first loop (the "no closures" one).
4079 // Closure arguments themselves can't be diverging, but
4080 // a previous argument can, e.g., `foo(panic!(), || {})`.
4081 if !check_closures {
4082 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4085 let is_closure = match arg.kind {
4086 ExprKind::Closure(..) => true,
4090 if is_closure != check_closures {
4094 debug!("checking the argument");
4095 let formal_ty = formal_tys[i];
4097 // The special-cased logic below has three functions:
4098 // 1. Provide as good of an expected type as possible.
4099 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4101 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4103 // 2. Coerce to the most detailed type that could be coerced
4104 // to, which is `expected_ty` if `rvalue_hint` returns an
4105 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4106 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4107 // We're processing function arguments so we definitely want to use
4108 // two-phase borrows.
4109 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4110 final_arg_types.push((i, checked_ty, coerce_ty));
4112 // 3. Relate the expected type and the formal one,
4113 // if the expected type was used for the coercion.
4114 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4118 // We also need to make sure we at least write the ty of the other
4119 // arguments which we skipped above.
4121 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4122 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4123 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4126 for arg in args.iter().skip(expected_arg_count) {
4127 let arg_ty = self.check_expr(&arg);
4129 // There are a few types which get autopromoted when passed via varargs
4130 // in C but we just error out instead and require explicit casts.
4131 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4133 ty::Float(ast::FloatTy::F32) => {
4134 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4136 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4137 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4139 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4140 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4143 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4144 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4145 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4153 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4154 vec![self.tcx.types.err; len]
4157 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4158 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4159 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4160 /// can be not easily comparable with predicate type (because of coercion). If the types match
4161 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4162 /// the corresponding argument's expression span instead of the `fn` call path span.
4163 fn point_at_arg_instead_of_call_if_possible(
4165 errors: &mut Vec<traits::FulfillmentError<'_>>,
4166 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4168 args: &'tcx [hir::Expr<'tcx>],
4170 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4171 // the `?` operator.
4172 if call_sp.desugaring_kind().is_some() {
4176 for error in errors {
4177 // Only if the cause is somewhere inside the expression we want try to point at arg.
4178 // Otherwise, it means that the cause is somewhere else and we should not change
4179 // anything because we can break the correct span.
4180 if !call_sp.contains(error.obligation.cause.span) {
4184 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate.kind() {
4185 // Collect the argument position for all arguments that could have caused this
4186 // `FulfillmentError`.
4187 let mut referenced_in = final_arg_types
4189 .map(|&(i, checked_ty, _)| (i, checked_ty))
4190 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4191 .flat_map(|(i, ty)| {
4192 let ty = self.resolve_vars_if_possible(&ty);
4193 // We walk the argument type because the argument's type could have
4194 // been `Option<T>`, but the `FulfillmentError` references `T`.
4195 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4201 .collect::<Vec<_>>();
4203 // Both checked and coerced types could have matched, thus we need to remove
4205 referenced_in.sort();
4206 referenced_in.dedup();
4208 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4209 // We make sure that only *one* argument matches the obligation failure
4210 // and we assign the obligation's span to its expression's.
4211 error.obligation.cause.span = args[ref_in].span;
4212 error.points_at_arg_span = true;
4218 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4219 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4220 /// were caused by them. If they were, we point at the corresponding type argument's span
4221 /// instead of the `fn` call path span.
4222 fn point_at_type_arg_instead_of_call_if_possible(
4224 errors: &mut Vec<traits::FulfillmentError<'_>>,
4225 call_expr: &'tcx hir::Expr<'tcx>,
4227 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4228 if let hir::ExprKind::Path(qpath) = &path.kind {
4229 if let hir::QPath::Resolved(_, path) = &qpath {
4230 for error in errors {
4231 if let ty::PredicateKind::Trait(predicate, _) =
4232 error.obligation.predicate.kind()
4234 // If any of the type arguments in this path segment caused the
4235 // `FullfillmentError`, point at its span (#61860).
4239 .filter_map(|seg| seg.args.as_ref())
4240 .flat_map(|a| a.args.iter())
4242 if let hir::GenericArg::Type(hir_ty) = &arg {
4243 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4246 // Avoid ICE with associated types. As this is best
4247 // effort only, it's ok to ignore the case. It
4248 // would trigger in `is_send::<T::AssocType>();`
4249 // from `typeck-default-trait-impl-assoc-type.rs`.
4251 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4252 let ty = self.resolve_vars_if_possible(&ty);
4253 if ty == predicate.skip_binder().self_ty() {
4254 error.obligation.cause.span = hir_ty.span;
4266 // AST fragment checking
4267 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4271 ast::LitKind::Str(..) => tcx.mk_static_str(),
4272 ast::LitKind::ByteStr(ref v) => {
4273 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4275 ast::LitKind::Byte(_) => tcx.types.u8,
4276 ast::LitKind::Char(_) => tcx.types.char,
4277 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4278 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4279 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4280 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4281 ty::Int(_) | ty::Uint(_) => Some(ty),
4282 ty::Char => Some(tcx.types.u8),
4283 ty::RawPtr(..) => Some(tcx.types.usize),
4284 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4287 opt_ty.unwrap_or_else(|| self.next_int_var())
4289 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4290 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4291 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4292 ty::Float(_) => Some(ty),
4295 opt_ty.unwrap_or_else(|| self.next_float_var())
4297 ast::LitKind::Bool(_) => tcx.types.bool,
4298 ast::LitKind::Err(_) => tcx.types.err,
4302 /// Unifies the output type with the expected type early, for more coercions
4303 /// and forward type information on the input expressions.
4304 fn expected_inputs_for_expected_output(
4307 expected_ret: Expectation<'tcx>,
4308 formal_ret: Ty<'tcx>,
4309 formal_args: &[Ty<'tcx>],
4310 ) -> Vec<Ty<'tcx>> {
4311 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4312 let ret_ty = match expected_ret.only_has_type(self) {
4314 None => return Vec::new(),
4316 let expect_args = self
4317 .fudge_inference_if_ok(|| {
4318 // Attempt to apply a subtyping relationship between the formal
4319 // return type (likely containing type variables if the function
4320 // is polymorphic) and the expected return type.
4321 // No argument expectations are produced if unification fails.
4322 let origin = self.misc(call_span);
4323 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4325 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4326 // to identity so the resulting type is not constrained.
4329 // Process any obligations locally as much as
4330 // we can. We don't care if some things turn
4331 // out unconstrained or ambiguous, as we're
4332 // just trying to get hints here.
4333 self.save_and_restore_in_snapshot_flag(|_| {
4334 let mut fulfill = TraitEngine::new(self.tcx);
4335 for obligation in ok.obligations {
4336 fulfill.register_predicate_obligation(self, obligation);
4338 fulfill.select_where_possible(self)
4342 Err(_) => return Err(()),
4345 // Record all the argument types, with the substitutions
4346 // produced from the above subtyping unification.
4347 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4349 .unwrap_or_default();
4351 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4352 formal_args, formal_ret, expect_args, expected_ret
4357 pub fn check_struct_path(
4361 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4362 let path_span = match *qpath {
4363 QPath::Resolved(_, ref path) => path.span,
4364 QPath::TypeRelative(ref qself, _) => qself.span,
4366 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4367 let variant = match def {
4369 self.set_tainted_by_errors();
4372 Res::Def(DefKind::Variant, _) => match ty.kind {
4373 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4374 _ => bug!("unexpected type: {:?}", ty),
4376 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4377 | Res::SelfTy(..) => match ty.kind {
4378 ty::Adt(adt, substs) if !adt.is_enum() => {
4379 Some((adt.non_enum_variant(), adt.did, substs))
4383 _ => bug!("unexpected definition: {:?}", def),
4386 if let Some((variant, did, substs)) = variant {
4387 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4388 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4390 // Check bounds on type arguments used in the path.
4391 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4393 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4394 self.add_obligations_for_parameters(cause, bounds);
4402 "expected struct, variant or union type, found {}",
4403 ty.sort_string(self.tcx)
4405 .span_label(path_span, "not a struct")
4411 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4412 // The newly resolved definition is written into `type_dependent_defs`.
4413 fn finish_resolving_struct_path(
4418 ) -> (Res, Ty<'tcx>) {
4420 QPath::Resolved(ref maybe_qself, ref path) => {
4421 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4422 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4425 QPath::TypeRelative(ref qself, ref segment) => {
4426 let ty = self.to_ty(qself);
4428 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4434 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4435 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4436 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4438 // Write back the new resolution.
4439 self.write_resolution(hir_id, result);
4441 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4446 /// Resolves an associated value path into a base type and associated constant, or method
4447 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4448 pub fn resolve_ty_and_res_ufcs<'b>(
4450 qpath: &'b QPath<'b>,
4453 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4454 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4455 let (ty, qself, item_segment) = match *qpath {
4456 QPath::Resolved(ref opt_qself, ref path) => {
4459 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4463 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4465 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4466 // Return directly on cache hit. This is useful to avoid doubly reporting
4467 // errors with default match binding modes. See #44614.
4469 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4470 return (def, Some(ty), slice::from_ref(&**item_segment));
4472 let item_name = item_segment.ident;
4473 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4474 let result = match error {
4475 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4476 _ => Err(ErrorReported),
4478 if item_name.name != kw::Invalid {
4479 if let Some(mut e) = self.report_method_error(
4483 SelfSource::QPath(qself),
4493 // Write back the new resolution.
4494 self.write_resolution(hir_id, result);
4496 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4498 slice::from_ref(&**item_segment),
4502 pub fn check_decl_initializer(
4504 local: &'tcx hir::Local<'tcx>,
4505 init: &'tcx hir::Expr<'tcx>,
4507 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4508 // for #42640 (default match binding modes).
4511 let ref_bindings = local.pat.contains_explicit_ref_binding();
4513 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4514 if let Some(m) = ref_bindings {
4515 // Somewhat subtle: if we have a `ref` binding in the pattern,
4516 // we want to avoid introducing coercions for the RHS. This is
4517 // both because it helps preserve sanity and, in the case of
4518 // ref mut, for soundness (issue #23116). In particular, in
4519 // the latter case, we need to be clear that the type of the
4520 // referent for the reference that results is *equal to* the
4521 // type of the place it is referencing, and not some
4522 // supertype thereof.
4523 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4524 self.demand_eqtype(init.span, local_ty, init_ty);
4527 self.check_expr_coercable_to_type(init, local_ty)
4531 /// Type check a `let` statement.
4532 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4533 // Determine and write the type which we'll check the pattern against.
4534 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4535 self.write_ty(local.hir_id, ty);
4537 // Type check the initializer.
4538 if let Some(ref init) = local.init {
4539 let init_ty = self.check_decl_initializer(local, &init);
4540 self.overwrite_local_ty_if_err(local, ty, init_ty);
4543 // Does the expected pattern type originate from an expression and what is the span?
4544 let (origin_expr, ty_span) = match (local.ty, local.init) {
4545 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4546 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4547 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4550 // Type check the pattern. Override if necessary to avoid knock-on errors.
4551 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4552 let pat_ty = self.node_ty(local.pat.hir_id);
4553 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4556 fn overwrite_local_ty_if_err(
4558 local: &'tcx hir::Local<'tcx>,
4562 if ty.references_error() {
4563 // Override the types everywhere with `types.err` to avoid knock on errors.
4564 self.write_ty(local.hir_id, ty);
4565 self.write_ty(local.pat.hir_id, ty);
4566 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4567 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4568 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4572 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4573 err.span_suggestion_short(
4574 span.shrink_to_hi(),
4575 "consider using a semicolon here",
4577 Applicability::MachineApplicable,
4581 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4582 // Don't do all the complex logic below for `DeclItem`.
4584 hir::StmtKind::Item(..) => return,
4585 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4588 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4590 // Hide the outer diverging and `has_errors` flags.
4591 let old_diverges = self.diverges.replace(Diverges::Maybe);
4592 let old_has_errors = self.has_errors.replace(false);
4595 hir::StmtKind::Local(ref l) => {
4596 self.check_decl_local(&l);
4599 hir::StmtKind::Item(_) => {}
4600 hir::StmtKind::Expr(ref expr) => {
4601 // Check with expected type of `()`.
4602 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4603 self.suggest_semicolon_at_end(expr.span, err);
4606 hir::StmtKind::Semi(ref expr) => {
4607 self.check_expr(&expr);
4611 // Combine the diverging and `has_error` flags.
4612 self.diverges.set(self.diverges.get() | old_diverges);
4613 self.has_errors.set(self.has_errors.get() | old_has_errors);
4616 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4617 let unit = self.tcx.mk_unit();
4618 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4620 // if the block produces a `!` value, that can always be
4621 // (effectively) coerced to unit.
4623 self.demand_suptype(blk.span, unit, ty);
4627 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4628 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4629 /// when given code like the following:
4631 /// if false { return 0i32; } else { 1u32 }
4632 /// // ^^^^ point at this instead of the whole `if` expression
4634 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4635 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4636 let arm_spans: Vec<Span> = arms
4639 self.in_progress_tables
4640 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4641 .and_then(|arm_ty| {
4642 if arm_ty.is_never() {
4645 Some(match &arm.body.kind {
4646 // Point at the tail expression when possible.
4647 hir::ExprKind::Block(block, _) => {
4648 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4656 if arm_spans.len() == 1 {
4657 return arm_spans[0];
4663 fn check_block_with_expected(
4665 blk: &'tcx hir::Block<'tcx>,
4666 expected: Expectation<'tcx>,
4669 let mut fcx_ps = self.ps.borrow_mut();
4670 let unsafety_state = fcx_ps.recurse(blk);
4671 replace(&mut *fcx_ps, unsafety_state)
4674 // In some cases, blocks have just one exit, but other blocks
4675 // can be targeted by multiple breaks. This can happen both
4676 // with labeled blocks as well as when we desugar
4677 // a `try { ... }` expression.
4681 // 'a: { if true { break 'a Err(()); } Ok(()) }
4683 // Here we would wind up with two coercions, one from
4684 // `Err(())` and the other from the tail expression
4685 // `Ok(())`. If the tail expression is omitted, that's a
4686 // "forced unit" -- unless the block diverges, in which
4687 // case we can ignore the tail expression (e.g., `'a: {
4688 // break 'a 22; }` would not force the type of the block
4690 let tail_expr = blk.expr.as_ref();
4691 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4692 let coerce = if blk.targeted_by_break {
4693 CoerceMany::new(coerce_to_ty)
4695 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4696 Some(e) => slice::from_ref(e),
4699 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4702 let prev_diverges = self.diverges.get();
4703 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4705 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4706 for s in blk.stmts {
4710 // check the tail expression **without** holding the
4711 // `enclosing_breakables` lock below.
4712 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4714 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4715 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4716 let coerce = ctxt.coerce.as_mut().unwrap();
4717 if let Some(tail_expr_ty) = tail_expr_ty {
4718 let tail_expr = tail_expr.unwrap();
4719 let span = self.get_expr_coercion_span(tail_expr);
4720 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4721 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4723 // Subtle: if there is no explicit tail expression,
4724 // that is typically equivalent to a tail expression
4725 // of `()` -- except if the block diverges. In that
4726 // case, there is no value supplied from the tail
4727 // expression (assuming there are no other breaks,
4728 // this implies that the type of the block will be
4731 // #41425 -- label the implicit `()` as being the
4732 // "found type" here, rather than the "expected type".
4733 if !self.diverges.get().is_always() {
4734 // #50009 -- Do not point at the entire fn block span, point at the return type
4735 // span, as it is the cause of the requirement, and
4736 // `consider_hint_about_removing_semicolon` will point at the last expression
4737 // if it were a relevant part of the error. This improves usability in editors
4738 // that highlight errors inline.
4739 let mut sp = blk.span;
4740 let mut fn_span = None;
4741 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4742 let ret_sp = decl.output.span();
4743 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4744 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4745 // output would otherwise be incorrect and even misleading. Make sure
4746 // the span we're aiming at correspond to a `fn` body.
4747 if block_sp == blk.span {
4749 fn_span = Some(ident.span);
4753 coerce.coerce_forced_unit(
4757 if let Some(expected_ty) = expected.only_has_type(self) {
4758 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4760 if let Some(fn_span) = fn_span {
4763 "implicitly returns `()` as its body has no tail or `return` \
4775 // If we can break from the block, then the block's exit is always reachable
4776 // (... as long as the entry is reachable) - regardless of the tail of the block.
4777 self.diverges.set(prev_diverges);
4780 let mut ty = ctxt.coerce.unwrap().complete(self);
4782 if self.has_errors.get() || ty.references_error() {
4783 ty = self.tcx.types.err
4786 self.write_ty(blk.hir_id, ty);
4788 *self.ps.borrow_mut() = prev;
4792 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4793 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4795 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4796 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4797 let body = self.tcx.hir().body(body_id);
4798 if let ExprKind::Block(block, _) = &body.value.kind {
4799 return Some(block.span);
4807 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4808 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4809 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4810 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4813 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4814 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4816 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4817 // This is less than ideal, it will not suggest a return type span on any
4818 // method called `main`, regardless of whether it is actually the entry point,
4819 // but it will still present it as the reason for the expected type.
4820 Some((&sig.decl, ident, ident.name != sym::main))
4822 Node::TraitItem(&hir::TraitItem {
4824 kind: hir::TraitItemKind::Fn(ref sig, ..),
4826 }) => Some((&sig.decl, ident, true)),
4827 Node::ImplItem(&hir::ImplItem {
4829 kind: hir::ImplItemKind::Fn(ref sig, ..),
4831 }) => Some((&sig.decl, ident, false)),
4836 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4837 /// suggestion can be made, `None` otherwise.
4838 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4839 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4840 // `while` before reaching it, as block tail returns are not available in them.
4841 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4842 let parent = self.tcx.hir().get(blk_id);
4843 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4847 /// On implicit return expressions with mismatched types, provides the following suggestions:
4849 /// - Points out the method's return type as the reason for the expected type.
4850 /// - Possible missing semicolon.
4851 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4852 pub fn suggest_mismatched_types_on_tail(
4854 err: &mut DiagnosticBuilder<'_>,
4855 expr: &'tcx hir::Expr<'tcx>,
4861 let expr = expr.peel_drop_temps();
4862 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4863 let mut pointing_at_return_type = false;
4864 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4865 pointing_at_return_type =
4866 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4868 pointing_at_return_type
4871 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4872 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4874 /// fn foo(x: usize) -> usize { x }
4875 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4879 err: &mut DiagnosticBuilder<'_>,
4880 expr: &hir::Expr<'_>,
4884 let hir = self.tcx.hir();
4885 let (def_id, sig) = match found.kind {
4886 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4887 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4891 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4892 let sig = self.normalize_associated_types_in(expr.span, &sig);
4893 if self.can_coerce(sig.output(), expected) {
4894 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4895 (String::new(), Applicability::MachineApplicable)
4897 ("...".to_string(), Applicability::HasPlaceholders)
4899 let mut msg = "call this function";
4900 match hir.get_if_local(def_id) {
4902 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4903 | Node::ImplItem(hir::ImplItem {
4904 kind: hir::ImplItemKind::Fn(_, body_id), ..
4906 | Node::TraitItem(hir::TraitItem {
4907 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4911 let body = hir.body(*body_id);
4915 .map(|param| match ¶m.pat.kind {
4916 hir::PatKind::Binding(_, _, ident, None)
4917 if ident.name != kw::SelfLower =>
4921 _ => "_".to_string(),
4923 .collect::<Vec<_>>()
4926 Some(Node::Expr(hir::Expr {
4927 kind: ExprKind::Closure(_, _, body_id, _, _),
4928 span: full_closure_span,
4931 if *full_closure_span == expr.span {
4934 msg = "call this closure";
4935 let body = hir.body(*body_id);
4939 .map(|param| match ¶m.pat.kind {
4940 hir::PatKind::Binding(_, _, ident, None)
4941 if ident.name != kw::SelfLower =>
4945 _ => "_".to_string(),
4947 .collect::<Vec<_>>()
4950 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4951 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4952 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
4953 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4954 msg = "instantiate this tuple variant";
4956 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
4957 msg = "instantiate this tuple struct";
4962 Some(Node::ForeignItem(hir::ForeignItem {
4963 kind: hir::ForeignItemKind::Fn(_, idents, _),
4969 if ident.name != kw::SelfLower {
4975 .collect::<Vec<_>>()
4978 Some(Node::TraitItem(hir::TraitItem {
4979 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
4985 if ident.name != kw::SelfLower {
4991 .collect::<Vec<_>>()
4996 err.span_suggestion_verbose(
4997 expr.span.shrink_to_hi(),
4998 &format!("use parentheses to {}", msg),
4999 format!("({})", sugg_call),
5007 pub fn suggest_deref_ref_or_into(
5009 err: &mut DiagnosticBuilder<'_>,
5010 expr: &hir::Expr<'_>,
5014 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5015 err.span_suggestion(sp, msg, suggestion, applicability);
5016 } else if let (ty::FnDef(def_id, ..), true) =
5017 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5019 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5020 let sp = self.sess().source_map().guess_head_span(sp);
5021 err.span_label(sp, &format!("{} defined here", found));
5023 } else if !self.check_for_cast(err, expr, found, expected) {
5024 let is_struct_pat_shorthand_field =
5025 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5026 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5027 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5028 let mut suggestions = iter::repeat(&expr_text)
5029 .zip(methods.iter())
5030 .filter_map(|(receiver, method)| {
5031 let method_call = format!(".{}()", method.ident);
5032 if receiver.ends_with(&method_call) {
5033 None // do not suggest code that is already there (#53348)
5035 let method_call_list = [".to_vec()", ".to_string()"];
5036 let sugg = if receiver.ends_with(".clone()")
5037 && method_call_list.contains(&method_call.as_str())
5039 let max_len = receiver.rfind('.').unwrap();
5040 format!("{}{}", &receiver[..max_len], method_call)
5042 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5043 format!("({}){}", receiver, method_call)
5045 format!("{}{}", receiver, method_call)
5048 Some(if is_struct_pat_shorthand_field {
5049 format!("{}: {}", receiver, sugg)
5056 if suggestions.peek().is_some() {
5057 err.span_suggestions(
5059 "try using a conversion method",
5061 Applicability::MaybeIncorrect,
5068 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5069 /// in the heap by calling `Box::new()`.
5070 fn suggest_boxing_when_appropriate(
5072 err: &mut DiagnosticBuilder<'_>,
5073 expr: &hir::Expr<'_>,
5077 if self.tcx.hir().is_const_context(expr.hir_id) {
5078 // Do not suggest `Box::new` in const context.
5081 if !expected.is_box() || found.is_box() {
5084 let boxed_found = self.tcx.mk_box(found);
5085 if let (true, Ok(snippet)) = (
5086 self.can_coerce(boxed_found, expected),
5087 self.sess().source_map().span_to_snippet(expr.span),
5089 err.span_suggestion(
5091 "store this in the heap by calling `Box::new`",
5092 format!("Box::new({})", snippet),
5093 Applicability::MachineApplicable,
5096 "for more on the distinction between the stack and the heap, read \
5097 https://doc.rust-lang.org/book/ch15-01-box.html, \
5098 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5099 https://doc.rust-lang.org/std/boxed/index.html",
5104 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5105 fn suggest_calling_boxed_future_when_appropriate(
5107 err: &mut DiagnosticBuilder<'_>,
5108 expr: &hir::Expr<'_>,
5114 if self.tcx.hir().is_const_context(expr.hir_id) {
5115 // Do not suggest `Box::new` in const context.
5118 let pin_did = self.tcx.lang_items().pin_type();
5119 match expected.kind {
5120 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5121 // This guards the `unwrap` and `mk_box` below.
5122 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5125 let boxed_found = self.tcx.mk_box(found);
5126 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5127 if let (true, Ok(snippet)) = (
5128 self.can_coerce(new_found, expected),
5129 self.sess().source_map().span_to_snippet(expr.span),
5132 ty::Adt(def, _) if def.is_box() => {
5133 err.help("use `Box::pin`");
5136 err.span_suggestion(
5138 "you need to pin and box this expression",
5139 format!("Box::pin({})", snippet),
5140 Applicability::MachineApplicable,
5150 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5154 /// bar_that_returns_u32()
5158 /// This routine checks if the return expression in a block would make sense on its own as a
5159 /// statement and the return type has been left as default or has been specified as `()`. If so,
5160 /// it suggests adding a semicolon.
5161 fn suggest_missing_semicolon(
5163 err: &mut DiagnosticBuilder<'_>,
5164 expression: &'tcx hir::Expr<'tcx>,
5168 if expected.is_unit() {
5169 // `BlockTailExpression` only relevant if the tail expr would be
5170 // useful on its own.
5171 match expression.kind {
5173 | ExprKind::MethodCall(..)
5174 | ExprKind::Loop(..)
5175 | ExprKind::Match(..)
5176 | ExprKind::Block(..) => {
5177 err.span_suggestion(
5178 cause_span.shrink_to_hi(),
5179 "try adding a semicolon",
5181 Applicability::MachineApplicable,
5189 /// A possible error is to forget to add a return type that is needed:
5193 /// bar_that_returns_u32()
5197 /// This routine checks if the return type is left as default, the method is not part of an
5198 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5200 fn suggest_missing_return_type(
5202 err: &mut DiagnosticBuilder<'_>,
5203 fn_decl: &hir::FnDecl<'_>,
5208 // Only suggest changing the return type for methods that
5209 // haven't set a return type at all (and aren't `fn main()` or an impl).
5210 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5211 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5212 err.span_suggestion(
5214 "try adding a return type",
5215 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5216 Applicability::MachineApplicable,
5220 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5221 err.span_label(span, "possibly return type missing here?");
5224 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5225 // `fn main()` must return `()`, do not suggest changing return type
5226 err.span_label(span, "expected `()` because of default return type");
5229 // expectation was caused by something else, not the default return
5230 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5231 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5232 // Only point to return type if the expected type is the return type, as if they
5233 // are not, the expectation must have been caused by something else.
5234 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5236 let ty = AstConv::ast_ty_to_ty(self, ty);
5237 debug!("suggest_missing_return_type: return type {:?}", ty);
5238 debug!("suggest_missing_return_type: expected type {:?}", ty);
5239 if ty.kind == expected.kind {
5240 err.span_label(sp, format!("expected `{}` because of return type", expected));
5248 /// A possible error is to forget to add `.await` when using futures:
5251 /// async fn make_u32() -> u32 {
5255 /// fn take_u32(x: u32) {}
5257 /// async fn foo() {
5258 /// let x = make_u32();
5263 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5264 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5265 /// `.await` to the tail of the expression.
5266 fn suggest_missing_await(
5268 err: &mut DiagnosticBuilder<'_>,
5269 expr: &hir::Expr<'_>,
5273 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5274 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5275 // body isn't `async`.
5276 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5277 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5278 let body = self.tcx().hir().body(body_id);
5279 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5281 // Check for `Future` implementations by constructing a predicate to
5282 // prove: `<T as Future>::Output == U`
5283 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5284 let item_def_id = self
5286 .associated_items(future_trait)
5287 .in_definition_order()
5291 // `<T as Future>::Output`
5292 let projection_ty = ty::ProjectionTy {
5296 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5302 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5306 .to_predicate(self.tcx);
5307 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5309 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5311 if self.infcx.predicate_may_hold(&obligation) {
5312 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5313 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5314 err.span_suggestion(
5316 "consider using `.await` here",
5317 format!("{}.await", code),
5318 Applicability::MaybeIncorrect,
5321 debug!("suggest_missing_await: no snippet for {:?}", sp);
5324 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5330 /// A common error is to add an extra semicolon:
5333 /// fn foo() -> usize {
5338 /// This routine checks if the final statement in a block is an
5339 /// expression with an explicit semicolon whose type is compatible
5340 /// with `expected_ty`. If so, it suggests removing the semicolon.
5341 fn consider_hint_about_removing_semicolon(
5343 blk: &'tcx hir::Block<'tcx>,
5344 expected_ty: Ty<'tcx>,
5345 err: &mut DiagnosticBuilder<'_>,
5347 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5348 err.span_suggestion(
5350 "consider removing this semicolon",
5352 Applicability::MachineApplicable,
5357 fn could_remove_semicolon(
5359 blk: &'tcx hir::Block<'tcx>,
5360 expected_ty: Ty<'tcx>,
5362 // Be helpful when the user wrote `{... expr;}` and
5363 // taking the `;` off is enough to fix the error.
5364 let last_stmt = blk.stmts.last()?;
5365 let last_expr = match last_stmt.kind {
5366 hir::StmtKind::Semi(ref e) => e,
5369 let last_expr_ty = self.node_ty(last_expr.hir_id);
5370 if matches!(last_expr_ty.kind, ty::Error)
5371 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5375 let original_span = original_sp(last_stmt.span, blk.span);
5376 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5379 // Instantiates the given path, which must refer to an item with the given
5380 // number of type parameters and type.
5381 pub fn instantiate_value_path(
5383 segments: &[hir::PathSegment<'_>],
5384 self_ty: Option<Ty<'tcx>>,
5388 ) -> (Ty<'tcx>, Res) {
5390 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5391 segments, self_ty, res, hir_id,
5396 let path_segs = match res {
5397 Res::Local(_) | Res::SelfCtor(_) => vec![],
5398 Res::Def(kind, def_id) => {
5399 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5401 _ => bug!("instantiate_value_path on {:?}", res),
5404 let mut user_self_ty = None;
5405 let mut is_alias_variant_ctor = false;
5407 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5408 if let Some(self_ty) = self_ty {
5409 let adt_def = self_ty.ty_adt_def().unwrap();
5410 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5411 is_alias_variant_ctor = true;
5414 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5415 let container = tcx.associated_item(def_id).container;
5416 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5418 ty::TraitContainer(trait_did) => {
5419 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5421 ty::ImplContainer(impl_def_id) => {
5422 if segments.len() == 1 {
5423 // `<T>::assoc` will end up here, and so
5424 // can `T::assoc`. It this came from an
5425 // inherent impl, we need to record the
5426 // `T` for posterity (see `UserSelfTy` for
5428 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5429 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5437 // Now that we have categorized what space the parameters for each
5438 // segment belong to, let's sort out the parameters that the user
5439 // provided (if any) into their appropriate spaces. We'll also report
5440 // errors if type parameters are provided in an inappropriate place.
5442 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5443 let generics_has_err = AstConv::prohibit_generics(
5445 segments.iter().enumerate().filter_map(|(index, seg)| {
5446 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5454 if let Res::Local(hid) = res {
5455 let ty = self.local_ty(span, hid).decl_ty;
5456 let ty = self.normalize_associated_types_in(span, &ty);
5457 self.write_ty(hir_id, ty);
5461 if generics_has_err {
5462 // Don't try to infer type parameters when prohibited generic arguments were given.
5463 user_self_ty = None;
5466 // Now we have to compare the types that the user *actually*
5467 // provided against the types that were *expected*. If the user
5468 // did not provide any types, then we want to substitute inference
5469 // variables. If the user provided some types, we may still need
5470 // to add defaults. If the user provided *too many* types, that's
5473 let mut infer_args_for_err = FxHashSet::default();
5474 for &PathSeg(def_id, index) in &path_segs {
5475 let seg = &segments[index];
5476 let generics = tcx.generics_of(def_id);
5477 // Argument-position `impl Trait` is treated as a normal generic
5478 // parameter internally, but we don't allow users to specify the
5479 // parameter's value explicitly, so we have to do some error-
5481 if let GenericArgCountResult {
5482 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5484 } = AstConv::check_generic_arg_count_for_call(
5485 tcx, span, &generics, &seg, false, // `is_method_call`
5487 infer_args_for_err.insert(index);
5488 self.set_tainted_by_errors(); // See issue #53251.
5492 let has_self = path_segs
5494 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5497 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5498 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5500 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5501 let variant = adt_def.non_enum_variant();
5502 let ctor_def_id = variant.ctor_def_id.unwrap();
5504 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5509 let mut err = tcx.sess.struct_span_err(
5511 "the `Self` constructor can only be used with tuple or unit structs",
5513 if let Some(adt_def) = ty.ty_adt_def() {
5514 match adt_def.adt_kind() {
5516 err.help("did you mean to use one of the enum's variants?");
5518 AdtKind::Struct | AdtKind::Union => {
5519 err.span_suggestion(
5521 "use curly brackets",
5522 String::from("Self { /* fields */ }"),
5523 Applicability::HasPlaceholders,
5530 return (tcx.types.err, res);
5536 let def_id = res.def_id();
5538 // The things we are substituting into the type should not contain
5539 // escaping late-bound regions, and nor should the base type scheme.
5540 let ty = tcx.type_of(def_id);
5542 let arg_count = GenericArgCountResult {
5543 explicit_late_bound: ExplicitLateBound::No,
5544 correct: if infer_args_for_err.is_empty() {
5547 Err(GenericArgCountMismatch::default())
5551 let substs = self_ctor_substs.unwrap_or_else(|| {
5552 AstConv::create_substs_for_generic_args(
5559 // Provide the generic args, and whether types should be inferred.
5561 if let Some(&PathSeg(_, index)) =
5562 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5564 // If we've encountered an `impl Trait`-related error, we're just
5565 // going to infer the arguments for better error messages.
5566 if !infer_args_for_err.contains(&index) {
5567 // Check whether the user has provided generic arguments.
5568 if let Some(ref data) = segments[index].args {
5569 return (Some(data), segments[index].infer_args);
5572 return (None, segments[index].infer_args);
5577 // Provide substitutions for parameters for which (valid) arguments have been provided.
5578 |param, arg| match (¶m.kind, arg) {
5579 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5580 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5582 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5583 self.to_ty(ty).into()
5585 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5586 self.to_const(&ct.value).into()
5588 _ => unreachable!(),
5590 // Provide substitutions for parameters for which arguments are inferred.
5591 |substs, param, infer_args| {
5593 GenericParamDefKind::Lifetime => {
5594 self.re_infer(Some(param), span).unwrap().into()
5596 GenericParamDefKind::Type { has_default, .. } => {
5597 if !infer_args && has_default {
5598 // If we have a default, then we it doesn't matter that we're not
5599 // inferring the type arguments: we provide the default where any
5601 let default = tcx.type_of(param.def_id);
5604 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5608 // If no type arguments were provided, we have to infer them.
5609 // This case also occurs as a result of some malformed input, e.g.
5610 // a lifetime argument being given instead of a type parameter.
5611 // Using inference instead of `Error` gives better error messages.
5612 self.var_for_def(span, param)
5615 GenericParamDefKind::Const => {
5616 // FIXME(const_generics:defaults)
5617 // No const parameters were provided, we have to infer them.
5618 self.var_for_def(span, param)
5624 assert!(!substs.has_escaping_bound_vars());
5625 assert!(!ty.has_escaping_bound_vars());
5627 // First, store the "user substs" for later.
5628 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5630 self.add_required_obligations(span, def_id, &substs);
5632 // Substitute the values for the type parameters into the type of
5633 // the referenced item.
5634 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5636 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5637 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5638 // is inherent, there is no `Self` parameter; instead, the impl needs
5639 // type parameters, which we can infer by unifying the provided `Self`
5640 // with the substituted impl type.
5641 // This also occurs for an enum variant on a type alias.
5642 let ty = tcx.type_of(impl_def_id);
5644 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5645 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5646 Ok(ok) => self.register_infer_ok_obligations(ok),
5648 self.tcx.sess.delay_span_bug(
5651 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5660 self.check_rustc_args_require_const(def_id, hir_id, span);
5662 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5663 self.write_substs(hir_id, substs);
5665 (ty_substituted, res)
5668 /// Add all the obligations that are required, substituting and normalized appropriately.
5669 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5670 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5672 for (i, mut obligation) in traits::predicates_for_generics(
5673 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5679 // This makes the error point at the bound, but we want to point at the argument
5680 if let Some(span) = spans.get(i) {
5681 obligation.cause.code = traits::BindingObligation(def_id, *span);
5683 self.register_predicate(obligation);
5687 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5688 // We're only interested in functions tagged with
5689 // #[rustc_args_required_const], so ignore anything that's not.
5690 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5694 // If our calling expression is indeed the function itself, we're good!
5695 // If not, generate an error that this can only be called directly.
5696 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5697 if let ExprKind::Call(ref callee, ..) = expr.kind {
5698 if callee.hir_id == hir_id {
5704 self.tcx.sess.span_err(
5706 "this function can only be invoked directly, not through a function pointer",
5710 /// Resolves `typ` by a single level if `typ` is a type variable.
5711 /// If no resolution is possible, then an error is reported.
5712 /// Numeric inference variables may be left unresolved.
5713 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5714 let ty = self.resolve_vars_with_obligations(ty);
5715 if !ty.is_ty_var() {
5718 if !self.is_tainted_by_errors() {
5719 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5720 .note("type must be known at this point")
5723 self.demand_suptype(sp, self.tcx.types.err, ty);
5728 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5731 ctxt: BreakableCtxt<'tcx>,
5733 ) -> (BreakableCtxt<'tcx>, R) {
5736 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5737 index = enclosing_breakables.stack.len();
5738 enclosing_breakables.by_id.insert(id, index);
5739 enclosing_breakables.stack.push(ctxt);
5743 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5744 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5745 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5746 enclosing_breakables.stack.pop().expect("missing breakable context")
5751 /// Instantiate a QueryResponse in a probe context, without a
5752 /// good ObligationCause.
5753 fn probe_instantiate_query_response(
5756 original_values: &OriginalQueryValues<'tcx>,
5757 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5758 ) -> InferResult<'tcx, Ty<'tcx>> {
5759 self.instantiate_query_response_and_region_obligations(
5760 &traits::ObligationCause::misc(span, self.body_id),
5767 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5768 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5769 let mut contained_in_place = false;
5771 while let hir::Node::Expr(parent_expr) =
5772 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5774 match &parent_expr.kind {
5775 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5776 if lhs.hir_id == expr_id {
5777 contained_in_place = true;
5783 expr_id = parent_expr.hir_id;
5790 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5791 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5793 assert_eq!(generics.parent, None);
5795 if generics.own_counts().types == 0 {
5799 let mut params_used = BitSet::new_empty(generics.params.len());
5801 if ty.references_error() {
5802 // If there is already another error, do not emit
5803 // an error for not using a type parameter.
5804 assert!(tcx.sess.has_errors());
5808 for leaf in ty.walk() {
5809 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5810 if let ty::Param(param) = leaf_ty.kind {
5811 debug!("found use of ty param {:?}", param);
5812 params_used.insert(param.index);
5817 for param in &generics.params {
5818 if !params_used.contains(param.index) {
5819 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5820 let span = tcx.def_span(param.def_id);
5825 "type parameter `{}` is unused",
5828 .span_label(span, "unused type parameter")
5835 fn fatally_break_rust(sess: &Session) {
5836 let handler = sess.diagnostic();
5837 handler.span_bug_no_panic(
5839 "It looks like you're trying to break rust; would you like some ICE?",
5841 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5842 handler.note_without_error(
5843 "we would appreciate a joke overview: \
5844 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5846 handler.note_without_error(&format!(
5847 "rustc {} running on {}",
5848 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5849 config::host_triple(),
5853 fn potentially_plural_count(count: usize, word: &str) -> String {
5854 format!("{} {}{}", count, word, pluralize!(count))