1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
80 mod generator_interior;
90 use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg};
92 use rustc_ast::util::parser::ExprPrecedence;
93 use rustc_attr as attr;
94 use rustc_data_structures::captures::Captures;
95 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
96 use rustc_errors::ErrorReported;
97 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
99 use rustc_hir::def::{CtorOf, DefKind, Res};
100 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
101 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
102 use rustc_hir::itemlikevisit::ItemLikeVisitor;
103 use rustc_hir::lang_items::{
104 FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem,
106 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
107 use rustc_index::bit_set::BitSet;
108 use rustc_index::vec::Idx;
109 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
110 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
111 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
112 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
113 use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
114 use rustc_middle::hir::map::blocks::FnLikeNode;
115 use rustc_middle::middle::region;
116 use rustc_middle::mir::interpret::ConstValue;
117 use rustc_middle::ty::adjustment::{
118 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
120 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
121 use rustc_middle::ty::query::Providers;
122 use rustc_middle::ty::subst::{
123 GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
125 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
126 use rustc_middle::ty::{
127 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
128 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
130 use rustc_session::config::{self, EntryFnType};
131 use rustc_session::lint;
132 use rustc_session::parse::feature_err;
133 use rustc_session::Session;
134 use rustc_span::hygiene::DesugaringKind;
135 use rustc_span::source_map::{original_sp, DUMMY_SP};
136 use rustc_span::symbol::{kw, sym, Ident};
137 use rustc_span::{self, BytePos, MultiSpan, Span};
138 use rustc_target::abi::VariantIdx;
139 use rustc_target::spec::abi::Abi;
140 use rustc_trait_selection::infer::InferCtxtExt as _;
141 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
142 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
143 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
144 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
145 use rustc_trait_selection::traits::{
146 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
149 use std::cell::{Cell, Ref, RefCell, RefMut};
151 use std::collections::hash_map::Entry;
153 use std::mem::replace;
154 use std::ops::{self, Deref};
157 use crate::require_c_abi_if_c_variadic;
158 use crate::util::common::indenter;
160 use self::autoderef::Autoderef;
161 use self::callee::DeferredCallResolution;
162 use self::coercion::{CoerceMany, DynamicCoerceMany};
163 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
164 use self::method::{MethodCallee, SelfSource};
165 pub use self::Expectation::*;
166 use self::TupleArgumentsFlag::*;
169 macro_rules! type_error_struct {
170 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
171 if $typ.references_error() {
172 $session.diagnostic().struct_dummy()
174 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
179 /// The type of a local binding, including the revealed type for anon types.
180 #[derive(Copy, Clone, Debug)]
181 pub struct LocalTy<'tcx> {
183 revealed_ty: Ty<'tcx>,
186 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
187 #[derive(Copy, Clone)]
188 struct MaybeInProgressTables<'a, 'tcx> {
189 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
192 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
193 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
194 match self.maybe_tables {
195 Some(tables) => tables.borrow(),
196 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
200 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
201 match self.maybe_tables {
202 Some(tables) => tables.borrow_mut(),
203 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
208 /// Closures defined within the function. For example:
211 /// bar(move|| { ... })
214 /// Here, the function `foo()` and the closure passed to
215 /// `bar()` will each have their own `FnCtxt`, but they will
216 /// share the inherited fields.
217 pub struct Inherited<'a, 'tcx> {
218 infcx: InferCtxt<'a, 'tcx>,
220 tables: MaybeInProgressTables<'a, 'tcx>,
222 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
224 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
226 // Some additional `Sized` obligations badly affect type inference.
227 // These obligations are added in a later stage of typeck.
228 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
230 // When we process a call like `c()` where `c` is a closure type,
231 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
232 // `FnOnce` closure. In that case, we defer full resolution of the
233 // call until upvar inference can kick in and make the
234 // decision. We keep these deferred resolutions grouped by the
235 // def-id of the closure, so that once we decide, we can easily go
236 // back and process them.
237 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
239 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
241 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
243 // Opaque types found in explicit return types and their
244 // associated fresh inference variable. Writeback resolves these
245 // variables to get the concrete type, which can be used to
246 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
247 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
249 /// A map from inference variables created from opaque
250 /// type instantiations (`ty::Infer`) to the actual opaque
251 /// type (`ty::Opaque`). Used during fallback to map unconstrained
252 /// opaque type inference variables to their corresponding
254 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
256 /// Each type parameter has an implicit region bound that
257 /// indicates it must outlive at least the function body (the user
258 /// may specify stronger requirements). This field indicates the
259 /// region of the callee. If it is `None`, then the parameter
260 /// environment is for an item or something where the "callee" is
262 implicit_region_bound: Option<ty::Region<'tcx>>,
264 body_id: Option<hir::BodyId>,
267 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
268 type Target = InferCtxt<'a, 'tcx>;
269 fn deref(&self) -> &Self::Target {
274 /// When type-checking an expression, we propagate downward
275 /// whatever type hint we are able in the form of an `Expectation`.
276 #[derive(Copy, Clone, Debug)]
277 pub enum Expectation<'tcx> {
278 /// We know nothing about what type this expression should have.
281 /// This expression should have the type given (or some subtype).
282 ExpectHasType(Ty<'tcx>),
284 /// This expression will be cast to the `Ty`.
285 ExpectCastableToType(Ty<'tcx>),
287 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
288 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
289 ExpectRvalueLikeUnsized(Ty<'tcx>),
292 impl<'a, 'tcx> Expectation<'tcx> {
293 // Disregard "castable to" expectations because they
294 // can lead us astray. Consider for example `if cond
295 // {22} else {c} as u8` -- if we propagate the
296 // "castable to u8" constraint to 22, it will pick the
297 // type 22u8, which is overly constrained (c might not
298 // be a u8). In effect, the problem is that the
299 // "castable to" expectation is not the tightest thing
300 // we can say, so we want to drop it in this case.
301 // The tightest thing we can say is "must unify with
302 // else branch". Note that in the case of a "has type"
303 // constraint, this limitation does not hold.
305 // If the expected type is just a type variable, then don't use
306 // an expected type. Otherwise, we might write parts of the type
307 // when checking the 'then' block which are incompatible with the
309 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
311 ExpectHasType(ety) => {
312 let ety = fcx.shallow_resolve(ety);
313 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
315 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
320 /// Provides an expectation for an rvalue expression given an *optional*
321 /// hint, which is not required for type safety (the resulting type might
322 /// be checked higher up, as is the case with `&expr` and `box expr`), but
323 /// is useful in determining the concrete type.
325 /// The primary use case is where the expected type is a fat pointer,
326 /// like `&[isize]`. For example, consider the following statement:
328 /// let x: &[isize] = &[1, 2, 3];
330 /// In this case, the expected type for the `&[1, 2, 3]` expression is
331 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
332 /// expectation `ExpectHasType([isize])`, that would be too strong --
333 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
334 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
335 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
336 /// which still is useful, because it informs integer literals and the like.
337 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
338 /// for examples of where this comes up,.
339 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
340 match fcx.tcx.struct_tail_without_normalization(ty).kind {
341 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
342 _ => ExpectHasType(ty),
346 // Resolves `expected` by a single level if it is a variable. If
347 // there is no expected type or resolution is not possible (e.g.,
348 // no constraints yet present), just returns `None`.
349 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
351 NoExpectation => NoExpectation,
352 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
353 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
354 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
358 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
359 match self.resolve(fcx) {
360 NoExpectation => None,
361 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
365 /// It sometimes happens that we want to turn an expectation into
366 /// a **hard constraint** (i.e., something that must be satisfied
367 /// for the program to type-check). `only_has_type` will return
368 /// such a constraint, if it exists.
369 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
370 match self.resolve(fcx) {
371 ExpectHasType(ty) => Some(ty),
372 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
376 /// Like `only_has_type`, but instead of returning `None` if no
377 /// hard constraint exists, creates a fresh type variable.
378 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
379 self.only_has_type(fcx).unwrap_or_else(|| {
380 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
385 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
392 fn maybe_mut_place(m: hir::Mutability) -> Self {
394 hir::Mutability::Mut => Needs::MutPlace,
395 hir::Mutability::Not => Needs::None,
400 #[derive(Copy, Clone)]
401 pub struct UnsafetyState {
403 pub unsafety: hir::Unsafety,
404 pub unsafe_push_count: u32,
409 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
410 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
413 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
414 use hir::BlockCheckMode;
415 match self.unsafety {
416 // If this unsafe, then if the outer function was already marked as
417 // unsafe we shouldn't attribute the unsafe'ness to the block. This
418 // way the block can be warned about instead of ignoring this
419 // extraneous block (functions are never warned about).
420 hir::Unsafety::Unsafe if self.from_fn => *self,
423 let (unsafety, def, count) = match blk.rules {
424 BlockCheckMode::PushUnsafeBlock(..) => {
425 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
427 BlockCheckMode::PopUnsafeBlock(..) => {
428 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
430 BlockCheckMode::UnsafeBlock(..) => {
431 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
433 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
435 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
441 #[derive(Debug, Copy, Clone)]
447 /// Tracks whether executing a node may exit normally (versus
448 /// return/break/panic, which "diverge", leaving dead code in their
449 /// wake). Tracked semi-automatically (through type variables marked
450 /// as diverging), with some manual adjustments for control-flow
451 /// primitives (approximating a CFG).
452 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
454 /// Potentially unknown, some cases converge,
455 /// others require a CFG to determine them.
458 /// Definitely known to diverge and therefore
459 /// not reach the next sibling or its parent.
461 /// The `Span` points to the expression
462 /// that caused us to diverge
463 /// (e.g. `return`, `break`, etc).
465 /// In some cases (e.g. a `match` expression
466 /// where all arms diverge), we may be
467 /// able to provide a more informative
468 /// message to the user.
469 /// If this is `None`, a default message
470 /// will be generated, which is suitable
472 custom_note: Option<&'static str>,
475 /// Same as `Always` but with a reachability
476 /// warning already emitted.
480 // Convenience impls for combining `Diverges`.
482 impl ops::BitAnd for Diverges {
484 fn bitand(self, other: Self) -> Self {
485 cmp::min(self, other)
489 impl ops::BitOr for Diverges {
491 fn bitor(self, other: Self) -> Self {
492 cmp::max(self, other)
496 impl ops::BitAndAssign for Diverges {
497 fn bitand_assign(&mut self, other: Self) {
498 *self = *self & other;
502 impl ops::BitOrAssign for Diverges {
503 fn bitor_assign(&mut self, other: Self) {
504 *self = *self | other;
509 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
510 fn always(span: Span) -> Diverges {
511 Diverges::Always { span, custom_note: None }
514 fn is_always(self) -> bool {
515 // Enum comparison ignores the
516 // contents of fields, so we just
517 // fill them in with garbage here.
518 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
522 pub struct BreakableCtxt<'tcx> {
525 // this is `null` for loops where break with a value is illegal,
526 // such as `while`, `for`, and `while let`
527 coerce: Option<DynamicCoerceMany<'tcx>>,
530 pub struct EnclosingBreakables<'tcx> {
531 stack: Vec<BreakableCtxt<'tcx>>,
532 by_id: HirIdMap<usize>,
535 impl<'tcx> EnclosingBreakables<'tcx> {
536 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
537 self.opt_find_breakable(target_id).unwrap_or_else(|| {
538 bug!("could not find enclosing breakable with id {}", target_id);
542 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
543 match self.by_id.get(&target_id) {
544 Some(ix) => Some(&mut self.stack[*ix]),
550 pub struct FnCtxt<'a, 'tcx> {
553 /// The parameter environment used for proving trait obligations
554 /// in this function. This can change when we descend into
555 /// closures (as they bring new things into scope), hence it is
556 /// not part of `Inherited` (as of the time of this writing,
557 /// closures do not yet change the environment, but they will
559 param_env: ty::ParamEnv<'tcx>,
561 /// Number of errors that had been reported when we started
562 /// checking this function. On exit, if we find that *more* errors
563 /// have been reported, we will skip regionck and other work that
564 /// expects the types within the function to be consistent.
565 // FIXME(matthewjasper) This should not exist, and it's not correct
566 // if type checking is run in parallel.
567 err_count_on_creation: usize,
569 /// If `Some`, this stores coercion information for returned
570 /// expressions. If `None`, this is in a context where return is
571 /// inappropriate, such as a const expression.
573 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
574 /// can track all the return expressions and then use them to
575 /// compute a useful coercion from the set, similar to a match
576 /// expression or other branching context. You can use methods
577 /// like `expected_ty` to access the declared return type (if
579 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
581 /// First span of a return site that we find. Used in error messages.
582 ret_coercion_span: RefCell<Option<Span>>,
584 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
586 ps: RefCell<UnsafetyState>,
588 /// Whether the last checked node generates a divergence (e.g.,
589 /// `return` will set this to `Always`). In general, when entering
590 /// an expression or other node in the tree, the initial value
591 /// indicates whether prior parts of the containing expression may
592 /// have diverged. It is then typically set to `Maybe` (and the
593 /// old value remembered) for processing the subparts of the
594 /// current expression. As each subpart is processed, they may set
595 /// the flag to `Always`, etc. Finally, at the end, we take the
596 /// result and "union" it with the original value, so that when we
597 /// return the flag indicates if any subpart of the parent
598 /// expression (up to and including this part) has diverged. So,
599 /// if you read it after evaluating a subexpression `X`, the value
600 /// you get indicates whether any subexpression that was
601 /// evaluating up to and including `X` diverged.
603 /// We currently use this flag only for diagnostic purposes:
605 /// - To warn about unreachable code: if, after processing a
606 /// sub-expression but before we have applied the effects of the
607 /// current node, we see that the flag is set to `Always`, we
608 /// can issue a warning. This corresponds to something like
609 /// `foo(return)`; we warn on the `foo()` expression. (We then
610 /// update the flag to `WarnedAlways` to suppress duplicate
611 /// reports.) Similarly, if we traverse to a fresh statement (or
612 /// tail expression) from a `Always` setting, we will issue a
613 /// warning. This corresponds to something like `{return;
614 /// foo();}` or `{return; 22}`, where we would warn on the
617 /// An expression represents dead code if, after checking it,
618 /// the diverges flag is set to something other than `Maybe`.
619 diverges: Cell<Diverges>,
621 /// Whether any child nodes have any type errors.
622 has_errors: Cell<bool>,
624 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
626 inh: &'a Inherited<'a, 'tcx>,
629 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
630 type Target = Inherited<'a, 'tcx>;
631 fn deref(&self) -> &Self::Target {
636 /// Helper type of a temporary returned by `Inherited::build(...)`.
637 /// Necessary because we can't write the following bound:
638 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
639 pub struct InheritedBuilder<'tcx> {
640 infcx: infer::InferCtxtBuilder<'tcx>,
644 impl Inherited<'_, 'tcx> {
645 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
646 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
649 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_owner),
655 impl<'tcx> InheritedBuilder<'tcx> {
656 fn enter<F, R>(&mut self, f: F) -> R
658 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
660 let def_id = self.def_id;
661 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
665 impl Inherited<'a, 'tcx> {
666 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
668 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
669 let body_id = tcx.hir().maybe_body_owned_by(item_id);
670 let implicit_region_bound = body_id.map(|body_id| {
671 let body = tcx.hir().body(body_id);
672 tcx.mk_region(ty::ReScope(region::Scope {
673 id: body.value.hir_id.local_id,
674 data: region::ScopeData::CallSite,
679 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
681 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
682 locals: RefCell::new(Default::default()),
683 deferred_sized_obligations: RefCell::new(Vec::new()),
684 deferred_call_resolutions: RefCell::new(Default::default()),
685 deferred_cast_checks: RefCell::new(Vec::new()),
686 deferred_generator_interiors: RefCell::new(Vec::new()),
687 opaque_types: RefCell::new(Default::default()),
688 opaque_types_vars: RefCell::new(Default::default()),
689 implicit_region_bound,
694 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
695 debug!("register_predicate({:?})", obligation);
696 if obligation.has_escaping_bound_vars() {
697 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
699 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
702 fn register_predicates<I>(&self, obligations: I)
704 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
706 for obligation in obligations {
707 self.register_predicate(obligation);
711 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
712 self.register_predicates(infer_ok.obligations);
716 fn normalize_associated_types_in<T>(
720 param_env: ty::ParamEnv<'tcx>,
724 T: TypeFoldable<'tcx>,
726 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
727 self.register_infer_ok_obligations(ok)
731 struct CheckItemTypesVisitor<'tcx> {
735 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
736 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
737 check_item_type(self.tcx, i);
739 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
740 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
743 pub fn check_wf_new(tcx: TyCtxt<'_>) {
744 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
745 tcx.hir().krate().par_visit_all_item_likes(&visit);
748 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
749 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
752 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
753 debug_assert!(crate_num == LOCAL_CRATE);
754 tcx.par_body_owners(|body_owner_def_id| {
755 tcx.ensure().typeck_tables_of(body_owner_def_id);
759 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
760 wfcheck::check_item_well_formed(tcx, def_id);
763 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
764 wfcheck::check_trait_item(tcx, def_id);
767 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
768 wfcheck::check_impl_item(tcx, def_id);
771 pub fn provide(providers: &mut Providers<'_>) {
772 method::provide(providers);
773 *providers = Providers {
776 diagnostic_only_typeck_tables_of,
780 check_item_well_formed,
781 check_trait_item_well_formed,
782 check_impl_item_well_formed,
783 check_mod_item_types,
788 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
789 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
792 /// If this `DefId` is a "primary tables entry", returns
793 /// `Some((body_id, header, decl))` with information about
794 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
797 /// If this function returns `Some`, then `typeck_tables(def_id)` will
798 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
799 /// may not succeed. In some cases where this function returns `None`
800 /// (notably closures), `typeck_tables(def_id)` would wind up
801 /// redirecting to the owning function.
805 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
806 match tcx.hir().get(id) {
807 Node::Item(item) => match item.kind {
808 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
809 Some((body, Some(ty), None, None))
811 hir::ItemKind::Fn(ref sig, .., body) => {
812 Some((body, None, Some(&sig.header), Some(&sig.decl)))
816 Node::TraitItem(item) => match item.kind {
817 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
818 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
819 Some((body, None, Some(&sig.header), Some(&sig.decl)))
823 Node::ImplItem(item) => match item.kind {
824 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
825 hir::ImplItemKind::Fn(ref sig, body) => {
826 Some((body, None, Some(&sig.header), Some(&sig.decl)))
830 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
835 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
836 // Closures' tables come from their outermost function,
837 // as they are part of the same "inference environment".
838 let outer_def_id = tcx.closure_base_def_id(def_id);
839 if outer_def_id != def_id {
840 return tcx.has_typeck_tables(outer_def_id);
843 if let Some(def_id) = def_id.as_local() {
844 let id = tcx.hir().local_def_id_to_hir_id(def_id);
845 primary_body_of(tcx, id).is_some()
851 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &DefIdSet {
852 &*tcx.typeck_tables_of(def_id).used_trait_imports
855 /// Inspects the substs of opaque types, replacing any inference variables
856 /// with proper generic parameter from the identity substs.
858 /// This is run after we normalize the function signature, to fix any inference
859 /// variables introduced by the projection of associated types. This ensures that
860 /// any opaque types used in the signature continue to refer to generic parameters,
861 /// allowing them to be considered for defining uses in the function body
863 /// For example, consider this code.
868 /// fn use_it(self) -> Self::MyItem
870 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
871 /// type MyItem = impl Iterator<Item = I>;
872 /// fn use_it(self) -> Self::MyItem {
878 /// When we normalize the signature of `use_it` from the impl block,
879 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
880 /// However, this projection result may contain inference variables, due
881 /// to the way that projection works. We didn't have any inference variables
882 /// in the signature to begin with - leaving them in will cause us to incorrectly
883 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
884 /// variables back to the actual generic parameters, we will correctly see that
885 /// we have a defining use of `MyItem`
886 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
888 T: TypeFoldable<'tcx>,
890 struct FixupFolder<'tcx> {
894 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
895 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
899 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
901 ty::Opaque(def_id, substs) => {
902 debug!("fixup_opaque_types: found type {:?}", ty);
903 // Here, we replace any inference variables that occur within
904 // the substs of an opaque type. By definition, any type occurring
905 // in the substs has a corresponding generic parameter, which is what
906 // we replace it with.
907 // This replacement is only run on the function signature, so any
908 // inference variables that we come across must be the rust of projection
909 // (there's no other way for a user to get inference variables into
910 // a function signature).
911 if ty.needs_infer() {
912 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
913 let old_param = substs[param.index as usize];
914 match old_param.unpack() {
915 GenericArgKind::Type(old_ty) => {
916 if let ty::Infer(_) = old_ty.kind {
917 // Replace inference type with a generic parameter
918 self.tcx.mk_param_from_def(param)
920 old_param.fold_with(self)
923 GenericArgKind::Const(old_const) => {
924 if let ty::ConstKind::Infer(_) = old_const.val {
925 // This should never happen - we currently do not support
926 // 'const projections', e.g.:
927 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
928 // which should be the only way for us to end up with a const inference
929 // variable after projection. If Rust ever gains support for this kind
930 // of projection, this should *probably* be changed to
931 // `self.tcx.mk_param_from_def(param)`
933 "Found infer const: `{:?}` in opaque type: {:?}",
938 old_param.fold_with(self)
941 GenericArgKind::Lifetime(old_region) => {
942 if let RegionKind::ReVar(_) = old_region {
943 self.tcx.mk_param_from_def(param)
945 old_param.fold_with(self)
950 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
951 debug!("fixup_opaque_types: new type: {:?}", new_ty);
957 _ => ty.super_fold_with(self),
962 debug!("fixup_opaque_types({:?})", val);
963 val.fold_with(&mut FixupFolder { tcx })
966 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> {
967 let fallback = move || tcx.type_of(def_id.to_def_id());
968 typeck_tables_of_with_fallback(tcx, def_id, fallback)
971 /// Used only to get `TypeckTables` for type inference during error recovery.
972 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
973 fn diagnostic_only_typeck_tables_of<'tcx>(
976 ) -> &ty::TypeckTables<'tcx> {
977 let fallback = move || {
978 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
979 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
982 typeck_tables_of_with_fallback(tcx, def_id, fallback)
985 fn typeck_tables_of_with_fallback<'tcx>(
988 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
989 ) -> &'tcx ty::TypeckTables<'tcx> {
990 // Closures' tables come from their outermost function,
991 // as they are part of the same "inference environment".
992 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
993 if outer_def_id != def_id {
994 return tcx.typeck_tables_of(outer_def_id);
997 let id = tcx.hir().as_local_hir_id(def_id);
998 let span = tcx.hir().span(id);
1000 // Figure out what primary body this item has.
1001 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
1002 span_bug!(span, "can't type-check body of {:?}", def_id);
1004 let body = tcx.hir().body(body_id);
1006 let tables = Inherited::build(tcx, def_id).enter(|inh| {
1007 let param_env = tcx.param_env(def_id);
1008 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1009 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1010 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1016 &hir::Generics::empty(),
1023 check_abi(tcx, span, fn_sig.abi());
1025 // Compute the fty from point of view of inside the fn.
1026 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1027 let fn_sig = inh.normalize_associated_types_in(
1034 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1036 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1039 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1040 let expected_type = body_ty
1041 .and_then(|ty| match ty.kind {
1042 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1045 .unwrap_or_else(fallback);
1046 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1047 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1049 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1050 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1055 // Gather locals in statics (because of block expressions).
1056 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1058 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1060 fcx.write_ty(id, revealed_ty);
1065 // All type checking constraints were added, try to fallback unsolved variables.
1066 fcx.select_obligations_where_possible(false, |_| {});
1067 let mut fallback_has_occurred = false;
1069 // We do fallback in two passes, to try to generate
1070 // better error messages.
1071 // The first time, we do *not* replace opaque types.
1072 for ty in &fcx.unsolved_variables() {
1073 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1075 // We now see if we can make progress. This might
1076 // cause us to unify inference variables for opaque types,
1077 // since we may have unified some other type variables
1078 // during the first phase of fallback.
1079 // This means that we only replace inference variables with their underlying
1080 // opaque types as a last resort.
1082 // In code like this:
1085 // type MyType = impl Copy;
1086 // fn produce() -> MyType { true }
1087 // fn bad_produce() -> MyType { panic!() }
1090 // we want to unify the opaque inference variable in `bad_produce`
1091 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1092 // This will produce a nice error message about conflicting concrete
1093 // types for `MyType`.
1095 // If we had tried to fallback the opaque inference variable to `MyType`,
1096 // we will generate a confusing type-check error that does not explicitly
1097 // refer to opaque types.
1098 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1100 // We now run fallback again, but this time we allow it to replace
1101 // unconstrained opaque type variables, in addition to performing
1102 // other kinds of fallback.
1103 for ty in &fcx.unsolved_variables() {
1104 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1107 // See if we can make any more progress.
1108 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1110 // Even though coercion casts provide type hints, we check casts after fallback for
1111 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1114 // Closure and generator analysis may run after fallback
1115 // because they don't constrain other type variables.
1116 fcx.closure_analyze(body);
1117 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1118 fcx.resolve_generator_interiors(def_id.to_def_id());
1120 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1121 let ty = fcx.normalize_ty(span, ty);
1122 fcx.require_type_is_sized(ty, span, code);
1125 fcx.select_all_obligations_or_error();
1127 if fn_decl.is_some() {
1128 fcx.regionck_fn(id, body);
1130 fcx.regionck_expr(body);
1133 fcx.resolve_type_vars_in_body(body)
1136 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1137 // it will need to hold.
1138 assert_eq!(tables.hir_owner, Some(id.owner));
1143 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1144 if !tcx.sess.target.target.is_abi_supported(abi) {
1149 "The ABI `{}` is not supported for the current target",
1156 struct GatherLocalsVisitor<'a, 'tcx> {
1157 fcx: &'a FnCtxt<'a, 'tcx>,
1158 parent_id: hir::HirId,
1161 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1162 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1165 // Infer the variable's type.
1166 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1167 kind: TypeVariableOriginKind::TypeInference,
1173 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1177 // Take type that the user specified.
1178 self.fcx.locals.borrow_mut().insert(nid, typ);
1185 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1186 type Map = intravisit::ErasedMap<'tcx>;
1188 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1189 NestedVisitorMap::None
1192 // Add explicitly-declared locals.
1193 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1194 let local_ty = match local.ty {
1196 let o_ty = self.fcx.to_ty(&ty);
1198 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1199 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1208 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1210 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1211 ty.hir_id, o_ty, revealed_ty, c_ty
1213 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1215 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1219 self.assign(local.span, local.hir_id, local_ty);
1222 "local variable {:?} is assigned type {}",
1224 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1226 intravisit::walk_local(self, local);
1229 // Add pattern bindings.
1230 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1231 if let PatKind::Binding(_, _, ident, _) = p.kind {
1232 let var_ty = self.assign(p.span, p.hir_id, None);
1234 if !self.fcx.tcx.features().unsized_locals {
1235 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1239 "pattern binding {} is assigned to {} with type {:?}",
1241 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1245 intravisit::walk_pat(self, p);
1248 // Don't descend into the bodies of nested closures.
1251 _: intravisit::FnKind<'tcx>,
1252 _: &'tcx hir::FnDecl<'tcx>,
1260 /// When `check_fn` is invoked on a generator (i.e., a body that
1261 /// includes yield), it returns back some information about the yield
1263 struct GeneratorTypes<'tcx> {
1264 /// Type of generator argument / values returned by `yield`.
1265 resume_ty: Ty<'tcx>,
1267 /// Type of value that is yielded.
1270 /// Types that are captured (see `GeneratorInterior` for more).
1273 /// Indicates if the generator is movable or static (immovable).
1274 movability: hir::Movability,
1277 /// Helper used for fns and closures. Does the grungy work of checking a function
1278 /// body and returns the function context used for that purpose, since in the case of a fn item
1279 /// there is still a bit more to do.
1282 /// * inherited: other fields inherited from the enclosing fn (if any)
1283 fn check_fn<'a, 'tcx>(
1284 inherited: &'a Inherited<'a, 'tcx>,
1285 param_env: ty::ParamEnv<'tcx>,
1286 fn_sig: ty::FnSig<'tcx>,
1287 decl: &'tcx hir::FnDecl<'tcx>,
1289 body: &'tcx hir::Body<'tcx>,
1290 can_be_generator: Option<hir::Movability>,
1291 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1292 let mut fn_sig = fn_sig;
1294 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1296 // Create the function context. This is either derived from scratch or,
1297 // in the case of closures, based on the outer context.
1298 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1299 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1302 let sess = tcx.sess;
1303 let hir = tcx.hir();
1305 let declared_ret_ty = fn_sig.output();
1306 let revealed_ret_ty =
1307 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1308 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1309 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1310 fn_sig = tcx.mk_fn_sig(
1311 fn_sig.inputs().iter().cloned(),
1318 let span = body.value.span;
1320 fn_maybe_err(tcx, span, fn_sig.abi);
1322 if body.generator_kind.is_some() && can_be_generator.is_some() {
1324 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1325 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1327 // Resume type defaults to `()` if the generator has no argument.
1328 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1330 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1333 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
1334 let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1335 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1337 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1338 // (as it's created inside the body itself, not passed in from outside).
1339 let maybe_va_list = if fn_sig.c_variadic {
1341 tcx.require_lang_item(VaListTypeLangItem, Some(body.params.last().unwrap().span));
1342 let region = tcx.mk_region(ty::ReScope(region::Scope {
1343 id: body.value.hir_id.local_id,
1344 data: region::ScopeData::CallSite,
1347 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1352 // Add formal parameters.
1353 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1354 let inputs_fn = fn_sig.inputs().iter().copied();
1355 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1356 // Check the pattern.
1357 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1359 // Check that argument is Sized.
1360 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1361 // for simple cases like `fn foo(x: Trait)`,
1362 // where we would error once on the parameter as a whole, and once on the binding `x`.
1363 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1364 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1367 fcx.write_ty(param.hir_id, param_ty);
1370 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1372 if let ty::Dynamic(..) = declared_ret_ty.kind {
1373 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1374 // been evaluated so that we have types available for all the nodes being returned, but that
1375 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1376 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1377 // while keeping the current ordering we will ignore the tail expression's type because we
1378 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1379 // because we will trigger "unreachable expression" lints unconditionally.
1380 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1381 // case that a newcomer might make, returning a bare trait, and in that case we populate
1382 // the tail expression's type so that the suggestion will be correct, but ignore all other
1384 fcx.check_expr(&body.value);
1385 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1386 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1388 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1389 fcx.check_return_expr(&body.value);
1392 // We insert the deferred_generator_interiors entry after visiting the body.
1393 // This ensures that all nested generators appear before the entry of this generator.
1394 // resolve_generator_interiors relies on this property.
1395 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1397 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1398 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1400 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1401 Some(GeneratorTypes {
1405 movability: can_be_generator.unwrap(),
1411 // Finalize the return check by taking the LUB of the return types
1412 // we saw and assigning it to the expected return type. This isn't
1413 // really expected to fail, since the coercions would have failed
1414 // earlier when trying to find a LUB.
1416 // However, the behavior around `!` is sort of complex. In the
1417 // event that the `actual_return_ty` comes back as `!`, that
1418 // indicates that the fn either does not return or "returns" only
1419 // values of type `!`. In this case, if there is an expected
1420 // return type that is *not* `!`, that should be ok. But if the
1421 // return type is being inferred, we want to "fallback" to `!`:
1423 // let x = move || panic!();
1425 // To allow for that, I am creating a type variable with diverging
1426 // fallback. This was deemed ever so slightly better than unifying
1427 // the return value with `!` because it allows for the caller to
1428 // make more assumptions about the return type (e.g., they could do
1430 // let y: Option<u32> = Some(x());
1432 // which would then cause this return type to become `u32`, not
1434 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1435 let mut actual_return_ty = coercion.complete(&fcx);
1436 if actual_return_ty.is_never() {
1437 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1438 kind: TypeVariableOriginKind::DivergingFn,
1442 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1444 // Check that the main return type implements the termination trait.
1445 if let Some(term_id) = tcx.lang_items().termination() {
1446 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1447 let main_id = hir.as_local_hir_id(def_id);
1448 if main_id == fn_id {
1449 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1450 let trait_ref = ty::TraitRef::new(term_id, substs);
1451 let return_ty_span = decl.output.span();
1452 let cause = traits::ObligationCause::new(
1455 ObligationCauseCode::MainFunctionType,
1458 inherited.register_predicate(traits::Obligation::new(
1461 trait_ref.without_const().to_predicate(),
1467 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1468 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1469 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1470 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1471 if declared_ret_ty.kind != ty::Never {
1472 sess.span_err(decl.output.span(), "return type should be `!`");
1475 let inputs = fn_sig.inputs();
1476 let span = hir.span(fn_id);
1477 if inputs.len() == 1 {
1478 let arg_is_panic_info = match inputs[0].kind {
1479 ty::Ref(region, ty, mutbl) => match ty.kind {
1480 ty::Adt(ref adt, _) => {
1481 adt.did == panic_info_did
1482 && mutbl == hir::Mutability::Not
1483 && *region != RegionKind::ReStatic
1490 if !arg_is_panic_info {
1491 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1494 if let Node::Item(item) = hir.get(fn_id) {
1495 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1496 if !generics.params.is_empty() {
1497 sess.span_err(span, "should have no type parameters");
1502 let span = sess.source_map().guess_head_span(span);
1503 sess.span_err(span, "function should have one argument");
1506 sess.err("language item required, but not found: `panic_info`");
1511 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1512 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1513 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1514 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1515 if declared_ret_ty.kind != ty::Never {
1516 sess.span_err(decl.output.span(), "return type should be `!`");
1519 let inputs = fn_sig.inputs();
1520 let span = hir.span(fn_id);
1521 if inputs.len() == 1 {
1522 let arg_is_alloc_layout = match inputs[0].kind {
1523 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1527 if !arg_is_alloc_layout {
1528 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1531 if let Node::Item(item) = hir.get(fn_id) {
1532 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1533 if !generics.params.is_empty() {
1536 "`#[alloc_error_handler]` function should have no type \
1543 let span = sess.source_map().guess_head_span(span);
1544 sess.span_err(span, "function should have one argument");
1547 sess.err("language item required, but not found: `alloc_layout`");
1555 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1556 let def_id = tcx.hir().local_def_id(id);
1557 let def = tcx.adt_def(def_id);
1558 def.destructor(tcx); // force the destructor to be evaluated
1559 check_representable(tcx, span, def_id);
1561 if def.repr.simd() {
1562 check_simd(tcx, span, def_id);
1565 check_transparent(tcx, span, def);
1566 check_packed(tcx, span, def);
1569 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1570 let def_id = tcx.hir().local_def_id(id);
1571 let def = tcx.adt_def(def_id);
1572 def.destructor(tcx); // force the destructor to be evaluated
1573 check_representable(tcx, span, def_id);
1574 check_transparent(tcx, span, def);
1575 check_union_fields(tcx, span, def_id);
1576 check_packed(tcx, span, def);
1579 /// When the `#![feature(untagged_unions)]` gate is active,
1580 /// check that the fields of the `union` does not contain fields that need dropping.
1581 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1582 let item_type = tcx.type_of(item_def_id);
1583 if let ty::Adt(def, substs) = item_type.kind {
1584 assert!(def.is_union());
1585 let fields = &def.non_enum_variant().fields;
1586 let param_env = tcx.param_env(item_def_id);
1587 for field in fields {
1588 let field_ty = field.ty(tcx, substs);
1589 // We are currently checking the type this field came from, so it must be local.
1590 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1591 if field_ty.needs_drop(tcx, param_env) {
1596 "unions may not contain fields that need dropping"
1598 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1604 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1609 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1610 /// projections that would result in "inheriting lifetimes".
1611 fn check_opaque<'tcx>(
1614 substs: SubstsRef<'tcx>,
1616 origin: &hir::OpaqueTyOrigin,
1618 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1619 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1622 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1623 /// in "inheriting lifetimes".
1624 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1625 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1627 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1632 struct ProhibitOpaqueVisitor<'tcx> {
1633 opaque_identity_ty: Ty<'tcx>,
1634 generics: &'tcx ty::Generics,
1637 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1638 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1639 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1640 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1643 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1644 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1645 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1646 return *index < self.generics.parent_count as u32;
1649 r.super_visit_with(self)
1652 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1653 if let ty::ConstKind::Unevaluated(..) = c.val {
1654 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1655 // which would violate this check. Even though the particular substitution is not used
1656 // within the const, this should still be fixed.
1659 c.super_visit_with(self)
1663 let prohibit_opaque = match item.kind {
1664 ItemKind::OpaqueTy(hir::OpaqueTy {
1665 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1668 let mut visitor = ProhibitOpaqueVisitor {
1669 opaque_identity_ty: tcx.mk_opaque(
1671 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1673 generics: tcx.generics_of(def_id),
1675 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1677 tcx.predicates_of(def_id)
1680 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1685 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1686 if prohibit_opaque {
1687 let is_async = match item.kind {
1688 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1689 hir::OpaqueTyOrigin::AsyncFn => true,
1692 _ => unreachable!(),
1698 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1700 if is_async { "async fn" } else { "impl Trait" },
1706 /// Checks that an opaque type does not contain cycles.
1707 fn check_opaque_for_cycles<'tcx>(
1710 substs: SubstsRef<'tcx>,
1712 origin: &hir::OpaqueTyOrigin,
1714 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1716 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1717 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1718 .span_label(span, "recursive `async fn`")
1719 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1723 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1724 err.span_label(span, "expands to a recursive type");
1725 if let ty::Opaque(..) = partially_expanded_type.kind {
1726 err.note("type resolves to itself");
1728 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1735 // Forbid defining intrinsics in Rust code,
1736 // as they must always be defined by the compiler.
1737 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1738 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1739 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1743 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1745 "check_item_type(it.hir_id={}, it.name={})",
1747 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1749 let _indenter = indenter();
1751 // Consts can play a role in type-checking, so they are included here.
1752 hir::ItemKind::Static(..) => {
1753 let def_id = tcx.hir().local_def_id(it.hir_id);
1754 tcx.ensure().typeck_tables_of(def_id);
1755 maybe_check_static_with_link_section(tcx, def_id, it.span);
1757 hir::ItemKind::Const(..) => {
1758 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1760 hir::ItemKind::Enum(ref enum_definition, _) => {
1761 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1763 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1764 hir::ItemKind::Impl { ref items, .. } => {
1765 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1766 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1767 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1768 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1769 let trait_def_id = impl_trait_ref.def_id;
1770 check_on_unimplemented(tcx, trait_def_id, it);
1773 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1774 let def_id = tcx.hir().local_def_id(it.hir_id);
1775 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1777 for item in items.iter() {
1778 let item = tcx.hir().trait_item(item.id);
1779 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1780 let abi = sig.header.abi;
1781 fn_maybe_err(tcx, item.ident.span, abi);
1785 hir::ItemKind::Struct(..) => {
1786 check_struct(tcx, it.hir_id, it.span);
1788 hir::ItemKind::Union(..) => {
1789 check_union(tcx, it.hir_id, it.span);
1791 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1792 let def_id = tcx.hir().local_def_id(it.hir_id);
1794 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1795 check_opaque(tcx, def_id, substs, it.span, &origin);
1797 hir::ItemKind::TyAlias(..) => {
1798 let def_id = tcx.hir().local_def_id(it.hir_id);
1799 let pty_ty = tcx.type_of(def_id);
1800 let generics = tcx.generics_of(def_id);
1801 check_type_params_are_used(tcx, &generics, pty_ty);
1803 hir::ItemKind::ForeignMod(ref m) => {
1804 check_abi(tcx, it.span, m.abi);
1806 if m.abi == Abi::RustIntrinsic {
1807 for item in m.items {
1808 intrinsic::check_intrinsic_type(tcx, item);
1810 } else if m.abi == Abi::PlatformIntrinsic {
1811 for item in m.items {
1812 intrinsic::check_platform_intrinsic_type(tcx, item);
1815 for item in m.items {
1816 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1817 let own_counts = generics.own_counts();
1818 if generics.params.len() - own_counts.lifetimes != 0 {
1819 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1820 (_, 0) => ("type", "types", Some("u32")),
1821 // We don't specify an example value, because we can't generate
1822 // a valid value for any type.
1823 (0, _) => ("const", "consts", None),
1824 _ => ("type or const", "types or consts", None),
1830 "foreign items may not have {} parameters",
1833 .span_label(item.span, &format!("can't have {} parameters", kinds))
1835 // FIXME: once we start storing spans for type arguments, turn this
1836 // into a suggestion.
1838 "replace the {} parameters with concrete {}{}",
1841 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1847 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1848 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1853 _ => { /* nothing to do */ }
1857 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1858 // Only restricted on wasm32 target for now
1859 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1863 // If `#[link_section]` is missing, then nothing to verify
1864 let attrs = tcx.codegen_fn_attrs(id);
1865 if attrs.link_section.is_none() {
1869 // For the wasm32 target statics with `#[link_section]` are placed into custom
1870 // sections of the final output file, but this isn't link custom sections of
1871 // other executable formats. Namely we can only embed a list of bytes,
1872 // nothing with pointers to anything else or relocations. If any relocation
1873 // show up, reject them here.
1874 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1875 // the consumer's responsibility to ensure all bytes that have been read
1876 // have defined values.
1877 match tcx.const_eval_poly(id.to_def_id()) {
1878 Ok(ConstValue::ByRef { alloc, .. }) => {
1879 if alloc.relocations().len() != 0 {
1880 let msg = "statics with a custom `#[link_section]` must be a \
1881 simple list of bytes on the wasm target with no \
1882 extra levels of indirection such as references";
1883 tcx.sess.span_err(span, msg);
1886 Ok(_) => bug!("Matching on non-ByRef static"),
1891 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1892 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1893 // an error would be reported if this fails.
1894 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1897 fn report_forbidden_specialization(
1899 impl_item: &hir::ImplItem<'_>,
1902 let mut err = struct_span_err!(
1906 "`{}` specializes an item from a parent `impl`, but \
1907 that item is not marked `default`",
1910 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1912 match tcx.span_of_impl(parent_impl) {
1914 err.span_label(span, "parent `impl` is here");
1916 "to specialize, `{}` in the parent `impl` must be marked `default`",
1921 err.note(&format!("parent implementation is in crate `{}`", cname));
1928 fn check_specialization_validity<'tcx>(
1930 trait_def: &ty::TraitDef,
1931 trait_item: &ty::AssocItem,
1933 impl_item: &hir::ImplItem<'_>,
1935 let kind = match impl_item.kind {
1936 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1937 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1938 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1939 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1942 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1943 Ok(ancestors) => ancestors,
1946 let mut ancestor_impls = ancestors
1948 .filter_map(|parent| {
1949 if parent.is_from_trait() {
1952 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1957 if ancestor_impls.peek().is_none() {
1958 // No parent, nothing to specialize.
1962 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1964 // Parent impl exists, and contains the parent item we're trying to specialize, but
1965 // doesn't mark it `default`.
1966 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1967 Some(Err(parent_impl.def_id()))
1970 // Parent impl contains item and makes it specializable.
1971 Some(_) => Some(Ok(())),
1973 // Parent impl doesn't mention the item. This means it's inherited from the
1974 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1975 // "defaultness" from the grandparent, else they are final.
1977 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1980 Some(Err(parent_impl.def_id()))
1986 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1987 // item. This is allowed, the item isn't actually getting specialized here.
1988 let result = opt_result.unwrap_or(Ok(()));
1990 if let Err(parent_impl) = result {
1991 report_forbidden_specialization(tcx, impl_item, parent_impl);
1995 fn check_impl_items_against_trait<'tcx>(
1997 full_impl_span: Span,
1998 impl_id: LocalDefId,
1999 impl_trait_ref: ty::TraitRef<'tcx>,
2000 impl_item_refs: &[hir::ImplItemRef<'_>],
2002 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2004 // If the trait reference itself is erroneous (so the compilation is going
2005 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2006 // isn't populated for such impls.
2007 if impl_trait_ref.references_error() {
2011 // Negative impls are not expected to have any items
2012 match tcx.impl_polarity(impl_id) {
2013 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2014 ty::ImplPolarity::Negative => {
2015 if let [first_item_ref, ..] = impl_item_refs {
2016 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2021 "negative impls cannot have any items"
2029 // Locate trait definition and items
2030 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2032 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2034 // Check existing impl methods to see if they are both present in trait
2035 // and compatible with trait signature
2036 for impl_item in impl_items() {
2037 let namespace = impl_item.kind.namespace();
2038 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2039 let ty_trait_item = tcx
2040 .associated_items(impl_trait_ref.def_id)
2041 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2043 // Not compatible, but needed for the error message
2044 tcx.associated_items(impl_trait_ref.def_id)
2045 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2049 // Check that impl definition matches trait definition
2050 if let Some(ty_trait_item) = ty_trait_item {
2051 match impl_item.kind {
2052 hir::ImplItemKind::Const(..) => {
2053 // Find associated const definition.
2054 if ty_trait_item.kind == ty::AssocKind::Const {
2063 let mut err = struct_span_err!(
2067 "item `{}` is an associated const, \
2068 which doesn't match its trait `{}`",
2070 impl_trait_ref.print_only_trait_path()
2072 err.span_label(impl_item.span, "does not match trait");
2073 // We can only get the spans from local trait definition
2074 // Same for E0324 and E0325
2075 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2076 err.span_label(trait_span, "item in trait");
2081 hir::ImplItemKind::Fn(..) => {
2082 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2083 if ty_trait_item.kind == ty::AssocKind::Fn {
2084 compare_impl_method(
2093 let mut err = struct_span_err!(
2097 "item `{}` is an associated method, \
2098 which doesn't match its trait `{}`",
2100 impl_trait_ref.print_only_trait_path()
2102 err.span_label(impl_item.span, "does not match trait");
2103 if let Some(trait_span) = opt_trait_span {
2104 err.span_label(trait_span, "item in trait");
2109 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2110 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2111 if ty_trait_item.kind == ty::AssocKind::Type {
2121 let mut err = struct_span_err!(
2125 "item `{}` is an associated type, \
2126 which doesn't match its trait `{}`",
2128 impl_trait_ref.print_only_trait_path()
2130 err.span_label(impl_item.span, "does not match trait");
2131 if let Some(trait_span) = opt_trait_span {
2132 err.span_label(trait_span, "item in trait");
2139 check_specialization_validity(
2143 impl_id.to_def_id(),
2149 // Check for missing items from trait
2150 let mut missing_items = Vec::new();
2151 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2152 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2153 let is_implemented = ancestors
2154 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2155 .map(|node_item| !node_item.defining_node.is_from_trait())
2158 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2159 if !trait_item.defaultness.has_value() {
2160 missing_items.push(*trait_item);
2166 if !missing_items.is_empty() {
2167 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2171 fn missing_items_err(
2174 missing_items: &[ty::AssocItem],
2175 full_impl_span: Span,
2177 let missing_items_msg = missing_items
2179 .map(|trait_item| trait_item.ident.to_string())
2180 .collect::<Vec<_>>()
2183 let mut err = struct_span_err!(
2187 "not all trait items implemented, missing: `{}`",
2190 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2192 // `Span` before impl block closing brace.
2193 let hi = full_impl_span.hi() - BytePos(1);
2194 // Point at the place right before the closing brace of the relevant `impl` to suggest
2195 // adding the associated item at the end of its body.
2196 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2197 // Obtain the level of indentation ending in `sugg_sp`.
2198 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2199 // Make the whitespace that will make the suggestion have the right indentation.
2200 let padding: String = (0..indentation).map(|_| " ").collect();
2202 for trait_item in missing_items {
2203 let snippet = suggestion_signature(&trait_item, tcx);
2204 let code = format!("{}{}\n{}", padding, snippet, padding);
2205 let msg = format!("implement the missing item: `{}`", snippet);
2206 let appl = Applicability::HasPlaceholders;
2207 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2208 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2209 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2211 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2217 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2218 fn bounds_from_generic_predicates(
2220 predicates: ty::GenericPredicates<'_>,
2221 ) -> (String, String) {
2222 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2223 let mut projections = vec![];
2224 for (predicate, _) in predicates.predicates {
2225 debug!("predicate {:?}", predicate);
2227 ty::PredicateKind::Trait(trait_predicate, _) => {
2228 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2229 let def_id = trait_predicate.skip_binder().def_id();
2230 if Some(def_id) != tcx.lang_items().sized_trait() {
2231 // Type params are `Sized` by default, do not add that restriction to the list
2232 // if it is a positive requirement.
2233 entry.push(trait_predicate.skip_binder().def_id());
2236 ty::PredicateKind::Projection(projection_pred) => {
2237 projections.push(projection_pred);
2242 let generics = if types.is_empty() {
2249 .filter_map(|t| match t.kind {
2250 ty::Param(_) => Some(t.to_string()),
2251 // Avoid suggesting the following:
2252 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2255 .collect::<Vec<_>>()
2259 let mut where_clauses = vec![];
2260 for (ty, bounds) in types {
2261 for bound in &bounds {
2262 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2265 for projection in &projections {
2266 let p = projection.skip_binder();
2267 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2268 // insert the associated types where they correspond, but for now let's be "lazy" and
2269 // propose this instead of the following valid resugaring:
2270 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2271 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2273 let where_clauses = if where_clauses.is_empty() {
2276 format!(" where {}", where_clauses.join(", "))
2278 (generics, where_clauses)
2281 /// Return placeholder code for the given function.
2282 fn fn_sig_suggestion(
2284 sig: &ty::FnSig<'_>,
2286 predicates: ty::GenericPredicates<'_>,
2287 assoc: &ty::AssocItem,
2294 Some(match ty.kind {
2295 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2296 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2297 let reg = match &format!("{}", reg)[..] {
2298 "'_" | "" => String::new(),
2299 reg => format!("{} ", reg),
2301 if assoc.fn_has_self_parameter {
2303 ty::Param(param) if param.name == kw::SelfUpper => {
2304 format!("&{}{}self", reg, mutability.prefix_str())
2307 _ => format!("self: {}", ty),
2310 format!("_: {:?}", ty)
2314 if assoc.fn_has_self_parameter && i == 0 {
2315 format!("self: {:?}", ty)
2317 format!("_: {:?}", ty)
2322 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2323 .filter_map(|arg| arg)
2324 .collect::<Vec<String>>()
2326 let output = sig.output();
2327 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2329 let unsafety = sig.unsafety.prefix_str();
2330 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2332 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2333 // not be present in the `fn` definition, not will we account for renamed
2334 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2335 // fill in a significant portion of the missing code, and other subsequent
2336 // suggestions can help the user fix the code.
2338 "{}fn {}{}({}){}{} {{ todo!() }}",
2339 unsafety, ident, generics, args, output, where_clauses
2343 /// Return placeholder code for the given associated item.
2344 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2345 /// structured suggestion.
2346 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2348 ty::AssocKind::Fn => {
2349 // We skip the binder here because the binder would deanonymize all
2350 // late-bound regions, and we don't want method signatures to show up
2351 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2352 // regions just fine, showing `fn(&MyType)`.
2355 tcx.fn_sig(assoc.def_id).skip_binder(),
2357 tcx.predicates_of(assoc.def_id),
2361 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2362 // FIXME(type_alias_impl_trait): we should print bounds here too.
2363 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2364 ty::AssocKind::Const => {
2365 let ty = tcx.type_of(assoc.def_id);
2366 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2367 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2372 /// Checks whether a type can be represented in memory. In particular, it
2373 /// identifies types that contain themselves without indirection through a
2374 /// pointer, which would mean their size is unbounded.
2375 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2376 let rty = tcx.type_of(item_def_id);
2378 // Check that it is possible to represent this type. This call identifies
2379 // (1) types that contain themselves and (2) types that contain a different
2380 // recursive type. It is only necessary to throw an error on those that
2381 // contain themselves. For case 2, there must be an inner type that will be
2382 // caught by case 1.
2383 match rty.is_representable(tcx, sp) {
2384 Representability::SelfRecursive(spans) => {
2385 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2387 err.span_label(span, "recursive without indirection");
2392 Representability::Representable | Representability::ContainsRecursive => (),
2397 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2398 let t = tcx.type_of(def_id);
2399 if let ty::Adt(def, substs) = t.kind {
2400 if def.is_struct() {
2401 let fields = &def.non_enum_variant().fields;
2402 if fields.is_empty() {
2403 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2406 let e = fields[0].ty(tcx, substs);
2407 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2408 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2409 .span_label(sp, "SIMD elements must have the same type")
2414 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2415 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2421 "SIMD vector element type should be machine type"
2431 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2432 let repr = def.repr;
2434 for attr in tcx.get_attrs(def.did).iter() {
2435 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2436 if let attr::ReprPacked(pack) = r {
2437 if let Some(repr_pack) = repr.pack {
2438 if pack as u64 != repr_pack.bytes() {
2443 "type has conflicting packed representation hints"
2451 if repr.align.is_some() {
2456 "type has conflicting packed and align representation hints"
2460 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2461 let mut err = struct_span_err!(
2465 "packed type cannot transitively contain a `#[repr(align)]` type"
2468 let hir = tcx.hir();
2469 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2470 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2472 tcx.def_span(def_spans[0].0),
2473 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2477 if def_spans.len() > 2 {
2478 let mut first = true;
2479 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2480 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2481 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2486 "`{}` contains a field of type `{}`",
2487 tcx.type_of(def.did),
2491 format!("...which contains a field of type `{}`", ident)
2505 fn check_packed_inner(
2508 stack: &mut Vec<DefId>,
2509 ) -> Option<Vec<(DefId, Span)>> {
2510 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2511 if def.is_struct() || def.is_union() {
2512 if def.repr.align.is_some() {
2513 return Some(vec![(def.did, DUMMY_SP)]);
2517 for field in &def.non_enum_variant().fields {
2518 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2519 if !stack.contains(&def.did) {
2520 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2521 defs.push((def.did, field.ident.span));
2534 /// Emit an error when encountering more or less than one variant in a transparent enum.
2535 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2536 let variant_spans: Vec<_> = adt
2539 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2541 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2542 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2543 err.span_label(sp, &msg);
2544 if let [start @ .., end] = &*variant_spans {
2545 for variant_span in start {
2546 err.span_label(*variant_span, "");
2548 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2553 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2555 fn bad_non_zero_sized_fields<'tcx>(
2557 adt: &'tcx ty::AdtDef,
2559 field_spans: impl Iterator<Item = Span>,
2562 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2563 let mut err = struct_span_err!(
2567 "{}transparent {} {}",
2568 if adt.is_enum() { "the variant of a " } else { "" },
2572 err.span_label(sp, &msg);
2573 for sp in field_spans {
2574 err.span_label(sp, "this field is non-zero-sized");
2579 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2580 if !adt.repr.transparent() {
2583 let sp = tcx.sess.source_map().guess_head_span(sp);
2585 if adt.is_union() && !tcx.features().transparent_unions {
2587 &tcx.sess.parse_sess,
2588 sym::transparent_unions,
2590 "transparent unions are unstable",
2595 if adt.variants.len() != 1 {
2596 bad_variant_count(tcx, adt, sp, adt.did);
2597 if adt.variants.is_empty() {
2598 // Don't bother checking the fields. No variants (and thus no fields) exist.
2603 // For each field, figure out if it's known to be a ZST and align(1)
2604 let field_infos = adt.all_fields().map(|field| {
2605 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2606 let param_env = tcx.param_env(field.did);
2607 let layout = tcx.layout_of(param_env.and(ty));
2608 // We are currently checking the type this field came from, so it must be local
2609 let span = tcx.hir().span_if_local(field.did).unwrap();
2610 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2611 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2615 let non_zst_fields =
2616 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2617 let non_zst_count = non_zst_fields.clone().count();
2618 if non_zst_count != 1 {
2619 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2621 for (span, zst, align1) in field_infos {
2627 "zero-sized field in transparent {} has alignment larger than 1",
2630 .span_label(span, "has alignment larger than 1")
2636 #[allow(trivial_numeric_casts)]
2637 pub fn check_enum<'tcx>(
2640 vs: &'tcx [hir::Variant<'tcx>],
2643 let def_id = tcx.hir().local_def_id(id);
2644 let def = tcx.adt_def(def_id);
2645 def.destructor(tcx); // force the destructor to be evaluated
2648 let attributes = tcx.get_attrs(def_id.to_def_id());
2649 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2654 "unsupported representation for zero-variant enum"
2656 .span_label(sp, "zero-variant enum")
2661 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2662 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2663 if !tcx.features().repr128 {
2665 &tcx.sess.parse_sess,
2668 "repr with 128-bit type is unstable",
2675 if let Some(ref e) = v.disr_expr {
2676 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2680 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2681 let is_unit = |var: &hir::Variant<'_>| match var.data {
2682 hir::VariantData::Unit(..) => true,
2686 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2687 let has_non_units = vs.iter().any(|var| !is_unit(var));
2688 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2689 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2691 if disr_non_unit || (disr_units && has_non_units) {
2693 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2698 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2699 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2700 // Check for duplicate discriminant values
2701 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2702 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2703 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2704 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2705 let i_span = match variant_i.disr_expr {
2706 Some(ref expr) => tcx.hir().span(expr.hir_id),
2707 None => tcx.hir().span(variant_i_hir_id),
2709 let span = match v.disr_expr {
2710 Some(ref expr) => tcx.hir().span(expr.hir_id),
2717 "discriminant value `{}` already exists",
2720 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2721 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2724 disr_vals.push(discr);
2727 check_representable(tcx, sp, def_id);
2728 check_transparent(tcx, sp, def);
2731 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2736 "expected unit struct, unit variant or constant, found {}{}",
2738 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2743 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2744 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2748 fn item_def_id(&self) -> Option<DefId> {
2752 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2753 // FIXME: refactor this into a method
2754 let node = self.tcx.hir().get(self.body_id);
2755 if let Some(fn_like) = FnLikeNode::from_node(node) {
2758 hir::Constness::NotConst
2762 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2764 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2765 let item_id = tcx.hir().ty_param_owner(hir_id);
2766 let item_def_id = tcx.hir().local_def_id(item_id);
2767 let generics = tcx.generics_of(item_def_id);
2768 let index = generics.param_def_id_to_index[&def_id];
2769 ty::GenericPredicates {
2771 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2772 |&predicate| match predicate {
2773 ty::PredicateKind::Trait(ref data, _)
2774 if data.skip_binder().self_ty().is_param(index) =>
2776 // HACK(eddyb) should get the original `Span`.
2777 let span = tcx.def_span(def_id);
2778 Some((predicate, span))
2786 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2788 Some(def) => infer::EarlyBoundRegion(span, def.name),
2789 None => infer::MiscVariable(span),
2791 Some(self.next_region_var(v))
2794 fn allow_ty_infer(&self) -> bool {
2798 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2799 if let Some(param) = param {
2800 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2805 self.next_ty_var(TypeVariableOrigin {
2806 kind: TypeVariableOriginKind::TypeInference,
2815 param: Option<&ty::GenericParamDef>,
2817 ) -> &'tcx Const<'tcx> {
2818 if let Some(param) = param {
2819 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2824 self.next_const_var(
2826 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2831 fn projected_ty_from_poly_trait_ref(
2835 item_segment: &hir::PathSegment<'_>,
2836 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2838 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2840 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2844 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2853 self.tcx().mk_projection(item_def_id, item_substs)
2856 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2857 if ty.has_escaping_bound_vars() {
2858 ty // FIXME: normalization and escaping regions
2860 self.normalize_associated_types_in(span, &ty)
2864 fn set_tainted_by_errors(&self) {
2865 self.infcx.set_tainted_by_errors()
2868 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2869 self.write_ty(hir_id, ty)
2873 /// Controls whether the arguments are tupled. This is used for the call
2876 /// Tupling means that all call-side arguments are packed into a tuple and
2877 /// passed as a single parameter. For example, if tupling is enabled, this
2880 /// fn f(x: (isize, isize))
2882 /// Can be called as:
2889 #[derive(Clone, Eq, PartialEq)]
2890 enum TupleArgumentsFlag {
2895 /// Controls how we perform fallback for unconstrained
2898 /// Do not fallback type variables to opaque types.
2900 /// Perform all possible kinds of fallback, including
2901 /// turning type variables to opaque types.
2905 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2907 inh: &'a Inherited<'a, 'tcx>,
2908 param_env: ty::ParamEnv<'tcx>,
2909 body_id: hir::HirId,
2910 ) -> FnCtxt<'a, 'tcx> {
2914 err_count_on_creation: inh.tcx.sess.err_count(),
2916 ret_coercion_span: RefCell::new(None),
2917 resume_yield_tys: None,
2918 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2919 diverges: Cell::new(Diverges::Maybe),
2920 has_errors: Cell::new(false),
2921 enclosing_breakables: RefCell::new(EnclosingBreakables {
2923 by_id: Default::default(),
2929 pub fn sess(&self) -> &Session {
2933 pub fn errors_reported_since_creation(&self) -> bool {
2934 self.tcx.sess.err_count() > self.err_count_on_creation
2937 /// Produces warning on the given node, if the current point in the
2938 /// function is unreachable, and there hasn't been another warning.
2939 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2940 // FIXME: Combine these two 'if' expressions into one once
2941 // let chains are implemented
2942 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2943 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2944 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2945 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2946 if !span.is_desugaring(DesugaringKind::CondTemporary)
2947 && !span.is_desugaring(DesugaringKind::Async)
2948 && !orig_span.is_desugaring(DesugaringKind::Await)
2950 self.diverges.set(Diverges::WarnedAlways);
2952 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2954 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2955 let msg = format!("unreachable {}", kind);
2957 .span_label(span, &msg)
2961 .unwrap_or("any code following this expression is unreachable"),
2969 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2970 ObligationCause::new(span, self.body_id, code)
2973 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2974 self.cause(span, ObligationCauseCode::MiscObligation)
2977 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2978 /// version (resolve_vars_if_possible), this version will
2979 /// also select obligations if it seems useful, in an effort
2980 /// to get more type information.
2981 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2982 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2984 // No Infer()? Nothing needs doing.
2985 if !ty.has_infer_types_or_consts() {
2986 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2990 // If `ty` is a type variable, see whether we already know what it is.
2991 ty = self.resolve_vars_if_possible(&ty);
2992 if !ty.has_infer_types_or_consts() {
2993 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2997 // If not, try resolving pending obligations as much as
2998 // possible. This can help substantially when there are
2999 // indirect dependencies that don't seem worth tracking
3001 self.select_obligations_where_possible(false, |_| {});
3002 ty = self.resolve_vars_if_possible(&ty);
3004 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3008 fn record_deferred_call_resolution(
3010 closure_def_id: DefId,
3011 r: DeferredCallResolution<'tcx>,
3013 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3014 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3017 fn remove_deferred_call_resolutions(
3019 closure_def_id: DefId,
3020 ) -> Vec<DeferredCallResolution<'tcx>> {
3021 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3022 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3025 pub fn tag(&self) -> String {
3026 format!("{:p}", self)
3029 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3030 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3031 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3036 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3038 "write_ty({:?}, {:?}) in fcx {}",
3040 self.resolve_vars_if_possible(&ty),
3043 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3045 if ty.references_error() {
3046 self.has_errors.set(true);
3047 self.set_tainted_by_errors();
3051 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3052 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3055 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3056 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3059 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3060 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3061 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3062 self.write_substs(hir_id, method.substs);
3064 // When the method is confirmed, the `method.substs` includes
3065 // parameters from not just the method, but also the impl of
3066 // the method -- in particular, the `Self` type will be fully
3067 // resolved. However, those are not something that the "user
3068 // specified" -- i.e., those types come from the inferred type
3069 // of the receiver, not something the user wrote. So when we
3070 // create the user-substs, we want to replace those earlier
3071 // types with just the types that the user actually wrote --
3072 // that is, those that appear on the *method itself*.
3074 // As an example, if the user wrote something like
3075 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3076 // type of `foo` (possibly adjusted), but we don't want to
3077 // include that. We want just the `[_, u32]` part.
3078 if !method.substs.is_noop() {
3079 let method_generics = self.tcx.generics_of(method.def_id);
3080 if !method_generics.params.is_empty() {
3081 let user_type_annotation = self.infcx.probe(|_| {
3082 let user_substs = UserSubsts {
3083 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3084 let i = param.index as usize;
3085 if i < method_generics.parent_count {
3086 self.infcx.var_for_def(DUMMY_SP, param)
3091 user_self_ty: None, // not relevant here
3094 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3100 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3101 self.write_user_type_annotation(hir_id, user_type_annotation);
3106 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3107 if !substs.is_noop() {
3108 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3110 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3114 /// Given the substs that we just converted from the HIR, try to
3115 /// canonicalize them and store them as user-given substitutions
3116 /// (i.e., substitutions that must be respected by the NLL check).
3118 /// This should be invoked **before any unifications have
3119 /// occurred**, so that annotations like `Vec<_>` are preserved
3121 pub fn write_user_type_annotation_from_substs(
3125 substs: SubstsRef<'tcx>,
3126 user_self_ty: Option<UserSelfTy<'tcx>>,
3129 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3130 user_self_ty={:?} in fcx {}",
3138 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3139 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3141 UserSubsts { substs, user_self_ty },
3143 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3144 self.write_user_type_annotation(hir_id, canonicalized);
3148 pub fn write_user_type_annotation(
3151 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3154 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3156 canonical_user_type_annotation,
3160 if !canonical_user_type_annotation.is_identity() {
3163 .user_provided_types_mut()
3164 .insert(hir_id, canonical_user_type_annotation);
3166 debug!("write_user_type_annotation: skipping identity substs");
3170 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3171 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3177 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3178 Entry::Vacant(entry) => {
3181 Entry::Occupied(mut entry) => {
3182 debug!(" - composing on top of {:?}", entry.get());
3183 match (&entry.get()[..], &adj[..]) {
3184 // Applying any adjustment on top of a NeverToAny
3185 // is a valid NeverToAny adjustment, because it can't
3187 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3189 Adjustment { kind: Adjust::Deref(_), .. },
3190 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3192 Adjustment { kind: Adjust::Deref(_), .. },
3193 .. // Any following adjustments are allowed.
3195 // A reborrow has no effect before a dereference.
3197 // FIXME: currently we never try to compose autoderefs
3198 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3200 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3201 expr, entry.get(), adj)
3203 *entry.get_mut() = adj;
3208 /// Basically whenever we are converting from a type scheme into
3209 /// the fn body space, we always want to normalize associated
3210 /// types as well. This function combines the two.
3211 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3213 T: TypeFoldable<'tcx>,
3215 let value = value.subst(self.tcx, substs);
3216 let result = self.normalize_associated_types_in(span, &value);
3217 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3221 /// As `instantiate_type_scheme`, but for the bounds found in a
3222 /// generic type scheme.
3223 fn instantiate_bounds(
3227 substs: SubstsRef<'tcx>,
3228 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3229 let bounds = self.tcx.predicates_of(def_id);
3230 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3231 let result = bounds.instantiate(self.tcx, substs);
3232 let result = self.normalize_associated_types_in(span, &result);
3234 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3235 bounds, substs, result, spans,
3240 /// Replaces the opaque types from the given value with type variables,
3241 /// and records the `OpaqueTypeMap` for later use during writeback. See
3242 /// `InferCtxt::instantiate_opaque_types` for more details.
3243 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3245 parent_id: hir::HirId,
3249 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3251 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3252 parent_def_id, value
3255 let (value, opaque_type_map) =
3256 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3257 parent_def_id.to_def_id(),
3264 let mut opaque_types = self.opaque_types.borrow_mut();
3265 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3266 for (ty, decl) in opaque_type_map {
3267 let _ = opaque_types.insert(ty, decl);
3268 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3274 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3276 T: TypeFoldable<'tcx>,
3278 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3281 fn normalize_associated_types_in_as_infer_ok<T>(
3285 ) -> InferOk<'tcx, T>
3287 T: TypeFoldable<'tcx>,
3289 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3292 pub fn require_type_meets(
3296 code: traits::ObligationCauseCode<'tcx>,
3299 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3302 pub fn require_type_is_sized(
3306 code: traits::ObligationCauseCode<'tcx>,
3308 if !ty.references_error() {
3309 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3310 self.require_type_meets(ty, span, code, lang_item);
3314 pub fn require_type_is_sized_deferred(
3318 code: traits::ObligationCauseCode<'tcx>,
3320 if !ty.references_error() {
3321 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3325 pub fn register_bound(
3329 cause: traits::ObligationCause<'tcx>,
3331 if !ty.references_error() {
3332 self.fulfillment_cx.borrow_mut().register_bound(
3342 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3343 let t = AstConv::ast_ty_to_ty(self, ast_t);
3344 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3348 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3349 let ty = self.to_ty(ast_ty);
3350 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3352 if Self::can_contain_user_lifetime_bounds(ty) {
3353 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3354 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3355 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3361 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3362 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3363 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3365 // HACK(eddyb) emulate what a `WellFormedConst` obligation would do.
3366 // This code should be replaced with the proper WF handling ASAP.
3367 if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
3368 assert!(promoted.is_none());
3370 // HACK(eddyb) let's hope these are always empty.
3371 // let obligations = self.nominal_obligations(def_id, substs);
3372 // self.out.extend(obligations);
3374 let cause = traits::ObligationCause::new(
3375 self.tcx.def_span(const_def_id.to_def_id()),
3377 traits::MiscObligation,
3379 self.register_predicate(traits::Obligation::new(
3382 ty::PredicateKind::ConstEvaluatable(def_id, substs),
3389 // If the type given by the user has free regions, save it for later, since
3390 // NLL would like to enforce those. Also pass in types that involve
3391 // projections, since those can resolve to `'static` bounds (modulo #54940,
3392 // which hopefully will be fixed by the time you see this comment, dear
3393 // reader, although I have my doubts). Also pass in types with inference
3394 // types, because they may be repeated. Other sorts of things are already
3395 // sufficiently enforced with erased regions. =)
3396 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3398 T: TypeFoldable<'tcx>,
3400 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3403 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3404 match self.tables.borrow().node_types().get(id) {
3406 None if self.is_tainted_by_errors() => self.tcx.types.err,
3409 "no type for node {}: {} in fcx {}",
3411 self.tcx.hir().node_to_string(id),
3418 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3419 /// outlive the region `r`.
3420 pub fn register_wf_obligation(
3424 code: traits::ObligationCauseCode<'tcx>,
3426 // WF obligations never themselves fail, so no real need to give a detailed cause:
3427 let cause = traits::ObligationCause::new(span, self.body_id, code);
3428 self.register_predicate(traits::Obligation::new(
3431 ty::PredicateKind::WellFormed(ty),
3435 /// Registers obligations that all types appearing in `substs` are well-formed.
3436 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3437 for ty in substs.types() {
3438 if !ty.references_error() {
3439 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3444 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3445 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3446 /// trait/region obligations.
3448 /// For example, if there is a function:
3451 /// fn foo<'a,T:'a>(...)
3454 /// and a reference:
3460 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3461 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3462 pub fn add_obligations_for_parameters(
3464 cause: traits::ObligationCause<'tcx>,
3465 predicates: ty::InstantiatedPredicates<'tcx>,
3467 assert!(!predicates.has_escaping_bound_vars());
3469 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3471 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3472 self.register_predicate(obligation);
3476 // FIXME(arielb1): use this instead of field.ty everywhere
3477 // Only for fields! Returns <none> for methods>
3478 // Indifferent to privacy flags
3482 field: &'tcx ty::FieldDef,
3483 substs: SubstsRef<'tcx>,
3485 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3488 fn check_casts(&self) {
3489 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3490 for cast in deferred_cast_checks.drain(..) {
3495 fn resolve_generator_interiors(&self, def_id: DefId) {
3496 let mut generators = self.deferred_generator_interiors.borrow_mut();
3497 for (body_id, interior, kind) in generators.drain(..) {
3498 self.select_obligations_where_possible(false, |_| {});
3499 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3503 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3505 // - Unconstrained ints are replaced with `i32`.
3507 // - Unconstrained floats are replaced with with `f64`.
3509 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3510 // is enabled. Otherwise, they are replaced with `()`.
3512 // Fallback becomes very dubious if we have encountered type-checking errors.
3513 // In that case, fallback to Error.
3514 // The return value indicates whether fallback has occurred.
3515 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3516 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3517 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3519 assert!(ty.is_ty_infer());
3520 let fallback = match self.type_is_unconstrained_numeric(ty) {
3521 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3522 UnconstrainedInt => self.tcx.types.i32,
3523 UnconstrainedFloat => self.tcx.types.f64,
3524 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3526 // This type variable was created from the instantiation of an opaque
3527 // type. The fact that we're attempting to perform fallback for it
3528 // means that the function neither constrained it to a concrete
3529 // type, nor to the opaque type itself.
3531 // For example, in this code:
3534 // type MyType = impl Copy;
3535 // fn defining_use() -> MyType { true }
3536 // fn other_use() -> MyType { defining_use() }
3539 // `defining_use` will constrain the instantiated inference
3540 // variable to `bool`, while `other_use` will constrain
3541 // the instantiated inference variable to `MyType`.
3543 // When we process opaque types during writeback, we
3544 // will handle cases like `other_use`, and not count
3545 // them as defining usages
3547 // However, we also need to handle cases like this:
3550 // pub type Foo = impl Copy;
3551 // fn produce() -> Option<Foo> {
3556 // In the above snippet, the inference variable created by
3557 // instantiating `Option<Foo>` will be completely unconstrained.
3558 // We treat this as a non-defining use by making the inference
3559 // variable fall back to the opaque type itself.
3560 if let FallbackMode::All = mode {
3561 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3563 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3575 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3576 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3580 fn select_all_obligations_or_error(&self) {
3581 debug!("select_all_obligations_or_error");
3582 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3583 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3587 /// Select as many obligations as we can at present.
3588 fn select_obligations_where_possible(
3590 fallback_has_occurred: bool,
3591 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3593 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3594 if let Err(mut errors) = result {
3595 mutate_fullfillment_errors(&mut errors);
3596 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3600 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3601 /// returns a type of `&T`, but the actual type we assign to the
3602 /// *expression* is `T`. So this function just peels off the return
3603 /// type by one layer to yield `T`.
3604 fn make_overloaded_place_return_type(
3606 method: MethodCallee<'tcx>,
3607 ) -> ty::TypeAndMut<'tcx> {
3608 // extract method return type, which will be &T;
3609 let ret_ty = method.sig.output();
3611 // method returns &T, but the type as visible to user is T, so deref
3612 ret_ty.builtin_deref(true).unwrap()
3617 expr: &hir::Expr<'_>,
3618 base_expr: &'tcx hir::Expr<'tcx>,
3622 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3623 // FIXME(#18741) -- this is almost but not quite the same as the
3624 // autoderef that normal method probing does. They could likely be
3627 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3628 let mut result = None;
3629 while result.is_none() && autoderef.next().is_some() {
3630 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3632 autoderef.finalize(self);
3636 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3637 /// (and otherwise adjust) `base_expr`, looking for a type which either
3638 /// supports builtin indexing or overloaded indexing.
3639 /// This loop implements one step in that search; the autoderef loop
3640 /// is implemented by `lookup_indexing`.
3643 expr: &hir::Expr<'_>,
3644 base_expr: &hir::Expr<'_>,
3645 autoderef: &Autoderef<'a, 'tcx>,
3648 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3649 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3651 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3653 expr, base_expr, adjusted_ty, index_ty
3656 for &unsize in &[false, true] {
3657 let mut self_ty = adjusted_ty;
3659 // We only unsize arrays here.
3660 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3661 self_ty = self.tcx.mk_slice(element_ty);
3667 // If some lookup succeeds, write callee into table and extract index/element
3668 // type from the method signature.
3669 // If some lookup succeeded, install method in table
3670 let input_ty = self.next_ty_var(TypeVariableOrigin {
3671 kind: TypeVariableOriginKind::AutoDeref,
3672 span: base_expr.span,
3674 let method = self.try_overloaded_place_op(
3682 let result = method.map(|ok| {
3683 debug!("try_index_step: success, using overloaded indexing");
3684 let method = self.register_infer_ok_obligations(ok);
3686 let mut adjustments = autoderef.adjust_steps(self, needs);
3687 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3688 let mutbl = match r_mutbl {
3689 hir::Mutability::Not => AutoBorrowMutability::Not,
3690 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3691 // Indexing can be desugared to a method call,
3692 // so maybe we could use two-phase here.
3693 // See the documentation of AllowTwoPhase for why that's
3694 // not the case today.
3695 allow_two_phase_borrow: AllowTwoPhase::No,
3698 adjustments.push(Adjustment {
3699 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3702 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3706 adjustments.push(Adjustment {
3707 kind: Adjust::Pointer(PointerCast::Unsize),
3708 target: method.sig.inputs()[0],
3711 self.apply_adjustments(base_expr, adjustments);
3713 self.write_method_call(expr.hir_id, method);
3714 (input_ty, self.make_overloaded_place_return_type(method).ty)
3716 if result.is_some() {
3724 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
3725 let (tr, name) = match (op, is_mut) {
3726 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3727 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3728 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3729 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3731 (tr, Ident::with_dummy_span(name))
3734 fn try_overloaded_place_op(
3738 arg_tys: &[Ty<'tcx>],
3741 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3742 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3744 // Try Mut first, if needed.
3745 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3746 let method = match (needs, mut_tr) {
3747 (Needs::MutPlace, Some(trait_did)) => {
3748 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3753 // Otherwise, fall back to the immutable version.
3754 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3755 match (method, imm_tr) {
3756 (None, Some(trait_did)) => {
3757 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3759 (method, _) => method,
3763 fn check_method_argument_types(
3766 expr: &'tcx hir::Expr<'tcx>,
3767 method: Result<MethodCallee<'tcx>, ()>,
3768 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3769 tuple_arguments: TupleArgumentsFlag,
3770 expected: Expectation<'tcx>,
3772 let has_error = match method {
3773 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3777 let err_inputs = self.err_args(args_no_rcvr.len());
3779 let err_inputs = match tuple_arguments {
3780 DontTupleArguments => err_inputs,
3781 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3784 self.check_argument_types(
3794 return self.tcx.types.err;
3797 let method = method.unwrap();
3798 // HACK(eddyb) ignore self in the definition (see above).
3799 let expected_arg_tys = self.expected_inputs_for_expected_output(
3802 method.sig.output(),
3803 &method.sig.inputs()[1..],
3805 self.check_argument_types(
3808 &method.sig.inputs()[1..],
3809 &expected_arg_tys[..],
3811 method.sig.c_variadic,
3813 self.tcx.hir().span_if_local(method.def_id),
3818 fn self_type_matches_expected_vid(
3820 trait_ref: ty::PolyTraitRef<'tcx>,
3821 expected_vid: ty::TyVid,
3823 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3825 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3826 trait_ref, self_ty, expected_vid
3828 match self_ty.kind {
3829 ty::Infer(ty::TyVar(found_vid)) => {
3830 // FIXME: consider using `sub_root_var` here so we
3831 // can see through subtyping.
3832 let found_vid = self.root_var(found_vid);
3833 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3834 expected_vid == found_vid
3840 fn obligations_for_self_ty<'b>(
3843 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3846 // FIXME: consider using `sub_root_var` here so we
3847 // can see through subtyping.
3848 let ty_var_root = self.root_var(self_ty);
3850 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3853 self.fulfillment_cx.borrow().pending_obligations()
3858 .pending_obligations()
3860 .filter_map(move |obligation| match obligation.predicate {
3861 ty::PredicateKind::Projection(ref data) => {
3862 Some((data.to_poly_trait_ref(self.tcx), obligation))
3864 ty::PredicateKind::Trait(ref data, _) => {
3865 Some((data.to_poly_trait_ref(), obligation))
3867 ty::PredicateKind::Subtype(..) => None,
3868 ty::PredicateKind::RegionOutlives(..) => None,
3869 ty::PredicateKind::TypeOutlives(..) => None,
3870 ty::PredicateKind::WellFormed(..) => None,
3871 ty::PredicateKind::ObjectSafe(..) => None,
3872 ty::PredicateKind::ConstEvaluatable(..) => None,
3873 ty::PredicateKind::ConstEquate(..) => None,
3874 // N.B., this predicate is created by breaking down a
3875 // `ClosureType: FnFoo()` predicate, where
3876 // `ClosureType` represents some `Closure`. It can't
3877 // possibly be referring to the current closure,
3878 // because we haven't produced the `Closure` for
3879 // this closure yet; this is exactly why the other
3880 // code is looking for a self type of a unresolved
3881 // inference variable.
3882 ty::PredicateKind::ClosureKind(..) => None,
3884 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3887 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3888 self.obligations_for_self_ty(self_ty)
3889 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3892 /// Generic function that factors out common logic from function calls,
3893 /// method calls and overloaded operators.
3894 fn check_argument_types(
3897 expr: &'tcx hir::Expr<'tcx>,
3898 fn_inputs: &[Ty<'tcx>],
3899 expected_arg_tys: &[Ty<'tcx>],
3900 args: &'tcx [hir::Expr<'tcx>],
3902 tuple_arguments: TupleArgumentsFlag,
3903 def_span: Option<Span>,
3906 // Grab the argument types, supplying fresh type variables
3907 // if the wrong number of arguments were supplied
3908 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3910 // All the input types from the fn signature must outlive the call
3911 // so as to validate implied bounds.
3912 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3913 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3916 let expected_arg_count = fn_inputs.len();
3918 let param_count_error = |expected_count: usize,
3923 let (span, start_span, args) = match &expr.kind {
3924 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3925 hir::ExprKind::MethodCall(path_segment, span, args) => (
3927 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3930 .and_then(|args| args.args.iter().last())
3931 // Account for `foo.bar::<T>()`.
3933 // Skip the closing `>`.
3936 .next_point(tcx.sess.source_map().next_point(arg.span()))
3939 &args[1..], // Skip the receiver.
3941 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3943 let arg_spans = if args.is_empty() {
3945 // ^^^-- supplied 0 arguments
3947 // expected 2 arguments
3948 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3951 // ^^^ - - - supplied 3 arguments
3953 // expected 2 arguments
3954 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3957 let mut err = tcx.sess.struct_span_err_with_code(
3960 "this function takes {}{} but {} {} supplied",
3961 if c_variadic { "at least " } else { "" },
3962 potentially_plural_count(expected_count, "argument"),
3963 potentially_plural_count(arg_count, "argument"),
3964 if arg_count == 1 { "was" } else { "were" }
3966 DiagnosticId::Error(error_code.to_owned()),
3968 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3969 for (i, span) in arg_spans.into_iter().enumerate() {
3972 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3976 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3977 err.span_label(def_s, "defined here");
3980 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3981 // remove closing `)` from the span
3982 let sugg_span = sugg_span.shrink_to_lo();
3983 err.span_suggestion(
3985 "expected the unit value `()`; create it with empty parentheses",
3987 Applicability::MachineApplicable,
3994 if c_variadic { "at least " } else { "" },
3995 potentially_plural_count(expected_count, "argument")
4002 let mut expected_arg_tys = expected_arg_tys.to_vec();
4004 let formal_tys = if tuple_arguments == TupleArguments {
4005 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4006 match tuple_type.kind {
4007 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4008 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4009 expected_arg_tys = vec![];
4010 self.err_args(args.len())
4012 ty::Tuple(arg_types) => {
4013 expected_arg_tys = match expected_arg_tys.get(0) {
4014 Some(&ty) => match ty.kind {
4015 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4020 arg_types.iter().map(|k| k.expect_ty()).collect()
4027 "cannot use call notation; the first type parameter \
4028 for the function trait is neither a tuple nor unit"
4031 expected_arg_tys = vec![];
4032 self.err_args(args.len())
4035 } else if expected_arg_count == supplied_arg_count {
4037 } else if c_variadic {
4038 if supplied_arg_count >= expected_arg_count {
4041 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4042 expected_arg_tys = vec![];
4043 self.err_args(supplied_arg_count)
4046 // is the missing argument of type `()`?
4047 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4048 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4049 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4050 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4054 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4056 expected_arg_tys = vec![];
4057 self.err_args(supplied_arg_count)
4061 "check_argument_types: formal_tys={:?}",
4062 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4065 // If there is no expectation, expect formal_tys.
4066 let expected_arg_tys =
4067 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4069 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4071 // Check the arguments.
4072 // We do this in a pretty awful way: first we type-check any arguments
4073 // that are not closures, then we type-check the closures. This is so
4074 // that we have more information about the types of arguments when we
4075 // type-check the functions. This isn't really the right way to do this.
4076 for &check_closures in &[false, true] {
4077 debug!("check_closures={}", check_closures);
4079 // More awful hacks: before we check argument types, try to do
4080 // an "opportunistic" vtable resolution of any trait bounds on
4081 // the call. This helps coercions.
4083 self.select_obligations_where_possible(false, |errors| {
4084 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4085 self.point_at_arg_instead_of_call_if_possible(
4087 &final_arg_types[..],
4094 // For C-variadic functions, we don't have a declared type for all of
4095 // the arguments hence we only do our usual type checking with
4096 // the arguments who's types we do know.
4097 let t = if c_variadic {
4099 } else if tuple_arguments == TupleArguments {
4104 for (i, arg) in args.iter().take(t).enumerate() {
4105 // Warn only for the first loop (the "no closures" one).
4106 // Closure arguments themselves can't be diverging, but
4107 // a previous argument can, e.g., `foo(panic!(), || {})`.
4108 if !check_closures {
4109 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4112 let is_closure = match arg.kind {
4113 ExprKind::Closure(..) => true,
4117 if is_closure != check_closures {
4121 debug!("checking the argument");
4122 let formal_ty = formal_tys[i];
4124 // The special-cased logic below has three functions:
4125 // 1. Provide as good of an expected type as possible.
4126 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4128 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4130 // 2. Coerce to the most detailed type that could be coerced
4131 // to, which is `expected_ty` if `rvalue_hint` returns an
4132 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4133 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4134 // We're processing function arguments so we definitely want to use
4135 // two-phase borrows.
4136 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4137 final_arg_types.push((i, checked_ty, coerce_ty));
4139 // 3. Relate the expected type and the formal one,
4140 // if the expected type was used for the coercion.
4141 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4145 // We also need to make sure we at least write the ty of the other
4146 // arguments which we skipped above.
4148 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4149 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4150 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4153 for arg in args.iter().skip(expected_arg_count) {
4154 let arg_ty = self.check_expr(&arg);
4156 // There are a few types which get autopromoted when passed via varargs
4157 // in C but we just error out instead and require explicit casts.
4158 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4160 ty::Float(ast::FloatTy::F32) => {
4161 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4163 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4164 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4166 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4167 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4170 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4171 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4172 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4180 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4181 vec![self.tcx.types.err; len]
4184 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4185 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4186 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4187 /// can be not easily comparable with predicate type (because of coercion). If the types match
4188 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4189 /// the corresponding argument's expression span instead of the `fn` call path span.
4190 fn point_at_arg_instead_of_call_if_possible(
4192 errors: &mut Vec<traits::FulfillmentError<'_>>,
4193 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4195 args: &'tcx [hir::Expr<'tcx>],
4197 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4198 // the `?` operator.
4199 if call_sp.desugaring_kind().is_some() {
4203 for error in errors {
4204 // Only if the cause is somewhere inside the expression we want try to point at arg.
4205 // Otherwise, it means that the cause is somewhere else and we should not change
4206 // anything because we can break the correct span.
4207 if !call_sp.contains(error.obligation.cause.span) {
4211 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate {
4212 // Collect the argument position for all arguments that could have caused this
4213 // `FulfillmentError`.
4214 let mut referenced_in = final_arg_types
4216 .map(|&(i, checked_ty, _)| (i, checked_ty))
4217 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4218 .flat_map(|(i, ty)| {
4219 let ty = self.resolve_vars_if_possible(&ty);
4220 // We walk the argument type because the argument's type could have
4221 // been `Option<T>`, but the `FulfillmentError` references `T`.
4222 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4228 .collect::<Vec<_>>();
4230 // Both checked and coerced types could have matched, thus we need to remove
4232 referenced_in.sort();
4233 referenced_in.dedup();
4235 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4236 // We make sure that only *one* argument matches the obligation failure
4237 // and we assign the obligation's span to its expression's.
4238 error.obligation.cause.span = args[ref_in].span;
4239 error.points_at_arg_span = true;
4245 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4246 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4247 /// were caused by them. If they were, we point at the corresponding type argument's span
4248 /// instead of the `fn` call path span.
4249 fn point_at_type_arg_instead_of_call_if_possible(
4251 errors: &mut Vec<traits::FulfillmentError<'_>>,
4252 call_expr: &'tcx hir::Expr<'tcx>,
4254 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4255 if let hir::ExprKind::Path(qpath) = &path.kind {
4256 if let hir::QPath::Resolved(_, path) = &qpath {
4257 for error in errors {
4258 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate {
4259 // If any of the type arguments in this path segment caused the
4260 // `FullfillmentError`, point at its span (#61860).
4264 .filter_map(|seg| seg.args.as_ref())
4265 .flat_map(|a| a.args.iter())
4267 if let hir::GenericArg::Type(hir_ty) = &arg {
4268 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4271 // Avoid ICE with associated types. As this is best
4272 // effort only, it's ok to ignore the case. It
4273 // would trigger in `is_send::<T::AssocType>();`
4274 // from `typeck-default-trait-impl-assoc-type.rs`.
4276 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4277 let ty = self.resolve_vars_if_possible(&ty);
4278 if ty == predicate.skip_binder().self_ty() {
4279 error.obligation.cause.span = hir_ty.span;
4291 // AST fragment checking
4292 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4296 ast::LitKind::Str(..) => tcx.mk_static_str(),
4297 ast::LitKind::ByteStr(ref v) => {
4298 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4300 ast::LitKind::Byte(_) => tcx.types.u8,
4301 ast::LitKind::Char(_) => tcx.types.char,
4302 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4303 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4304 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4305 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4306 ty::Int(_) | ty::Uint(_) => Some(ty),
4307 ty::Char => Some(tcx.types.u8),
4308 ty::RawPtr(..) => Some(tcx.types.usize),
4309 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4312 opt_ty.unwrap_or_else(|| self.next_int_var())
4314 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4315 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4316 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4317 ty::Float(_) => Some(ty),
4320 opt_ty.unwrap_or_else(|| self.next_float_var())
4322 ast::LitKind::Bool(_) => tcx.types.bool,
4323 ast::LitKind::Err(_) => tcx.types.err,
4327 /// Unifies the output type with the expected type early, for more coercions
4328 /// and forward type information on the input expressions.
4329 fn expected_inputs_for_expected_output(
4332 expected_ret: Expectation<'tcx>,
4333 formal_ret: Ty<'tcx>,
4334 formal_args: &[Ty<'tcx>],
4335 ) -> Vec<Ty<'tcx>> {
4336 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4337 let ret_ty = match expected_ret.only_has_type(self) {
4339 None => return Vec::new(),
4341 let expect_args = self
4342 .fudge_inference_if_ok(|| {
4343 // Attempt to apply a subtyping relationship between the formal
4344 // return type (likely containing type variables if the function
4345 // is polymorphic) and the expected return type.
4346 // No argument expectations are produced if unification fails.
4347 let origin = self.misc(call_span);
4348 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4350 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4351 // to identity so the resulting type is not constrained.
4354 // Process any obligations locally as much as
4355 // we can. We don't care if some things turn
4356 // out unconstrained or ambiguous, as we're
4357 // just trying to get hints here.
4358 self.save_and_restore_in_snapshot_flag(|_| {
4359 let mut fulfill = TraitEngine::new(self.tcx);
4360 for obligation in ok.obligations {
4361 fulfill.register_predicate_obligation(self, obligation);
4363 fulfill.select_where_possible(self)
4367 Err(_) => return Err(()),
4370 // Record all the argument types, with the substitutions
4371 // produced from the above subtyping unification.
4372 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4374 .unwrap_or_default();
4376 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4377 formal_args, formal_ret, expect_args, expected_ret
4382 pub fn check_struct_path(
4386 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4387 let path_span = match *qpath {
4388 QPath::Resolved(_, ref path) => path.span,
4389 QPath::TypeRelative(ref qself, _) => qself.span,
4391 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4392 let variant = match def {
4394 self.set_tainted_by_errors();
4397 Res::Def(DefKind::Variant, _) => match ty.kind {
4398 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4399 _ => bug!("unexpected type: {:?}", ty),
4401 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4402 | Res::SelfTy(..) => match ty.kind {
4403 ty::Adt(adt, substs) if !adt.is_enum() => {
4404 Some((adt.non_enum_variant(), adt.did, substs))
4408 _ => bug!("unexpected definition: {:?}", def),
4411 if let Some((variant, did, substs)) = variant {
4412 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4413 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4415 // Check bounds on type arguments used in the path.
4416 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4418 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4419 self.add_obligations_for_parameters(cause, bounds);
4427 "expected struct, variant or union type, found {}",
4428 ty.sort_string(self.tcx)
4430 .span_label(path_span, "not a struct")
4436 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4437 // The newly resolved definition is written into `type_dependent_defs`.
4438 fn finish_resolving_struct_path(
4443 ) -> (Res, Ty<'tcx>) {
4445 QPath::Resolved(ref maybe_qself, ref path) => {
4446 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4447 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4450 QPath::TypeRelative(ref qself, ref segment) => {
4451 let ty = self.to_ty(qself);
4453 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4459 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4460 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4461 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4463 // Write back the new resolution.
4464 self.write_resolution(hir_id, result);
4466 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4471 /// Resolves an associated value path into a base type and associated constant, or method
4472 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4473 pub fn resolve_ty_and_res_ufcs<'b>(
4475 qpath: &'b QPath<'b>,
4478 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4479 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4480 let (ty, qself, item_segment) = match *qpath {
4481 QPath::Resolved(ref opt_qself, ref path) => {
4484 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4488 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4490 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4491 // Return directly on cache hit. This is useful to avoid doubly reporting
4492 // errors with default match binding modes. See #44614.
4494 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4495 return (def, Some(ty), slice::from_ref(&**item_segment));
4497 let item_name = item_segment.ident;
4498 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4499 let result = match error {
4500 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4501 _ => Err(ErrorReported),
4503 if item_name.name != kw::Invalid {
4504 if let Some(mut e) = self.report_method_error(
4508 SelfSource::QPath(qself),
4518 // Write back the new resolution.
4519 self.write_resolution(hir_id, result);
4521 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4523 slice::from_ref(&**item_segment),
4527 pub fn check_decl_initializer(
4529 local: &'tcx hir::Local<'tcx>,
4530 init: &'tcx hir::Expr<'tcx>,
4532 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4533 // for #42640 (default match binding modes).
4536 let ref_bindings = local.pat.contains_explicit_ref_binding();
4538 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4539 if let Some(m) = ref_bindings {
4540 // Somewhat subtle: if we have a `ref` binding in the pattern,
4541 // we want to avoid introducing coercions for the RHS. This is
4542 // both because it helps preserve sanity and, in the case of
4543 // ref mut, for soundness (issue #23116). In particular, in
4544 // the latter case, we need to be clear that the type of the
4545 // referent for the reference that results is *equal to* the
4546 // type of the place it is referencing, and not some
4547 // supertype thereof.
4548 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4549 self.demand_eqtype(init.span, local_ty, init_ty);
4552 self.check_expr_coercable_to_type(init, local_ty)
4556 /// Type check a `let` statement.
4557 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4558 // Determine and write the type which we'll check the pattern against.
4559 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4560 self.write_ty(local.hir_id, ty);
4562 // Type check the initializer.
4563 if let Some(ref init) = local.init {
4564 let init_ty = self.check_decl_initializer(local, &init);
4565 self.overwrite_local_ty_if_err(local, ty, init_ty);
4568 // Does the expected pattern type originate from an expression and what is the span?
4569 let (origin_expr, ty_span) = match (local.ty, local.init) {
4570 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4571 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4572 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4575 // Type check the pattern. Override if necessary to avoid knock-on errors.
4576 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4577 let pat_ty = self.node_ty(local.pat.hir_id);
4578 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4581 fn overwrite_local_ty_if_err(
4583 local: &'tcx hir::Local<'tcx>,
4587 if ty.references_error() {
4588 // Override the types everywhere with `types.err` to avoid knock on errors.
4589 self.write_ty(local.hir_id, ty);
4590 self.write_ty(local.pat.hir_id, ty);
4591 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4592 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4593 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4597 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4598 err.span_suggestion_short(
4599 span.shrink_to_hi(),
4600 "consider using a semicolon here",
4602 Applicability::MachineApplicable,
4606 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4607 // Don't do all the complex logic below for `DeclItem`.
4609 hir::StmtKind::Item(..) => return,
4610 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4613 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4615 // Hide the outer diverging and `has_errors` flags.
4616 let old_diverges = self.diverges.replace(Diverges::Maybe);
4617 let old_has_errors = self.has_errors.replace(false);
4620 hir::StmtKind::Local(ref l) => {
4621 self.check_decl_local(&l);
4624 hir::StmtKind::Item(_) => {}
4625 hir::StmtKind::Expr(ref expr) => {
4626 // Check with expected type of `()`.
4627 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4628 self.suggest_semicolon_at_end(expr.span, err);
4631 hir::StmtKind::Semi(ref expr) => {
4632 self.check_expr(&expr);
4636 // Combine the diverging and `has_error` flags.
4637 self.diverges.set(self.diverges.get() | old_diverges);
4638 self.has_errors.set(self.has_errors.get() | old_has_errors);
4641 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4642 let unit = self.tcx.mk_unit();
4643 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4645 // if the block produces a `!` value, that can always be
4646 // (effectively) coerced to unit.
4648 self.demand_suptype(blk.span, unit, ty);
4652 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4653 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4654 /// when given code like the following:
4656 /// if false { return 0i32; } else { 1u32 }
4657 /// // ^^^^ point at this instead of the whole `if` expression
4659 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4660 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4661 let arm_spans: Vec<Span> = arms
4664 self.in_progress_tables
4665 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4666 .and_then(|arm_ty| {
4667 if arm_ty.is_never() {
4670 Some(match &arm.body.kind {
4671 // Point at the tail expression when possible.
4672 hir::ExprKind::Block(block, _) => {
4673 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4681 if arm_spans.len() == 1 {
4682 return arm_spans[0];
4688 fn check_block_with_expected(
4690 blk: &'tcx hir::Block<'tcx>,
4691 expected: Expectation<'tcx>,
4694 let mut fcx_ps = self.ps.borrow_mut();
4695 let unsafety_state = fcx_ps.recurse(blk);
4696 replace(&mut *fcx_ps, unsafety_state)
4699 // In some cases, blocks have just one exit, but other blocks
4700 // can be targeted by multiple breaks. This can happen both
4701 // with labeled blocks as well as when we desugar
4702 // a `try { ... }` expression.
4706 // 'a: { if true { break 'a Err(()); } Ok(()) }
4708 // Here we would wind up with two coercions, one from
4709 // `Err(())` and the other from the tail expression
4710 // `Ok(())`. If the tail expression is omitted, that's a
4711 // "forced unit" -- unless the block diverges, in which
4712 // case we can ignore the tail expression (e.g., `'a: {
4713 // break 'a 22; }` would not force the type of the block
4715 let tail_expr = blk.expr.as_ref();
4716 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4717 let coerce = if blk.targeted_by_break {
4718 CoerceMany::new(coerce_to_ty)
4720 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4721 Some(e) => slice::from_ref(e),
4724 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4727 let prev_diverges = self.diverges.get();
4728 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4730 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4731 for s in blk.stmts {
4735 // check the tail expression **without** holding the
4736 // `enclosing_breakables` lock below.
4737 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4739 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4740 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4741 let coerce = ctxt.coerce.as_mut().unwrap();
4742 if let Some(tail_expr_ty) = tail_expr_ty {
4743 let tail_expr = tail_expr.unwrap();
4744 let span = self.get_expr_coercion_span(tail_expr);
4745 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4746 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4748 // Subtle: if there is no explicit tail expression,
4749 // that is typically equivalent to a tail expression
4750 // of `()` -- except if the block diverges. In that
4751 // case, there is no value supplied from the tail
4752 // expression (assuming there are no other breaks,
4753 // this implies that the type of the block will be
4756 // #41425 -- label the implicit `()` as being the
4757 // "found type" here, rather than the "expected type".
4758 if !self.diverges.get().is_always() {
4759 // #50009 -- Do not point at the entire fn block span, point at the return type
4760 // span, as it is the cause of the requirement, and
4761 // `consider_hint_about_removing_semicolon` will point at the last expression
4762 // if it were a relevant part of the error. This improves usability in editors
4763 // that highlight errors inline.
4764 let mut sp = blk.span;
4765 let mut fn_span = None;
4766 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4767 let ret_sp = decl.output.span();
4768 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4769 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4770 // output would otherwise be incorrect and even misleading. Make sure
4771 // the span we're aiming at correspond to a `fn` body.
4772 if block_sp == blk.span {
4774 fn_span = Some(ident.span);
4778 coerce.coerce_forced_unit(
4782 if let Some(expected_ty) = expected.only_has_type(self) {
4783 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4785 if let Some(fn_span) = fn_span {
4788 "implicitly returns `()` as its body has no tail or `return` \
4800 // If we can break from the block, then the block's exit is always reachable
4801 // (... as long as the entry is reachable) - regardless of the tail of the block.
4802 self.diverges.set(prev_diverges);
4805 let mut ty = ctxt.coerce.unwrap().complete(self);
4807 if self.has_errors.get() || ty.references_error() {
4808 ty = self.tcx.types.err
4811 self.write_ty(blk.hir_id, ty);
4813 *self.ps.borrow_mut() = prev;
4817 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4818 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4820 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4821 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4822 let body = self.tcx.hir().body(body_id);
4823 if let ExprKind::Block(block, _) = &body.value.kind {
4824 return Some(block.span);
4832 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4833 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4834 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4835 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4838 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4839 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4841 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4842 // This is less than ideal, it will not suggest a return type span on any
4843 // method called `main`, regardless of whether it is actually the entry point,
4844 // but it will still present it as the reason for the expected type.
4845 Some((&sig.decl, ident, ident.name != sym::main))
4847 Node::TraitItem(&hir::TraitItem {
4849 kind: hir::TraitItemKind::Fn(ref sig, ..),
4851 }) => Some((&sig.decl, ident, true)),
4852 Node::ImplItem(&hir::ImplItem {
4854 kind: hir::ImplItemKind::Fn(ref sig, ..),
4856 }) => Some((&sig.decl, ident, false)),
4861 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4862 /// suggestion can be made, `None` otherwise.
4863 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4864 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4865 // `while` before reaching it, as block tail returns are not available in them.
4866 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4867 let parent = self.tcx.hir().get(blk_id);
4868 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4872 /// On implicit return expressions with mismatched types, provides the following suggestions:
4874 /// - Points out the method's return type as the reason for the expected type.
4875 /// - Possible missing semicolon.
4876 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4877 pub fn suggest_mismatched_types_on_tail(
4879 err: &mut DiagnosticBuilder<'_>,
4880 expr: &'tcx hir::Expr<'tcx>,
4886 let expr = expr.peel_drop_temps();
4887 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4888 let mut pointing_at_return_type = false;
4889 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4890 pointing_at_return_type =
4891 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4893 pointing_at_return_type
4896 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4897 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4899 /// fn foo(x: usize) -> usize { x }
4900 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4904 err: &mut DiagnosticBuilder<'_>,
4905 expr: &hir::Expr<'_>,
4909 let hir = self.tcx.hir();
4910 let (def_id, sig) = match found.kind {
4911 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4912 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4916 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4917 let sig = self.normalize_associated_types_in(expr.span, &sig);
4918 if self.can_coerce(sig.output(), expected) {
4919 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4920 (String::new(), Applicability::MachineApplicable)
4922 ("...".to_string(), Applicability::HasPlaceholders)
4924 let mut msg = "call this function";
4925 match hir.get_if_local(def_id) {
4927 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4928 | Node::ImplItem(hir::ImplItem {
4929 kind: hir::ImplItemKind::Fn(_, body_id), ..
4931 | Node::TraitItem(hir::TraitItem {
4932 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4936 let body = hir.body(*body_id);
4940 .map(|param| match ¶m.pat.kind {
4941 hir::PatKind::Binding(_, _, ident, None)
4942 if ident.name != kw::SelfLower =>
4946 _ => "_".to_string(),
4948 .collect::<Vec<_>>()
4951 Some(Node::Expr(hir::Expr {
4952 kind: ExprKind::Closure(_, _, body_id, _, _),
4953 span: full_closure_span,
4956 if *full_closure_span == expr.span {
4959 msg = "call this closure";
4960 let body = hir.body(*body_id);
4964 .map(|param| match ¶m.pat.kind {
4965 hir::PatKind::Binding(_, _, ident, None)
4966 if ident.name != kw::SelfLower =>
4970 _ => "_".to_string(),
4972 .collect::<Vec<_>>()
4975 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4976 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4977 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
4978 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4979 msg = "instantiate this tuple variant";
4981 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
4982 msg = "instantiate this tuple struct";
4987 Some(Node::ForeignItem(hir::ForeignItem {
4988 kind: hir::ForeignItemKind::Fn(_, idents, _),
4994 if ident.name != kw::SelfLower {
5000 .collect::<Vec<_>>()
5003 Some(Node::TraitItem(hir::TraitItem {
5004 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5010 if ident.name != kw::SelfLower {
5016 .collect::<Vec<_>>()
5021 err.span_suggestion_verbose(
5022 expr.span.shrink_to_hi(),
5023 &format!("use parentheses to {}", msg),
5024 format!("({})", sugg_call),
5032 pub fn suggest_deref_ref_or_into(
5034 err: &mut DiagnosticBuilder<'_>,
5035 expr: &hir::Expr<'_>,
5039 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5040 err.span_suggestion(sp, msg, suggestion, applicability);
5041 } else if let (ty::FnDef(def_id, ..), true) =
5042 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5044 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5045 let sp = self.sess().source_map().guess_head_span(sp);
5046 err.span_label(sp, &format!("{} defined here", found));
5048 } else if !self.check_for_cast(err, expr, found, expected) {
5049 let is_struct_pat_shorthand_field =
5050 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5051 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5052 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5053 let mut suggestions = iter::repeat(&expr_text)
5054 .zip(methods.iter())
5055 .filter_map(|(receiver, method)| {
5056 let method_call = format!(".{}()", method.ident);
5057 if receiver.ends_with(&method_call) {
5058 None // do not suggest code that is already there (#53348)
5060 let method_call_list = [".to_vec()", ".to_string()"];
5061 let sugg = if receiver.ends_with(".clone()")
5062 && method_call_list.contains(&method_call.as_str())
5064 let max_len = receiver.rfind('.').unwrap();
5065 format!("{}{}", &receiver[..max_len], method_call)
5067 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5068 format!("({}){}", receiver, method_call)
5070 format!("{}{}", receiver, method_call)
5073 Some(if is_struct_pat_shorthand_field {
5074 format!("{}: {}", receiver, sugg)
5081 if suggestions.peek().is_some() {
5082 err.span_suggestions(
5084 "try using a conversion method",
5086 Applicability::MaybeIncorrect,
5093 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5094 /// in the heap by calling `Box::new()`.
5095 fn suggest_boxing_when_appropriate(
5097 err: &mut DiagnosticBuilder<'_>,
5098 expr: &hir::Expr<'_>,
5102 if self.tcx.hir().is_const_context(expr.hir_id) {
5103 // Do not suggest `Box::new` in const context.
5106 if !expected.is_box() || found.is_box() {
5109 let boxed_found = self.tcx.mk_box(found);
5110 if let (true, Ok(snippet)) = (
5111 self.can_coerce(boxed_found, expected),
5112 self.sess().source_map().span_to_snippet(expr.span),
5114 err.span_suggestion(
5116 "store this in the heap by calling `Box::new`",
5117 format!("Box::new({})", snippet),
5118 Applicability::MachineApplicable,
5121 "for more on the distinction between the stack and the heap, read \
5122 https://doc.rust-lang.org/book/ch15-01-box.html, \
5123 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5124 https://doc.rust-lang.org/std/boxed/index.html",
5129 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5130 fn suggest_calling_boxed_future_when_appropriate(
5132 err: &mut DiagnosticBuilder<'_>,
5133 expr: &hir::Expr<'_>,
5139 if self.tcx.hir().is_const_context(expr.hir_id) {
5140 // Do not suggest `Box::new` in const context.
5143 let pin_did = self.tcx.lang_items().pin_type();
5144 match expected.kind {
5145 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5146 // This guards the `unwrap` and `mk_box` below.
5147 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5150 let boxed_found = self.tcx.mk_box(found);
5151 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5152 if let (true, Ok(snippet)) = (
5153 self.can_coerce(new_found, expected),
5154 self.sess().source_map().span_to_snippet(expr.span),
5157 ty::Adt(def, _) if def.is_box() => {
5158 err.help("use `Box::pin`");
5161 err.span_suggestion(
5163 "you need to pin and box this expression",
5164 format!("Box::pin({})", snippet),
5165 Applicability::MachineApplicable,
5175 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5179 /// bar_that_returns_u32()
5183 /// This routine checks if the return expression in a block would make sense on its own as a
5184 /// statement and the return type has been left as default or has been specified as `()`. If so,
5185 /// it suggests adding a semicolon.
5186 fn suggest_missing_semicolon(
5188 err: &mut DiagnosticBuilder<'_>,
5189 expression: &'tcx hir::Expr<'tcx>,
5193 if expected.is_unit() {
5194 // `BlockTailExpression` only relevant if the tail expr would be
5195 // useful on its own.
5196 match expression.kind {
5198 | ExprKind::MethodCall(..)
5199 | ExprKind::Loop(..)
5200 | ExprKind::Match(..)
5201 | ExprKind::Block(..) => {
5202 err.span_suggestion(
5203 cause_span.shrink_to_hi(),
5204 "try adding a semicolon",
5206 Applicability::MachineApplicable,
5214 /// A possible error is to forget to add a return type that is needed:
5218 /// bar_that_returns_u32()
5222 /// This routine checks if the return type is left as default, the method is not part of an
5223 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5225 fn suggest_missing_return_type(
5227 err: &mut DiagnosticBuilder<'_>,
5228 fn_decl: &hir::FnDecl<'_>,
5233 // Only suggest changing the return type for methods that
5234 // haven't set a return type at all (and aren't `fn main()` or an impl).
5235 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5236 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5237 err.span_suggestion(
5239 "try adding a return type",
5240 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5241 Applicability::MachineApplicable,
5245 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5246 err.span_label(span, "possibly return type missing here?");
5249 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5250 // `fn main()` must return `()`, do not suggest changing return type
5251 err.span_label(span, "expected `()` because of default return type");
5254 // expectation was caused by something else, not the default return
5255 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5256 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5257 // Only point to return type if the expected type is the return type, as if they
5258 // are not, the expectation must have been caused by something else.
5259 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5261 let ty = AstConv::ast_ty_to_ty(self, ty);
5262 debug!("suggest_missing_return_type: return type {:?}", ty);
5263 debug!("suggest_missing_return_type: expected type {:?}", ty);
5264 if ty.kind == expected.kind {
5265 err.span_label(sp, format!("expected `{}` because of return type", expected));
5273 /// A possible error is to forget to add `.await` when using futures:
5276 /// async fn make_u32() -> u32 {
5280 /// fn take_u32(x: u32) {}
5282 /// async fn foo() {
5283 /// let x = make_u32();
5288 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5289 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5290 /// `.await` to the tail of the expression.
5291 fn suggest_missing_await(
5293 err: &mut DiagnosticBuilder<'_>,
5294 expr: &hir::Expr<'_>,
5298 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5299 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5300 // body isn't `async`.
5301 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5302 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5303 let body = self.tcx().hir().body(body_id);
5304 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5306 // Check for `Future` implementations by constructing a predicate to
5307 // prove: `<T as Future>::Output == U`
5308 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5309 let item_def_id = self
5311 .associated_items(future_trait)
5312 .in_definition_order()
5316 // `<T as Future>::Output`
5317 let projection_ty = ty::ProjectionTy {
5321 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5327 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5331 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5333 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5335 if self.infcx.predicate_may_hold(&obligation) {
5336 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5337 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5338 err.span_suggestion(
5340 "consider using `.await` here",
5341 format!("{}.await", code),
5342 Applicability::MaybeIncorrect,
5345 debug!("suggest_missing_await: no snippet for {:?}", sp);
5348 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5354 /// A common error is to add an extra semicolon:
5357 /// fn foo() -> usize {
5362 /// This routine checks if the final statement in a block is an
5363 /// expression with an explicit semicolon whose type is compatible
5364 /// with `expected_ty`. If so, it suggests removing the semicolon.
5365 fn consider_hint_about_removing_semicolon(
5367 blk: &'tcx hir::Block<'tcx>,
5368 expected_ty: Ty<'tcx>,
5369 err: &mut DiagnosticBuilder<'_>,
5371 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5372 err.span_suggestion(
5374 "consider removing this semicolon",
5376 Applicability::MachineApplicable,
5381 fn could_remove_semicolon(
5383 blk: &'tcx hir::Block<'tcx>,
5384 expected_ty: Ty<'tcx>,
5386 // Be helpful when the user wrote `{... expr;}` and
5387 // taking the `;` off is enough to fix the error.
5388 let last_stmt = blk.stmts.last()?;
5389 let last_expr = match last_stmt.kind {
5390 hir::StmtKind::Semi(ref e) => e,
5393 let last_expr_ty = self.node_ty(last_expr.hir_id);
5394 if matches!(last_expr_ty.kind, ty::Error)
5395 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5399 let original_span = original_sp(last_stmt.span, blk.span);
5400 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5403 // Instantiates the given path, which must refer to an item with the given
5404 // number of type parameters and type.
5405 pub fn instantiate_value_path(
5407 segments: &[hir::PathSegment<'_>],
5408 self_ty: Option<Ty<'tcx>>,
5412 ) -> (Ty<'tcx>, Res) {
5414 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5415 segments, self_ty, res, hir_id,
5420 let path_segs = match res {
5421 Res::Local(_) | Res::SelfCtor(_) => vec![],
5422 Res::Def(kind, def_id) => {
5423 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5425 _ => bug!("instantiate_value_path on {:?}", res),
5428 let mut user_self_ty = None;
5429 let mut is_alias_variant_ctor = false;
5431 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5432 if let Some(self_ty) = self_ty {
5433 let adt_def = self_ty.ty_adt_def().unwrap();
5434 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5435 is_alias_variant_ctor = true;
5438 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5439 let container = tcx.associated_item(def_id).container;
5440 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5442 ty::TraitContainer(trait_did) => {
5443 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5445 ty::ImplContainer(impl_def_id) => {
5446 if segments.len() == 1 {
5447 // `<T>::assoc` will end up here, and so
5448 // can `T::assoc`. It this came from an
5449 // inherent impl, we need to record the
5450 // `T` for posterity (see `UserSelfTy` for
5452 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5453 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5461 // Now that we have categorized what space the parameters for each
5462 // segment belong to, let's sort out the parameters that the user
5463 // provided (if any) into their appropriate spaces. We'll also report
5464 // errors if type parameters are provided in an inappropriate place.
5466 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5467 let generics_has_err = AstConv::prohibit_generics(
5469 segments.iter().enumerate().filter_map(|(index, seg)| {
5470 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5478 if let Res::Local(hid) = res {
5479 let ty = self.local_ty(span, hid).decl_ty;
5480 let ty = self.normalize_associated_types_in(span, &ty);
5481 self.write_ty(hir_id, ty);
5485 if generics_has_err {
5486 // Don't try to infer type parameters when prohibited generic arguments were given.
5487 user_self_ty = None;
5490 // Now we have to compare the types that the user *actually*
5491 // provided against the types that were *expected*. If the user
5492 // did not provide any types, then we want to substitute inference
5493 // variables. If the user provided some types, we may still need
5494 // to add defaults. If the user provided *too many* types, that's
5497 let mut infer_args_for_err = FxHashSet::default();
5498 for &PathSeg(def_id, index) in &path_segs {
5499 let seg = &segments[index];
5500 let generics = tcx.generics_of(def_id);
5501 // Argument-position `impl Trait` is treated as a normal generic
5502 // parameter internally, but we don't allow users to specify the
5503 // parameter's value explicitly, so we have to do some error-
5505 if let Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }) =
5506 AstConv::check_generic_arg_count_for_call(
5507 tcx, span, &generics, &seg, false, // `is_method_call`
5510 infer_args_for_err.insert(index);
5511 self.set_tainted_by_errors(); // See issue #53251.
5515 let has_self = path_segs
5517 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5520 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5521 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5523 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5524 let variant = adt_def.non_enum_variant();
5525 let ctor_def_id = variant.ctor_def_id.unwrap();
5527 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5532 let mut err = tcx.sess.struct_span_err(
5534 "the `Self` constructor can only be used with tuple or unit structs",
5536 if let Some(adt_def) = ty.ty_adt_def() {
5537 match adt_def.adt_kind() {
5539 err.help("did you mean to use one of the enum's variants?");
5541 AdtKind::Struct | AdtKind::Union => {
5542 err.span_suggestion(
5544 "use curly brackets",
5545 String::from("Self { /* fields */ }"),
5546 Applicability::HasPlaceholders,
5553 return (tcx.types.err, res);
5559 let def_id = res.def_id();
5561 // The things we are substituting into the type should not contain
5562 // escaping late-bound regions, and nor should the base type scheme.
5563 let ty = tcx.type_of(def_id);
5565 let substs = self_ctor_substs.unwrap_or_else(|| {
5566 AstConv::create_substs_for_generic_args(
5572 infer_args_for_err.is_empty(),
5573 // Provide the generic args, and whether types should be inferred.
5575 if let Some(&PathSeg(_, index)) =
5576 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5578 // If we've encountered an `impl Trait`-related error, we're just
5579 // going to infer the arguments for better error messages.
5580 if !infer_args_for_err.contains(&index) {
5581 // Check whether the user has provided generic arguments.
5582 if let Some(ref data) = segments[index].args {
5583 return (Some(data), segments[index].infer_args);
5586 return (None, segments[index].infer_args);
5591 // Provide substitutions for parameters for which (valid) arguments have been provided.
5592 |param, arg| match (¶m.kind, arg) {
5593 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5594 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5596 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5597 self.to_ty(ty).into()
5599 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5600 self.to_const(&ct.value).into()
5602 _ => unreachable!(),
5604 // Provide substitutions for parameters for which arguments are inferred.
5605 |substs, param, infer_args| {
5607 GenericParamDefKind::Lifetime => {
5608 self.re_infer(Some(param), span).unwrap().into()
5610 GenericParamDefKind::Type { has_default, .. } => {
5611 if !infer_args && has_default {
5612 // If we have a default, then we it doesn't matter that we're not
5613 // inferring the type arguments: we provide the default where any
5615 let default = tcx.type_of(param.def_id);
5618 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5622 // If no type arguments were provided, we have to infer them.
5623 // This case also occurs as a result of some malformed input, e.g.
5624 // a lifetime argument being given instead of a type parameter.
5625 // Using inference instead of `Error` gives better error messages.
5626 self.var_for_def(span, param)
5629 GenericParamDefKind::Const => {
5630 // FIXME(const_generics:defaults)
5631 // No const parameters were provided, we have to infer them.
5632 self.var_for_def(span, param)
5638 assert!(!substs.has_escaping_bound_vars());
5639 assert!(!ty.has_escaping_bound_vars());
5641 // First, store the "user substs" for later.
5642 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5644 self.add_required_obligations(span, def_id, &substs);
5646 // Substitute the values for the type parameters into the type of
5647 // the referenced item.
5648 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5650 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5651 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5652 // is inherent, there is no `Self` parameter; instead, the impl needs
5653 // type parameters, which we can infer by unifying the provided `Self`
5654 // with the substituted impl type.
5655 // This also occurs for an enum variant on a type alias.
5656 let ty = tcx.type_of(impl_def_id);
5658 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5659 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5660 Ok(ok) => self.register_infer_ok_obligations(ok),
5662 self.tcx.sess.delay_span_bug(
5665 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5674 self.check_rustc_args_require_const(def_id, hir_id, span);
5676 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5677 self.write_substs(hir_id, substs);
5679 (ty_substituted, res)
5682 /// Add all the obligations that are required, substituting and normalized appropriately.
5683 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5684 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5686 for (i, mut obligation) in traits::predicates_for_generics(
5687 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5693 // This makes the error point at the bound, but we want to point at the argument
5694 if let Some(span) = spans.get(i) {
5695 obligation.cause.code = traits::BindingObligation(def_id, *span);
5697 self.register_predicate(obligation);
5701 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5702 // We're only interested in functions tagged with
5703 // #[rustc_args_required_const], so ignore anything that's not.
5704 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5708 // If our calling expression is indeed the function itself, we're good!
5709 // If not, generate an error that this can only be called directly.
5710 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5711 if let ExprKind::Call(ref callee, ..) = expr.kind {
5712 if callee.hir_id == hir_id {
5718 self.tcx.sess.span_err(
5720 "this function can only be invoked directly, not through a function pointer",
5724 /// Resolves `typ` by a single level if `typ` is a type variable.
5725 /// If no resolution is possible, then an error is reported.
5726 /// Numeric inference variables may be left unresolved.
5727 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5728 let ty = self.resolve_vars_with_obligations(ty);
5729 if !ty.is_ty_var() {
5732 if !self.is_tainted_by_errors() {
5733 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5734 .note("type must be known at this point")
5737 self.demand_suptype(sp, self.tcx.types.err, ty);
5742 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5745 ctxt: BreakableCtxt<'tcx>,
5747 ) -> (BreakableCtxt<'tcx>, R) {
5750 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5751 index = enclosing_breakables.stack.len();
5752 enclosing_breakables.by_id.insert(id, index);
5753 enclosing_breakables.stack.push(ctxt);
5757 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5758 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5759 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5760 enclosing_breakables.stack.pop().expect("missing breakable context")
5765 /// Instantiate a QueryResponse in a probe context, without a
5766 /// good ObligationCause.
5767 fn probe_instantiate_query_response(
5770 original_values: &OriginalQueryValues<'tcx>,
5771 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5772 ) -> InferResult<'tcx, Ty<'tcx>> {
5773 self.instantiate_query_response_and_region_obligations(
5774 &traits::ObligationCause::misc(span, self.body_id),
5781 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5782 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5783 let mut contained_in_place = false;
5785 while let hir::Node::Expr(parent_expr) =
5786 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5788 match &parent_expr.kind {
5789 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5790 if lhs.hir_id == expr_id {
5791 contained_in_place = true;
5797 expr_id = parent_expr.hir_id;
5804 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5805 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5807 assert_eq!(generics.parent, None);
5809 if generics.own_counts().types == 0 {
5813 let mut params_used = BitSet::new_empty(generics.params.len());
5815 if ty.references_error() {
5816 // If there is already another error, do not emit
5817 // an error for not using a type parameter.
5818 assert!(tcx.sess.has_errors());
5822 for leaf in ty.walk() {
5823 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5824 if let ty::Param(param) = leaf_ty.kind {
5825 debug!("found use of ty param {:?}", param);
5826 params_used.insert(param.index);
5831 for param in &generics.params {
5832 if !params_used.contains(param.index) {
5833 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5834 let span = tcx.def_span(param.def_id);
5839 "type parameter `{}` is unused",
5842 .span_label(span, "unused type parameter")
5849 fn fatally_break_rust(sess: &Session) {
5850 let handler = sess.diagnostic();
5851 handler.span_bug_no_panic(
5853 "It looks like you're trying to break rust; would you like some ICE?",
5855 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5856 handler.note_without_error(
5857 "we would appreciate a joke overview: \
5858 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5860 handler.note_without_error(&format!(
5861 "rustc {} running on {}",
5862 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5863 config::host_triple(),
5867 fn potentially_plural_count(count: usize, word: &str) -> String {
5868 format!("{} {}{}", count, word, pluralize!(count))