1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
80 mod generator_interior;
91 AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
94 use rustc_ast::util::parser::ExprPrecedence;
95 use rustc_attr as attr;
96 use rustc_data_structures::captures::Captures;
97 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
98 use rustc_errors::ErrorReported;
99 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
100 use rustc_hir as hir;
101 use rustc_hir::def::{CtorOf, DefKind, Res};
102 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
103 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
104 use rustc_hir::itemlikevisit::ItemLikeVisitor;
105 use rustc_hir::lang_items::{
106 FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem,
108 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
109 use rustc_index::bit_set::BitSet;
110 use rustc_index::vec::Idx;
111 use rustc_infer::infer;
112 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
113 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
114 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
115 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
116 use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
117 use rustc_middle::hir::map::blocks::FnLikeNode;
118 use rustc_middle::mir::interpret::ConstValue;
119 use rustc_middle::ty::adjustment::{
120 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
122 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
123 use rustc_middle::ty::query::Providers;
124 use rustc_middle::ty::subst::{
125 GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
127 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
128 use rustc_middle::ty::{
129 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
130 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
132 use rustc_session::config::{self, EntryFnType};
133 use rustc_session::lint;
134 use rustc_session::parse::feature_err;
135 use rustc_session::Session;
136 use rustc_span::hygiene::DesugaringKind;
137 use rustc_span::source_map::{original_sp, DUMMY_SP};
138 use rustc_span::symbol::{kw, sym, Ident};
139 use rustc_span::{self, BytePos, MultiSpan, Span};
140 use rustc_target::abi::VariantIdx;
141 use rustc_target::spec::abi::Abi;
142 use rustc_trait_selection::infer::InferCtxtExt as _;
143 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
144 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
145 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
146 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
147 use rustc_trait_selection::traits::{
148 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
151 use std::cell::{Cell, Ref, RefCell, RefMut};
153 use std::collections::hash_map::Entry;
155 use std::mem::replace;
156 use std::ops::{self, Deref};
159 use crate::require_c_abi_if_c_variadic;
160 use crate::util::common::indenter;
162 use self::autoderef::Autoderef;
163 use self::callee::DeferredCallResolution;
164 use self::coercion::{CoerceMany, DynamicCoerceMany};
165 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
166 use self::method::{MethodCallee, SelfSource};
167 pub use self::Expectation::*;
168 use self::TupleArgumentsFlag::*;
171 macro_rules! type_error_struct {
172 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
173 if $typ.references_error() {
174 $session.diagnostic().struct_dummy()
176 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
181 /// The type of a local binding, including the revealed type for anon types.
182 #[derive(Copy, Clone, Debug)]
183 pub struct LocalTy<'tcx> {
185 revealed_ty: Ty<'tcx>,
188 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
189 #[derive(Copy, Clone)]
190 struct MaybeInProgressTables<'a, 'tcx> {
191 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
194 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
195 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
196 match self.maybe_tables {
197 Some(tables) => tables.borrow(),
198 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
202 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
203 match self.maybe_tables {
204 Some(tables) => tables.borrow_mut(),
205 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
210 /// Closures defined within the function. For example:
213 /// bar(move|| { ... })
216 /// Here, the function `foo()` and the closure passed to
217 /// `bar()` will each have their own `FnCtxt`, but they will
218 /// share the inherited fields.
219 pub struct Inherited<'a, 'tcx> {
220 infcx: InferCtxt<'a, 'tcx>,
222 tables: MaybeInProgressTables<'a, 'tcx>,
224 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
226 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
228 // Some additional `Sized` obligations badly affect type inference.
229 // These obligations are added in a later stage of typeck.
230 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
232 // When we process a call like `c()` where `c` is a closure type,
233 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
234 // `FnOnce` closure. In that case, we defer full resolution of the
235 // call until upvar inference can kick in and make the
236 // decision. We keep these deferred resolutions grouped by the
237 // def-id of the closure, so that once we decide, we can easily go
238 // back and process them.
239 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
241 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
243 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
245 // Opaque types found in explicit return types and their
246 // associated fresh inference variable. Writeback resolves these
247 // variables to get the concrete type, which can be used to
248 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
249 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
251 /// A map from inference variables created from opaque
252 /// type instantiations (`ty::Infer`) to the actual opaque
253 /// type (`ty::Opaque`). Used during fallback to map unconstrained
254 /// opaque type inference variables to their corresponding
256 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
258 /// Each type parameter has an implicit region bound that
259 /// indicates it must outlive at least the function body (the user
260 /// may specify stronger requirements). This field indicates the
261 /// region of the callee. If it is `None`, then the parameter
262 /// environment is for an item or something where the "callee" is
264 implicit_region_bound: Option<ty::Region<'tcx>>,
266 body_id: Option<hir::BodyId>,
269 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
270 type Target = InferCtxt<'a, 'tcx>;
271 fn deref(&self) -> &Self::Target {
276 /// When type-checking an expression, we propagate downward
277 /// whatever type hint we are able in the form of an `Expectation`.
278 #[derive(Copy, Clone, Debug)]
279 pub enum Expectation<'tcx> {
280 /// We know nothing about what type this expression should have.
283 /// This expression should have the type given (or some subtype).
284 ExpectHasType(Ty<'tcx>),
286 /// This expression will be cast to the `Ty`.
287 ExpectCastableToType(Ty<'tcx>),
289 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
290 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
291 ExpectRvalueLikeUnsized(Ty<'tcx>),
294 impl<'a, 'tcx> Expectation<'tcx> {
295 // Disregard "castable to" expectations because they
296 // can lead us astray. Consider for example `if cond
297 // {22} else {c} as u8` -- if we propagate the
298 // "castable to u8" constraint to 22, it will pick the
299 // type 22u8, which is overly constrained (c might not
300 // be a u8). In effect, the problem is that the
301 // "castable to" expectation is not the tightest thing
302 // we can say, so we want to drop it in this case.
303 // The tightest thing we can say is "must unify with
304 // else branch". Note that in the case of a "has type"
305 // constraint, this limitation does not hold.
307 // If the expected type is just a type variable, then don't use
308 // an expected type. Otherwise, we might write parts of the type
309 // when checking the 'then' block which are incompatible with the
311 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
313 ExpectHasType(ety) => {
314 let ety = fcx.shallow_resolve(ety);
315 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
317 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
322 /// Provides an expectation for an rvalue expression given an *optional*
323 /// hint, which is not required for type safety (the resulting type might
324 /// be checked higher up, as is the case with `&expr` and `box expr`), but
325 /// is useful in determining the concrete type.
327 /// The primary use case is where the expected type is a fat pointer,
328 /// like `&[isize]`. For example, consider the following statement:
330 /// let x: &[isize] = &[1, 2, 3];
332 /// In this case, the expected type for the `&[1, 2, 3]` expression is
333 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
334 /// expectation `ExpectHasType([isize])`, that would be too strong --
335 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
336 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
337 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
338 /// which still is useful, because it informs integer literals and the like.
339 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
340 /// for examples of where this comes up,.
341 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
342 match fcx.tcx.struct_tail_without_normalization(ty).kind {
343 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
344 _ => ExpectHasType(ty),
348 // Resolves `expected` by a single level if it is a variable. If
349 // there is no expected type or resolution is not possible (e.g.,
350 // no constraints yet present), just returns `None`.
351 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
353 NoExpectation => NoExpectation,
354 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
355 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
356 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
360 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
361 match self.resolve(fcx) {
362 NoExpectation => None,
363 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
367 /// It sometimes happens that we want to turn an expectation into
368 /// a **hard constraint** (i.e., something that must be satisfied
369 /// for the program to type-check). `only_has_type` will return
370 /// such a constraint, if it exists.
371 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
372 match self.resolve(fcx) {
373 ExpectHasType(ty) => Some(ty),
374 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
378 /// Like `only_has_type`, but instead of returning `None` if no
379 /// hard constraint exists, creates a fresh type variable.
380 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
381 self.only_has_type(fcx).unwrap_or_else(|| {
382 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
387 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
394 fn maybe_mut_place(m: hir::Mutability) -> Self {
396 hir::Mutability::Mut => Needs::MutPlace,
397 hir::Mutability::Not => Needs::None,
402 #[derive(Copy, Clone)]
403 pub struct UnsafetyState {
405 pub unsafety: hir::Unsafety,
406 pub unsafe_push_count: u32,
411 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
412 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
415 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
416 use hir::BlockCheckMode;
417 match self.unsafety {
418 // If this unsafe, then if the outer function was already marked as
419 // unsafe we shouldn't attribute the unsafe'ness to the block. This
420 // way the block can be warned about instead of ignoring this
421 // extraneous block (functions are never warned about).
422 hir::Unsafety::Unsafe if self.from_fn => *self,
425 let (unsafety, def, count) = match blk.rules {
426 BlockCheckMode::PushUnsafeBlock(..) => {
427 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
429 BlockCheckMode::PopUnsafeBlock(..) => {
430 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
432 BlockCheckMode::UnsafeBlock(..) => {
433 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
435 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
437 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
443 #[derive(Debug, Copy, Clone)]
449 /// Tracks whether executing a node may exit normally (versus
450 /// return/break/panic, which "diverge", leaving dead code in their
451 /// wake). Tracked semi-automatically (through type variables marked
452 /// as diverging), with some manual adjustments for control-flow
453 /// primitives (approximating a CFG).
454 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
456 /// Potentially unknown, some cases converge,
457 /// others require a CFG to determine them.
460 /// Definitely known to diverge and therefore
461 /// not reach the next sibling or its parent.
463 /// The `Span` points to the expression
464 /// that caused us to diverge
465 /// (e.g. `return`, `break`, etc).
467 /// In some cases (e.g. a `match` expression
468 /// where all arms diverge), we may be
469 /// able to provide a more informative
470 /// message to the user.
471 /// If this is `None`, a default message
472 /// will be generated, which is suitable
474 custom_note: Option<&'static str>,
477 /// Same as `Always` but with a reachability
478 /// warning already emitted.
482 // Convenience impls for combining `Diverges`.
484 impl ops::BitAnd for Diverges {
486 fn bitand(self, other: Self) -> Self {
487 cmp::min(self, other)
491 impl ops::BitOr for Diverges {
493 fn bitor(self, other: Self) -> Self {
494 cmp::max(self, other)
498 impl ops::BitAndAssign for Diverges {
499 fn bitand_assign(&mut self, other: Self) {
500 *self = *self & other;
504 impl ops::BitOrAssign for Diverges {
505 fn bitor_assign(&mut self, other: Self) {
506 *self = *self | other;
511 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
512 fn always(span: Span) -> Diverges {
513 Diverges::Always { span, custom_note: None }
516 fn is_always(self) -> bool {
517 // Enum comparison ignores the
518 // contents of fields, so we just
519 // fill them in with garbage here.
520 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
524 pub struct BreakableCtxt<'tcx> {
527 // this is `null` for loops where break with a value is illegal,
528 // such as `while`, `for`, and `while let`
529 coerce: Option<DynamicCoerceMany<'tcx>>,
532 pub struct EnclosingBreakables<'tcx> {
533 stack: Vec<BreakableCtxt<'tcx>>,
534 by_id: HirIdMap<usize>,
537 impl<'tcx> EnclosingBreakables<'tcx> {
538 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
539 self.opt_find_breakable(target_id).unwrap_or_else(|| {
540 bug!("could not find enclosing breakable with id {}", target_id);
544 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
545 match self.by_id.get(&target_id) {
546 Some(ix) => Some(&mut self.stack[*ix]),
552 pub struct FnCtxt<'a, 'tcx> {
555 /// The parameter environment used for proving trait obligations
556 /// in this function. This can change when we descend into
557 /// closures (as they bring new things into scope), hence it is
558 /// not part of `Inherited` (as of the time of this writing,
559 /// closures do not yet change the environment, but they will
561 param_env: ty::ParamEnv<'tcx>,
563 /// Number of errors that had been reported when we started
564 /// checking this function. On exit, if we find that *more* errors
565 /// have been reported, we will skip regionck and other work that
566 /// expects the types within the function to be consistent.
567 // FIXME(matthewjasper) This should not exist, and it's not correct
568 // if type checking is run in parallel.
569 err_count_on_creation: usize,
571 /// If `Some`, this stores coercion information for returned
572 /// expressions. If `None`, this is in a context where return is
573 /// inappropriate, such as a const expression.
575 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
576 /// can track all the return expressions and then use them to
577 /// compute a useful coercion from the set, similar to a match
578 /// expression or other branching context. You can use methods
579 /// like `expected_ty` to access the declared return type (if
581 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
583 /// First span of a return site that we find. Used in error messages.
584 ret_coercion_span: RefCell<Option<Span>>,
586 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
588 ps: RefCell<UnsafetyState>,
590 /// Whether the last checked node generates a divergence (e.g.,
591 /// `return` will set this to `Always`). In general, when entering
592 /// an expression or other node in the tree, the initial value
593 /// indicates whether prior parts of the containing expression may
594 /// have diverged. It is then typically set to `Maybe` (and the
595 /// old value remembered) for processing the subparts of the
596 /// current expression. As each subpart is processed, they may set
597 /// the flag to `Always`, etc. Finally, at the end, we take the
598 /// result and "union" it with the original value, so that when we
599 /// return the flag indicates if any subpart of the parent
600 /// expression (up to and including this part) has diverged. So,
601 /// if you read it after evaluating a subexpression `X`, the value
602 /// you get indicates whether any subexpression that was
603 /// evaluating up to and including `X` diverged.
605 /// We currently use this flag only for diagnostic purposes:
607 /// - To warn about unreachable code: if, after processing a
608 /// sub-expression but before we have applied the effects of the
609 /// current node, we see that the flag is set to `Always`, we
610 /// can issue a warning. This corresponds to something like
611 /// `foo(return)`; we warn on the `foo()` expression. (We then
612 /// update the flag to `WarnedAlways` to suppress duplicate
613 /// reports.) Similarly, if we traverse to a fresh statement (or
614 /// tail expression) from a `Always` setting, we will issue a
615 /// warning. This corresponds to something like `{return;
616 /// foo();}` or `{return; 22}`, where we would warn on the
619 /// An expression represents dead code if, after checking it,
620 /// the diverges flag is set to something other than `Maybe`.
621 diverges: Cell<Diverges>,
623 /// Whether any child nodes have any type errors.
624 has_errors: Cell<bool>,
626 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
628 inh: &'a Inherited<'a, 'tcx>,
631 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
632 type Target = Inherited<'a, 'tcx>;
633 fn deref(&self) -> &Self::Target {
638 /// Helper type of a temporary returned by `Inherited::build(...)`.
639 /// Necessary because we can't write the following bound:
640 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
641 pub struct InheritedBuilder<'tcx> {
642 infcx: infer::InferCtxtBuilder<'tcx>,
646 impl Inherited<'_, 'tcx> {
647 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
648 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
651 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_owner),
657 impl<'tcx> InheritedBuilder<'tcx> {
658 fn enter<F, R>(&mut self, f: F) -> R
660 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
662 let def_id = self.def_id;
663 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
667 impl Inherited<'a, 'tcx> {
668 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
670 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
671 let body_id = tcx.hir().maybe_body_owned_by(item_id);
674 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
676 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
677 locals: RefCell::new(Default::default()),
678 deferred_sized_obligations: RefCell::new(Vec::new()),
679 deferred_call_resolutions: RefCell::new(Default::default()),
680 deferred_cast_checks: RefCell::new(Vec::new()),
681 deferred_generator_interiors: RefCell::new(Vec::new()),
682 opaque_types: RefCell::new(Default::default()),
683 opaque_types_vars: RefCell::new(Default::default()),
684 implicit_region_bound: None,
689 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
690 debug!("register_predicate({:?})", obligation);
691 if obligation.has_escaping_bound_vars() {
692 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
694 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
697 fn register_predicates<I>(&self, obligations: I)
699 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
701 for obligation in obligations {
702 self.register_predicate(obligation);
706 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
707 self.register_predicates(infer_ok.obligations);
711 fn normalize_associated_types_in<T>(
715 param_env: ty::ParamEnv<'tcx>,
719 T: TypeFoldable<'tcx>,
721 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
722 self.register_infer_ok_obligations(ok)
726 struct CheckItemTypesVisitor<'tcx> {
730 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
731 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
732 check_item_type(self.tcx, i);
734 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
735 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
738 pub fn check_wf_new(tcx: TyCtxt<'_>) {
739 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
740 tcx.hir().krate().par_visit_all_item_likes(&visit);
743 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
744 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
747 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
748 debug_assert!(crate_num == LOCAL_CRATE);
749 tcx.par_body_owners(|body_owner_def_id| {
750 tcx.ensure().typeck_tables_of(body_owner_def_id);
754 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
755 wfcheck::check_item_well_formed(tcx, def_id);
758 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
759 wfcheck::check_trait_item(tcx, def_id);
762 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
763 wfcheck::check_impl_item(tcx, def_id);
766 pub fn provide(providers: &mut Providers<'_>) {
767 method::provide(providers);
768 *providers = Providers {
771 diagnostic_only_typeck_tables_of,
775 check_item_well_formed,
776 check_trait_item_well_formed,
777 check_impl_item_well_formed,
778 check_mod_item_types,
783 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
784 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
787 /// If this `DefId` is a "primary tables entry", returns
788 /// `Some((body_id, header, decl))` with information about
789 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
792 /// If this function returns `Some`, then `typeck_tables(def_id)` will
793 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
794 /// may not succeed. In some cases where this function returns `None`
795 /// (notably closures), `typeck_tables(def_id)` would wind up
796 /// redirecting to the owning function.
800 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
801 match tcx.hir().get(id) {
802 Node::Item(item) => match item.kind {
803 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
804 Some((body, Some(ty), None, None))
806 hir::ItemKind::Fn(ref sig, .., body) => {
807 Some((body, None, Some(&sig.header), Some(&sig.decl)))
811 Node::TraitItem(item) => match item.kind {
812 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
813 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
814 Some((body, None, Some(&sig.header), Some(&sig.decl)))
818 Node::ImplItem(item) => match item.kind {
819 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
820 hir::ImplItemKind::Fn(ref sig, body) => {
821 Some((body, None, Some(&sig.header), Some(&sig.decl)))
825 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
830 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
831 // Closures' tables come from their outermost function,
832 // as they are part of the same "inference environment".
833 let outer_def_id = tcx.closure_base_def_id(def_id);
834 if outer_def_id != def_id {
835 return tcx.has_typeck_tables(outer_def_id);
838 if let Some(def_id) = def_id.as_local() {
839 let id = tcx.hir().local_def_id_to_hir_id(def_id);
840 primary_body_of(tcx, id).is_some()
846 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &DefIdSet {
847 &*tcx.typeck_tables_of(def_id).used_trait_imports
850 /// Inspects the substs of opaque types, replacing any inference variables
851 /// with proper generic parameter from the identity substs.
853 /// This is run after we normalize the function signature, to fix any inference
854 /// variables introduced by the projection of associated types. This ensures that
855 /// any opaque types used in the signature continue to refer to generic parameters,
856 /// allowing them to be considered for defining uses in the function body
858 /// For example, consider this code.
863 /// fn use_it(self) -> Self::MyItem
865 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
866 /// type MyItem = impl Iterator<Item = I>;
867 /// fn use_it(self) -> Self::MyItem {
873 /// When we normalize the signature of `use_it` from the impl block,
874 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
875 /// However, this projection result may contain inference variables, due
876 /// to the way that projection works. We didn't have any inference variables
877 /// in the signature to begin with - leaving them in will cause us to incorrectly
878 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
879 /// variables back to the actual generic parameters, we will correctly see that
880 /// we have a defining use of `MyItem`
881 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
883 T: TypeFoldable<'tcx>,
885 struct FixupFolder<'tcx> {
889 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
890 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
894 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
896 ty::Opaque(def_id, substs) => {
897 debug!("fixup_opaque_types: found type {:?}", ty);
898 // Here, we replace any inference variables that occur within
899 // the substs of an opaque type. By definition, any type occurring
900 // in the substs has a corresponding generic parameter, which is what
901 // we replace it with.
902 // This replacement is only run on the function signature, so any
903 // inference variables that we come across must be the rust of projection
904 // (there's no other way for a user to get inference variables into
905 // a function signature).
906 if ty.needs_infer() {
907 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
908 let old_param = substs[param.index as usize];
909 match old_param.unpack() {
910 GenericArgKind::Type(old_ty) => {
911 if let ty::Infer(_) = old_ty.kind {
912 // Replace inference type with a generic parameter
913 self.tcx.mk_param_from_def(param)
915 old_param.fold_with(self)
918 GenericArgKind::Const(old_const) => {
919 if let ty::ConstKind::Infer(_) = old_const.val {
920 // This should never happen - we currently do not support
921 // 'const projections', e.g.:
922 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
923 // which should be the only way for us to end up with a const inference
924 // variable after projection. If Rust ever gains support for this kind
925 // of projection, this should *probably* be changed to
926 // `self.tcx.mk_param_from_def(param)`
928 "Found infer const: `{:?}` in opaque type: {:?}",
933 old_param.fold_with(self)
936 GenericArgKind::Lifetime(old_region) => {
937 if let RegionKind::ReVar(_) = old_region {
938 self.tcx.mk_param_from_def(param)
940 old_param.fold_with(self)
945 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
946 debug!("fixup_opaque_types: new type: {:?}", new_ty);
952 _ => ty.super_fold_with(self),
957 debug!("fixup_opaque_types({:?})", val);
958 val.fold_with(&mut FixupFolder { tcx })
961 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> {
962 let fallback = move || tcx.type_of(def_id.to_def_id());
963 typeck_tables_of_with_fallback(tcx, def_id, fallback)
966 /// Used only to get `TypeckTables` for type inference during error recovery.
967 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
968 fn diagnostic_only_typeck_tables_of<'tcx>(
971 ) -> &ty::TypeckTables<'tcx> {
972 let fallback = move || {
973 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
974 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
977 typeck_tables_of_with_fallback(tcx, def_id, fallback)
980 fn typeck_tables_of_with_fallback<'tcx>(
983 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
984 ) -> &'tcx ty::TypeckTables<'tcx> {
985 // Closures' tables come from their outermost function,
986 // as they are part of the same "inference environment".
987 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
988 if outer_def_id != def_id {
989 return tcx.typeck_tables_of(outer_def_id);
992 let id = tcx.hir().as_local_hir_id(def_id);
993 let span = tcx.hir().span(id);
995 // Figure out what primary body this item has.
996 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
997 span_bug!(span, "can't type-check body of {:?}", def_id);
999 let body = tcx.hir().body(body_id);
1001 let tables = Inherited::build(tcx, def_id).enter(|inh| {
1002 let param_env = tcx.param_env(def_id);
1003 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1004 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1005 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1011 &hir::Generics::empty(),
1018 check_abi(tcx, span, fn_sig.abi());
1020 // Compute the fty from point of view of inside the fn.
1021 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1022 let fn_sig = inh.normalize_associated_types_in(
1029 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1031 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1034 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1035 let expected_type = body_ty
1036 .and_then(|ty| match ty.kind {
1037 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1040 .unwrap_or_else(fallback);
1041 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1042 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1044 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1045 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1050 // Gather locals in statics (because of block expressions).
1051 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1053 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1055 fcx.write_ty(id, revealed_ty);
1060 // All type checking constraints were added, try to fallback unsolved variables.
1061 fcx.select_obligations_where_possible(false, |_| {});
1062 let mut fallback_has_occurred = false;
1064 // We do fallback in two passes, to try to generate
1065 // better error messages.
1066 // The first time, we do *not* replace opaque types.
1067 for ty in &fcx.unsolved_variables() {
1068 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1070 // We now see if we can make progress. This might
1071 // cause us to unify inference variables for opaque types,
1072 // since we may have unified some other type variables
1073 // during the first phase of fallback.
1074 // This means that we only replace inference variables with their underlying
1075 // opaque types as a last resort.
1077 // In code like this:
1080 // type MyType = impl Copy;
1081 // fn produce() -> MyType { true }
1082 // fn bad_produce() -> MyType { panic!() }
1085 // we want to unify the opaque inference variable in `bad_produce`
1086 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1087 // This will produce a nice error message about conflicting concrete
1088 // types for `MyType`.
1090 // If we had tried to fallback the opaque inference variable to `MyType`,
1091 // we will generate a confusing type-check error that does not explicitly
1092 // refer to opaque types.
1093 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1095 // We now run fallback again, but this time we allow it to replace
1096 // unconstrained opaque type variables, in addition to performing
1097 // other kinds of fallback.
1098 for ty in &fcx.unsolved_variables() {
1099 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1102 // See if we can make any more progress.
1103 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1105 // Even though coercion casts provide type hints, we check casts after fallback for
1106 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1109 // Closure and generator analysis may run after fallback
1110 // because they don't constrain other type variables.
1111 fcx.closure_analyze(body);
1112 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1113 fcx.resolve_generator_interiors(def_id.to_def_id());
1115 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1116 let ty = fcx.normalize_ty(span, ty);
1117 fcx.require_type_is_sized(ty, span, code);
1120 fcx.select_all_obligations_or_error();
1122 if fn_decl.is_some() {
1123 fcx.regionck_fn(id, body);
1125 fcx.regionck_expr(body);
1128 fcx.resolve_type_vars_in_body(body)
1131 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1132 // it will need to hold.
1133 assert_eq!(tables.hir_owner, Some(id.owner));
1138 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1139 if !tcx.sess.target.target.is_abi_supported(abi) {
1144 "The ABI `{}` is not supported for the current target",
1151 struct GatherLocalsVisitor<'a, 'tcx> {
1152 fcx: &'a FnCtxt<'a, 'tcx>,
1153 parent_id: hir::HirId,
1156 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1157 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1160 // Infer the variable's type.
1161 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1162 kind: TypeVariableOriginKind::TypeInference,
1168 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1172 // Take type that the user specified.
1173 self.fcx.locals.borrow_mut().insert(nid, typ);
1180 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1181 type Map = intravisit::ErasedMap<'tcx>;
1183 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1184 NestedVisitorMap::None
1187 // Add explicitly-declared locals.
1188 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1189 let local_ty = match local.ty {
1191 let o_ty = self.fcx.to_ty(&ty);
1193 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1194 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1203 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1205 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1206 ty.hir_id, o_ty, revealed_ty, c_ty
1208 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1210 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1214 self.assign(local.span, local.hir_id, local_ty);
1217 "local variable {:?} is assigned type {}",
1219 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1221 intravisit::walk_local(self, local);
1224 // Add pattern bindings.
1225 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1226 if let PatKind::Binding(_, _, ident, _) = p.kind {
1227 let var_ty = self.assign(p.span, p.hir_id, None);
1229 if !self.fcx.tcx.features().unsized_locals {
1230 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1234 "pattern binding {} is assigned to {} with type {:?}",
1236 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1240 intravisit::walk_pat(self, p);
1243 // Don't descend into the bodies of nested closures.
1246 _: intravisit::FnKind<'tcx>,
1247 _: &'tcx hir::FnDecl<'tcx>,
1255 /// When `check_fn` is invoked on a generator (i.e., a body that
1256 /// includes yield), it returns back some information about the yield
1258 struct GeneratorTypes<'tcx> {
1259 /// Type of generator argument / values returned by `yield`.
1260 resume_ty: Ty<'tcx>,
1262 /// Type of value that is yielded.
1265 /// Types that are captured (see `GeneratorInterior` for more).
1268 /// Indicates if the generator is movable or static (immovable).
1269 movability: hir::Movability,
1272 /// Helper used for fns and closures. Does the grungy work of checking a function
1273 /// body and returns the function context used for that purpose, since in the case of a fn item
1274 /// there is still a bit more to do.
1277 /// * inherited: other fields inherited from the enclosing fn (if any)
1278 fn check_fn<'a, 'tcx>(
1279 inherited: &'a Inherited<'a, 'tcx>,
1280 param_env: ty::ParamEnv<'tcx>,
1281 fn_sig: ty::FnSig<'tcx>,
1282 decl: &'tcx hir::FnDecl<'tcx>,
1284 body: &'tcx hir::Body<'tcx>,
1285 can_be_generator: Option<hir::Movability>,
1286 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1287 let mut fn_sig = fn_sig;
1289 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1291 // Create the function context. This is either derived from scratch or,
1292 // in the case of closures, based on the outer context.
1293 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1294 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1297 let sess = tcx.sess;
1298 let hir = tcx.hir();
1300 let declared_ret_ty = fn_sig.output();
1301 let revealed_ret_ty =
1302 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1303 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1304 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1305 fn_sig = tcx.mk_fn_sig(
1306 fn_sig.inputs().iter().cloned(),
1313 let span = body.value.span;
1315 fn_maybe_err(tcx, span, fn_sig.abi);
1317 if body.generator_kind.is_some() && can_be_generator.is_some() {
1319 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1320 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1322 // Resume type defaults to `()` if the generator has no argument.
1323 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1325 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1328 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
1329 let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1330 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1332 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1333 // (as it's created inside the body itself, not passed in from outside).
1334 let maybe_va_list = if fn_sig.c_variadic {
1335 let span = body.params.last().unwrap().span;
1336 let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
1337 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1339 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1344 // Add formal parameters.
1345 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1346 let inputs_fn = fn_sig.inputs().iter().copied();
1347 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1348 // Check the pattern.
1349 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1351 // Check that argument is Sized.
1352 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1353 // for simple cases like `fn foo(x: Trait)`,
1354 // where we would error once on the parameter as a whole, and once on the binding `x`.
1355 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1356 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1359 fcx.write_ty(param.hir_id, param_ty);
1362 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1364 if let ty::Dynamic(..) = declared_ret_ty.kind {
1365 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1366 // been evaluated so that we have types available for all the nodes being returned, but that
1367 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1368 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1369 // while keeping the current ordering we will ignore the tail expression's type because we
1370 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1371 // because we will trigger "unreachable expression" lints unconditionally.
1372 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1373 // case that a newcomer might make, returning a bare trait, and in that case we populate
1374 // the tail expression's type so that the suggestion will be correct, but ignore all other
1376 fcx.check_expr(&body.value);
1377 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1378 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1380 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1381 fcx.check_return_expr(&body.value);
1384 // We insert the deferred_generator_interiors entry after visiting the body.
1385 // This ensures that all nested generators appear before the entry of this generator.
1386 // resolve_generator_interiors relies on this property.
1387 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1389 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1390 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1392 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1393 Some(GeneratorTypes {
1397 movability: can_be_generator.unwrap(),
1403 // Finalize the return check by taking the LUB of the return types
1404 // we saw and assigning it to the expected return type. This isn't
1405 // really expected to fail, since the coercions would have failed
1406 // earlier when trying to find a LUB.
1408 // However, the behavior around `!` is sort of complex. In the
1409 // event that the `actual_return_ty` comes back as `!`, that
1410 // indicates that the fn either does not return or "returns" only
1411 // values of type `!`. In this case, if there is an expected
1412 // return type that is *not* `!`, that should be ok. But if the
1413 // return type is being inferred, we want to "fallback" to `!`:
1415 // let x = move || panic!();
1417 // To allow for that, I am creating a type variable with diverging
1418 // fallback. This was deemed ever so slightly better than unifying
1419 // the return value with `!` because it allows for the caller to
1420 // make more assumptions about the return type (e.g., they could do
1422 // let y: Option<u32> = Some(x());
1424 // which would then cause this return type to become `u32`, not
1426 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1427 let mut actual_return_ty = coercion.complete(&fcx);
1428 if actual_return_ty.is_never() {
1429 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1430 kind: TypeVariableOriginKind::DivergingFn,
1434 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1436 // Check that the main return type implements the termination trait.
1437 if let Some(term_id) = tcx.lang_items().termination() {
1438 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1439 let main_id = hir.as_local_hir_id(def_id);
1440 if main_id == fn_id {
1441 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1442 let trait_ref = ty::TraitRef::new(term_id, substs);
1443 let return_ty_span = decl.output.span();
1444 let cause = traits::ObligationCause::new(
1447 ObligationCauseCode::MainFunctionType,
1450 inherited.register_predicate(traits::Obligation::new(
1453 trait_ref.without_const().to_predicate(tcx),
1459 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1460 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1461 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1462 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1463 if declared_ret_ty.kind != ty::Never {
1464 sess.span_err(decl.output.span(), "return type should be `!`");
1467 let inputs = fn_sig.inputs();
1468 let span = hir.span(fn_id);
1469 if inputs.len() == 1 {
1470 let arg_is_panic_info = match inputs[0].kind {
1471 ty::Ref(region, ty, mutbl) => match ty.kind {
1472 ty::Adt(ref adt, _) => {
1473 adt.did == panic_info_did
1474 && mutbl == hir::Mutability::Not
1475 && *region != RegionKind::ReStatic
1482 if !arg_is_panic_info {
1483 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1486 if let Node::Item(item) = hir.get(fn_id) {
1487 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1488 if !generics.params.is_empty() {
1489 sess.span_err(span, "should have no type parameters");
1494 let span = sess.source_map().guess_head_span(span);
1495 sess.span_err(span, "function should have one argument");
1498 sess.err("language item required, but not found: `panic_info`");
1503 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1504 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1505 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1506 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1507 if declared_ret_ty.kind != ty::Never {
1508 sess.span_err(decl.output.span(), "return type should be `!`");
1511 let inputs = fn_sig.inputs();
1512 let span = hir.span(fn_id);
1513 if inputs.len() == 1 {
1514 let arg_is_alloc_layout = match inputs[0].kind {
1515 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1519 if !arg_is_alloc_layout {
1520 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1523 if let Node::Item(item) = hir.get(fn_id) {
1524 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1525 if !generics.params.is_empty() {
1528 "`#[alloc_error_handler]` function should have no type \
1535 let span = sess.source_map().guess_head_span(span);
1536 sess.span_err(span, "function should have one argument");
1539 sess.err("language item required, but not found: `alloc_layout`");
1547 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1548 let def_id = tcx.hir().local_def_id(id);
1549 let def = tcx.adt_def(def_id);
1550 def.destructor(tcx); // force the destructor to be evaluated
1551 check_representable(tcx, span, def_id);
1553 if def.repr.simd() {
1554 check_simd(tcx, span, def_id);
1557 check_transparent(tcx, span, def);
1558 check_packed(tcx, span, def);
1561 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1562 let def_id = tcx.hir().local_def_id(id);
1563 let def = tcx.adt_def(def_id);
1564 def.destructor(tcx); // force the destructor to be evaluated
1565 check_representable(tcx, span, def_id);
1566 check_transparent(tcx, span, def);
1567 check_union_fields(tcx, span, def_id);
1568 check_packed(tcx, span, def);
1571 /// When the `#![feature(untagged_unions)]` gate is active,
1572 /// check that the fields of the `union` does not contain fields that need dropping.
1573 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1574 let item_type = tcx.type_of(item_def_id);
1575 if let ty::Adt(def, substs) = item_type.kind {
1576 assert!(def.is_union());
1577 let fields = &def.non_enum_variant().fields;
1578 let param_env = tcx.param_env(item_def_id);
1579 for field in fields {
1580 let field_ty = field.ty(tcx, substs);
1581 // We are currently checking the type this field came from, so it must be local.
1582 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1583 if field_ty.needs_drop(tcx, param_env) {
1588 "unions may not contain fields that need dropping"
1590 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1596 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1601 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1602 /// projections that would result in "inheriting lifetimes".
1603 fn check_opaque<'tcx>(
1606 substs: SubstsRef<'tcx>,
1608 origin: &hir::OpaqueTyOrigin,
1610 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1611 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1614 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1615 /// in "inheriting lifetimes".
1616 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1617 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1619 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1624 struct ProhibitOpaqueVisitor<'tcx> {
1625 opaque_identity_ty: Ty<'tcx>,
1626 generics: &'tcx ty::Generics,
1629 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1630 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1631 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1632 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1635 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1636 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1637 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1638 return *index < self.generics.parent_count as u32;
1641 r.super_visit_with(self)
1644 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1645 if let ty::ConstKind::Unevaluated(..) = c.val {
1646 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1647 // which would violate this check. Even though the particular substitution is not used
1648 // within the const, this should still be fixed.
1651 c.super_visit_with(self)
1655 let prohibit_opaque = match item.kind {
1656 ItemKind::OpaqueTy(hir::OpaqueTy {
1657 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1660 let mut visitor = ProhibitOpaqueVisitor {
1661 opaque_identity_ty: tcx.mk_opaque(
1663 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1665 generics: tcx.generics_of(def_id),
1667 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1669 tcx.predicates_of(def_id)
1672 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1677 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1678 if prohibit_opaque {
1679 let is_async = match item.kind {
1680 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1681 hir::OpaqueTyOrigin::AsyncFn => true,
1684 _ => unreachable!(),
1690 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1692 if is_async { "async fn" } else { "impl Trait" },
1698 /// Checks that an opaque type does not contain cycles.
1699 fn check_opaque_for_cycles<'tcx>(
1702 substs: SubstsRef<'tcx>,
1704 origin: &hir::OpaqueTyOrigin,
1706 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1708 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1709 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1710 .span_label(span, "recursive `async fn`")
1711 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1715 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1716 err.span_label(span, "expands to a recursive type");
1717 if let ty::Opaque(..) = partially_expanded_type.kind {
1718 err.note("type resolves to itself");
1720 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1727 // Forbid defining intrinsics in Rust code,
1728 // as they must always be defined by the compiler.
1729 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1730 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1731 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1735 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1737 "check_item_type(it.hir_id={}, it.name={})",
1739 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1741 let _indenter = indenter();
1743 // Consts can play a role in type-checking, so they are included here.
1744 hir::ItemKind::Static(..) => {
1745 let def_id = tcx.hir().local_def_id(it.hir_id);
1746 tcx.ensure().typeck_tables_of(def_id);
1747 maybe_check_static_with_link_section(tcx, def_id, it.span);
1749 hir::ItemKind::Const(..) => {
1750 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1752 hir::ItemKind::Enum(ref enum_definition, _) => {
1753 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1755 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1756 hir::ItemKind::Impl { ref items, .. } => {
1757 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1758 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1759 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1760 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1761 let trait_def_id = impl_trait_ref.def_id;
1762 check_on_unimplemented(tcx, trait_def_id, it);
1765 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1766 let def_id = tcx.hir().local_def_id(it.hir_id);
1767 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1769 for item in items.iter() {
1770 let item = tcx.hir().trait_item(item.id);
1771 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1772 let abi = sig.header.abi;
1773 fn_maybe_err(tcx, item.ident.span, abi);
1777 hir::ItemKind::Struct(..) => {
1778 check_struct(tcx, it.hir_id, it.span);
1780 hir::ItemKind::Union(..) => {
1781 check_union(tcx, it.hir_id, it.span);
1783 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1784 let def_id = tcx.hir().local_def_id(it.hir_id);
1786 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1787 check_opaque(tcx, def_id, substs, it.span, &origin);
1789 hir::ItemKind::TyAlias(..) => {
1790 let def_id = tcx.hir().local_def_id(it.hir_id);
1791 let pty_ty = tcx.type_of(def_id);
1792 let generics = tcx.generics_of(def_id);
1793 check_type_params_are_used(tcx, &generics, pty_ty);
1795 hir::ItemKind::ForeignMod(ref m) => {
1796 check_abi(tcx, it.span, m.abi);
1798 if m.abi == Abi::RustIntrinsic {
1799 for item in m.items {
1800 intrinsic::check_intrinsic_type(tcx, item);
1802 } else if m.abi == Abi::PlatformIntrinsic {
1803 for item in m.items {
1804 intrinsic::check_platform_intrinsic_type(tcx, item);
1807 for item in m.items {
1808 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1809 let own_counts = generics.own_counts();
1810 if generics.params.len() - own_counts.lifetimes != 0 {
1811 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1812 (_, 0) => ("type", "types", Some("u32")),
1813 // We don't specify an example value, because we can't generate
1814 // a valid value for any type.
1815 (0, _) => ("const", "consts", None),
1816 _ => ("type or const", "types or consts", None),
1822 "foreign items may not have {} parameters",
1825 .span_label(item.span, &format!("can't have {} parameters", kinds))
1827 // FIXME: once we start storing spans for type arguments, turn this
1828 // into a suggestion.
1830 "replace the {} parameters with concrete {}{}",
1833 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1839 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1840 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1845 _ => { /* nothing to do */ }
1849 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1850 // Only restricted on wasm32 target for now
1851 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1855 // If `#[link_section]` is missing, then nothing to verify
1856 let attrs = tcx.codegen_fn_attrs(id);
1857 if attrs.link_section.is_none() {
1861 // For the wasm32 target statics with `#[link_section]` are placed into custom
1862 // sections of the final output file, but this isn't link custom sections of
1863 // other executable formats. Namely we can only embed a list of bytes,
1864 // nothing with pointers to anything else or relocations. If any relocation
1865 // show up, reject them here.
1866 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1867 // the consumer's responsibility to ensure all bytes that have been read
1868 // have defined values.
1869 match tcx.const_eval_poly(id.to_def_id()) {
1870 Ok(ConstValue::ByRef { alloc, .. }) => {
1871 if alloc.relocations().len() != 0 {
1872 let msg = "statics with a custom `#[link_section]` must be a \
1873 simple list of bytes on the wasm target with no \
1874 extra levels of indirection such as references";
1875 tcx.sess.span_err(span, msg);
1878 Ok(_) => bug!("Matching on non-ByRef static"),
1883 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1884 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1885 // an error would be reported if this fails.
1886 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1889 fn report_forbidden_specialization(
1891 impl_item: &hir::ImplItem<'_>,
1894 let mut err = struct_span_err!(
1898 "`{}` specializes an item from a parent `impl`, but \
1899 that item is not marked `default`",
1902 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1904 match tcx.span_of_impl(parent_impl) {
1906 err.span_label(span, "parent `impl` is here");
1908 "to specialize, `{}` in the parent `impl` must be marked `default`",
1913 err.note(&format!("parent implementation is in crate `{}`", cname));
1920 fn check_specialization_validity<'tcx>(
1922 trait_def: &ty::TraitDef,
1923 trait_item: &ty::AssocItem,
1925 impl_item: &hir::ImplItem<'_>,
1927 let kind = match impl_item.kind {
1928 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1929 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1930 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1931 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1934 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1935 Ok(ancestors) => ancestors,
1938 let mut ancestor_impls = ancestors
1940 .filter_map(|parent| {
1941 if parent.is_from_trait() {
1944 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1949 if ancestor_impls.peek().is_none() {
1950 // No parent, nothing to specialize.
1954 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1956 // Parent impl exists, and contains the parent item we're trying to specialize, but
1957 // doesn't mark it `default`.
1958 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1959 Some(Err(parent_impl.def_id()))
1962 // Parent impl contains item and makes it specializable.
1963 Some(_) => Some(Ok(())),
1965 // Parent impl doesn't mention the item. This means it's inherited from the
1966 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1967 // "defaultness" from the grandparent, else they are final.
1969 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1972 Some(Err(parent_impl.def_id()))
1978 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1979 // item. This is allowed, the item isn't actually getting specialized here.
1980 let result = opt_result.unwrap_or(Ok(()));
1982 if let Err(parent_impl) = result {
1983 report_forbidden_specialization(tcx, impl_item, parent_impl);
1987 fn check_impl_items_against_trait<'tcx>(
1989 full_impl_span: Span,
1990 impl_id: LocalDefId,
1991 impl_trait_ref: ty::TraitRef<'tcx>,
1992 impl_item_refs: &[hir::ImplItemRef<'_>],
1994 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1996 // If the trait reference itself is erroneous (so the compilation is going
1997 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1998 // isn't populated for such impls.
1999 if impl_trait_ref.references_error() {
2003 // Negative impls are not expected to have any items
2004 match tcx.impl_polarity(impl_id) {
2005 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2006 ty::ImplPolarity::Negative => {
2007 if let [first_item_ref, ..] = impl_item_refs {
2008 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2013 "negative impls cannot have any items"
2021 // Locate trait definition and items
2022 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2024 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2026 // Check existing impl methods to see if they are both present in trait
2027 // and compatible with trait signature
2028 for impl_item in impl_items() {
2029 let namespace = impl_item.kind.namespace();
2030 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2031 let ty_trait_item = tcx
2032 .associated_items(impl_trait_ref.def_id)
2033 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2035 // Not compatible, but needed for the error message
2036 tcx.associated_items(impl_trait_ref.def_id)
2037 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2041 // Check that impl definition matches trait definition
2042 if let Some(ty_trait_item) = ty_trait_item {
2043 match impl_item.kind {
2044 hir::ImplItemKind::Const(..) => {
2045 // Find associated const definition.
2046 if ty_trait_item.kind == ty::AssocKind::Const {
2055 let mut err = struct_span_err!(
2059 "item `{}` is an associated const, \
2060 which doesn't match its trait `{}`",
2062 impl_trait_ref.print_only_trait_path()
2064 err.span_label(impl_item.span, "does not match trait");
2065 // We can only get the spans from local trait definition
2066 // Same for E0324 and E0325
2067 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2068 err.span_label(trait_span, "item in trait");
2073 hir::ImplItemKind::Fn(..) => {
2074 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2075 if ty_trait_item.kind == ty::AssocKind::Fn {
2076 compare_impl_method(
2085 let mut err = struct_span_err!(
2089 "item `{}` is an associated method, \
2090 which doesn't match its trait `{}`",
2092 impl_trait_ref.print_only_trait_path()
2094 err.span_label(impl_item.span, "does not match trait");
2095 if let Some(trait_span) = opt_trait_span {
2096 err.span_label(trait_span, "item in trait");
2101 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2102 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2103 if ty_trait_item.kind == ty::AssocKind::Type {
2113 let mut err = struct_span_err!(
2117 "item `{}` is an associated type, \
2118 which doesn't match its trait `{}`",
2120 impl_trait_ref.print_only_trait_path()
2122 err.span_label(impl_item.span, "does not match trait");
2123 if let Some(trait_span) = opt_trait_span {
2124 err.span_label(trait_span, "item in trait");
2131 check_specialization_validity(
2135 impl_id.to_def_id(),
2141 // Check for missing items from trait
2142 let mut missing_items = Vec::new();
2143 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2144 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2145 let is_implemented = ancestors
2146 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2147 .map(|node_item| !node_item.defining_node.is_from_trait())
2150 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2151 if !trait_item.defaultness.has_value() {
2152 missing_items.push(*trait_item);
2158 if !missing_items.is_empty() {
2159 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2163 fn missing_items_err(
2166 missing_items: &[ty::AssocItem],
2167 full_impl_span: Span,
2169 let missing_items_msg = missing_items
2171 .map(|trait_item| trait_item.ident.to_string())
2172 .collect::<Vec<_>>()
2175 let mut err = struct_span_err!(
2179 "not all trait items implemented, missing: `{}`",
2182 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2184 // `Span` before impl block closing brace.
2185 let hi = full_impl_span.hi() - BytePos(1);
2186 // Point at the place right before the closing brace of the relevant `impl` to suggest
2187 // adding the associated item at the end of its body.
2188 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2189 // Obtain the level of indentation ending in `sugg_sp`.
2190 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2191 // Make the whitespace that will make the suggestion have the right indentation.
2192 let padding: String = (0..indentation).map(|_| " ").collect();
2194 for trait_item in missing_items {
2195 let snippet = suggestion_signature(&trait_item, tcx);
2196 let code = format!("{}{}\n{}", padding, snippet, padding);
2197 let msg = format!("implement the missing item: `{}`", snippet);
2198 let appl = Applicability::HasPlaceholders;
2199 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2200 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2201 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2203 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2209 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2210 fn bounds_from_generic_predicates(
2212 predicates: ty::GenericPredicates<'_>,
2213 ) -> (String, String) {
2214 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2215 let mut projections = vec![];
2216 for (predicate, _) in predicates.predicates {
2217 debug!("predicate {:?}", predicate);
2218 match predicate.kind() {
2219 ty::PredicateKind::Trait(trait_predicate, _) => {
2220 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2221 let def_id = trait_predicate.skip_binder().def_id();
2222 if Some(def_id) != tcx.lang_items().sized_trait() {
2223 // Type params are `Sized` by default, do not add that restriction to the list
2224 // if it is a positive requirement.
2225 entry.push(trait_predicate.skip_binder().def_id());
2228 ty::PredicateKind::Projection(projection_pred) => {
2229 projections.push(projection_pred);
2234 let generics = if types.is_empty() {
2241 .filter_map(|t| match t.kind {
2242 ty::Param(_) => Some(t.to_string()),
2243 // Avoid suggesting the following:
2244 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2247 .collect::<Vec<_>>()
2251 let mut where_clauses = vec![];
2252 for (ty, bounds) in types {
2253 for bound in &bounds {
2254 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2257 for projection in &projections {
2258 let p = projection.skip_binder();
2259 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2260 // insert the associated types where they correspond, but for now let's be "lazy" and
2261 // propose this instead of the following valid resugaring:
2262 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2263 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2265 let where_clauses = if where_clauses.is_empty() {
2268 format!(" where {}", where_clauses.join(", "))
2270 (generics, where_clauses)
2273 /// Return placeholder code for the given function.
2274 fn fn_sig_suggestion(
2276 sig: &ty::FnSig<'_>,
2278 predicates: ty::GenericPredicates<'_>,
2279 assoc: &ty::AssocItem,
2286 Some(match ty.kind {
2287 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2288 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2289 let reg = match &format!("{}", reg)[..] {
2290 "'_" | "" => String::new(),
2291 reg => format!("{} ", reg),
2293 if assoc.fn_has_self_parameter {
2295 ty::Param(param) if param.name == kw::SelfUpper => {
2296 format!("&{}{}self", reg, mutability.prefix_str())
2299 _ => format!("self: {}", ty),
2302 format!("_: {:?}", ty)
2306 if assoc.fn_has_self_parameter && i == 0 {
2307 format!("self: {:?}", ty)
2309 format!("_: {:?}", ty)
2314 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2315 .filter_map(|arg| arg)
2316 .collect::<Vec<String>>()
2318 let output = sig.output();
2319 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2321 let unsafety = sig.unsafety.prefix_str();
2322 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2324 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2325 // not be present in the `fn` definition, not will we account for renamed
2326 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2327 // fill in a significant portion of the missing code, and other subsequent
2328 // suggestions can help the user fix the code.
2330 "{}fn {}{}({}){}{} {{ todo!() }}",
2331 unsafety, ident, generics, args, output, where_clauses
2335 /// Return placeholder code for the given associated item.
2336 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2337 /// structured suggestion.
2338 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2340 ty::AssocKind::Fn => {
2341 // We skip the binder here because the binder would deanonymize all
2342 // late-bound regions, and we don't want method signatures to show up
2343 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2344 // regions just fine, showing `fn(&MyType)`.
2347 tcx.fn_sig(assoc.def_id).skip_binder(),
2349 tcx.predicates_of(assoc.def_id),
2353 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2354 // FIXME(type_alias_impl_trait): we should print bounds here too.
2355 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2356 ty::AssocKind::Const => {
2357 let ty = tcx.type_of(assoc.def_id);
2358 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2359 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2364 /// Checks whether a type can be represented in memory. In particular, it
2365 /// identifies types that contain themselves without indirection through a
2366 /// pointer, which would mean their size is unbounded.
2367 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2368 let rty = tcx.type_of(item_def_id);
2370 // Check that it is possible to represent this type. This call identifies
2371 // (1) types that contain themselves and (2) types that contain a different
2372 // recursive type. It is only necessary to throw an error on those that
2373 // contain themselves. For case 2, there must be an inner type that will be
2374 // caught by case 1.
2375 match rty.is_representable(tcx, sp) {
2376 Representability::SelfRecursive(spans) => {
2377 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2379 err.span_label(span, "recursive without indirection");
2384 Representability::Representable | Representability::ContainsRecursive => (),
2389 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2390 let t = tcx.type_of(def_id);
2391 if let ty::Adt(def, substs) = t.kind {
2392 if def.is_struct() {
2393 let fields = &def.non_enum_variant().fields;
2394 if fields.is_empty() {
2395 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2398 let e = fields[0].ty(tcx, substs);
2399 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2400 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2401 .span_label(sp, "SIMD elements must have the same type")
2406 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2407 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2413 "SIMD vector element type should be machine type"
2423 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2424 let repr = def.repr;
2426 for attr in tcx.get_attrs(def.did).iter() {
2427 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2428 if let attr::ReprPacked(pack) = r {
2429 if let Some(repr_pack) = repr.pack {
2430 if pack as u64 != repr_pack.bytes() {
2435 "type has conflicting packed representation hints"
2443 if repr.align.is_some() {
2448 "type has conflicting packed and align representation hints"
2452 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2453 let mut err = struct_span_err!(
2457 "packed type cannot transitively contain a `#[repr(align)]` type"
2460 let hir = tcx.hir();
2461 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2462 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2464 tcx.def_span(def_spans[0].0),
2465 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2469 if def_spans.len() > 2 {
2470 let mut first = true;
2471 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2472 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2473 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2478 "`{}` contains a field of type `{}`",
2479 tcx.type_of(def.did),
2483 format!("...which contains a field of type `{}`", ident)
2497 fn check_packed_inner(
2500 stack: &mut Vec<DefId>,
2501 ) -> Option<Vec<(DefId, Span)>> {
2502 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2503 if def.is_struct() || def.is_union() {
2504 if def.repr.align.is_some() {
2505 return Some(vec![(def.did, DUMMY_SP)]);
2509 for field in &def.non_enum_variant().fields {
2510 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2511 if !stack.contains(&def.did) {
2512 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2513 defs.push((def.did, field.ident.span));
2526 /// Emit an error when encountering more or less than one variant in a transparent enum.
2527 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2528 let variant_spans: Vec<_> = adt
2531 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2533 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2534 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2535 err.span_label(sp, &msg);
2536 if let [start @ .., end] = &*variant_spans {
2537 for variant_span in start {
2538 err.span_label(*variant_span, "");
2540 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2545 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2547 fn bad_non_zero_sized_fields<'tcx>(
2549 adt: &'tcx ty::AdtDef,
2551 field_spans: impl Iterator<Item = Span>,
2554 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2555 let mut err = struct_span_err!(
2559 "{}transparent {} {}",
2560 if adt.is_enum() { "the variant of a " } else { "" },
2564 err.span_label(sp, &msg);
2565 for sp in field_spans {
2566 err.span_label(sp, "this field is non-zero-sized");
2571 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2572 if !adt.repr.transparent() {
2575 let sp = tcx.sess.source_map().guess_head_span(sp);
2577 if adt.is_union() && !tcx.features().transparent_unions {
2579 &tcx.sess.parse_sess,
2580 sym::transparent_unions,
2582 "transparent unions are unstable",
2587 if adt.variants.len() != 1 {
2588 bad_variant_count(tcx, adt, sp, adt.did);
2589 if adt.variants.is_empty() {
2590 // Don't bother checking the fields. No variants (and thus no fields) exist.
2595 // For each field, figure out if it's known to be a ZST and align(1)
2596 let field_infos = adt.all_fields().map(|field| {
2597 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2598 let param_env = tcx.param_env(field.did);
2599 let layout = tcx.layout_of(param_env.and(ty));
2600 // We are currently checking the type this field came from, so it must be local
2601 let span = tcx.hir().span_if_local(field.did).unwrap();
2602 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2603 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2607 let non_zst_fields =
2608 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2609 let non_zst_count = non_zst_fields.clone().count();
2610 if non_zst_count != 1 {
2611 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2613 for (span, zst, align1) in field_infos {
2619 "zero-sized field in transparent {} has alignment larger than 1",
2622 .span_label(span, "has alignment larger than 1")
2628 #[allow(trivial_numeric_casts)]
2629 pub fn check_enum<'tcx>(
2632 vs: &'tcx [hir::Variant<'tcx>],
2635 let def_id = tcx.hir().local_def_id(id);
2636 let def = tcx.adt_def(def_id);
2637 def.destructor(tcx); // force the destructor to be evaluated
2640 let attributes = tcx.get_attrs(def_id.to_def_id());
2641 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2646 "unsupported representation for zero-variant enum"
2648 .span_label(sp, "zero-variant enum")
2653 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2654 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2655 if !tcx.features().repr128 {
2657 &tcx.sess.parse_sess,
2660 "repr with 128-bit type is unstable",
2667 if let Some(ref e) = v.disr_expr {
2668 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2672 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2673 let is_unit = |var: &hir::Variant<'_>| match var.data {
2674 hir::VariantData::Unit(..) => true,
2678 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2679 let has_non_units = vs.iter().any(|var| !is_unit(var));
2680 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2681 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2683 if disr_non_unit || (disr_units && has_non_units) {
2685 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2690 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2691 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2692 // Check for duplicate discriminant values
2693 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2694 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2695 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2696 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2697 let i_span = match variant_i.disr_expr {
2698 Some(ref expr) => tcx.hir().span(expr.hir_id),
2699 None => tcx.hir().span(variant_i_hir_id),
2701 let span = match v.disr_expr {
2702 Some(ref expr) => tcx.hir().span(expr.hir_id),
2709 "discriminant value `{}` already exists",
2712 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2713 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2716 disr_vals.push(discr);
2719 check_representable(tcx, sp, def_id);
2720 check_transparent(tcx, sp, def);
2723 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2728 "expected unit struct, unit variant or constant, found {}{}",
2730 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2735 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2736 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2740 fn item_def_id(&self) -> Option<DefId> {
2744 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2745 // FIXME: refactor this into a method
2746 let node = self.tcx.hir().get(self.body_id);
2747 if let Some(fn_like) = FnLikeNode::from_node(node) {
2750 hir::Constness::NotConst
2754 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2756 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2757 let item_id = tcx.hir().ty_param_owner(hir_id);
2758 let item_def_id = tcx.hir().local_def_id(item_id);
2759 let generics = tcx.generics_of(item_def_id);
2760 let index = generics.param_def_id_to_index[&def_id];
2761 ty::GenericPredicates {
2763 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2764 |predicate| match predicate.kind() {
2765 ty::PredicateKind::Trait(ref data, _)
2766 if data.skip_binder().self_ty().is_param(index) =>
2768 // HACK(eddyb) should get the original `Span`.
2769 let span = tcx.def_span(def_id);
2770 Some((predicate, span))
2778 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2780 Some(def) => infer::EarlyBoundRegion(span, def.name),
2781 None => infer::MiscVariable(span),
2783 Some(self.next_region_var(v))
2786 fn allow_ty_infer(&self) -> bool {
2790 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2791 if let Some(param) = param {
2792 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2797 self.next_ty_var(TypeVariableOrigin {
2798 kind: TypeVariableOriginKind::TypeInference,
2807 param: Option<&ty::GenericParamDef>,
2809 ) -> &'tcx Const<'tcx> {
2810 if let Some(param) = param {
2811 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2816 self.next_const_var(
2818 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2823 fn projected_ty_from_poly_trait_ref(
2827 item_segment: &hir::PathSegment<'_>,
2828 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2830 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2832 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2836 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2845 self.tcx().mk_projection(item_def_id, item_substs)
2848 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2849 if ty.has_escaping_bound_vars() {
2850 ty // FIXME: normalization and escaping regions
2852 self.normalize_associated_types_in(span, &ty)
2856 fn set_tainted_by_errors(&self) {
2857 self.infcx.set_tainted_by_errors()
2860 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2861 self.write_ty(hir_id, ty)
2865 /// Controls whether the arguments are tupled. This is used for the call
2868 /// Tupling means that all call-side arguments are packed into a tuple and
2869 /// passed as a single parameter. For example, if tupling is enabled, this
2872 /// fn f(x: (isize, isize))
2874 /// Can be called as:
2881 #[derive(Clone, Eq, PartialEq)]
2882 enum TupleArgumentsFlag {
2887 /// Controls how we perform fallback for unconstrained
2890 /// Do not fallback type variables to opaque types.
2892 /// Perform all possible kinds of fallback, including
2893 /// turning type variables to opaque types.
2897 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2899 inh: &'a Inherited<'a, 'tcx>,
2900 param_env: ty::ParamEnv<'tcx>,
2901 body_id: hir::HirId,
2902 ) -> FnCtxt<'a, 'tcx> {
2906 err_count_on_creation: inh.tcx.sess.err_count(),
2908 ret_coercion_span: RefCell::new(None),
2909 resume_yield_tys: None,
2910 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2911 diverges: Cell::new(Diverges::Maybe),
2912 has_errors: Cell::new(false),
2913 enclosing_breakables: RefCell::new(EnclosingBreakables {
2915 by_id: Default::default(),
2921 pub fn sess(&self) -> &Session {
2925 pub fn errors_reported_since_creation(&self) -> bool {
2926 self.tcx.sess.err_count() > self.err_count_on_creation
2929 /// Produces warning on the given node, if the current point in the
2930 /// function is unreachable, and there hasn't been another warning.
2931 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2932 // FIXME: Combine these two 'if' expressions into one once
2933 // let chains are implemented
2934 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2935 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2936 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2937 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2938 if !span.is_desugaring(DesugaringKind::CondTemporary)
2939 && !span.is_desugaring(DesugaringKind::Async)
2940 && !orig_span.is_desugaring(DesugaringKind::Await)
2942 self.diverges.set(Diverges::WarnedAlways);
2944 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2946 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2947 let msg = format!("unreachable {}", kind);
2949 .span_label(span, &msg)
2953 .unwrap_or("any code following this expression is unreachable"),
2961 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2962 ObligationCause::new(span, self.body_id, code)
2965 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2966 self.cause(span, ObligationCauseCode::MiscObligation)
2969 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2970 /// version (resolve_vars_if_possible), this version will
2971 /// also select obligations if it seems useful, in an effort
2972 /// to get more type information.
2973 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2974 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2976 // No Infer()? Nothing needs doing.
2977 if !ty.has_infer_types_or_consts() {
2978 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2982 // If `ty` is a type variable, see whether we already know what it is.
2983 ty = self.resolve_vars_if_possible(&ty);
2984 if !ty.has_infer_types_or_consts() {
2985 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2989 // If not, try resolving pending obligations as much as
2990 // possible. This can help substantially when there are
2991 // indirect dependencies that don't seem worth tracking
2993 self.select_obligations_where_possible(false, |_| {});
2994 ty = self.resolve_vars_if_possible(&ty);
2996 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3000 fn record_deferred_call_resolution(
3002 closure_def_id: DefId,
3003 r: DeferredCallResolution<'tcx>,
3005 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3006 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3009 fn remove_deferred_call_resolutions(
3011 closure_def_id: DefId,
3012 ) -> Vec<DeferredCallResolution<'tcx>> {
3013 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3014 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3017 pub fn tag(&self) -> String {
3018 format!("{:p}", self)
3021 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3022 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3023 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3028 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3030 "write_ty({:?}, {:?}) in fcx {}",
3032 self.resolve_vars_if_possible(&ty),
3035 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3037 if ty.references_error() {
3038 self.has_errors.set(true);
3039 self.set_tainted_by_errors();
3043 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3044 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3047 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3048 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3051 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3052 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3053 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3054 self.write_substs(hir_id, method.substs);
3056 // When the method is confirmed, the `method.substs` includes
3057 // parameters from not just the method, but also the impl of
3058 // the method -- in particular, the `Self` type will be fully
3059 // resolved. However, those are not something that the "user
3060 // specified" -- i.e., those types come from the inferred type
3061 // of the receiver, not something the user wrote. So when we
3062 // create the user-substs, we want to replace those earlier
3063 // types with just the types that the user actually wrote --
3064 // that is, those that appear on the *method itself*.
3066 // As an example, if the user wrote something like
3067 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3068 // type of `foo` (possibly adjusted), but we don't want to
3069 // include that. We want just the `[_, u32]` part.
3070 if !method.substs.is_noop() {
3071 let method_generics = self.tcx.generics_of(method.def_id);
3072 if !method_generics.params.is_empty() {
3073 let user_type_annotation = self.infcx.probe(|_| {
3074 let user_substs = UserSubsts {
3075 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3076 let i = param.index as usize;
3077 if i < method_generics.parent_count {
3078 self.infcx.var_for_def(DUMMY_SP, param)
3083 user_self_ty: None, // not relevant here
3086 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3092 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3093 self.write_user_type_annotation(hir_id, user_type_annotation);
3098 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3099 if !substs.is_noop() {
3100 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3102 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3106 /// Given the substs that we just converted from the HIR, try to
3107 /// canonicalize them and store them as user-given substitutions
3108 /// (i.e., substitutions that must be respected by the NLL check).
3110 /// This should be invoked **before any unifications have
3111 /// occurred**, so that annotations like `Vec<_>` are preserved
3113 pub fn write_user_type_annotation_from_substs(
3117 substs: SubstsRef<'tcx>,
3118 user_self_ty: Option<UserSelfTy<'tcx>>,
3121 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3122 user_self_ty={:?} in fcx {}",
3130 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3131 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3133 UserSubsts { substs, user_self_ty },
3135 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3136 self.write_user_type_annotation(hir_id, canonicalized);
3140 pub fn write_user_type_annotation(
3143 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3146 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3148 canonical_user_type_annotation,
3152 if !canonical_user_type_annotation.is_identity() {
3155 .user_provided_types_mut()
3156 .insert(hir_id, canonical_user_type_annotation);
3158 debug!("write_user_type_annotation: skipping identity substs");
3162 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3163 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3169 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3170 Entry::Vacant(entry) => {
3173 Entry::Occupied(mut entry) => {
3174 debug!(" - composing on top of {:?}", entry.get());
3175 match (&entry.get()[..], &adj[..]) {
3176 // Applying any adjustment on top of a NeverToAny
3177 // is a valid NeverToAny adjustment, because it can't
3179 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3181 Adjustment { kind: Adjust::Deref(_), .. },
3182 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3184 Adjustment { kind: Adjust::Deref(_), .. },
3185 .. // Any following adjustments are allowed.
3187 // A reborrow has no effect before a dereference.
3189 // FIXME: currently we never try to compose autoderefs
3190 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3192 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3193 expr, entry.get(), adj)
3195 *entry.get_mut() = adj;
3200 /// Basically whenever we are converting from a type scheme into
3201 /// the fn body space, we always want to normalize associated
3202 /// types as well. This function combines the two.
3203 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3205 T: TypeFoldable<'tcx>,
3207 let value = value.subst(self.tcx, substs);
3208 let result = self.normalize_associated_types_in(span, &value);
3209 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3213 /// As `instantiate_type_scheme`, but for the bounds found in a
3214 /// generic type scheme.
3215 fn instantiate_bounds(
3219 substs: SubstsRef<'tcx>,
3220 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3221 let bounds = self.tcx.predicates_of(def_id);
3222 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3223 let result = bounds.instantiate(self.tcx, substs);
3224 let result = self.normalize_associated_types_in(span, &result);
3226 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3227 bounds, substs, result, spans,
3232 /// Replaces the opaque types from the given value with type variables,
3233 /// and records the `OpaqueTypeMap` for later use during writeback. See
3234 /// `InferCtxt::instantiate_opaque_types` for more details.
3235 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3237 parent_id: hir::HirId,
3241 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3243 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3244 parent_def_id, value
3247 let (value, opaque_type_map) =
3248 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3249 parent_def_id.to_def_id(),
3256 let mut opaque_types = self.opaque_types.borrow_mut();
3257 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3258 for (ty, decl) in opaque_type_map {
3259 let _ = opaque_types.insert(ty, decl);
3260 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3266 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3268 T: TypeFoldable<'tcx>,
3270 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3273 fn normalize_associated_types_in_as_infer_ok<T>(
3277 ) -> InferOk<'tcx, T>
3279 T: TypeFoldable<'tcx>,
3281 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3284 pub fn require_type_meets(
3288 code: traits::ObligationCauseCode<'tcx>,
3291 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3294 pub fn require_type_is_sized(
3298 code: traits::ObligationCauseCode<'tcx>,
3300 if !ty.references_error() {
3301 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3302 self.require_type_meets(ty, span, code, lang_item);
3306 pub fn require_type_is_sized_deferred(
3310 code: traits::ObligationCauseCode<'tcx>,
3312 if !ty.references_error() {
3313 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3317 pub fn register_bound(
3321 cause: traits::ObligationCause<'tcx>,
3323 if !ty.references_error() {
3324 self.fulfillment_cx.borrow_mut().register_bound(
3334 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3335 let t = AstConv::ast_ty_to_ty(self, ast_t);
3336 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3340 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3341 let ty = self.to_ty(ast_ty);
3342 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3344 if Self::can_contain_user_lifetime_bounds(ty) {
3345 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3346 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3347 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3353 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3354 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3355 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3357 // HACK(eddyb) emulate what a `WellFormedConst` obligation would do.
3358 // This code should be replaced with the proper WF handling ASAP.
3359 if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
3360 assert!(promoted.is_none());
3362 // HACK(eddyb) let's hope these are always empty.
3363 // let obligations = self.nominal_obligations(def_id, substs);
3364 // self.out.extend(obligations);
3366 let cause = traits::ObligationCause::new(
3367 self.tcx.def_span(const_def_id.to_def_id()),
3369 traits::MiscObligation,
3371 self.register_predicate(traits::Obligation::new(
3374 ty::PredicateKind::ConstEvaluatable(def_id, substs).to_predicate(self.tcx),
3381 // If the type given by the user has free regions, save it for later, since
3382 // NLL would like to enforce those. Also pass in types that involve
3383 // projections, since those can resolve to `'static` bounds (modulo #54940,
3384 // which hopefully will be fixed by the time you see this comment, dear
3385 // reader, although I have my doubts). Also pass in types with inference
3386 // types, because they may be repeated. Other sorts of things are already
3387 // sufficiently enforced with erased regions. =)
3388 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3390 T: TypeFoldable<'tcx>,
3392 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3395 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3396 match self.tables.borrow().node_types().get(id) {
3398 None if self.is_tainted_by_errors() => self.tcx.types.err,
3401 "no type for node {}: {} in fcx {}",
3403 self.tcx.hir().node_to_string(id),
3410 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3411 /// outlive the region `r`.
3412 pub fn register_wf_obligation(
3416 code: traits::ObligationCauseCode<'tcx>,
3418 // WF obligations never themselves fail, so no real need to give a detailed cause:
3419 let cause = traits::ObligationCause::new(span, self.body_id, code);
3420 self.register_predicate(traits::Obligation::new(
3423 ty::PredicateKind::WellFormed(ty).to_predicate(self.tcx),
3427 /// Registers obligations that all types appearing in `substs` are well-formed.
3428 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3429 for ty in substs.types() {
3430 if !ty.references_error() {
3431 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3436 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3437 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3438 /// trait/region obligations.
3440 /// For example, if there is a function:
3443 /// fn foo<'a,T:'a>(...)
3446 /// and a reference:
3452 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3453 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3454 pub fn add_obligations_for_parameters(
3456 cause: traits::ObligationCause<'tcx>,
3457 predicates: ty::InstantiatedPredicates<'tcx>,
3459 assert!(!predicates.has_escaping_bound_vars());
3461 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3463 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3464 self.register_predicate(obligation);
3468 // FIXME(arielb1): use this instead of field.ty everywhere
3469 // Only for fields! Returns <none> for methods>
3470 // Indifferent to privacy flags
3474 field: &'tcx ty::FieldDef,
3475 substs: SubstsRef<'tcx>,
3477 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3480 fn check_casts(&self) {
3481 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3482 for cast in deferred_cast_checks.drain(..) {
3487 fn resolve_generator_interiors(&self, def_id: DefId) {
3488 let mut generators = self.deferred_generator_interiors.borrow_mut();
3489 for (body_id, interior, kind) in generators.drain(..) {
3490 self.select_obligations_where_possible(false, |_| {});
3491 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3495 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3497 // - Unconstrained ints are replaced with `i32`.
3499 // - Unconstrained floats are replaced with with `f64`.
3501 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3502 // is enabled. Otherwise, they are replaced with `()`.
3504 // Fallback becomes very dubious if we have encountered type-checking errors.
3505 // In that case, fallback to Error.
3506 // The return value indicates whether fallback has occurred.
3507 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3508 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3509 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3511 assert!(ty.is_ty_infer());
3512 let fallback = match self.type_is_unconstrained_numeric(ty) {
3513 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3514 UnconstrainedInt => self.tcx.types.i32,
3515 UnconstrainedFloat => self.tcx.types.f64,
3516 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3518 // This type variable was created from the instantiation of an opaque
3519 // type. The fact that we're attempting to perform fallback for it
3520 // means that the function neither constrained it to a concrete
3521 // type, nor to the opaque type itself.
3523 // For example, in this code:
3526 // type MyType = impl Copy;
3527 // fn defining_use() -> MyType { true }
3528 // fn other_use() -> MyType { defining_use() }
3531 // `defining_use` will constrain the instantiated inference
3532 // variable to `bool`, while `other_use` will constrain
3533 // the instantiated inference variable to `MyType`.
3535 // When we process opaque types during writeback, we
3536 // will handle cases like `other_use`, and not count
3537 // them as defining usages
3539 // However, we also need to handle cases like this:
3542 // pub type Foo = impl Copy;
3543 // fn produce() -> Option<Foo> {
3548 // In the above snippet, the inference variable created by
3549 // instantiating `Option<Foo>` will be completely unconstrained.
3550 // We treat this as a non-defining use by making the inference
3551 // variable fall back to the opaque type itself.
3552 if let FallbackMode::All = mode {
3553 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3555 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3567 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3568 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3572 fn select_all_obligations_or_error(&self) {
3573 debug!("select_all_obligations_or_error");
3574 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3575 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3579 /// Select as many obligations as we can at present.
3580 fn select_obligations_where_possible(
3582 fallback_has_occurred: bool,
3583 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3585 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3586 if let Err(mut errors) = result {
3587 mutate_fullfillment_errors(&mut errors);
3588 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3592 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3593 /// returns a type of `&T`, but the actual type we assign to the
3594 /// *expression* is `T`. So this function just peels off the return
3595 /// type by one layer to yield `T`.
3596 fn make_overloaded_place_return_type(
3598 method: MethodCallee<'tcx>,
3599 ) -> ty::TypeAndMut<'tcx> {
3600 // extract method return type, which will be &T;
3601 let ret_ty = method.sig.output();
3603 // method returns &T, but the type as visible to user is T, so deref
3604 ret_ty.builtin_deref(true).unwrap()
3609 expr: &hir::Expr<'_>,
3610 base_expr: &'tcx hir::Expr<'tcx>,
3614 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3615 // FIXME(#18741) -- this is almost but not quite the same as the
3616 // autoderef that normal method probing does. They could likely be
3619 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3620 let mut result = None;
3621 while result.is_none() && autoderef.next().is_some() {
3622 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3624 autoderef.finalize(self);
3628 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3629 /// (and otherwise adjust) `base_expr`, looking for a type which either
3630 /// supports builtin indexing or overloaded indexing.
3631 /// This loop implements one step in that search; the autoderef loop
3632 /// is implemented by `lookup_indexing`.
3635 expr: &hir::Expr<'_>,
3636 base_expr: &hir::Expr<'_>,
3637 autoderef: &Autoderef<'a, 'tcx>,
3640 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3641 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3643 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3645 expr, base_expr, adjusted_ty, index_ty
3648 for &unsize in &[false, true] {
3649 let mut self_ty = adjusted_ty;
3651 // We only unsize arrays here.
3652 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3653 self_ty = self.tcx.mk_slice(element_ty);
3659 // If some lookup succeeds, write callee into table and extract index/element
3660 // type from the method signature.
3661 // If some lookup succeeded, install method in table
3662 let input_ty = self.next_ty_var(TypeVariableOrigin {
3663 kind: TypeVariableOriginKind::AutoDeref,
3664 span: base_expr.span,
3666 let method = self.try_overloaded_place_op(
3674 let result = method.map(|ok| {
3675 debug!("try_index_step: success, using overloaded indexing");
3676 let method = self.register_infer_ok_obligations(ok);
3678 let mut adjustments = autoderef.adjust_steps(self, needs);
3679 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3680 let mutbl = match r_mutbl {
3681 hir::Mutability::Not => AutoBorrowMutability::Not,
3682 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3683 // Indexing can be desugared to a method call,
3684 // so maybe we could use two-phase here.
3685 // See the documentation of AllowTwoPhase for why that's
3686 // not the case today.
3687 allow_two_phase_borrow: AllowTwoPhase::No,
3690 adjustments.push(Adjustment {
3691 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3694 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3698 adjustments.push(Adjustment {
3699 kind: Adjust::Pointer(PointerCast::Unsize),
3700 target: method.sig.inputs()[0],
3703 self.apply_adjustments(base_expr, adjustments);
3705 self.write_method_call(expr.hir_id, method);
3706 (input_ty, self.make_overloaded_place_return_type(method).ty)
3708 if result.is_some() {
3716 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
3717 let (tr, name) = match (op, is_mut) {
3718 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3719 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3720 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3721 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3723 (tr, Ident::with_dummy_span(name))
3726 fn try_overloaded_place_op(
3730 arg_tys: &[Ty<'tcx>],
3733 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3734 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3736 // Try Mut first, if needed.
3737 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3738 let method = match (needs, mut_tr) {
3739 (Needs::MutPlace, Some(trait_did)) => {
3740 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3745 // Otherwise, fall back to the immutable version.
3746 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3747 match (method, imm_tr) {
3748 (None, Some(trait_did)) => {
3749 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3751 (method, _) => method,
3755 fn check_method_argument_types(
3758 expr: &'tcx hir::Expr<'tcx>,
3759 method: Result<MethodCallee<'tcx>, ()>,
3760 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3761 tuple_arguments: TupleArgumentsFlag,
3762 expected: Expectation<'tcx>,
3764 let has_error = match method {
3765 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3769 let err_inputs = self.err_args(args_no_rcvr.len());
3771 let err_inputs = match tuple_arguments {
3772 DontTupleArguments => err_inputs,
3773 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3776 self.check_argument_types(
3786 return self.tcx.types.err;
3789 let method = method.unwrap();
3790 // HACK(eddyb) ignore self in the definition (see above).
3791 let expected_arg_tys = self.expected_inputs_for_expected_output(
3794 method.sig.output(),
3795 &method.sig.inputs()[1..],
3797 self.check_argument_types(
3800 &method.sig.inputs()[1..],
3801 &expected_arg_tys[..],
3803 method.sig.c_variadic,
3805 self.tcx.hir().span_if_local(method.def_id),
3810 fn self_type_matches_expected_vid(
3812 trait_ref: ty::PolyTraitRef<'tcx>,
3813 expected_vid: ty::TyVid,
3815 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3817 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3818 trait_ref, self_ty, expected_vid
3820 match self_ty.kind {
3821 ty::Infer(ty::TyVar(found_vid)) => {
3822 // FIXME: consider using `sub_root_var` here so we
3823 // can see through subtyping.
3824 let found_vid = self.root_var(found_vid);
3825 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3826 expected_vid == found_vid
3832 fn obligations_for_self_ty<'b>(
3835 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3838 // FIXME: consider using `sub_root_var` here so we
3839 // can see through subtyping.
3840 let ty_var_root = self.root_var(self_ty);
3842 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3845 self.fulfillment_cx.borrow().pending_obligations()
3850 .pending_obligations()
3852 .filter_map(move |obligation| match obligation.predicate.kind() {
3853 ty::PredicateKind::Projection(ref data) => {
3854 Some((data.to_poly_trait_ref(self.tcx), obligation))
3856 ty::PredicateKind::Trait(ref data, _) => {
3857 Some((data.to_poly_trait_ref(), obligation))
3859 ty::PredicateKind::Subtype(..) => None,
3860 ty::PredicateKind::RegionOutlives(..) => None,
3861 ty::PredicateKind::TypeOutlives(..) => None,
3862 ty::PredicateKind::WellFormed(..) => None,
3863 ty::PredicateKind::ObjectSafe(..) => None,
3864 ty::PredicateKind::ConstEvaluatable(..) => None,
3865 ty::PredicateKind::ConstEquate(..) => None,
3866 // N.B., this predicate is created by breaking down a
3867 // `ClosureType: FnFoo()` predicate, where
3868 // `ClosureType` represents some `Closure`. It can't
3869 // possibly be referring to the current closure,
3870 // because we haven't produced the `Closure` for
3871 // this closure yet; this is exactly why the other
3872 // code is looking for a self type of a unresolved
3873 // inference variable.
3874 ty::PredicateKind::ClosureKind(..) => None,
3876 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3879 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3880 self.obligations_for_self_ty(self_ty)
3881 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3884 /// Generic function that factors out common logic from function calls,
3885 /// method calls and overloaded operators.
3886 fn check_argument_types(
3889 expr: &'tcx hir::Expr<'tcx>,
3890 fn_inputs: &[Ty<'tcx>],
3891 expected_arg_tys: &[Ty<'tcx>],
3892 args: &'tcx [hir::Expr<'tcx>],
3894 tuple_arguments: TupleArgumentsFlag,
3895 def_span: Option<Span>,
3898 // Grab the argument types, supplying fresh type variables
3899 // if the wrong number of arguments were supplied
3900 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3902 // All the input types from the fn signature must outlive the call
3903 // so as to validate implied bounds.
3904 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3905 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3908 let expected_arg_count = fn_inputs.len();
3910 let param_count_error = |expected_count: usize,
3915 let (span, start_span, args) = match &expr.kind {
3916 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3917 hir::ExprKind::MethodCall(path_segment, span, args) => (
3919 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3922 .and_then(|args| args.args.iter().last())
3923 // Account for `foo.bar::<T>()`.
3925 // Skip the closing `>`.
3928 .next_point(tcx.sess.source_map().next_point(arg.span()))
3931 &args[1..], // Skip the receiver.
3933 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3935 let arg_spans = if args.is_empty() {
3937 // ^^^-- supplied 0 arguments
3939 // expected 2 arguments
3940 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3943 // ^^^ - - - supplied 3 arguments
3945 // expected 2 arguments
3946 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3949 let mut err = tcx.sess.struct_span_err_with_code(
3952 "this function takes {}{} but {} {} supplied",
3953 if c_variadic { "at least " } else { "" },
3954 potentially_plural_count(expected_count, "argument"),
3955 potentially_plural_count(arg_count, "argument"),
3956 if arg_count == 1 { "was" } else { "were" }
3958 DiagnosticId::Error(error_code.to_owned()),
3960 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3961 for (i, span) in arg_spans.into_iter().enumerate() {
3964 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3968 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3969 err.span_label(def_s, "defined here");
3972 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3973 // remove closing `)` from the span
3974 let sugg_span = sugg_span.shrink_to_lo();
3975 err.span_suggestion(
3977 "expected the unit value `()`; create it with empty parentheses",
3979 Applicability::MachineApplicable,
3986 if c_variadic { "at least " } else { "" },
3987 potentially_plural_count(expected_count, "argument")
3994 let mut expected_arg_tys = expected_arg_tys.to_vec();
3996 let formal_tys = if tuple_arguments == TupleArguments {
3997 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3998 match tuple_type.kind {
3999 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4000 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4001 expected_arg_tys = vec![];
4002 self.err_args(args.len())
4004 ty::Tuple(arg_types) => {
4005 expected_arg_tys = match expected_arg_tys.get(0) {
4006 Some(&ty) => match ty.kind {
4007 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4012 arg_types.iter().map(|k| k.expect_ty()).collect()
4019 "cannot use call notation; the first type parameter \
4020 for the function trait is neither a tuple nor unit"
4023 expected_arg_tys = vec![];
4024 self.err_args(args.len())
4027 } else if expected_arg_count == supplied_arg_count {
4029 } else if c_variadic {
4030 if supplied_arg_count >= expected_arg_count {
4033 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4034 expected_arg_tys = vec![];
4035 self.err_args(supplied_arg_count)
4038 // is the missing argument of type `()`?
4039 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4040 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4041 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4042 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4046 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4048 expected_arg_tys = vec![];
4049 self.err_args(supplied_arg_count)
4053 "check_argument_types: formal_tys={:?}",
4054 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4057 // If there is no expectation, expect formal_tys.
4058 let expected_arg_tys =
4059 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4061 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4063 // Check the arguments.
4064 // We do this in a pretty awful way: first we type-check any arguments
4065 // that are not closures, then we type-check the closures. This is so
4066 // that we have more information about the types of arguments when we
4067 // type-check the functions. This isn't really the right way to do this.
4068 for &check_closures in &[false, true] {
4069 debug!("check_closures={}", check_closures);
4071 // More awful hacks: before we check argument types, try to do
4072 // an "opportunistic" vtable resolution of any trait bounds on
4073 // the call. This helps coercions.
4075 self.select_obligations_where_possible(false, |errors| {
4076 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4077 self.point_at_arg_instead_of_call_if_possible(
4079 &final_arg_types[..],
4086 // For C-variadic functions, we don't have a declared type for all of
4087 // the arguments hence we only do our usual type checking with
4088 // the arguments who's types we do know.
4089 let t = if c_variadic {
4091 } else if tuple_arguments == TupleArguments {
4096 for (i, arg) in args.iter().take(t).enumerate() {
4097 // Warn only for the first loop (the "no closures" one).
4098 // Closure arguments themselves can't be diverging, but
4099 // a previous argument can, e.g., `foo(panic!(), || {})`.
4100 if !check_closures {
4101 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4104 let is_closure = match arg.kind {
4105 ExprKind::Closure(..) => true,
4109 if is_closure != check_closures {
4113 debug!("checking the argument");
4114 let formal_ty = formal_tys[i];
4116 // The special-cased logic below has three functions:
4117 // 1. Provide as good of an expected type as possible.
4118 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4120 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4122 // 2. Coerce to the most detailed type that could be coerced
4123 // to, which is `expected_ty` if `rvalue_hint` returns an
4124 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4125 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4126 // We're processing function arguments so we definitely want to use
4127 // two-phase borrows.
4128 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4129 final_arg_types.push((i, checked_ty, coerce_ty));
4131 // 3. Relate the expected type and the formal one,
4132 // if the expected type was used for the coercion.
4133 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4137 // We also need to make sure we at least write the ty of the other
4138 // arguments which we skipped above.
4140 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4141 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4142 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4145 for arg in args.iter().skip(expected_arg_count) {
4146 let arg_ty = self.check_expr(&arg);
4148 // There are a few types which get autopromoted when passed via varargs
4149 // in C but we just error out instead and require explicit casts.
4150 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4152 ty::Float(ast::FloatTy::F32) => {
4153 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4155 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4156 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4158 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4159 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4162 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4163 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4164 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4172 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4173 vec![self.tcx.types.err; len]
4176 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4177 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4178 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4179 /// can be not easily comparable with predicate type (because of coercion). If the types match
4180 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4181 /// the corresponding argument's expression span instead of the `fn` call path span.
4182 fn point_at_arg_instead_of_call_if_possible(
4184 errors: &mut Vec<traits::FulfillmentError<'_>>,
4185 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4187 args: &'tcx [hir::Expr<'tcx>],
4189 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4190 // the `?` operator.
4191 if call_sp.desugaring_kind().is_some() {
4195 for error in errors {
4196 // Only if the cause is somewhere inside the expression we want try to point at arg.
4197 // Otherwise, it means that the cause is somewhere else and we should not change
4198 // anything because we can break the correct span.
4199 if !call_sp.contains(error.obligation.cause.span) {
4203 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate.kind() {
4204 // Collect the argument position for all arguments that could have caused this
4205 // `FulfillmentError`.
4206 let mut referenced_in = final_arg_types
4208 .map(|&(i, checked_ty, _)| (i, checked_ty))
4209 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4210 .flat_map(|(i, ty)| {
4211 let ty = self.resolve_vars_if_possible(&ty);
4212 // We walk the argument type because the argument's type could have
4213 // been `Option<T>`, but the `FulfillmentError` references `T`.
4214 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4220 .collect::<Vec<_>>();
4222 // Both checked and coerced types could have matched, thus we need to remove
4224 referenced_in.sort();
4225 referenced_in.dedup();
4227 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4228 // We make sure that only *one* argument matches the obligation failure
4229 // and we assign the obligation's span to its expression's.
4230 error.obligation.cause.span = args[ref_in].span;
4231 error.points_at_arg_span = true;
4237 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4238 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4239 /// were caused by them. If they were, we point at the corresponding type argument's span
4240 /// instead of the `fn` call path span.
4241 fn point_at_type_arg_instead_of_call_if_possible(
4243 errors: &mut Vec<traits::FulfillmentError<'_>>,
4244 call_expr: &'tcx hir::Expr<'tcx>,
4246 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4247 if let hir::ExprKind::Path(qpath) = &path.kind {
4248 if let hir::QPath::Resolved(_, path) = &qpath {
4249 for error in errors {
4250 if let ty::PredicateKind::Trait(predicate, _) =
4251 error.obligation.predicate.kind()
4253 // If any of the type arguments in this path segment caused the
4254 // `FullfillmentError`, point at its span (#61860).
4258 .filter_map(|seg| seg.args.as_ref())
4259 .flat_map(|a| a.args.iter())
4261 if let hir::GenericArg::Type(hir_ty) = &arg {
4262 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4265 // Avoid ICE with associated types. As this is best
4266 // effort only, it's ok to ignore the case. It
4267 // would trigger in `is_send::<T::AssocType>();`
4268 // from `typeck-default-trait-impl-assoc-type.rs`.
4270 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4271 let ty = self.resolve_vars_if_possible(&ty);
4272 if ty == predicate.skip_binder().self_ty() {
4273 error.obligation.cause.span = hir_ty.span;
4285 // AST fragment checking
4286 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4290 ast::LitKind::Str(..) => tcx.mk_static_str(),
4291 ast::LitKind::ByteStr(ref v) => {
4292 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4294 ast::LitKind::Byte(_) => tcx.types.u8,
4295 ast::LitKind::Char(_) => tcx.types.char,
4296 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4297 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4298 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4299 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4300 ty::Int(_) | ty::Uint(_) => Some(ty),
4301 ty::Char => Some(tcx.types.u8),
4302 ty::RawPtr(..) => Some(tcx.types.usize),
4303 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4306 opt_ty.unwrap_or_else(|| self.next_int_var())
4308 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4309 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4310 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4311 ty::Float(_) => Some(ty),
4314 opt_ty.unwrap_or_else(|| self.next_float_var())
4316 ast::LitKind::Bool(_) => tcx.types.bool,
4317 ast::LitKind::Err(_) => tcx.types.err,
4321 /// Unifies the output type with the expected type early, for more coercions
4322 /// and forward type information on the input expressions.
4323 fn expected_inputs_for_expected_output(
4326 expected_ret: Expectation<'tcx>,
4327 formal_ret: Ty<'tcx>,
4328 formal_args: &[Ty<'tcx>],
4329 ) -> Vec<Ty<'tcx>> {
4330 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4331 let ret_ty = match expected_ret.only_has_type(self) {
4333 None => return Vec::new(),
4335 let expect_args = self
4336 .fudge_inference_if_ok(|| {
4337 // Attempt to apply a subtyping relationship between the formal
4338 // return type (likely containing type variables if the function
4339 // is polymorphic) and the expected return type.
4340 // No argument expectations are produced if unification fails.
4341 let origin = self.misc(call_span);
4342 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4344 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4345 // to identity so the resulting type is not constrained.
4348 // Process any obligations locally as much as
4349 // we can. We don't care if some things turn
4350 // out unconstrained or ambiguous, as we're
4351 // just trying to get hints here.
4352 self.save_and_restore_in_snapshot_flag(|_| {
4353 let mut fulfill = TraitEngine::new(self.tcx);
4354 for obligation in ok.obligations {
4355 fulfill.register_predicate_obligation(self, obligation);
4357 fulfill.select_where_possible(self)
4361 Err(_) => return Err(()),
4364 // Record all the argument types, with the substitutions
4365 // produced from the above subtyping unification.
4366 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4368 .unwrap_or_default();
4370 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4371 formal_args, formal_ret, expect_args, expected_ret
4376 pub fn check_struct_path(
4380 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4381 let path_span = match *qpath {
4382 QPath::Resolved(_, ref path) => path.span,
4383 QPath::TypeRelative(ref qself, _) => qself.span,
4385 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4386 let variant = match def {
4388 self.set_tainted_by_errors();
4391 Res::Def(DefKind::Variant, _) => match ty.kind {
4392 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4393 _ => bug!("unexpected type: {:?}", ty),
4395 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4396 | Res::SelfTy(..) => match ty.kind {
4397 ty::Adt(adt, substs) if !adt.is_enum() => {
4398 Some((adt.non_enum_variant(), adt.did, substs))
4402 _ => bug!("unexpected definition: {:?}", def),
4405 if let Some((variant, did, substs)) = variant {
4406 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4407 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4409 // Check bounds on type arguments used in the path.
4410 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4412 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4413 self.add_obligations_for_parameters(cause, bounds);
4421 "expected struct, variant or union type, found {}",
4422 ty.sort_string(self.tcx)
4424 .span_label(path_span, "not a struct")
4430 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4431 // The newly resolved definition is written into `type_dependent_defs`.
4432 fn finish_resolving_struct_path(
4437 ) -> (Res, Ty<'tcx>) {
4439 QPath::Resolved(ref maybe_qself, ref path) => {
4440 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4441 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4444 QPath::TypeRelative(ref qself, ref segment) => {
4445 let ty = self.to_ty(qself);
4447 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4453 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4454 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4455 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4457 // Write back the new resolution.
4458 self.write_resolution(hir_id, result);
4460 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4465 /// Resolves an associated value path into a base type and associated constant, or method
4466 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4467 pub fn resolve_ty_and_res_ufcs<'b>(
4469 qpath: &'b QPath<'b>,
4472 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4473 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4474 let (ty, qself, item_segment) = match *qpath {
4475 QPath::Resolved(ref opt_qself, ref path) => {
4478 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4482 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4484 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4485 // Return directly on cache hit. This is useful to avoid doubly reporting
4486 // errors with default match binding modes. See #44614.
4488 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4489 return (def, Some(ty), slice::from_ref(&**item_segment));
4491 let item_name = item_segment.ident;
4492 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4493 let result = match error {
4494 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4495 _ => Err(ErrorReported),
4497 if item_name.name != kw::Invalid {
4498 if let Some(mut e) = self.report_method_error(
4502 SelfSource::QPath(qself),
4512 // Write back the new resolution.
4513 self.write_resolution(hir_id, result);
4515 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4517 slice::from_ref(&**item_segment),
4521 pub fn check_decl_initializer(
4523 local: &'tcx hir::Local<'tcx>,
4524 init: &'tcx hir::Expr<'tcx>,
4526 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4527 // for #42640 (default match binding modes).
4530 let ref_bindings = local.pat.contains_explicit_ref_binding();
4532 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4533 if let Some(m) = ref_bindings {
4534 // Somewhat subtle: if we have a `ref` binding in the pattern,
4535 // we want to avoid introducing coercions for the RHS. This is
4536 // both because it helps preserve sanity and, in the case of
4537 // ref mut, for soundness (issue #23116). In particular, in
4538 // the latter case, we need to be clear that the type of the
4539 // referent for the reference that results is *equal to* the
4540 // type of the place it is referencing, and not some
4541 // supertype thereof.
4542 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4543 self.demand_eqtype(init.span, local_ty, init_ty);
4546 self.check_expr_coercable_to_type(init, local_ty)
4550 /// Type check a `let` statement.
4551 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4552 // Determine and write the type which we'll check the pattern against.
4553 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4554 self.write_ty(local.hir_id, ty);
4556 // Type check the initializer.
4557 if let Some(ref init) = local.init {
4558 let init_ty = self.check_decl_initializer(local, &init);
4559 self.overwrite_local_ty_if_err(local, ty, init_ty);
4562 // Does the expected pattern type originate from an expression and what is the span?
4563 let (origin_expr, ty_span) = match (local.ty, local.init) {
4564 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4565 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4566 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4569 // Type check the pattern. Override if necessary to avoid knock-on errors.
4570 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4571 let pat_ty = self.node_ty(local.pat.hir_id);
4572 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4575 fn overwrite_local_ty_if_err(
4577 local: &'tcx hir::Local<'tcx>,
4581 if ty.references_error() {
4582 // Override the types everywhere with `types.err` to avoid knock on errors.
4583 self.write_ty(local.hir_id, ty);
4584 self.write_ty(local.pat.hir_id, ty);
4585 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4586 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4587 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4591 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4592 err.span_suggestion_short(
4593 span.shrink_to_hi(),
4594 "consider using a semicolon here",
4596 Applicability::MachineApplicable,
4600 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4601 // Don't do all the complex logic below for `DeclItem`.
4603 hir::StmtKind::Item(..) => return,
4604 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4607 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4609 // Hide the outer diverging and `has_errors` flags.
4610 let old_diverges = self.diverges.replace(Diverges::Maybe);
4611 let old_has_errors = self.has_errors.replace(false);
4614 hir::StmtKind::Local(ref l) => {
4615 self.check_decl_local(&l);
4618 hir::StmtKind::Item(_) => {}
4619 hir::StmtKind::Expr(ref expr) => {
4620 // Check with expected type of `()`.
4621 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4622 self.suggest_semicolon_at_end(expr.span, err);
4625 hir::StmtKind::Semi(ref expr) => {
4626 self.check_expr(&expr);
4630 // Combine the diverging and `has_error` flags.
4631 self.diverges.set(self.diverges.get() | old_diverges);
4632 self.has_errors.set(self.has_errors.get() | old_has_errors);
4635 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4636 let unit = self.tcx.mk_unit();
4637 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4639 // if the block produces a `!` value, that can always be
4640 // (effectively) coerced to unit.
4642 self.demand_suptype(blk.span, unit, ty);
4646 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4647 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4648 /// when given code like the following:
4650 /// if false { return 0i32; } else { 1u32 }
4651 /// // ^^^^ point at this instead of the whole `if` expression
4653 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4654 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4655 let arm_spans: Vec<Span> = arms
4658 self.in_progress_tables
4659 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4660 .and_then(|arm_ty| {
4661 if arm_ty.is_never() {
4664 Some(match &arm.body.kind {
4665 // Point at the tail expression when possible.
4666 hir::ExprKind::Block(block, _) => {
4667 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4675 if arm_spans.len() == 1 {
4676 return arm_spans[0];
4682 fn check_block_with_expected(
4684 blk: &'tcx hir::Block<'tcx>,
4685 expected: Expectation<'tcx>,
4688 let mut fcx_ps = self.ps.borrow_mut();
4689 let unsafety_state = fcx_ps.recurse(blk);
4690 replace(&mut *fcx_ps, unsafety_state)
4693 // In some cases, blocks have just one exit, but other blocks
4694 // can be targeted by multiple breaks. This can happen both
4695 // with labeled blocks as well as when we desugar
4696 // a `try { ... }` expression.
4700 // 'a: { if true { break 'a Err(()); } Ok(()) }
4702 // Here we would wind up with two coercions, one from
4703 // `Err(())` and the other from the tail expression
4704 // `Ok(())`. If the tail expression is omitted, that's a
4705 // "forced unit" -- unless the block diverges, in which
4706 // case we can ignore the tail expression (e.g., `'a: {
4707 // break 'a 22; }` would not force the type of the block
4709 let tail_expr = blk.expr.as_ref();
4710 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4711 let coerce = if blk.targeted_by_break {
4712 CoerceMany::new(coerce_to_ty)
4714 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4715 Some(e) => slice::from_ref(e),
4718 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4721 let prev_diverges = self.diverges.get();
4722 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4724 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4725 for s in blk.stmts {
4729 // check the tail expression **without** holding the
4730 // `enclosing_breakables` lock below.
4731 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4733 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4734 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4735 let coerce = ctxt.coerce.as_mut().unwrap();
4736 if let Some(tail_expr_ty) = tail_expr_ty {
4737 let tail_expr = tail_expr.unwrap();
4738 let span = self.get_expr_coercion_span(tail_expr);
4739 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4740 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4742 // Subtle: if there is no explicit tail expression,
4743 // that is typically equivalent to a tail expression
4744 // of `()` -- except if the block diverges. In that
4745 // case, there is no value supplied from the tail
4746 // expression (assuming there are no other breaks,
4747 // this implies that the type of the block will be
4750 // #41425 -- label the implicit `()` as being the
4751 // "found type" here, rather than the "expected type".
4752 if !self.diverges.get().is_always() {
4753 // #50009 -- Do not point at the entire fn block span, point at the return type
4754 // span, as it is the cause of the requirement, and
4755 // `consider_hint_about_removing_semicolon` will point at the last expression
4756 // if it were a relevant part of the error. This improves usability in editors
4757 // that highlight errors inline.
4758 let mut sp = blk.span;
4759 let mut fn_span = None;
4760 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4761 let ret_sp = decl.output.span();
4762 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4763 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4764 // output would otherwise be incorrect and even misleading. Make sure
4765 // the span we're aiming at correspond to a `fn` body.
4766 if block_sp == blk.span {
4768 fn_span = Some(ident.span);
4772 coerce.coerce_forced_unit(
4776 if let Some(expected_ty) = expected.only_has_type(self) {
4777 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4779 if let Some(fn_span) = fn_span {
4782 "implicitly returns `()` as its body has no tail or `return` \
4794 // If we can break from the block, then the block's exit is always reachable
4795 // (... as long as the entry is reachable) - regardless of the tail of the block.
4796 self.diverges.set(prev_diverges);
4799 let mut ty = ctxt.coerce.unwrap().complete(self);
4801 if self.has_errors.get() || ty.references_error() {
4802 ty = self.tcx.types.err
4805 self.write_ty(blk.hir_id, ty);
4807 *self.ps.borrow_mut() = prev;
4811 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4812 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4814 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4815 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4816 let body = self.tcx.hir().body(body_id);
4817 if let ExprKind::Block(block, _) = &body.value.kind {
4818 return Some(block.span);
4826 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4827 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4828 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4829 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4832 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4833 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4835 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4836 // This is less than ideal, it will not suggest a return type span on any
4837 // method called `main`, regardless of whether it is actually the entry point,
4838 // but it will still present it as the reason for the expected type.
4839 Some((&sig.decl, ident, ident.name != sym::main))
4841 Node::TraitItem(&hir::TraitItem {
4843 kind: hir::TraitItemKind::Fn(ref sig, ..),
4845 }) => Some((&sig.decl, ident, true)),
4846 Node::ImplItem(&hir::ImplItem {
4848 kind: hir::ImplItemKind::Fn(ref sig, ..),
4850 }) => Some((&sig.decl, ident, false)),
4855 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4856 /// suggestion can be made, `None` otherwise.
4857 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4858 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4859 // `while` before reaching it, as block tail returns are not available in them.
4860 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4861 let parent = self.tcx.hir().get(blk_id);
4862 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4866 /// On implicit return expressions with mismatched types, provides the following suggestions:
4868 /// - Points out the method's return type as the reason for the expected type.
4869 /// - Possible missing semicolon.
4870 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4871 pub fn suggest_mismatched_types_on_tail(
4873 err: &mut DiagnosticBuilder<'_>,
4874 expr: &'tcx hir::Expr<'tcx>,
4880 let expr = expr.peel_drop_temps();
4881 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4882 let mut pointing_at_return_type = false;
4883 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4884 pointing_at_return_type =
4885 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4887 pointing_at_return_type
4890 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4891 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4893 /// fn foo(x: usize) -> usize { x }
4894 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4898 err: &mut DiagnosticBuilder<'_>,
4899 expr: &hir::Expr<'_>,
4903 let hir = self.tcx.hir();
4904 let (def_id, sig) = match found.kind {
4905 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4906 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4910 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4911 let sig = self.normalize_associated_types_in(expr.span, &sig);
4912 if self.can_coerce(sig.output(), expected) {
4913 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4914 (String::new(), Applicability::MachineApplicable)
4916 ("...".to_string(), Applicability::HasPlaceholders)
4918 let mut msg = "call this function";
4919 match hir.get_if_local(def_id) {
4921 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4922 | Node::ImplItem(hir::ImplItem {
4923 kind: hir::ImplItemKind::Fn(_, body_id), ..
4925 | Node::TraitItem(hir::TraitItem {
4926 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4930 let body = hir.body(*body_id);
4934 .map(|param| match ¶m.pat.kind {
4935 hir::PatKind::Binding(_, _, ident, None)
4936 if ident.name != kw::SelfLower =>
4940 _ => "_".to_string(),
4942 .collect::<Vec<_>>()
4945 Some(Node::Expr(hir::Expr {
4946 kind: ExprKind::Closure(_, _, body_id, _, _),
4947 span: full_closure_span,
4950 if *full_closure_span == expr.span {
4953 msg = "call this closure";
4954 let body = hir.body(*body_id);
4958 .map(|param| match ¶m.pat.kind {
4959 hir::PatKind::Binding(_, _, ident, None)
4960 if ident.name != kw::SelfLower =>
4964 _ => "_".to_string(),
4966 .collect::<Vec<_>>()
4969 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4970 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4971 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
4972 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4973 msg = "instantiate this tuple variant";
4975 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
4976 msg = "instantiate this tuple struct";
4981 Some(Node::ForeignItem(hir::ForeignItem {
4982 kind: hir::ForeignItemKind::Fn(_, idents, _),
4988 if ident.name != kw::SelfLower {
4994 .collect::<Vec<_>>()
4997 Some(Node::TraitItem(hir::TraitItem {
4998 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5004 if ident.name != kw::SelfLower {
5010 .collect::<Vec<_>>()
5015 err.span_suggestion_verbose(
5016 expr.span.shrink_to_hi(),
5017 &format!("use parentheses to {}", msg),
5018 format!("({})", sugg_call),
5026 pub fn suggest_deref_ref_or_into(
5028 err: &mut DiagnosticBuilder<'_>,
5029 expr: &hir::Expr<'_>,
5033 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5034 err.span_suggestion(sp, msg, suggestion, applicability);
5035 } else if let (ty::FnDef(def_id, ..), true) =
5036 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5038 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5039 let sp = self.sess().source_map().guess_head_span(sp);
5040 err.span_label(sp, &format!("{} defined here", found));
5042 } else if !self.check_for_cast(err, expr, found, expected) {
5043 let is_struct_pat_shorthand_field =
5044 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5045 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5046 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5047 let mut suggestions = iter::repeat(&expr_text)
5048 .zip(methods.iter())
5049 .filter_map(|(receiver, method)| {
5050 let method_call = format!(".{}()", method.ident);
5051 if receiver.ends_with(&method_call) {
5052 None // do not suggest code that is already there (#53348)
5054 let method_call_list = [".to_vec()", ".to_string()"];
5055 let sugg = if receiver.ends_with(".clone()")
5056 && method_call_list.contains(&method_call.as_str())
5058 let max_len = receiver.rfind('.').unwrap();
5059 format!("{}{}", &receiver[..max_len], method_call)
5061 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5062 format!("({}){}", receiver, method_call)
5064 format!("{}{}", receiver, method_call)
5067 Some(if is_struct_pat_shorthand_field {
5068 format!("{}: {}", receiver, sugg)
5075 if suggestions.peek().is_some() {
5076 err.span_suggestions(
5078 "try using a conversion method",
5080 Applicability::MaybeIncorrect,
5087 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5088 /// in the heap by calling `Box::new()`.
5089 fn suggest_boxing_when_appropriate(
5091 err: &mut DiagnosticBuilder<'_>,
5092 expr: &hir::Expr<'_>,
5096 if self.tcx.hir().is_const_context(expr.hir_id) {
5097 // Do not suggest `Box::new` in const context.
5100 if !expected.is_box() || found.is_box() {
5103 let boxed_found = self.tcx.mk_box(found);
5104 if let (true, Ok(snippet)) = (
5105 self.can_coerce(boxed_found, expected),
5106 self.sess().source_map().span_to_snippet(expr.span),
5108 err.span_suggestion(
5110 "store this in the heap by calling `Box::new`",
5111 format!("Box::new({})", snippet),
5112 Applicability::MachineApplicable,
5115 "for more on the distinction between the stack and the heap, read \
5116 https://doc.rust-lang.org/book/ch15-01-box.html, \
5117 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5118 https://doc.rust-lang.org/std/boxed/index.html",
5123 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5124 fn suggest_calling_boxed_future_when_appropriate(
5126 err: &mut DiagnosticBuilder<'_>,
5127 expr: &hir::Expr<'_>,
5133 if self.tcx.hir().is_const_context(expr.hir_id) {
5134 // Do not suggest `Box::new` in const context.
5137 let pin_did = self.tcx.lang_items().pin_type();
5138 match expected.kind {
5139 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5140 // This guards the `unwrap` and `mk_box` below.
5141 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5144 let boxed_found = self.tcx.mk_box(found);
5145 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5146 if let (true, Ok(snippet)) = (
5147 self.can_coerce(new_found, expected),
5148 self.sess().source_map().span_to_snippet(expr.span),
5151 ty::Adt(def, _) if def.is_box() => {
5152 err.help("use `Box::pin`");
5155 err.span_suggestion(
5157 "you need to pin and box this expression",
5158 format!("Box::pin({})", snippet),
5159 Applicability::MachineApplicable,
5169 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5173 /// bar_that_returns_u32()
5177 /// This routine checks if the return expression in a block would make sense on its own as a
5178 /// statement and the return type has been left as default or has been specified as `()`. If so,
5179 /// it suggests adding a semicolon.
5180 fn suggest_missing_semicolon(
5182 err: &mut DiagnosticBuilder<'_>,
5183 expression: &'tcx hir::Expr<'tcx>,
5187 if expected.is_unit() {
5188 // `BlockTailExpression` only relevant if the tail expr would be
5189 // useful on its own.
5190 match expression.kind {
5192 | ExprKind::MethodCall(..)
5193 | ExprKind::Loop(..)
5194 | ExprKind::Match(..)
5195 | ExprKind::Block(..) => {
5196 err.span_suggestion(
5197 cause_span.shrink_to_hi(),
5198 "try adding a semicolon",
5200 Applicability::MachineApplicable,
5208 /// A possible error is to forget to add a return type that is needed:
5212 /// bar_that_returns_u32()
5216 /// This routine checks if the return type is left as default, the method is not part of an
5217 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5219 fn suggest_missing_return_type(
5221 err: &mut DiagnosticBuilder<'_>,
5222 fn_decl: &hir::FnDecl<'_>,
5227 // Only suggest changing the return type for methods that
5228 // haven't set a return type at all (and aren't `fn main()` or an impl).
5229 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5230 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5231 err.span_suggestion(
5233 "try adding a return type",
5234 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5235 Applicability::MachineApplicable,
5239 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5240 err.span_label(span, "possibly return type missing here?");
5243 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5244 // `fn main()` must return `()`, do not suggest changing return type
5245 err.span_label(span, "expected `()` because of default return type");
5248 // expectation was caused by something else, not the default return
5249 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5250 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5251 // Only point to return type if the expected type is the return type, as if they
5252 // are not, the expectation must have been caused by something else.
5253 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5255 let ty = AstConv::ast_ty_to_ty(self, ty);
5256 debug!("suggest_missing_return_type: return type {:?}", ty);
5257 debug!("suggest_missing_return_type: expected type {:?}", ty);
5258 if ty.kind == expected.kind {
5259 err.span_label(sp, format!("expected `{}` because of return type", expected));
5267 /// A possible error is to forget to add `.await` when using futures:
5270 /// async fn make_u32() -> u32 {
5274 /// fn take_u32(x: u32) {}
5276 /// async fn foo() {
5277 /// let x = make_u32();
5282 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5283 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5284 /// `.await` to the tail of the expression.
5285 fn suggest_missing_await(
5287 err: &mut DiagnosticBuilder<'_>,
5288 expr: &hir::Expr<'_>,
5292 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5293 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5294 // body isn't `async`.
5295 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5296 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5297 let body = self.tcx().hir().body(body_id);
5298 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5300 // Check for `Future` implementations by constructing a predicate to
5301 // prove: `<T as Future>::Output == U`
5302 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5303 let item_def_id = self
5305 .associated_items(future_trait)
5306 .in_definition_order()
5310 // `<T as Future>::Output`
5311 let projection_ty = ty::ProjectionTy {
5315 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5321 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5325 .to_predicate(self.tcx);
5326 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5328 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5330 if self.infcx.predicate_may_hold(&obligation) {
5331 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5332 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5333 err.span_suggestion(
5335 "consider using `.await` here",
5336 format!("{}.await", code),
5337 Applicability::MaybeIncorrect,
5340 debug!("suggest_missing_await: no snippet for {:?}", sp);
5343 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5349 /// A common error is to add an extra semicolon:
5352 /// fn foo() -> usize {
5357 /// This routine checks if the final statement in a block is an
5358 /// expression with an explicit semicolon whose type is compatible
5359 /// with `expected_ty`. If so, it suggests removing the semicolon.
5360 fn consider_hint_about_removing_semicolon(
5362 blk: &'tcx hir::Block<'tcx>,
5363 expected_ty: Ty<'tcx>,
5364 err: &mut DiagnosticBuilder<'_>,
5366 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5367 err.span_suggestion(
5369 "consider removing this semicolon",
5371 Applicability::MachineApplicable,
5376 fn could_remove_semicolon(
5378 blk: &'tcx hir::Block<'tcx>,
5379 expected_ty: Ty<'tcx>,
5381 // Be helpful when the user wrote `{... expr;}` and
5382 // taking the `;` off is enough to fix the error.
5383 let last_stmt = blk.stmts.last()?;
5384 let last_expr = match last_stmt.kind {
5385 hir::StmtKind::Semi(ref e) => e,
5388 let last_expr_ty = self.node_ty(last_expr.hir_id);
5389 if matches!(last_expr_ty.kind, ty::Error)
5390 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5394 let original_span = original_sp(last_stmt.span, blk.span);
5395 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5398 // Instantiates the given path, which must refer to an item with the given
5399 // number of type parameters and type.
5400 pub fn instantiate_value_path(
5402 segments: &[hir::PathSegment<'_>],
5403 self_ty: Option<Ty<'tcx>>,
5407 ) -> (Ty<'tcx>, Res) {
5409 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5410 segments, self_ty, res, hir_id,
5415 let path_segs = match res {
5416 Res::Local(_) | Res::SelfCtor(_) => vec![],
5417 Res::Def(kind, def_id) => {
5418 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5420 _ => bug!("instantiate_value_path on {:?}", res),
5423 let mut user_self_ty = None;
5424 let mut is_alias_variant_ctor = false;
5426 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5427 if let Some(self_ty) = self_ty {
5428 let adt_def = self_ty.ty_adt_def().unwrap();
5429 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5430 is_alias_variant_ctor = true;
5433 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5434 let container = tcx.associated_item(def_id).container;
5435 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5437 ty::TraitContainer(trait_did) => {
5438 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5440 ty::ImplContainer(impl_def_id) => {
5441 if segments.len() == 1 {
5442 // `<T>::assoc` will end up here, and so
5443 // can `T::assoc`. It this came from an
5444 // inherent impl, we need to record the
5445 // `T` for posterity (see `UserSelfTy` for
5447 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5448 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5456 // Now that we have categorized what space the parameters for each
5457 // segment belong to, let's sort out the parameters that the user
5458 // provided (if any) into their appropriate spaces. We'll also report
5459 // errors if type parameters are provided in an inappropriate place.
5461 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5462 let generics_has_err = AstConv::prohibit_generics(
5464 segments.iter().enumerate().filter_map(|(index, seg)| {
5465 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5473 if let Res::Local(hid) = res {
5474 let ty = self.local_ty(span, hid).decl_ty;
5475 let ty = self.normalize_associated_types_in(span, &ty);
5476 self.write_ty(hir_id, ty);
5480 if generics_has_err {
5481 // Don't try to infer type parameters when prohibited generic arguments were given.
5482 user_self_ty = None;
5485 // Now we have to compare the types that the user *actually*
5486 // provided against the types that were *expected*. If the user
5487 // did not provide any types, then we want to substitute inference
5488 // variables. If the user provided some types, we may still need
5489 // to add defaults. If the user provided *too many* types, that's
5492 let mut infer_args_for_err = FxHashSet::default();
5493 for &PathSeg(def_id, index) in &path_segs {
5494 let seg = &segments[index];
5495 let generics = tcx.generics_of(def_id);
5496 // Argument-position `impl Trait` is treated as a normal generic
5497 // parameter internally, but we don't allow users to specify the
5498 // parameter's value explicitly, so we have to do some error-
5500 if let GenericArgCountResult {
5501 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5503 } = AstConv::check_generic_arg_count_for_call(
5504 tcx, span, &generics, &seg, false, // `is_method_call`
5506 infer_args_for_err.insert(index);
5507 self.set_tainted_by_errors(); // See issue #53251.
5511 let has_self = path_segs
5513 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5516 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5517 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5519 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5520 let variant = adt_def.non_enum_variant();
5521 let ctor_def_id = variant.ctor_def_id.unwrap();
5523 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5528 let mut err = tcx.sess.struct_span_err(
5530 "the `Self` constructor can only be used with tuple or unit structs",
5532 if let Some(adt_def) = ty.ty_adt_def() {
5533 match adt_def.adt_kind() {
5535 err.help("did you mean to use one of the enum's variants?");
5537 AdtKind::Struct | AdtKind::Union => {
5538 err.span_suggestion(
5540 "use curly brackets",
5541 String::from("Self { /* fields */ }"),
5542 Applicability::HasPlaceholders,
5549 return (tcx.types.err, res);
5555 let def_id = res.def_id();
5557 // The things we are substituting into the type should not contain
5558 // escaping late-bound regions, and nor should the base type scheme.
5559 let ty = tcx.type_of(def_id);
5561 let arg_count = GenericArgCountResult {
5562 explicit_late_bound: ExplicitLateBound::No,
5563 correct: if infer_args_for_err.is_empty() {
5566 Err(GenericArgCountMismatch::default())
5570 let substs = self_ctor_substs.unwrap_or_else(|| {
5571 AstConv::create_substs_for_generic_args(
5578 // Provide the generic args, and whether types should be inferred.
5580 if let Some(&PathSeg(_, index)) =
5581 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5583 // If we've encountered an `impl Trait`-related error, we're just
5584 // going to infer the arguments for better error messages.
5585 if !infer_args_for_err.contains(&index) {
5586 // Check whether the user has provided generic arguments.
5587 if let Some(ref data) = segments[index].args {
5588 return (Some(data), segments[index].infer_args);
5591 return (None, segments[index].infer_args);
5596 // Provide substitutions for parameters for which (valid) arguments have been provided.
5597 |param, arg| match (¶m.kind, arg) {
5598 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5599 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5601 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5602 self.to_ty(ty).into()
5604 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5605 self.to_const(&ct.value).into()
5607 _ => unreachable!(),
5609 // Provide substitutions for parameters for which arguments are inferred.
5610 |substs, param, infer_args| {
5612 GenericParamDefKind::Lifetime => {
5613 self.re_infer(Some(param), span).unwrap().into()
5615 GenericParamDefKind::Type { has_default, .. } => {
5616 if !infer_args && has_default {
5617 // If we have a default, then we it doesn't matter that we're not
5618 // inferring the type arguments: we provide the default where any
5620 let default = tcx.type_of(param.def_id);
5623 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5627 // If no type arguments were provided, we have to infer them.
5628 // This case also occurs as a result of some malformed input, e.g.
5629 // a lifetime argument being given instead of a type parameter.
5630 // Using inference instead of `Error` gives better error messages.
5631 self.var_for_def(span, param)
5634 GenericParamDefKind::Const => {
5635 // FIXME(const_generics:defaults)
5636 // No const parameters were provided, we have to infer them.
5637 self.var_for_def(span, param)
5643 assert!(!substs.has_escaping_bound_vars());
5644 assert!(!ty.has_escaping_bound_vars());
5646 // First, store the "user substs" for later.
5647 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5649 self.add_required_obligations(span, def_id, &substs);
5651 // Substitute the values for the type parameters into the type of
5652 // the referenced item.
5653 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5655 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5656 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5657 // is inherent, there is no `Self` parameter; instead, the impl needs
5658 // type parameters, which we can infer by unifying the provided `Self`
5659 // with the substituted impl type.
5660 // This also occurs for an enum variant on a type alias.
5661 let ty = tcx.type_of(impl_def_id);
5663 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5664 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5665 Ok(ok) => self.register_infer_ok_obligations(ok),
5667 self.tcx.sess.delay_span_bug(
5670 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5679 self.check_rustc_args_require_const(def_id, hir_id, span);
5681 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5682 self.write_substs(hir_id, substs);
5684 (ty_substituted, res)
5687 /// Add all the obligations that are required, substituting and normalized appropriately.
5688 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5689 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5691 for (i, mut obligation) in traits::predicates_for_generics(
5692 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5698 // This makes the error point at the bound, but we want to point at the argument
5699 if let Some(span) = spans.get(i) {
5700 obligation.cause.code = traits::BindingObligation(def_id, *span);
5702 self.register_predicate(obligation);
5706 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5707 // We're only interested in functions tagged with
5708 // #[rustc_args_required_const], so ignore anything that's not.
5709 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5713 // If our calling expression is indeed the function itself, we're good!
5714 // If not, generate an error that this can only be called directly.
5715 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5716 if let ExprKind::Call(ref callee, ..) = expr.kind {
5717 if callee.hir_id == hir_id {
5723 self.tcx.sess.span_err(
5725 "this function can only be invoked directly, not through a function pointer",
5729 /// Resolves `typ` by a single level if `typ` is a type variable.
5730 /// If no resolution is possible, then an error is reported.
5731 /// Numeric inference variables may be left unresolved.
5732 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5733 let ty = self.resolve_vars_with_obligations(ty);
5734 if !ty.is_ty_var() {
5737 if !self.is_tainted_by_errors() {
5738 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5739 .note("type must be known at this point")
5742 self.demand_suptype(sp, self.tcx.types.err, ty);
5747 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5750 ctxt: BreakableCtxt<'tcx>,
5752 ) -> (BreakableCtxt<'tcx>, R) {
5755 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5756 index = enclosing_breakables.stack.len();
5757 enclosing_breakables.by_id.insert(id, index);
5758 enclosing_breakables.stack.push(ctxt);
5762 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5763 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5764 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5765 enclosing_breakables.stack.pop().expect("missing breakable context")
5770 /// Instantiate a QueryResponse in a probe context, without a
5771 /// good ObligationCause.
5772 fn probe_instantiate_query_response(
5775 original_values: &OriginalQueryValues<'tcx>,
5776 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5777 ) -> InferResult<'tcx, Ty<'tcx>> {
5778 self.instantiate_query_response_and_region_obligations(
5779 &traits::ObligationCause::misc(span, self.body_id),
5786 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5787 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5788 let mut contained_in_place = false;
5790 while let hir::Node::Expr(parent_expr) =
5791 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5793 match &parent_expr.kind {
5794 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5795 if lhs.hir_id == expr_id {
5796 contained_in_place = true;
5802 expr_id = parent_expr.hir_id;
5809 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5810 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5812 assert_eq!(generics.parent, None);
5814 if generics.own_counts().types == 0 {
5818 let mut params_used = BitSet::new_empty(generics.params.len());
5820 if ty.references_error() {
5821 // If there is already another error, do not emit
5822 // an error for not using a type parameter.
5823 assert!(tcx.sess.has_errors());
5827 for leaf in ty.walk() {
5828 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5829 if let ty::Param(param) = leaf_ty.kind {
5830 debug!("found use of ty param {:?}", param);
5831 params_used.insert(param.index);
5836 for param in &generics.params {
5837 if !params_used.contains(param.index) {
5838 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5839 let span = tcx.def_span(param.def_id);
5844 "type parameter `{}` is unused",
5847 .span_label(span, "unused type parameter")
5854 fn fatally_break_rust(sess: &Session) {
5855 let handler = sess.diagnostic();
5856 handler.span_bug_no_panic(
5858 "It looks like you're trying to break rust; would you like some ICE?",
5860 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5861 handler.note_without_error(
5862 "we would appreciate a joke overview: \
5863 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5865 handler.note_without_error(&format!(
5866 "rustc {} running on {}",
5867 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5868 config::host_triple(),
5872 fn potentially_plural_count(count: usize, word: &str) -> String {
5873 format!("{} {}{}", count, word, pluralize!(count))