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,
1626 ty: Option<Ty<'tcx>>,
1629 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1630 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1631 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1632 if t != self.opaque_identity_ty && t.super_visit_with(self) {
1639 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1640 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1641 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1642 return *index < self.generics.parent_count as u32;
1645 r.super_visit_with(self)
1648 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1649 if let ty::ConstKind::Unevaluated(..) = c.val {
1650 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1651 // which would violate this check. Even though the particular substitution is not used
1652 // within the const, this should still be fixed.
1655 c.super_visit_with(self)
1659 if let ItemKind::OpaqueTy(hir::OpaqueTy {
1660 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1664 let mut visitor = ProhibitOpaqueVisitor {
1665 opaque_identity_ty: tcx.mk_opaque(
1667 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1669 generics: tcx.generics_of(def_id),
1672 let prohibit_opaque = tcx
1673 .predicates_of(def_id)
1676 .any(|(predicate, _)| predicate.visit_with(&mut visitor));
1678 "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
1679 prohibit_opaque, visitor
1682 if prohibit_opaque {
1683 let is_async = match item.kind {
1684 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1685 hir::OpaqueTyOrigin::AsyncFn => true,
1688 _ => unreachable!(),
1691 let mut err = struct_span_err!(
1695 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1697 if is_async { "async fn" } else { "impl Trait" },
1700 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
1701 if snippet == "Self" {
1702 if let Some(ty) = visitor.ty {
1703 err.span_suggestion(
1705 "consider spelling out the type instead",
1706 format!("{:?}", ty),
1707 Applicability::MaybeIncorrect,
1717 /// Checks that an opaque type does not contain cycles.
1718 fn check_opaque_for_cycles<'tcx>(
1721 substs: SubstsRef<'tcx>,
1723 origin: &hir::OpaqueTyOrigin,
1725 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1727 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1728 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1729 .span_label(span, "recursive `async fn`")
1730 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1734 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1735 err.span_label(span, "expands to a recursive type");
1736 if let ty::Opaque(..) = partially_expanded_type.kind {
1737 err.note("type resolves to itself");
1739 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1746 // Forbid defining intrinsics in Rust code,
1747 // as they must always be defined by the compiler.
1748 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1749 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1750 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1754 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1756 "check_item_type(it.hir_id={}, it.name={})",
1758 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1760 let _indenter = indenter();
1762 // Consts can play a role in type-checking, so they are included here.
1763 hir::ItemKind::Static(..) => {
1764 let def_id = tcx.hir().local_def_id(it.hir_id);
1765 tcx.ensure().typeck_tables_of(def_id);
1766 maybe_check_static_with_link_section(tcx, def_id, it.span);
1768 hir::ItemKind::Const(..) => {
1769 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1771 hir::ItemKind::Enum(ref enum_definition, _) => {
1772 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1774 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1775 hir::ItemKind::Impl { ref items, .. } => {
1776 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1777 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1778 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1779 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1780 let trait_def_id = impl_trait_ref.def_id;
1781 check_on_unimplemented(tcx, trait_def_id, it);
1784 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1785 let def_id = tcx.hir().local_def_id(it.hir_id);
1786 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1788 for item in items.iter() {
1789 let item = tcx.hir().trait_item(item.id);
1790 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1791 let abi = sig.header.abi;
1792 fn_maybe_err(tcx, item.ident.span, abi);
1796 hir::ItemKind::Struct(..) => {
1797 check_struct(tcx, it.hir_id, it.span);
1799 hir::ItemKind::Union(..) => {
1800 check_union(tcx, it.hir_id, it.span);
1802 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1803 let def_id = tcx.hir().local_def_id(it.hir_id);
1805 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1806 check_opaque(tcx, def_id, substs, it.span, &origin);
1808 hir::ItemKind::TyAlias(..) => {
1809 let def_id = tcx.hir().local_def_id(it.hir_id);
1810 let pty_ty = tcx.type_of(def_id);
1811 let generics = tcx.generics_of(def_id);
1812 check_type_params_are_used(tcx, &generics, pty_ty);
1814 hir::ItemKind::ForeignMod(ref m) => {
1815 check_abi(tcx, it.span, m.abi);
1817 if m.abi == Abi::RustIntrinsic {
1818 for item in m.items {
1819 intrinsic::check_intrinsic_type(tcx, item);
1821 } else if m.abi == Abi::PlatformIntrinsic {
1822 for item in m.items {
1823 intrinsic::check_platform_intrinsic_type(tcx, item);
1826 for item in m.items {
1827 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1828 let own_counts = generics.own_counts();
1829 if generics.params.len() - own_counts.lifetimes != 0 {
1830 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1831 (_, 0) => ("type", "types", Some("u32")),
1832 // We don't specify an example value, because we can't generate
1833 // a valid value for any type.
1834 (0, _) => ("const", "consts", None),
1835 _ => ("type or const", "types or consts", None),
1841 "foreign items may not have {} parameters",
1844 .span_label(item.span, &format!("can't have {} parameters", kinds))
1846 // FIXME: once we start storing spans for type arguments, turn this
1847 // into a suggestion.
1849 "replace the {} parameters with concrete {}{}",
1852 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1858 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1859 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1864 _ => { /* nothing to do */ }
1868 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1869 // Only restricted on wasm32 target for now
1870 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1874 // If `#[link_section]` is missing, then nothing to verify
1875 let attrs = tcx.codegen_fn_attrs(id);
1876 if attrs.link_section.is_none() {
1880 // For the wasm32 target statics with `#[link_section]` are placed into custom
1881 // sections of the final output file, but this isn't link custom sections of
1882 // other executable formats. Namely we can only embed a list of bytes,
1883 // nothing with pointers to anything else or relocations. If any relocation
1884 // show up, reject them here.
1885 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1886 // the consumer's responsibility to ensure all bytes that have been read
1887 // have defined values.
1888 match tcx.const_eval_poly(id.to_def_id()) {
1889 Ok(ConstValue::ByRef { alloc, .. }) => {
1890 if alloc.relocations().len() != 0 {
1891 let msg = "statics with a custom `#[link_section]` must be a \
1892 simple list of bytes on the wasm target with no \
1893 extra levels of indirection such as references";
1894 tcx.sess.span_err(span, msg);
1897 Ok(_) => bug!("Matching on non-ByRef static"),
1902 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1903 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1904 // an error would be reported if this fails.
1905 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1908 fn report_forbidden_specialization(
1910 impl_item: &hir::ImplItem<'_>,
1913 let mut err = struct_span_err!(
1917 "`{}` specializes an item from a parent `impl`, but \
1918 that item is not marked `default`",
1921 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1923 match tcx.span_of_impl(parent_impl) {
1925 err.span_label(span, "parent `impl` is here");
1927 "to specialize, `{}` in the parent `impl` must be marked `default`",
1932 err.note(&format!("parent implementation is in crate `{}`", cname));
1939 fn check_specialization_validity<'tcx>(
1941 trait_def: &ty::TraitDef,
1942 trait_item: &ty::AssocItem,
1944 impl_item: &hir::ImplItem<'_>,
1946 let kind = match impl_item.kind {
1947 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1948 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1949 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1950 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1953 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1954 Ok(ancestors) => ancestors,
1957 let mut ancestor_impls = ancestors
1959 .filter_map(|parent| {
1960 if parent.is_from_trait() {
1963 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1968 if ancestor_impls.peek().is_none() {
1969 // No parent, nothing to specialize.
1973 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1975 // Parent impl exists, and contains the parent item we're trying to specialize, but
1976 // doesn't mark it `default`.
1977 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1978 Some(Err(parent_impl.def_id()))
1981 // Parent impl contains item and makes it specializable.
1982 Some(_) => Some(Ok(())),
1984 // Parent impl doesn't mention the item. This means it's inherited from the
1985 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1986 // "defaultness" from the grandparent, else they are final.
1988 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1991 Some(Err(parent_impl.def_id()))
1997 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1998 // item. This is allowed, the item isn't actually getting specialized here.
1999 let result = opt_result.unwrap_or(Ok(()));
2001 if let Err(parent_impl) = result {
2002 report_forbidden_specialization(tcx, impl_item, parent_impl);
2006 fn check_impl_items_against_trait<'tcx>(
2008 full_impl_span: Span,
2009 impl_id: LocalDefId,
2010 impl_trait_ref: ty::TraitRef<'tcx>,
2011 impl_item_refs: &[hir::ImplItemRef<'_>],
2013 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2015 // If the trait reference itself is erroneous (so the compilation is going
2016 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2017 // isn't populated for such impls.
2018 if impl_trait_ref.references_error() {
2022 // Negative impls are not expected to have any items
2023 match tcx.impl_polarity(impl_id) {
2024 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2025 ty::ImplPolarity::Negative => {
2026 if let [first_item_ref, ..] = impl_item_refs {
2027 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2032 "negative impls cannot have any items"
2040 // Locate trait definition and items
2041 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2043 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2045 // Check existing impl methods to see if they are both present in trait
2046 // and compatible with trait signature
2047 for impl_item in impl_items() {
2048 let namespace = impl_item.kind.namespace();
2049 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2050 let ty_trait_item = tcx
2051 .associated_items(impl_trait_ref.def_id)
2052 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2054 // Not compatible, but needed for the error message
2055 tcx.associated_items(impl_trait_ref.def_id)
2056 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2060 // Check that impl definition matches trait definition
2061 if let Some(ty_trait_item) = ty_trait_item {
2062 match impl_item.kind {
2063 hir::ImplItemKind::Const(..) => {
2064 // Find associated const definition.
2065 if ty_trait_item.kind == ty::AssocKind::Const {
2074 let mut err = struct_span_err!(
2078 "item `{}` is an associated const, \
2079 which doesn't match its trait `{}`",
2081 impl_trait_ref.print_only_trait_path()
2083 err.span_label(impl_item.span, "does not match trait");
2084 // We can only get the spans from local trait definition
2085 // Same for E0324 and E0325
2086 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2087 err.span_label(trait_span, "item in trait");
2092 hir::ImplItemKind::Fn(..) => {
2093 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2094 if ty_trait_item.kind == ty::AssocKind::Fn {
2095 compare_impl_method(
2104 let mut err = struct_span_err!(
2108 "item `{}` is an associated method, \
2109 which doesn't match its trait `{}`",
2111 impl_trait_ref.print_only_trait_path()
2113 err.span_label(impl_item.span, "does not match trait");
2114 if let Some(trait_span) = opt_trait_span {
2115 err.span_label(trait_span, "item in trait");
2120 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2121 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2122 if ty_trait_item.kind == ty::AssocKind::Type {
2132 let mut err = struct_span_err!(
2136 "item `{}` is an associated type, \
2137 which doesn't match its trait `{}`",
2139 impl_trait_ref.print_only_trait_path()
2141 err.span_label(impl_item.span, "does not match trait");
2142 if let Some(trait_span) = opt_trait_span {
2143 err.span_label(trait_span, "item in trait");
2150 check_specialization_validity(
2154 impl_id.to_def_id(),
2160 // Check for missing items from trait
2161 let mut missing_items = Vec::new();
2162 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2163 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2164 let is_implemented = ancestors
2165 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2166 .map(|node_item| !node_item.defining_node.is_from_trait())
2169 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2170 if !trait_item.defaultness.has_value() {
2171 missing_items.push(*trait_item);
2177 if !missing_items.is_empty() {
2178 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2182 fn missing_items_err(
2185 missing_items: &[ty::AssocItem],
2186 full_impl_span: Span,
2188 let missing_items_msg = missing_items
2190 .map(|trait_item| trait_item.ident.to_string())
2191 .collect::<Vec<_>>()
2194 let mut err = struct_span_err!(
2198 "not all trait items implemented, missing: `{}`",
2201 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2203 // `Span` before impl block closing brace.
2204 let hi = full_impl_span.hi() - BytePos(1);
2205 // Point at the place right before the closing brace of the relevant `impl` to suggest
2206 // adding the associated item at the end of its body.
2207 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2208 // Obtain the level of indentation ending in `sugg_sp`.
2209 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2210 // Make the whitespace that will make the suggestion have the right indentation.
2211 let padding: String = (0..indentation).map(|_| " ").collect();
2213 for trait_item in missing_items {
2214 let snippet = suggestion_signature(&trait_item, tcx);
2215 let code = format!("{}{}\n{}", padding, snippet, padding);
2216 let msg = format!("implement the missing item: `{}`", snippet);
2217 let appl = Applicability::HasPlaceholders;
2218 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2219 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2220 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2222 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2228 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2229 fn bounds_from_generic_predicates(
2231 predicates: ty::GenericPredicates<'_>,
2232 ) -> (String, String) {
2233 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2234 let mut projections = vec![];
2235 for (predicate, _) in predicates.predicates {
2236 debug!("predicate {:?}", predicate);
2237 match predicate.kind() {
2238 ty::PredicateKind::Trait(trait_predicate, _) => {
2239 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2240 let def_id = trait_predicate.skip_binder().def_id();
2241 if Some(def_id) != tcx.lang_items().sized_trait() {
2242 // Type params are `Sized` by default, do not add that restriction to the list
2243 // if it is a positive requirement.
2244 entry.push(trait_predicate.skip_binder().def_id());
2247 ty::PredicateKind::Projection(projection_pred) => {
2248 projections.push(projection_pred);
2253 let generics = if types.is_empty() {
2260 .filter_map(|t| match t.kind {
2261 ty::Param(_) => Some(t.to_string()),
2262 // Avoid suggesting the following:
2263 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2266 .collect::<Vec<_>>()
2270 let mut where_clauses = vec![];
2271 for (ty, bounds) in types {
2272 for bound in &bounds {
2273 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2276 for projection in &projections {
2277 let p = projection.skip_binder();
2278 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2279 // insert the associated types where they correspond, but for now let's be "lazy" and
2280 // propose this instead of the following valid resugaring:
2281 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2282 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2284 let where_clauses = if where_clauses.is_empty() {
2287 format!(" where {}", where_clauses.join(", "))
2289 (generics, where_clauses)
2292 /// Return placeholder code for the given function.
2293 fn fn_sig_suggestion(
2295 sig: &ty::FnSig<'_>,
2297 predicates: ty::GenericPredicates<'_>,
2298 assoc: &ty::AssocItem,
2305 Some(match ty.kind {
2306 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2307 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2308 let reg = match &format!("{}", reg)[..] {
2309 "'_" | "" => String::new(),
2310 reg => format!("{} ", reg),
2312 if assoc.fn_has_self_parameter {
2314 ty::Param(param) if param.name == kw::SelfUpper => {
2315 format!("&{}{}self", reg, mutability.prefix_str())
2318 _ => format!("self: {}", ty),
2321 format!("_: {:?}", ty)
2325 if assoc.fn_has_self_parameter && i == 0 {
2326 format!("self: {:?}", ty)
2328 format!("_: {:?}", ty)
2333 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2334 .filter_map(|arg| arg)
2335 .collect::<Vec<String>>()
2337 let output = sig.output();
2338 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2340 let unsafety = sig.unsafety.prefix_str();
2341 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2343 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2344 // not be present in the `fn` definition, not will we account for renamed
2345 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2346 // fill in a significant portion of the missing code, and other subsequent
2347 // suggestions can help the user fix the code.
2349 "{}fn {}{}({}){}{} {{ todo!() }}",
2350 unsafety, ident, generics, args, output, where_clauses
2354 /// Return placeholder code for the given associated item.
2355 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2356 /// structured suggestion.
2357 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2359 ty::AssocKind::Fn => {
2360 // We skip the binder here because the binder would deanonymize all
2361 // late-bound regions, and we don't want method signatures to show up
2362 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2363 // regions just fine, showing `fn(&MyType)`.
2366 tcx.fn_sig(assoc.def_id).skip_binder(),
2368 tcx.predicates_of(assoc.def_id),
2372 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2373 // FIXME(type_alias_impl_trait): we should print bounds here too.
2374 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2375 ty::AssocKind::Const => {
2376 let ty = tcx.type_of(assoc.def_id);
2377 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2378 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2383 /// Checks whether a type can be represented in memory. In particular, it
2384 /// identifies types that contain themselves without indirection through a
2385 /// pointer, which would mean their size is unbounded.
2386 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2387 let rty = tcx.type_of(item_def_id);
2389 // Check that it is possible to represent this type. This call identifies
2390 // (1) types that contain themselves and (2) types that contain a different
2391 // recursive type. It is only necessary to throw an error on those that
2392 // contain themselves. For case 2, there must be an inner type that will be
2393 // caught by case 1.
2394 match rty.is_representable(tcx, sp) {
2395 Representability::SelfRecursive(spans) => {
2396 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2398 err.span_label(span, "recursive without indirection");
2403 Representability::Representable | Representability::ContainsRecursive => (),
2408 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2409 let t = tcx.type_of(def_id);
2410 if let ty::Adt(def, substs) = t.kind {
2411 if def.is_struct() {
2412 let fields = &def.non_enum_variant().fields;
2413 if fields.is_empty() {
2414 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2417 let e = fields[0].ty(tcx, substs);
2418 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2419 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2420 .span_label(sp, "SIMD elements must have the same type")
2425 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2426 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2432 "SIMD vector element type should be machine type"
2442 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2443 let repr = def.repr;
2445 for attr in tcx.get_attrs(def.did).iter() {
2446 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2447 if let attr::ReprPacked(pack) = r {
2448 if let Some(repr_pack) = repr.pack {
2449 if pack as u64 != repr_pack.bytes() {
2454 "type has conflicting packed representation hints"
2462 if repr.align.is_some() {
2467 "type has conflicting packed and align representation hints"
2471 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2472 let mut err = struct_span_err!(
2476 "packed type cannot transitively contain a `#[repr(align)]` type"
2479 let hir = tcx.hir();
2480 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2481 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2483 tcx.def_span(def_spans[0].0),
2484 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2488 if def_spans.len() > 2 {
2489 let mut first = true;
2490 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2491 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2492 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2497 "`{}` contains a field of type `{}`",
2498 tcx.type_of(def.did),
2502 format!("...which contains a field of type `{}`", ident)
2516 fn check_packed_inner(
2519 stack: &mut Vec<DefId>,
2520 ) -> Option<Vec<(DefId, Span)>> {
2521 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2522 if def.is_struct() || def.is_union() {
2523 if def.repr.align.is_some() {
2524 return Some(vec![(def.did, DUMMY_SP)]);
2528 for field in &def.non_enum_variant().fields {
2529 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2530 if !stack.contains(&def.did) {
2531 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2532 defs.push((def.did, field.ident.span));
2545 /// Emit an error when encountering more or less than one variant in a transparent enum.
2546 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2547 let variant_spans: Vec<_> = adt
2550 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2552 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2553 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2554 err.span_label(sp, &msg);
2555 if let [start @ .., end] = &*variant_spans {
2556 for variant_span in start {
2557 err.span_label(*variant_span, "");
2559 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2564 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2566 fn bad_non_zero_sized_fields<'tcx>(
2568 adt: &'tcx ty::AdtDef,
2570 field_spans: impl Iterator<Item = Span>,
2573 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2574 let mut err = struct_span_err!(
2578 "{}transparent {} {}",
2579 if adt.is_enum() { "the variant of a " } else { "" },
2583 err.span_label(sp, &msg);
2584 for sp in field_spans {
2585 err.span_label(sp, "this field is non-zero-sized");
2590 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2591 if !adt.repr.transparent() {
2594 let sp = tcx.sess.source_map().guess_head_span(sp);
2596 if adt.is_union() && !tcx.features().transparent_unions {
2598 &tcx.sess.parse_sess,
2599 sym::transparent_unions,
2601 "transparent unions are unstable",
2606 if adt.variants.len() != 1 {
2607 bad_variant_count(tcx, adt, sp, adt.did);
2608 if adt.variants.is_empty() {
2609 // Don't bother checking the fields. No variants (and thus no fields) exist.
2614 // For each field, figure out if it's known to be a ZST and align(1)
2615 let field_infos = adt.all_fields().map(|field| {
2616 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2617 let param_env = tcx.param_env(field.did);
2618 let layout = tcx.layout_of(param_env.and(ty));
2619 // We are currently checking the type this field came from, so it must be local
2620 let span = tcx.hir().span_if_local(field.did).unwrap();
2621 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2622 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2626 let non_zst_fields =
2627 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2628 let non_zst_count = non_zst_fields.clone().count();
2629 if non_zst_count != 1 {
2630 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2632 for (span, zst, align1) in field_infos {
2638 "zero-sized field in transparent {} has alignment larger than 1",
2641 .span_label(span, "has alignment larger than 1")
2647 #[allow(trivial_numeric_casts)]
2648 pub fn check_enum<'tcx>(
2651 vs: &'tcx [hir::Variant<'tcx>],
2654 let def_id = tcx.hir().local_def_id(id);
2655 let def = tcx.adt_def(def_id);
2656 def.destructor(tcx); // force the destructor to be evaluated
2659 let attributes = tcx.get_attrs(def_id.to_def_id());
2660 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2665 "unsupported representation for zero-variant enum"
2667 .span_label(sp, "zero-variant enum")
2672 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2673 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2674 if !tcx.features().repr128 {
2676 &tcx.sess.parse_sess,
2679 "repr with 128-bit type is unstable",
2686 if let Some(ref e) = v.disr_expr {
2687 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2691 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2692 let is_unit = |var: &hir::Variant<'_>| match var.data {
2693 hir::VariantData::Unit(..) => true,
2697 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2698 let has_non_units = vs.iter().any(|var| !is_unit(var));
2699 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2700 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2702 if disr_non_unit || (disr_units && has_non_units) {
2704 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2709 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2710 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2711 // Check for duplicate discriminant values
2712 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2713 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2714 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2715 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2716 let i_span = match variant_i.disr_expr {
2717 Some(ref expr) => tcx.hir().span(expr.hir_id),
2718 None => tcx.hir().span(variant_i_hir_id),
2720 let span = match v.disr_expr {
2721 Some(ref expr) => tcx.hir().span(expr.hir_id),
2728 "discriminant value `{}` already exists",
2731 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2732 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2735 disr_vals.push(discr);
2738 check_representable(tcx, sp, def_id);
2739 check_transparent(tcx, sp, def);
2742 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2747 "expected unit struct, unit variant or constant, found {}{}",
2749 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2754 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2755 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2759 fn item_def_id(&self) -> Option<DefId> {
2763 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2764 // FIXME: refactor this into a method
2765 let node = self.tcx.hir().get(self.body_id);
2766 if let Some(fn_like) = FnLikeNode::from_node(node) {
2769 hir::Constness::NotConst
2773 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2775 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2776 let item_id = tcx.hir().ty_param_owner(hir_id);
2777 let item_def_id = tcx.hir().local_def_id(item_id);
2778 let generics = tcx.generics_of(item_def_id);
2779 let index = generics.param_def_id_to_index[&def_id];
2780 ty::GenericPredicates {
2782 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2783 |predicate| match predicate.kind() {
2784 ty::PredicateKind::Trait(ref data, _)
2785 if data.skip_binder().self_ty().is_param(index) =>
2787 // HACK(eddyb) should get the original `Span`.
2788 let span = tcx.def_span(def_id);
2789 Some((predicate, span))
2797 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2799 Some(def) => infer::EarlyBoundRegion(span, def.name),
2800 None => infer::MiscVariable(span),
2802 Some(self.next_region_var(v))
2805 fn allow_ty_infer(&self) -> bool {
2809 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2810 if let Some(param) = param {
2811 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2816 self.next_ty_var(TypeVariableOrigin {
2817 kind: TypeVariableOriginKind::TypeInference,
2826 param: Option<&ty::GenericParamDef>,
2828 ) -> &'tcx Const<'tcx> {
2829 if let Some(param) = param {
2830 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2835 self.next_const_var(
2837 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2842 fn projected_ty_from_poly_trait_ref(
2846 item_segment: &hir::PathSegment<'_>,
2847 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2849 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2851 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2855 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2864 self.tcx().mk_projection(item_def_id, item_substs)
2867 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2868 if ty.has_escaping_bound_vars() {
2869 ty // FIXME: normalization and escaping regions
2871 self.normalize_associated_types_in(span, &ty)
2875 fn set_tainted_by_errors(&self) {
2876 self.infcx.set_tainted_by_errors()
2879 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2880 self.write_ty(hir_id, ty)
2884 /// Controls whether the arguments are tupled. This is used for the call
2887 /// Tupling means that all call-side arguments are packed into a tuple and
2888 /// passed as a single parameter. For example, if tupling is enabled, this
2891 /// fn f(x: (isize, isize))
2893 /// Can be called as:
2900 #[derive(Clone, Eq, PartialEq)]
2901 enum TupleArgumentsFlag {
2906 /// Controls how we perform fallback for unconstrained
2909 /// Do not fallback type variables to opaque types.
2911 /// Perform all possible kinds of fallback, including
2912 /// turning type variables to opaque types.
2916 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2918 inh: &'a Inherited<'a, 'tcx>,
2919 param_env: ty::ParamEnv<'tcx>,
2920 body_id: hir::HirId,
2921 ) -> FnCtxt<'a, 'tcx> {
2925 err_count_on_creation: inh.tcx.sess.err_count(),
2927 ret_coercion_span: RefCell::new(None),
2928 resume_yield_tys: None,
2929 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2930 diverges: Cell::new(Diverges::Maybe),
2931 has_errors: Cell::new(false),
2932 enclosing_breakables: RefCell::new(EnclosingBreakables {
2934 by_id: Default::default(),
2940 pub fn sess(&self) -> &Session {
2944 pub fn errors_reported_since_creation(&self) -> bool {
2945 self.tcx.sess.err_count() > self.err_count_on_creation
2948 /// Produces warning on the given node, if the current point in the
2949 /// function is unreachable, and there hasn't been another warning.
2950 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2951 // FIXME: Combine these two 'if' expressions into one once
2952 // let chains are implemented
2953 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2954 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2955 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2956 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2957 if !span.is_desugaring(DesugaringKind::CondTemporary)
2958 && !span.is_desugaring(DesugaringKind::Async)
2959 && !orig_span.is_desugaring(DesugaringKind::Await)
2961 self.diverges.set(Diverges::WarnedAlways);
2963 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2965 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2966 let msg = format!("unreachable {}", kind);
2968 .span_label(span, &msg)
2972 .unwrap_or("any code following this expression is unreachable"),
2980 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2981 ObligationCause::new(span, self.body_id, code)
2984 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2985 self.cause(span, ObligationCauseCode::MiscObligation)
2988 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2989 /// version (resolve_vars_if_possible), this version will
2990 /// also select obligations if it seems useful, in an effort
2991 /// to get more type information.
2992 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2993 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2995 // No Infer()? Nothing needs doing.
2996 if !ty.has_infer_types_or_consts() {
2997 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3001 // If `ty` is a type variable, see whether we already know what it is.
3002 ty = self.resolve_vars_if_possible(&ty);
3003 if !ty.has_infer_types_or_consts() {
3004 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3008 // If not, try resolving pending obligations as much as
3009 // possible. This can help substantially when there are
3010 // indirect dependencies that don't seem worth tracking
3012 self.select_obligations_where_possible(false, |_| {});
3013 ty = self.resolve_vars_if_possible(&ty);
3015 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3019 fn record_deferred_call_resolution(
3021 closure_def_id: DefId,
3022 r: DeferredCallResolution<'tcx>,
3024 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3025 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3028 fn remove_deferred_call_resolutions(
3030 closure_def_id: DefId,
3031 ) -> Vec<DeferredCallResolution<'tcx>> {
3032 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3033 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3036 pub fn tag(&self) -> String {
3037 format!("{:p}", self)
3040 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3041 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3042 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3047 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3049 "write_ty({:?}, {:?}) in fcx {}",
3051 self.resolve_vars_if_possible(&ty),
3054 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3056 if ty.references_error() {
3057 self.has_errors.set(true);
3058 self.set_tainted_by_errors();
3062 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3063 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3066 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3067 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3070 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3071 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3072 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3073 self.write_substs(hir_id, method.substs);
3075 // When the method is confirmed, the `method.substs` includes
3076 // parameters from not just the method, but also the impl of
3077 // the method -- in particular, the `Self` type will be fully
3078 // resolved. However, those are not something that the "user
3079 // specified" -- i.e., those types come from the inferred type
3080 // of the receiver, not something the user wrote. So when we
3081 // create the user-substs, we want to replace those earlier
3082 // types with just the types that the user actually wrote --
3083 // that is, those that appear on the *method itself*.
3085 // As an example, if the user wrote something like
3086 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3087 // type of `foo` (possibly adjusted), but we don't want to
3088 // include that. We want just the `[_, u32]` part.
3089 if !method.substs.is_noop() {
3090 let method_generics = self.tcx.generics_of(method.def_id);
3091 if !method_generics.params.is_empty() {
3092 let user_type_annotation = self.infcx.probe(|_| {
3093 let user_substs = UserSubsts {
3094 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3095 let i = param.index as usize;
3096 if i < method_generics.parent_count {
3097 self.infcx.var_for_def(DUMMY_SP, param)
3102 user_self_ty: None, // not relevant here
3105 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3111 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3112 self.write_user_type_annotation(hir_id, user_type_annotation);
3117 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3118 if !substs.is_noop() {
3119 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3121 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3125 /// Given the substs that we just converted from the HIR, try to
3126 /// canonicalize them and store them as user-given substitutions
3127 /// (i.e., substitutions that must be respected by the NLL check).
3129 /// This should be invoked **before any unifications have
3130 /// occurred**, so that annotations like `Vec<_>` are preserved
3132 pub fn write_user_type_annotation_from_substs(
3136 substs: SubstsRef<'tcx>,
3137 user_self_ty: Option<UserSelfTy<'tcx>>,
3140 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3141 user_self_ty={:?} in fcx {}",
3149 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3150 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3152 UserSubsts { substs, user_self_ty },
3154 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3155 self.write_user_type_annotation(hir_id, canonicalized);
3159 pub fn write_user_type_annotation(
3162 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3165 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3167 canonical_user_type_annotation,
3171 if !canonical_user_type_annotation.is_identity() {
3174 .user_provided_types_mut()
3175 .insert(hir_id, canonical_user_type_annotation);
3177 debug!("write_user_type_annotation: skipping identity substs");
3181 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3182 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3188 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3189 Entry::Vacant(entry) => {
3192 Entry::Occupied(mut entry) => {
3193 debug!(" - composing on top of {:?}", entry.get());
3194 match (&entry.get()[..], &adj[..]) {
3195 // Applying any adjustment on top of a NeverToAny
3196 // is a valid NeverToAny adjustment, because it can't
3198 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3200 Adjustment { kind: Adjust::Deref(_), .. },
3201 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3203 Adjustment { kind: Adjust::Deref(_), .. },
3204 .. // Any following adjustments are allowed.
3206 // A reborrow has no effect before a dereference.
3208 // FIXME: currently we never try to compose autoderefs
3209 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3211 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3212 expr, entry.get(), adj)
3214 *entry.get_mut() = adj;
3219 /// Basically whenever we are converting from a type scheme into
3220 /// the fn body space, we always want to normalize associated
3221 /// types as well. This function combines the two.
3222 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3224 T: TypeFoldable<'tcx>,
3226 let value = value.subst(self.tcx, substs);
3227 let result = self.normalize_associated_types_in(span, &value);
3228 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3232 /// As `instantiate_type_scheme`, but for the bounds found in a
3233 /// generic type scheme.
3234 fn instantiate_bounds(
3238 substs: SubstsRef<'tcx>,
3239 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3240 let bounds = self.tcx.predicates_of(def_id);
3241 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3242 let result = bounds.instantiate(self.tcx, substs);
3243 let result = self.normalize_associated_types_in(span, &result);
3245 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3246 bounds, substs, result, spans,
3251 /// Replaces the opaque types from the given value with type variables,
3252 /// and records the `OpaqueTypeMap` for later use during writeback. See
3253 /// `InferCtxt::instantiate_opaque_types` for more details.
3254 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3256 parent_id: hir::HirId,
3260 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3262 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3263 parent_def_id, value
3266 let (value, opaque_type_map) =
3267 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3268 parent_def_id.to_def_id(),
3275 let mut opaque_types = self.opaque_types.borrow_mut();
3276 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3277 for (ty, decl) in opaque_type_map {
3278 let _ = opaque_types.insert(ty, decl);
3279 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3285 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3287 T: TypeFoldable<'tcx>,
3289 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3292 fn normalize_associated_types_in_as_infer_ok<T>(
3296 ) -> InferOk<'tcx, T>
3298 T: TypeFoldable<'tcx>,
3300 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3303 pub fn require_type_meets(
3307 code: traits::ObligationCauseCode<'tcx>,
3310 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3313 pub fn require_type_is_sized(
3317 code: traits::ObligationCauseCode<'tcx>,
3319 if !ty.references_error() {
3320 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3321 self.require_type_meets(ty, span, code, lang_item);
3325 pub fn require_type_is_sized_deferred(
3329 code: traits::ObligationCauseCode<'tcx>,
3331 if !ty.references_error() {
3332 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3336 pub fn register_bound(
3340 cause: traits::ObligationCause<'tcx>,
3342 if !ty.references_error() {
3343 self.fulfillment_cx.borrow_mut().register_bound(
3353 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3354 let t = AstConv::ast_ty_to_ty(self, ast_t);
3355 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3359 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3360 let ty = self.to_ty(ast_ty);
3361 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3363 if Self::can_contain_user_lifetime_bounds(ty) {
3364 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3365 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3366 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3372 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3373 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3374 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3375 self.register_wf_obligation(
3377 self.tcx.hir().span(ast_c.hir_id),
3378 ObligationCauseCode::MiscObligation,
3383 // If the type given by the user has free regions, save it for later, since
3384 // NLL would like to enforce those. Also pass in types that involve
3385 // projections, since those can resolve to `'static` bounds (modulo #54940,
3386 // which hopefully will be fixed by the time you see this comment, dear
3387 // reader, although I have my doubts). Also pass in types with inference
3388 // types, because they may be repeated. Other sorts of things are already
3389 // sufficiently enforced with erased regions. =)
3390 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3392 T: TypeFoldable<'tcx>,
3394 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3397 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3398 match self.tables.borrow().node_types().get(id) {
3400 None if self.is_tainted_by_errors() => self.tcx.types.err,
3403 "no type for node {}: {} in fcx {}",
3405 self.tcx.hir().node_to_string(id),
3412 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3413 pub fn register_wf_obligation(
3415 arg: subst::GenericArg<'tcx>,
3417 code: traits::ObligationCauseCode<'tcx>,
3419 // WF obligations never themselves fail, so no real need to give a detailed cause:
3420 let cause = traits::ObligationCause::new(span, self.body_id, code);
3421 self.register_predicate(traits::Obligation::new(
3424 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3428 /// Registers obligations that all `substs` are well-formed.
3429 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3430 for arg in substs.iter().filter(|arg| {
3431 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3433 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3437 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3438 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3439 /// trait/region obligations.
3441 /// For example, if there is a function:
3444 /// fn foo<'a,T:'a>(...)
3447 /// and a reference:
3453 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3454 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3455 pub fn add_obligations_for_parameters(
3457 cause: traits::ObligationCause<'tcx>,
3458 predicates: ty::InstantiatedPredicates<'tcx>,
3460 assert!(!predicates.has_escaping_bound_vars());
3462 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3464 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3465 self.register_predicate(obligation);
3469 // FIXME(arielb1): use this instead of field.ty everywhere
3470 // Only for fields! Returns <none> for methods>
3471 // Indifferent to privacy flags
3475 field: &'tcx ty::FieldDef,
3476 substs: SubstsRef<'tcx>,
3478 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3481 fn check_casts(&self) {
3482 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3483 for cast in deferred_cast_checks.drain(..) {
3488 fn resolve_generator_interiors(&self, def_id: DefId) {
3489 let mut generators = self.deferred_generator_interiors.borrow_mut();
3490 for (body_id, interior, kind) in generators.drain(..) {
3491 self.select_obligations_where_possible(false, |_| {});
3492 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3496 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3498 // - Unconstrained ints are replaced with `i32`.
3500 // - Unconstrained floats are replaced with with `f64`.
3502 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3503 // is enabled. Otherwise, they are replaced with `()`.
3505 // Fallback becomes very dubious if we have encountered type-checking errors.
3506 // In that case, fallback to Error.
3507 // The return value indicates whether fallback has occurred.
3508 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3509 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3510 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3512 assert!(ty.is_ty_infer());
3513 let fallback = match self.type_is_unconstrained_numeric(ty) {
3514 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3515 UnconstrainedInt => self.tcx.types.i32,
3516 UnconstrainedFloat => self.tcx.types.f64,
3517 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3519 // This type variable was created from the instantiation of an opaque
3520 // type. The fact that we're attempting to perform fallback for it
3521 // means that the function neither constrained it to a concrete
3522 // type, nor to the opaque type itself.
3524 // For example, in this code:
3527 // type MyType = impl Copy;
3528 // fn defining_use() -> MyType { true }
3529 // fn other_use() -> MyType { defining_use() }
3532 // `defining_use` will constrain the instantiated inference
3533 // variable to `bool`, while `other_use` will constrain
3534 // the instantiated inference variable to `MyType`.
3536 // When we process opaque types during writeback, we
3537 // will handle cases like `other_use`, and not count
3538 // them as defining usages
3540 // However, we also need to handle cases like this:
3543 // pub type Foo = impl Copy;
3544 // fn produce() -> Option<Foo> {
3549 // In the above snippet, the inference variable created by
3550 // instantiating `Option<Foo>` will be completely unconstrained.
3551 // We treat this as a non-defining use by making the inference
3552 // variable fall back to the opaque type itself.
3553 if let FallbackMode::All = mode {
3554 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3556 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3568 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3569 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3573 fn select_all_obligations_or_error(&self) {
3574 debug!("select_all_obligations_or_error");
3575 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3576 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3580 /// Select as many obligations as we can at present.
3581 fn select_obligations_where_possible(
3583 fallback_has_occurred: bool,
3584 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3586 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3587 if let Err(mut errors) = result {
3588 mutate_fullfillment_errors(&mut errors);
3589 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3593 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3594 /// returns a type of `&T`, but the actual type we assign to the
3595 /// *expression* is `T`. So this function just peels off the return
3596 /// type by one layer to yield `T`.
3597 fn make_overloaded_place_return_type(
3599 method: MethodCallee<'tcx>,
3600 ) -> ty::TypeAndMut<'tcx> {
3601 // extract method return type, which will be &T;
3602 let ret_ty = method.sig.output();
3604 // method returns &T, but the type as visible to user is T, so deref
3605 ret_ty.builtin_deref(true).unwrap()
3610 expr: &hir::Expr<'_>,
3611 base_expr: &'tcx hir::Expr<'tcx>,
3615 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3616 // FIXME(#18741) -- this is almost but not quite the same as the
3617 // autoderef that normal method probing does. They could likely be
3620 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3621 let mut result = None;
3622 while result.is_none() && autoderef.next().is_some() {
3623 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3625 autoderef.finalize(self);
3629 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3630 /// (and otherwise adjust) `base_expr`, looking for a type which either
3631 /// supports builtin indexing or overloaded indexing.
3632 /// This loop implements one step in that search; the autoderef loop
3633 /// is implemented by `lookup_indexing`.
3636 expr: &hir::Expr<'_>,
3637 base_expr: &hir::Expr<'_>,
3638 autoderef: &Autoderef<'a, 'tcx>,
3641 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3642 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3644 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3646 expr, base_expr, adjusted_ty, index_ty
3649 for &unsize in &[false, true] {
3650 let mut self_ty = adjusted_ty;
3652 // We only unsize arrays here.
3653 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3654 self_ty = self.tcx.mk_slice(element_ty);
3660 // If some lookup succeeds, write callee into table and extract index/element
3661 // type from the method signature.
3662 // If some lookup succeeded, install method in table
3663 let input_ty = self.next_ty_var(TypeVariableOrigin {
3664 kind: TypeVariableOriginKind::AutoDeref,
3665 span: base_expr.span,
3667 let method = self.try_overloaded_place_op(
3675 let result = method.map(|ok| {
3676 debug!("try_index_step: success, using overloaded indexing");
3677 let method = self.register_infer_ok_obligations(ok);
3679 let mut adjustments = autoderef.adjust_steps(self, needs);
3680 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3681 let mutbl = match r_mutbl {
3682 hir::Mutability::Not => AutoBorrowMutability::Not,
3683 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3684 // Indexing can be desugared to a method call,
3685 // so maybe we could use two-phase here.
3686 // See the documentation of AllowTwoPhase for why that's
3687 // not the case today.
3688 allow_two_phase_borrow: AllowTwoPhase::No,
3691 adjustments.push(Adjustment {
3692 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3695 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3699 adjustments.push(Adjustment {
3700 kind: Adjust::Pointer(PointerCast::Unsize),
3701 target: method.sig.inputs()[0],
3704 self.apply_adjustments(base_expr, adjustments);
3706 self.write_method_call(expr.hir_id, method);
3707 (input_ty, self.make_overloaded_place_return_type(method).ty)
3709 if result.is_some() {
3717 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
3718 let (tr, name) = match (op, is_mut) {
3719 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3720 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3721 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3722 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3724 (tr, Ident::with_dummy_span(name))
3727 fn try_overloaded_place_op(
3731 arg_tys: &[Ty<'tcx>],
3734 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3735 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3737 // Try Mut first, if needed.
3738 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3739 let method = match (needs, mut_tr) {
3740 (Needs::MutPlace, Some(trait_did)) => {
3741 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3746 // Otherwise, fall back to the immutable version.
3747 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3748 match (method, imm_tr) {
3749 (None, Some(trait_did)) => {
3750 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3752 (method, _) => method,
3756 fn check_method_argument_types(
3759 expr: &'tcx hir::Expr<'tcx>,
3760 method: Result<MethodCallee<'tcx>, ()>,
3761 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3762 tuple_arguments: TupleArgumentsFlag,
3763 expected: Expectation<'tcx>,
3765 let has_error = match method {
3766 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3770 let err_inputs = self.err_args(args_no_rcvr.len());
3772 let err_inputs = match tuple_arguments {
3773 DontTupleArguments => err_inputs,
3774 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3777 self.check_argument_types(
3787 return self.tcx.types.err;
3790 let method = method.unwrap();
3791 // HACK(eddyb) ignore self in the definition (see above).
3792 let expected_arg_tys = self.expected_inputs_for_expected_output(
3795 method.sig.output(),
3796 &method.sig.inputs()[1..],
3798 self.check_argument_types(
3801 &method.sig.inputs()[1..],
3802 &expected_arg_tys[..],
3804 method.sig.c_variadic,
3806 self.tcx.hir().span_if_local(method.def_id),
3811 fn self_type_matches_expected_vid(
3813 trait_ref: ty::PolyTraitRef<'tcx>,
3814 expected_vid: ty::TyVid,
3816 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3818 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3819 trait_ref, self_ty, expected_vid
3821 match self_ty.kind {
3822 ty::Infer(ty::TyVar(found_vid)) => {
3823 // FIXME: consider using `sub_root_var` here so we
3824 // can see through subtyping.
3825 let found_vid = self.root_var(found_vid);
3826 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3827 expected_vid == found_vid
3833 fn obligations_for_self_ty<'b>(
3836 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3839 // FIXME: consider using `sub_root_var` here so we
3840 // can see through subtyping.
3841 let ty_var_root = self.root_var(self_ty);
3843 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3846 self.fulfillment_cx.borrow().pending_obligations()
3851 .pending_obligations()
3853 .filter_map(move |obligation| match obligation.predicate.kind() {
3854 ty::PredicateKind::Projection(ref data) => {
3855 Some((data.to_poly_trait_ref(self.tcx), obligation))
3857 ty::PredicateKind::Trait(ref data, _) => {
3858 Some((data.to_poly_trait_ref(), obligation))
3860 ty::PredicateKind::Subtype(..) => None,
3861 ty::PredicateKind::RegionOutlives(..) => None,
3862 ty::PredicateKind::TypeOutlives(..) => None,
3863 ty::PredicateKind::WellFormed(..) => None,
3864 ty::PredicateKind::ObjectSafe(..) => None,
3865 ty::PredicateKind::ConstEvaluatable(..) => None,
3866 ty::PredicateKind::ConstEquate(..) => None,
3867 // N.B., this predicate is created by breaking down a
3868 // `ClosureType: FnFoo()` predicate, where
3869 // `ClosureType` represents some `Closure`. It can't
3870 // possibly be referring to the current closure,
3871 // because we haven't produced the `Closure` for
3872 // this closure yet; this is exactly why the other
3873 // code is looking for a self type of a unresolved
3874 // inference variable.
3875 ty::PredicateKind::ClosureKind(..) => None,
3877 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3880 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3881 self.obligations_for_self_ty(self_ty)
3882 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3885 /// Generic function that factors out common logic from function calls,
3886 /// method calls and overloaded operators.
3887 fn check_argument_types(
3890 expr: &'tcx hir::Expr<'tcx>,
3891 fn_inputs: &[Ty<'tcx>],
3892 expected_arg_tys: &[Ty<'tcx>],
3893 args: &'tcx [hir::Expr<'tcx>],
3895 tuple_arguments: TupleArgumentsFlag,
3896 def_span: Option<Span>,
3899 // Grab the argument types, supplying fresh type variables
3900 // if the wrong number of arguments were supplied
3901 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3903 // All the input types from the fn signature must outlive the call
3904 // so as to validate implied bounds.
3905 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3906 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3909 let expected_arg_count = fn_inputs.len();
3911 let param_count_error = |expected_count: usize,
3916 let (span, start_span, args) = match &expr.kind {
3917 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3918 hir::ExprKind::MethodCall(path_segment, span, args) => (
3920 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3923 .and_then(|args| args.args.iter().last())
3924 // Account for `foo.bar::<T>()`.
3926 // Skip the closing `>`.
3929 .next_point(tcx.sess.source_map().next_point(arg.span()))
3932 &args[1..], // Skip the receiver.
3934 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3936 let arg_spans = if args.is_empty() {
3938 // ^^^-- supplied 0 arguments
3940 // expected 2 arguments
3941 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3944 // ^^^ - - - supplied 3 arguments
3946 // expected 2 arguments
3947 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3950 let mut err = tcx.sess.struct_span_err_with_code(
3953 "this function takes {}{} but {} {} supplied",
3954 if c_variadic { "at least " } else { "" },
3955 potentially_plural_count(expected_count, "argument"),
3956 potentially_plural_count(arg_count, "argument"),
3957 if arg_count == 1 { "was" } else { "were" }
3959 DiagnosticId::Error(error_code.to_owned()),
3961 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3962 for (i, span) in arg_spans.into_iter().enumerate() {
3965 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3969 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3970 err.span_label(def_s, "defined here");
3973 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3974 // remove closing `)` from the span
3975 let sugg_span = sugg_span.shrink_to_lo();
3976 err.span_suggestion(
3978 "expected the unit value `()`; create it with empty parentheses",
3980 Applicability::MachineApplicable,
3987 if c_variadic { "at least " } else { "" },
3988 potentially_plural_count(expected_count, "argument")
3995 let mut expected_arg_tys = expected_arg_tys.to_vec();
3997 let formal_tys = if tuple_arguments == TupleArguments {
3998 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3999 match tuple_type.kind {
4000 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4001 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4002 expected_arg_tys = vec![];
4003 self.err_args(args.len())
4005 ty::Tuple(arg_types) => {
4006 expected_arg_tys = match expected_arg_tys.get(0) {
4007 Some(&ty) => match ty.kind {
4008 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4013 arg_types.iter().map(|k| k.expect_ty()).collect()
4020 "cannot use call notation; the first type parameter \
4021 for the function trait is neither a tuple nor unit"
4024 expected_arg_tys = vec![];
4025 self.err_args(args.len())
4028 } else if expected_arg_count == supplied_arg_count {
4030 } else if c_variadic {
4031 if supplied_arg_count >= expected_arg_count {
4034 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4035 expected_arg_tys = vec![];
4036 self.err_args(supplied_arg_count)
4039 // is the missing argument of type `()`?
4040 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4041 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4042 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4043 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4047 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4049 expected_arg_tys = vec![];
4050 self.err_args(supplied_arg_count)
4054 "check_argument_types: formal_tys={:?}",
4055 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4058 // If there is no expectation, expect formal_tys.
4059 let expected_arg_tys =
4060 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4062 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4064 // Check the arguments.
4065 // We do this in a pretty awful way: first we type-check any arguments
4066 // that are not closures, then we type-check the closures. This is so
4067 // that we have more information about the types of arguments when we
4068 // type-check the functions. This isn't really the right way to do this.
4069 for &check_closures in &[false, true] {
4070 debug!("check_closures={}", check_closures);
4072 // More awful hacks: before we check argument types, try to do
4073 // an "opportunistic" vtable resolution of any trait bounds on
4074 // the call. This helps coercions.
4076 self.select_obligations_where_possible(false, |errors| {
4077 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4078 self.point_at_arg_instead_of_call_if_possible(
4080 &final_arg_types[..],
4087 // For C-variadic functions, we don't have a declared type for all of
4088 // the arguments hence we only do our usual type checking with
4089 // the arguments who's types we do know.
4090 let t = if c_variadic {
4092 } else if tuple_arguments == TupleArguments {
4097 for (i, arg) in args.iter().take(t).enumerate() {
4098 // Warn only for the first loop (the "no closures" one).
4099 // Closure arguments themselves can't be diverging, but
4100 // a previous argument can, e.g., `foo(panic!(), || {})`.
4101 if !check_closures {
4102 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4105 let is_closure = match arg.kind {
4106 ExprKind::Closure(..) => true,
4110 if is_closure != check_closures {
4114 debug!("checking the argument");
4115 let formal_ty = formal_tys[i];
4117 // The special-cased logic below has three functions:
4118 // 1. Provide as good of an expected type as possible.
4119 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4121 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4123 // 2. Coerce to the most detailed type that could be coerced
4124 // to, which is `expected_ty` if `rvalue_hint` returns an
4125 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4126 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4127 // We're processing function arguments so we definitely want to use
4128 // two-phase borrows.
4129 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4130 final_arg_types.push((i, checked_ty, coerce_ty));
4132 // 3. Relate the expected type and the formal one,
4133 // if the expected type was used for the coercion.
4134 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4138 // We also need to make sure we at least write the ty of the other
4139 // arguments which we skipped above.
4141 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4142 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4143 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4146 for arg in args.iter().skip(expected_arg_count) {
4147 let arg_ty = self.check_expr(&arg);
4149 // There are a few types which get autopromoted when passed via varargs
4150 // in C but we just error out instead and require explicit casts.
4151 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4153 ty::Float(ast::FloatTy::F32) => {
4154 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4156 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4157 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4159 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4160 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4163 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4164 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4165 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4173 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4174 vec![self.tcx.types.err; len]
4177 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4178 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4179 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4180 /// can be not easily comparable with predicate type (because of coercion). If the types match
4181 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4182 /// the corresponding argument's expression span instead of the `fn` call path span.
4183 fn point_at_arg_instead_of_call_if_possible(
4185 errors: &mut Vec<traits::FulfillmentError<'_>>,
4186 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4188 args: &'tcx [hir::Expr<'tcx>],
4190 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4191 // the `?` operator.
4192 if call_sp.desugaring_kind().is_some() {
4196 for error in errors {
4197 // Only if the cause is somewhere inside the expression we want try to point at arg.
4198 // Otherwise, it means that the cause is somewhere else and we should not change
4199 // anything because we can break the correct span.
4200 if !call_sp.contains(error.obligation.cause.span) {
4204 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate.kind() {
4205 // Collect the argument position for all arguments that could have caused this
4206 // `FulfillmentError`.
4207 let mut referenced_in = final_arg_types
4209 .map(|&(i, checked_ty, _)| (i, checked_ty))
4210 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4211 .flat_map(|(i, ty)| {
4212 let ty = self.resolve_vars_if_possible(&ty);
4213 // We walk the argument type because the argument's type could have
4214 // been `Option<T>`, but the `FulfillmentError` references `T`.
4215 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4221 .collect::<Vec<_>>();
4223 // Both checked and coerced types could have matched, thus we need to remove
4225 referenced_in.sort();
4226 referenced_in.dedup();
4228 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4229 // We make sure that only *one* argument matches the obligation failure
4230 // and we assign the obligation's span to its expression's.
4231 error.obligation.cause.span = args[ref_in].span;
4232 error.points_at_arg_span = true;
4238 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4239 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4240 /// were caused by them. If they were, we point at the corresponding type argument's span
4241 /// instead of the `fn` call path span.
4242 fn point_at_type_arg_instead_of_call_if_possible(
4244 errors: &mut Vec<traits::FulfillmentError<'_>>,
4245 call_expr: &'tcx hir::Expr<'tcx>,
4247 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4248 if let hir::ExprKind::Path(qpath) = &path.kind {
4249 if let hir::QPath::Resolved(_, path) = &qpath {
4250 for error in errors {
4251 if let ty::PredicateKind::Trait(predicate, _) =
4252 error.obligation.predicate.kind()
4254 // If any of the type arguments in this path segment caused the
4255 // `FullfillmentError`, point at its span (#61860).
4259 .filter_map(|seg| seg.args.as_ref())
4260 .flat_map(|a| a.args.iter())
4262 if let hir::GenericArg::Type(hir_ty) = &arg {
4263 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4266 // Avoid ICE with associated types. As this is best
4267 // effort only, it's ok to ignore the case. It
4268 // would trigger in `is_send::<T::AssocType>();`
4269 // from `typeck-default-trait-impl-assoc-type.rs`.
4271 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4272 let ty = self.resolve_vars_if_possible(&ty);
4273 if ty == predicate.skip_binder().self_ty() {
4274 error.obligation.cause.span = hir_ty.span;
4286 // AST fragment checking
4287 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4291 ast::LitKind::Str(..) => tcx.mk_static_str(),
4292 ast::LitKind::ByteStr(ref v) => {
4293 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4295 ast::LitKind::Byte(_) => tcx.types.u8,
4296 ast::LitKind::Char(_) => tcx.types.char,
4297 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4298 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4299 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4300 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4301 ty::Int(_) | ty::Uint(_) => Some(ty),
4302 ty::Char => Some(tcx.types.u8),
4303 ty::RawPtr(..) => Some(tcx.types.usize),
4304 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4307 opt_ty.unwrap_or_else(|| self.next_int_var())
4309 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4310 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4311 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4312 ty::Float(_) => Some(ty),
4315 opt_ty.unwrap_or_else(|| self.next_float_var())
4317 ast::LitKind::Bool(_) => tcx.types.bool,
4318 ast::LitKind::Err(_) => tcx.types.err,
4322 /// Unifies the output type with the expected type early, for more coercions
4323 /// and forward type information on the input expressions.
4324 fn expected_inputs_for_expected_output(
4327 expected_ret: Expectation<'tcx>,
4328 formal_ret: Ty<'tcx>,
4329 formal_args: &[Ty<'tcx>],
4330 ) -> Vec<Ty<'tcx>> {
4331 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4332 let ret_ty = match expected_ret.only_has_type(self) {
4334 None => return Vec::new(),
4336 let expect_args = self
4337 .fudge_inference_if_ok(|| {
4338 // Attempt to apply a subtyping relationship between the formal
4339 // return type (likely containing type variables if the function
4340 // is polymorphic) and the expected return type.
4341 // No argument expectations are produced if unification fails.
4342 let origin = self.misc(call_span);
4343 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4345 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4346 // to identity so the resulting type is not constrained.
4349 // Process any obligations locally as much as
4350 // we can. We don't care if some things turn
4351 // out unconstrained or ambiguous, as we're
4352 // just trying to get hints here.
4353 self.save_and_restore_in_snapshot_flag(|_| {
4354 let mut fulfill = TraitEngine::new(self.tcx);
4355 for obligation in ok.obligations {
4356 fulfill.register_predicate_obligation(self, obligation);
4358 fulfill.select_where_possible(self)
4362 Err(_) => return Err(()),
4365 // Record all the argument types, with the substitutions
4366 // produced from the above subtyping unification.
4367 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4369 .unwrap_or_default();
4371 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4372 formal_args, formal_ret, expect_args, expected_ret
4377 pub fn check_struct_path(
4381 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4382 let path_span = match *qpath {
4383 QPath::Resolved(_, ref path) => path.span,
4384 QPath::TypeRelative(ref qself, _) => qself.span,
4386 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4387 let variant = match def {
4389 self.set_tainted_by_errors();
4392 Res::Def(DefKind::Variant, _) => match ty.kind {
4393 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4394 _ => bug!("unexpected type: {:?}", ty),
4396 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4397 | Res::SelfTy(..) => match ty.kind {
4398 ty::Adt(adt, substs) if !adt.is_enum() => {
4399 Some((adt.non_enum_variant(), adt.did, substs))
4403 _ => bug!("unexpected definition: {:?}", def),
4406 if let Some((variant, did, substs)) = variant {
4407 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4408 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4410 // Check bounds on type arguments used in the path.
4411 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4413 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4414 self.add_obligations_for_parameters(cause, bounds);
4422 "expected struct, variant or union type, found {}",
4423 ty.sort_string(self.tcx)
4425 .span_label(path_span, "not a struct")
4431 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4432 // The newly resolved definition is written into `type_dependent_defs`.
4433 fn finish_resolving_struct_path(
4438 ) -> (Res, Ty<'tcx>) {
4440 QPath::Resolved(ref maybe_qself, ref path) => {
4441 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4442 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4445 QPath::TypeRelative(ref qself, ref segment) => {
4446 let ty = self.to_ty(qself);
4448 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4454 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4455 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4456 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4458 // Write back the new resolution.
4459 self.write_resolution(hir_id, result);
4461 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4466 /// Resolves an associated value path into a base type and associated constant, or method
4467 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4468 pub fn resolve_ty_and_res_ufcs<'b>(
4470 qpath: &'b QPath<'b>,
4473 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4474 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4475 let (ty, qself, item_segment) = match *qpath {
4476 QPath::Resolved(ref opt_qself, ref path) => {
4479 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4483 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4485 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4486 // Return directly on cache hit. This is useful to avoid doubly reporting
4487 // errors with default match binding modes. See #44614.
4489 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4490 return (def, Some(ty), slice::from_ref(&**item_segment));
4492 let item_name = item_segment.ident;
4493 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4494 let result = match error {
4495 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4496 _ => Err(ErrorReported),
4498 if item_name.name != kw::Invalid {
4499 if let Some(mut e) = self.report_method_error(
4503 SelfSource::QPath(qself),
4513 // Write back the new resolution.
4514 self.write_resolution(hir_id, result);
4516 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4518 slice::from_ref(&**item_segment),
4522 pub fn check_decl_initializer(
4524 local: &'tcx hir::Local<'tcx>,
4525 init: &'tcx hir::Expr<'tcx>,
4527 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4528 // for #42640 (default match binding modes).
4531 let ref_bindings = local.pat.contains_explicit_ref_binding();
4533 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4534 if let Some(m) = ref_bindings {
4535 // Somewhat subtle: if we have a `ref` binding in the pattern,
4536 // we want to avoid introducing coercions for the RHS. This is
4537 // both because it helps preserve sanity and, in the case of
4538 // ref mut, for soundness (issue #23116). In particular, in
4539 // the latter case, we need to be clear that the type of the
4540 // referent for the reference that results is *equal to* the
4541 // type of the place it is referencing, and not some
4542 // supertype thereof.
4543 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4544 self.demand_eqtype(init.span, local_ty, init_ty);
4547 self.check_expr_coercable_to_type(init, local_ty)
4551 /// Type check a `let` statement.
4552 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4553 // Determine and write the type which we'll check the pattern against.
4554 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4555 self.write_ty(local.hir_id, ty);
4557 // Type check the initializer.
4558 if let Some(ref init) = local.init {
4559 let init_ty = self.check_decl_initializer(local, &init);
4560 self.overwrite_local_ty_if_err(local, ty, init_ty);
4563 // Does the expected pattern type originate from an expression and what is the span?
4564 let (origin_expr, ty_span) = match (local.ty, local.init) {
4565 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4566 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4567 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4570 // Type check the pattern. Override if necessary to avoid knock-on errors.
4571 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4572 let pat_ty = self.node_ty(local.pat.hir_id);
4573 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4576 fn overwrite_local_ty_if_err(
4578 local: &'tcx hir::Local<'tcx>,
4582 if ty.references_error() {
4583 // Override the types everywhere with `types.err` to avoid knock on errors.
4584 self.write_ty(local.hir_id, ty);
4585 self.write_ty(local.pat.hir_id, ty);
4586 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4587 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4588 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4592 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4593 err.span_suggestion_short(
4594 span.shrink_to_hi(),
4595 "consider using a semicolon here",
4597 Applicability::MachineApplicable,
4601 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4602 // Don't do all the complex logic below for `DeclItem`.
4604 hir::StmtKind::Item(..) => return,
4605 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4608 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4610 // Hide the outer diverging and `has_errors` flags.
4611 let old_diverges = self.diverges.replace(Diverges::Maybe);
4612 let old_has_errors = self.has_errors.replace(false);
4615 hir::StmtKind::Local(ref l) => {
4616 self.check_decl_local(&l);
4619 hir::StmtKind::Item(_) => {}
4620 hir::StmtKind::Expr(ref expr) => {
4621 // Check with expected type of `()`.
4622 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4623 self.suggest_semicolon_at_end(expr.span, err);
4626 hir::StmtKind::Semi(ref expr) => {
4627 self.check_expr(&expr);
4631 // Combine the diverging and `has_error` flags.
4632 self.diverges.set(self.diverges.get() | old_diverges);
4633 self.has_errors.set(self.has_errors.get() | old_has_errors);
4636 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4637 let unit = self.tcx.mk_unit();
4638 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4640 // if the block produces a `!` value, that can always be
4641 // (effectively) coerced to unit.
4643 self.demand_suptype(blk.span, unit, ty);
4647 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4648 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4649 /// when given code like the following:
4651 /// if false { return 0i32; } else { 1u32 }
4652 /// // ^^^^ point at this instead of the whole `if` expression
4654 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4655 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4656 let arm_spans: Vec<Span> = arms
4659 self.in_progress_tables
4660 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4661 .and_then(|arm_ty| {
4662 if arm_ty.is_never() {
4665 Some(match &arm.body.kind {
4666 // Point at the tail expression when possible.
4667 hir::ExprKind::Block(block, _) => {
4668 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4676 if arm_spans.len() == 1 {
4677 return arm_spans[0];
4683 fn check_block_with_expected(
4685 blk: &'tcx hir::Block<'tcx>,
4686 expected: Expectation<'tcx>,
4689 let mut fcx_ps = self.ps.borrow_mut();
4690 let unsafety_state = fcx_ps.recurse(blk);
4691 replace(&mut *fcx_ps, unsafety_state)
4694 // In some cases, blocks have just one exit, but other blocks
4695 // can be targeted by multiple breaks. This can happen both
4696 // with labeled blocks as well as when we desugar
4697 // a `try { ... }` expression.
4701 // 'a: { if true { break 'a Err(()); } Ok(()) }
4703 // Here we would wind up with two coercions, one from
4704 // `Err(())` and the other from the tail expression
4705 // `Ok(())`. If the tail expression is omitted, that's a
4706 // "forced unit" -- unless the block diverges, in which
4707 // case we can ignore the tail expression (e.g., `'a: {
4708 // break 'a 22; }` would not force the type of the block
4710 let tail_expr = blk.expr.as_ref();
4711 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4712 let coerce = if blk.targeted_by_break {
4713 CoerceMany::new(coerce_to_ty)
4715 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4716 Some(e) => slice::from_ref(e),
4719 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4722 let prev_diverges = self.diverges.get();
4723 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4725 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4726 for s in blk.stmts {
4730 // check the tail expression **without** holding the
4731 // `enclosing_breakables` lock below.
4732 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4734 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4735 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4736 let coerce = ctxt.coerce.as_mut().unwrap();
4737 if let Some(tail_expr_ty) = tail_expr_ty {
4738 let tail_expr = tail_expr.unwrap();
4739 let span = self.get_expr_coercion_span(tail_expr);
4740 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4741 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4743 // Subtle: if there is no explicit tail expression,
4744 // that is typically equivalent to a tail expression
4745 // of `()` -- except if the block diverges. In that
4746 // case, there is no value supplied from the tail
4747 // expression (assuming there are no other breaks,
4748 // this implies that the type of the block will be
4751 // #41425 -- label the implicit `()` as being the
4752 // "found type" here, rather than the "expected type".
4753 if !self.diverges.get().is_always() {
4754 // #50009 -- Do not point at the entire fn block span, point at the return type
4755 // span, as it is the cause of the requirement, and
4756 // `consider_hint_about_removing_semicolon` will point at the last expression
4757 // if it were a relevant part of the error. This improves usability in editors
4758 // that highlight errors inline.
4759 let mut sp = blk.span;
4760 let mut fn_span = None;
4761 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4762 let ret_sp = decl.output.span();
4763 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4764 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4765 // output would otherwise be incorrect and even misleading. Make sure
4766 // the span we're aiming at correspond to a `fn` body.
4767 if block_sp == blk.span {
4769 fn_span = Some(ident.span);
4773 coerce.coerce_forced_unit(
4777 if let Some(expected_ty) = expected.only_has_type(self) {
4778 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4780 if let Some(fn_span) = fn_span {
4783 "implicitly returns `()` as its body has no tail or `return` \
4795 // If we can break from the block, then the block's exit is always reachable
4796 // (... as long as the entry is reachable) - regardless of the tail of the block.
4797 self.diverges.set(prev_diverges);
4800 let mut ty = ctxt.coerce.unwrap().complete(self);
4802 if self.has_errors.get() || ty.references_error() {
4803 ty = self.tcx.types.err
4806 self.write_ty(blk.hir_id, ty);
4808 *self.ps.borrow_mut() = prev;
4812 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4813 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4815 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4816 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4817 let body = self.tcx.hir().body(body_id);
4818 if let ExprKind::Block(block, _) = &body.value.kind {
4819 return Some(block.span);
4827 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4828 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4829 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4830 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4833 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4834 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4836 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4837 // This is less than ideal, it will not suggest a return type span on any
4838 // method called `main`, regardless of whether it is actually the entry point,
4839 // but it will still present it as the reason for the expected type.
4840 Some((&sig.decl, ident, ident.name != sym::main))
4842 Node::TraitItem(&hir::TraitItem {
4844 kind: hir::TraitItemKind::Fn(ref sig, ..),
4846 }) => Some((&sig.decl, ident, true)),
4847 Node::ImplItem(&hir::ImplItem {
4849 kind: hir::ImplItemKind::Fn(ref sig, ..),
4851 }) => Some((&sig.decl, ident, false)),
4856 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4857 /// suggestion can be made, `None` otherwise.
4858 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4859 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4860 // `while` before reaching it, as block tail returns are not available in them.
4861 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4862 let parent = self.tcx.hir().get(blk_id);
4863 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4867 /// On implicit return expressions with mismatched types, provides the following suggestions:
4869 /// - Points out the method's return type as the reason for the expected type.
4870 /// - Possible missing semicolon.
4871 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4872 pub fn suggest_mismatched_types_on_tail(
4874 err: &mut DiagnosticBuilder<'_>,
4875 expr: &'tcx hir::Expr<'tcx>,
4881 let expr = expr.peel_drop_temps();
4882 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4883 let mut pointing_at_return_type = false;
4884 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4885 pointing_at_return_type =
4886 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4888 pointing_at_return_type
4891 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4892 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4894 /// fn foo(x: usize) -> usize { x }
4895 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4899 err: &mut DiagnosticBuilder<'_>,
4900 expr: &hir::Expr<'_>,
4904 let hir = self.tcx.hir();
4905 let (def_id, sig) = match found.kind {
4906 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4907 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4911 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4912 let sig = self.normalize_associated_types_in(expr.span, &sig);
4913 if self.can_coerce(sig.output(), expected) {
4914 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4915 (String::new(), Applicability::MachineApplicable)
4917 ("...".to_string(), Applicability::HasPlaceholders)
4919 let mut msg = "call this function";
4920 match hir.get_if_local(def_id) {
4922 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4923 | Node::ImplItem(hir::ImplItem {
4924 kind: hir::ImplItemKind::Fn(_, body_id), ..
4926 | Node::TraitItem(hir::TraitItem {
4927 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4931 let body = hir.body(*body_id);
4935 .map(|param| match ¶m.pat.kind {
4936 hir::PatKind::Binding(_, _, ident, None)
4937 if ident.name != kw::SelfLower =>
4941 _ => "_".to_string(),
4943 .collect::<Vec<_>>()
4946 Some(Node::Expr(hir::Expr {
4947 kind: ExprKind::Closure(_, _, body_id, _, _),
4948 span: full_closure_span,
4951 if *full_closure_span == expr.span {
4954 msg = "call this closure";
4955 let body = hir.body(*body_id);
4959 .map(|param| match ¶m.pat.kind {
4960 hir::PatKind::Binding(_, _, ident, None)
4961 if ident.name != kw::SelfLower =>
4965 _ => "_".to_string(),
4967 .collect::<Vec<_>>()
4970 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4971 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4972 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
4973 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4974 msg = "instantiate this tuple variant";
4976 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
4977 msg = "instantiate this tuple struct";
4982 Some(Node::ForeignItem(hir::ForeignItem {
4983 kind: hir::ForeignItemKind::Fn(_, idents, _),
4989 if ident.name != kw::SelfLower {
4995 .collect::<Vec<_>>()
4998 Some(Node::TraitItem(hir::TraitItem {
4999 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5005 if ident.name != kw::SelfLower {
5011 .collect::<Vec<_>>()
5016 err.span_suggestion_verbose(
5017 expr.span.shrink_to_hi(),
5018 &format!("use parentheses to {}", msg),
5019 format!("({})", sugg_call),
5027 pub fn suggest_deref_ref_or_into(
5029 err: &mut DiagnosticBuilder<'_>,
5030 expr: &hir::Expr<'_>,
5034 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5035 err.span_suggestion(sp, msg, suggestion, applicability);
5036 } else if let (ty::FnDef(def_id, ..), true) =
5037 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5039 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5040 let sp = self.sess().source_map().guess_head_span(sp);
5041 err.span_label(sp, &format!("{} defined here", found));
5043 } else if !self.check_for_cast(err, expr, found, expected) {
5044 let is_struct_pat_shorthand_field =
5045 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5046 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5047 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5048 let mut suggestions = iter::repeat(&expr_text)
5049 .zip(methods.iter())
5050 .filter_map(|(receiver, method)| {
5051 let method_call = format!(".{}()", method.ident);
5052 if receiver.ends_with(&method_call) {
5053 None // do not suggest code that is already there (#53348)
5055 let method_call_list = [".to_vec()", ".to_string()"];
5056 let sugg = if receiver.ends_with(".clone()")
5057 && method_call_list.contains(&method_call.as_str())
5059 let max_len = receiver.rfind('.').unwrap();
5060 format!("{}{}", &receiver[..max_len], method_call)
5062 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5063 format!("({}){}", receiver, method_call)
5065 format!("{}{}", receiver, method_call)
5068 Some(if is_struct_pat_shorthand_field {
5069 format!("{}: {}", receiver, sugg)
5076 if suggestions.peek().is_some() {
5077 err.span_suggestions(
5079 "try using a conversion method",
5081 Applicability::MaybeIncorrect,
5088 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5089 /// in the heap by calling `Box::new()`.
5090 fn suggest_boxing_when_appropriate(
5092 err: &mut DiagnosticBuilder<'_>,
5093 expr: &hir::Expr<'_>,
5097 if self.tcx.hir().is_const_context(expr.hir_id) {
5098 // Do not suggest `Box::new` in const context.
5101 if !expected.is_box() || found.is_box() {
5104 let boxed_found = self.tcx.mk_box(found);
5105 if let (true, Ok(snippet)) = (
5106 self.can_coerce(boxed_found, expected),
5107 self.sess().source_map().span_to_snippet(expr.span),
5109 err.span_suggestion(
5111 "store this in the heap by calling `Box::new`",
5112 format!("Box::new({})", snippet),
5113 Applicability::MachineApplicable,
5116 "for more on the distinction between the stack and the heap, read \
5117 https://doc.rust-lang.org/book/ch15-01-box.html, \
5118 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5119 https://doc.rust-lang.org/std/boxed/index.html",
5124 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5125 fn suggest_calling_boxed_future_when_appropriate(
5127 err: &mut DiagnosticBuilder<'_>,
5128 expr: &hir::Expr<'_>,
5134 if self.tcx.hir().is_const_context(expr.hir_id) {
5135 // Do not suggest `Box::new` in const context.
5138 let pin_did = self.tcx.lang_items().pin_type();
5139 match expected.kind {
5140 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5141 // This guards the `unwrap` and `mk_box` below.
5142 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5145 let boxed_found = self.tcx.mk_box(found);
5146 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5147 if let (true, Ok(snippet)) = (
5148 self.can_coerce(new_found, expected),
5149 self.sess().source_map().span_to_snippet(expr.span),
5152 ty::Adt(def, _) if def.is_box() => {
5153 err.help("use `Box::pin`");
5156 err.span_suggestion(
5158 "you need to pin and box this expression",
5159 format!("Box::pin({})", snippet),
5160 Applicability::MachineApplicable,
5170 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5174 /// bar_that_returns_u32()
5178 /// This routine checks if the return expression in a block would make sense on its own as a
5179 /// statement and the return type has been left as default or has been specified as `()`. If so,
5180 /// it suggests adding a semicolon.
5181 fn suggest_missing_semicolon(
5183 err: &mut DiagnosticBuilder<'_>,
5184 expression: &'tcx hir::Expr<'tcx>,
5188 if expected.is_unit() {
5189 // `BlockTailExpression` only relevant if the tail expr would be
5190 // useful on its own.
5191 match expression.kind {
5193 | ExprKind::MethodCall(..)
5194 | ExprKind::Loop(..)
5195 | ExprKind::Match(..)
5196 | ExprKind::Block(..) => {
5197 err.span_suggestion(
5198 cause_span.shrink_to_hi(),
5199 "try adding a semicolon",
5201 Applicability::MachineApplicable,
5209 /// A possible error is to forget to add a return type that is needed:
5213 /// bar_that_returns_u32()
5217 /// This routine checks if the return type is left as default, the method is not part of an
5218 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5220 fn suggest_missing_return_type(
5222 err: &mut DiagnosticBuilder<'_>,
5223 fn_decl: &hir::FnDecl<'_>,
5228 // Only suggest changing the return type for methods that
5229 // haven't set a return type at all (and aren't `fn main()` or an impl).
5230 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5231 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5232 err.span_suggestion(
5234 "try adding a return type",
5235 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5236 Applicability::MachineApplicable,
5240 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5241 err.span_label(span, "possibly return type missing here?");
5244 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5245 // `fn main()` must return `()`, do not suggest changing return type
5246 err.span_label(span, "expected `()` because of default return type");
5249 // expectation was caused by something else, not the default return
5250 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5251 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5252 // Only point to return type if the expected type is the return type, as if they
5253 // are not, the expectation must have been caused by something else.
5254 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5256 let ty = AstConv::ast_ty_to_ty(self, ty);
5257 debug!("suggest_missing_return_type: return type {:?}", ty);
5258 debug!("suggest_missing_return_type: expected type {:?}", ty);
5259 if ty.kind == expected.kind {
5260 err.span_label(sp, format!("expected `{}` because of return type", expected));
5268 /// A possible error is to forget to add `.await` when using futures:
5271 /// async fn make_u32() -> u32 {
5275 /// fn take_u32(x: u32) {}
5277 /// async fn foo() {
5278 /// let x = make_u32();
5283 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5284 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5285 /// `.await` to the tail of the expression.
5286 fn suggest_missing_await(
5288 err: &mut DiagnosticBuilder<'_>,
5289 expr: &hir::Expr<'_>,
5293 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5294 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5295 // body isn't `async`.
5296 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5297 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5298 let body = self.tcx().hir().body(body_id);
5299 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5301 // Check for `Future` implementations by constructing a predicate to
5302 // prove: `<T as Future>::Output == U`
5303 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5304 let item_def_id = self
5306 .associated_items(future_trait)
5307 .in_definition_order()
5311 // `<T as Future>::Output`
5312 let projection_ty = ty::ProjectionTy {
5316 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5322 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5326 .to_predicate(self.tcx);
5327 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5329 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5331 if self.infcx.predicate_may_hold(&obligation) {
5332 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5333 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5334 err.span_suggestion(
5336 "consider using `.await` here",
5337 format!("{}.await", code),
5338 Applicability::MaybeIncorrect,
5341 debug!("suggest_missing_await: no snippet for {:?}", sp);
5344 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5350 /// A common error is to add an extra semicolon:
5353 /// fn foo() -> usize {
5358 /// This routine checks if the final statement in a block is an
5359 /// expression with an explicit semicolon whose type is compatible
5360 /// with `expected_ty`. If so, it suggests removing the semicolon.
5361 fn consider_hint_about_removing_semicolon(
5363 blk: &'tcx hir::Block<'tcx>,
5364 expected_ty: Ty<'tcx>,
5365 err: &mut DiagnosticBuilder<'_>,
5367 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5368 err.span_suggestion(
5370 "consider removing this semicolon",
5372 Applicability::MachineApplicable,
5377 fn could_remove_semicolon(
5379 blk: &'tcx hir::Block<'tcx>,
5380 expected_ty: Ty<'tcx>,
5382 // Be helpful when the user wrote `{... expr;}` and
5383 // taking the `;` off is enough to fix the error.
5384 let last_stmt = blk.stmts.last()?;
5385 let last_expr = match last_stmt.kind {
5386 hir::StmtKind::Semi(ref e) => e,
5389 let last_expr_ty = self.node_ty(last_expr.hir_id);
5390 if matches!(last_expr_ty.kind, ty::Error)
5391 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5395 let original_span = original_sp(last_stmt.span, blk.span);
5396 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5399 // Instantiates the given path, which must refer to an item with the given
5400 // number of type parameters and type.
5401 pub fn instantiate_value_path(
5403 segments: &[hir::PathSegment<'_>],
5404 self_ty: Option<Ty<'tcx>>,
5408 ) -> (Ty<'tcx>, Res) {
5410 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5411 segments, self_ty, res, hir_id,
5416 let path_segs = match res {
5417 Res::Local(_) | Res::SelfCtor(_) => vec![],
5418 Res::Def(kind, def_id) => {
5419 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5421 _ => bug!("instantiate_value_path on {:?}", res),
5424 let mut user_self_ty = None;
5425 let mut is_alias_variant_ctor = false;
5427 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5428 if let Some(self_ty) = self_ty {
5429 let adt_def = self_ty.ty_adt_def().unwrap();
5430 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5431 is_alias_variant_ctor = true;
5434 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5435 let container = tcx.associated_item(def_id).container;
5436 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5438 ty::TraitContainer(trait_did) => {
5439 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5441 ty::ImplContainer(impl_def_id) => {
5442 if segments.len() == 1 {
5443 // `<T>::assoc` will end up here, and so
5444 // can `T::assoc`. It this came from an
5445 // inherent impl, we need to record the
5446 // `T` for posterity (see `UserSelfTy` for
5448 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5449 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5457 // Now that we have categorized what space the parameters for each
5458 // segment belong to, let's sort out the parameters that the user
5459 // provided (if any) into their appropriate spaces. We'll also report
5460 // errors if type parameters are provided in an inappropriate place.
5462 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5463 let generics_has_err = AstConv::prohibit_generics(
5465 segments.iter().enumerate().filter_map(|(index, seg)| {
5466 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5474 if let Res::Local(hid) = res {
5475 let ty = self.local_ty(span, hid).decl_ty;
5476 let ty = self.normalize_associated_types_in(span, &ty);
5477 self.write_ty(hir_id, ty);
5481 if generics_has_err {
5482 // Don't try to infer type parameters when prohibited generic arguments were given.
5483 user_self_ty = None;
5486 // Now we have to compare the types that the user *actually*
5487 // provided against the types that were *expected*. If the user
5488 // did not provide any types, then we want to substitute inference
5489 // variables. If the user provided some types, we may still need
5490 // to add defaults. If the user provided *too many* types, that's
5493 let mut infer_args_for_err = FxHashSet::default();
5494 for &PathSeg(def_id, index) in &path_segs {
5495 let seg = &segments[index];
5496 let generics = tcx.generics_of(def_id);
5497 // Argument-position `impl Trait` is treated as a normal generic
5498 // parameter internally, but we don't allow users to specify the
5499 // parameter's value explicitly, so we have to do some error-
5501 if let GenericArgCountResult {
5502 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5504 } = AstConv::check_generic_arg_count_for_call(
5505 tcx, span, &generics, &seg, false, // `is_method_call`
5507 infer_args_for_err.insert(index);
5508 self.set_tainted_by_errors(); // See issue #53251.
5512 let has_self = path_segs
5514 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5517 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5518 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5520 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5521 let variant = adt_def.non_enum_variant();
5522 let ctor_def_id = variant.ctor_def_id.unwrap();
5524 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5529 let mut err = tcx.sess.struct_span_err(
5531 "the `Self` constructor can only be used with tuple or unit structs",
5533 if let Some(adt_def) = ty.ty_adt_def() {
5534 match adt_def.adt_kind() {
5536 err.help("did you mean to use one of the enum's variants?");
5538 AdtKind::Struct | AdtKind::Union => {
5539 err.span_suggestion(
5541 "use curly brackets",
5542 String::from("Self { /* fields */ }"),
5543 Applicability::HasPlaceholders,
5550 return (tcx.types.err, res);
5556 let def_id = res.def_id();
5558 // The things we are substituting into the type should not contain
5559 // escaping late-bound regions, and nor should the base type scheme.
5560 let ty = tcx.type_of(def_id);
5562 let arg_count = GenericArgCountResult {
5563 explicit_late_bound: ExplicitLateBound::No,
5564 correct: if infer_args_for_err.is_empty() {
5567 Err(GenericArgCountMismatch::default())
5571 let substs = self_ctor_substs.unwrap_or_else(|| {
5572 AstConv::create_substs_for_generic_args(
5579 // Provide the generic args, and whether types should be inferred.
5581 if let Some(&PathSeg(_, index)) =
5582 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5584 // If we've encountered an `impl Trait`-related error, we're just
5585 // going to infer the arguments for better error messages.
5586 if !infer_args_for_err.contains(&index) {
5587 // Check whether the user has provided generic arguments.
5588 if let Some(ref data) = segments[index].args {
5589 return (Some(data), segments[index].infer_args);
5592 return (None, segments[index].infer_args);
5597 // Provide substitutions for parameters for which (valid) arguments have been provided.
5598 |param, arg| match (¶m.kind, arg) {
5599 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5600 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5602 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5603 self.to_ty(ty).into()
5605 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5606 self.to_const(&ct.value).into()
5608 _ => unreachable!(),
5610 // Provide substitutions for parameters for which arguments are inferred.
5611 |substs, param, infer_args| {
5613 GenericParamDefKind::Lifetime => {
5614 self.re_infer(Some(param), span).unwrap().into()
5616 GenericParamDefKind::Type { has_default, .. } => {
5617 if !infer_args && has_default {
5618 // If we have a default, then we it doesn't matter that we're not
5619 // inferring the type arguments: we provide the default where any
5621 let default = tcx.type_of(param.def_id);
5624 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5628 // If no type arguments were provided, we have to infer them.
5629 // This case also occurs as a result of some malformed input, e.g.
5630 // a lifetime argument being given instead of a type parameter.
5631 // Using inference instead of `Error` gives better error messages.
5632 self.var_for_def(span, param)
5635 GenericParamDefKind::Const => {
5636 // FIXME(const_generics:defaults)
5637 // No const parameters were provided, we have to infer them.
5638 self.var_for_def(span, param)
5644 assert!(!substs.has_escaping_bound_vars());
5645 assert!(!ty.has_escaping_bound_vars());
5647 // First, store the "user substs" for later.
5648 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5650 self.add_required_obligations(span, def_id, &substs);
5652 // Substitute the values for the type parameters into the type of
5653 // the referenced item.
5654 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5656 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5657 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5658 // is inherent, there is no `Self` parameter; instead, the impl needs
5659 // type parameters, which we can infer by unifying the provided `Self`
5660 // with the substituted impl type.
5661 // This also occurs for an enum variant on a type alias.
5662 let ty = tcx.type_of(impl_def_id);
5664 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5665 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5666 Ok(ok) => self.register_infer_ok_obligations(ok),
5668 self.tcx.sess.delay_span_bug(
5671 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5680 self.check_rustc_args_require_const(def_id, hir_id, span);
5682 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5683 self.write_substs(hir_id, substs);
5685 (ty_substituted, res)
5688 /// Add all the obligations that are required, substituting and normalized appropriately.
5689 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5690 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5692 for (i, mut obligation) in traits::predicates_for_generics(
5693 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5699 // This makes the error point at the bound, but we want to point at the argument
5700 if let Some(span) = spans.get(i) {
5701 obligation.cause.code = traits::BindingObligation(def_id, *span);
5703 self.register_predicate(obligation);
5707 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5708 // We're only interested in functions tagged with
5709 // #[rustc_args_required_const], so ignore anything that's not.
5710 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5714 // If our calling expression is indeed the function itself, we're good!
5715 // If not, generate an error that this can only be called directly.
5716 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5717 if let ExprKind::Call(ref callee, ..) = expr.kind {
5718 if callee.hir_id == hir_id {
5724 self.tcx.sess.span_err(
5726 "this function can only be invoked directly, not through a function pointer",
5730 /// Resolves `typ` by a single level if `typ` is a type variable.
5731 /// If no resolution is possible, then an error is reported.
5732 /// Numeric inference variables may be left unresolved.
5733 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5734 let ty = self.resolve_vars_with_obligations(ty);
5735 if !ty.is_ty_var() {
5738 if !self.is_tainted_by_errors() {
5739 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5740 .note("type must be known at this point")
5743 self.demand_suptype(sp, self.tcx.types.err, ty);
5748 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5751 ctxt: BreakableCtxt<'tcx>,
5753 ) -> (BreakableCtxt<'tcx>, R) {
5756 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5757 index = enclosing_breakables.stack.len();
5758 enclosing_breakables.by_id.insert(id, index);
5759 enclosing_breakables.stack.push(ctxt);
5763 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5764 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5765 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5766 enclosing_breakables.stack.pop().expect("missing breakable context")
5771 /// Instantiate a QueryResponse in a probe context, without a
5772 /// good ObligationCause.
5773 fn probe_instantiate_query_response(
5776 original_values: &OriginalQueryValues<'tcx>,
5777 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5778 ) -> InferResult<'tcx, Ty<'tcx>> {
5779 self.instantiate_query_response_and_region_obligations(
5780 &traits::ObligationCause::misc(span, self.body_id),
5787 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5788 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5789 let mut contained_in_place = false;
5791 while let hir::Node::Expr(parent_expr) =
5792 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5794 match &parent_expr.kind {
5795 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5796 if lhs.hir_id == expr_id {
5797 contained_in_place = true;
5803 expr_id = parent_expr.hir_id;
5810 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5811 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5813 assert_eq!(generics.parent, None);
5815 if generics.own_counts().types == 0 {
5819 let mut params_used = BitSet::new_empty(generics.params.len());
5821 if ty.references_error() {
5822 // If there is already another error, do not emit
5823 // an error for not using a type parameter.
5824 assert!(tcx.sess.has_errors());
5828 for leaf in ty.walk() {
5829 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5830 if let ty::Param(param) = leaf_ty.kind {
5831 debug!("found use of ty param {:?}", param);
5832 params_used.insert(param.index);
5837 for param in &generics.params {
5838 if !params_used.contains(param.index) {
5839 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5840 let span = tcx.def_span(param.def_id);
5845 "type parameter `{}` is unused",
5848 .span_label(span, "unused type parameter")
5855 fn fatally_break_rust(sess: &Session) {
5856 let handler = sess.diagnostic();
5857 handler.span_bug_no_panic(
5859 "It looks like you're trying to break rust; would you like some ICE?",
5861 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5862 handler.note_without_error(
5863 "we would appreciate a joke overview: \
5864 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5866 handler.note_without_error(&format!(
5867 "rustc {} running on {}",
5868 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5869 config::host_triple(),
5873 fn potentially_plural_count(count: usize, word: &str) -> String {
5874 format!("{} {}{}", count, word, pluralize!(count))