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 - writeback: writes the final types within a function body, replacing
35 type variables with their final inferred types. These final types
36 are written into the `tcx.node_types` table, which should *never* contain
37 any reference to a type variable.
41 While type checking a function, the intermediate types for the
42 expressions, blocks, and so forth contained within the function are
43 stored in `fcx.node_types` and `fcx.node_substs`. These types
44 may contain unresolved type variables. After type checking is
45 complete, the functions in the writeback module are used to take the
46 types from this table, resolve them, and then write them into their
47 permanent home in the type context `tcx`.
49 This means that during inferencing you should use `fcx.write_ty()`
50 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
51 nodes within the function.
53 The types of top-level items, which never contain unbound type
54 variables, are stored directly into the `tcx` tables.
56 N.B., a type variable is not the same thing as a type parameter. A
57 type variable is rather an "instance" of a type parameter: that is,
58 given a generic function `fn foo<T>(t: T)`: while checking the
59 function `foo`, the type `ty_param(0)` refers to the type `T`, which
60 is treated in abstract. When `foo()` is called, however, `T` will be
61 substituted for a fresh type variable `N`. This variable will
62 eventually be resolved to some concrete type (which might itself be
77 mod generator_interior;
88 AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
91 use rustc_ast::util::parser::ExprPrecedence;
92 use rustc_attr as attr;
93 use rustc_data_structures::captures::Captures;
94 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
95 use rustc_errors::ErrorReported;
96 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
98 use rustc_hir::def::{CtorOf, DefKind, Res};
99 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
100 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
101 use rustc_hir::itemlikevisit::ItemLikeVisitor;
102 use rustc_hir::lang_items::{
103 FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem,
105 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
106 use rustc_index::bit_set::BitSet;
107 use rustc_index::vec::Idx;
108 use rustc_infer::infer;
109 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
110 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
111 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
112 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
113 use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
114 use rustc_middle::hir::map::blocks::FnLikeNode;
115 use rustc_middle::mir::interpret::ConstValue;
116 use rustc_middle::ty::adjustment::{
117 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
119 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
120 use rustc_middle::ty::query::Providers;
121 use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
122 use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts};
123 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
124 use rustc_middle::ty::{
125 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
126 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
128 use rustc_session::config::{self, EntryFnType};
129 use rustc_session::lint;
130 use rustc_session::parse::feature_err;
131 use rustc_session::Session;
132 use rustc_span::hygiene::DesugaringKind;
133 use rustc_span::source_map::{original_sp, DUMMY_SP};
134 use rustc_span::symbol::{kw, sym, Ident};
135 use rustc_span::{self, BytePos, MultiSpan, Span};
136 use rustc_target::abi::VariantIdx;
137 use rustc_target::spec::abi::Abi;
138 use rustc_trait_selection::infer::InferCtxtExt as _;
139 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
140 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
141 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
142 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
143 use rustc_trait_selection::traits::{
144 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
147 use std::cell::{Cell, Ref, RefCell, RefMut};
149 use std::collections::hash_map::Entry;
151 use std::mem::replace;
152 use std::ops::{self, Deref};
155 use crate::require_c_abi_if_c_variadic;
156 use crate::util::common::indenter;
158 use self::autoderef::Autoderef;
159 use self::callee::DeferredCallResolution;
160 use self::coercion::{CoerceMany, DynamicCoerceMany};
161 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
162 use self::method::{MethodCallee, SelfSource};
163 pub use self::Expectation::*;
164 use self::TupleArgumentsFlag::*;
167 macro_rules! type_error_struct {
168 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
169 if $typ.references_error() {
170 $session.diagnostic().struct_dummy()
172 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
177 /// The type of a local binding, including the revealed type for anon types.
178 #[derive(Copy, Clone, Debug)]
179 pub struct LocalTy<'tcx> {
181 revealed_ty: Ty<'tcx>,
184 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
185 #[derive(Copy, Clone)]
186 struct MaybeInProgressTables<'a, 'tcx> {
187 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
190 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
191 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
192 match self.maybe_tables {
193 Some(tables) => tables.borrow(),
194 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
198 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
199 match self.maybe_tables {
200 Some(tables) => tables.borrow_mut(),
201 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
206 /// Closures defined within the function. For example:
209 /// bar(move|| { ... })
212 /// Here, the function `foo()` and the closure passed to
213 /// `bar()` will each have their own `FnCtxt`, but they will
214 /// share the inherited fields.
215 pub struct Inherited<'a, 'tcx> {
216 infcx: InferCtxt<'a, 'tcx>,
218 tables: MaybeInProgressTables<'a, 'tcx>,
220 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
222 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
224 // Some additional `Sized` obligations badly affect type inference.
225 // These obligations are added in a later stage of typeck.
226 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
228 // When we process a call like `c()` where `c` is a closure type,
229 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
230 // `FnOnce` closure. In that case, we defer full resolution of the
231 // call until upvar inference can kick in and make the
232 // decision. We keep these deferred resolutions grouped by the
233 // def-id of the closure, so that once we decide, we can easily go
234 // back and process them.
235 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
237 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
239 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
241 // Opaque types found in explicit return types and their
242 // associated fresh inference variable. Writeback resolves these
243 // variables to get the concrete type, which can be used to
244 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
245 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
247 /// A map from inference variables created from opaque
248 /// type instantiations (`ty::Infer`) to the actual opaque
249 /// type (`ty::Opaque`). Used during fallback to map unconstrained
250 /// opaque type inference variables to their corresponding
252 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
254 /// Each type parameter has an implicit region bound that
255 /// indicates it must outlive at least the function body (the user
256 /// may specify stronger requirements). This field indicates the
257 /// region of the callee. If it is `None`, then the parameter
258 /// environment is for an item or something where the "callee" is
260 implicit_region_bound: Option<ty::Region<'tcx>>,
262 body_id: Option<hir::BodyId>,
265 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
266 type Target = InferCtxt<'a, 'tcx>;
267 fn deref(&self) -> &Self::Target {
272 /// When type-checking an expression, we propagate downward
273 /// whatever type hint we are able in the form of an `Expectation`.
274 #[derive(Copy, Clone, Debug)]
275 pub enum Expectation<'tcx> {
276 /// We know nothing about what type this expression should have.
279 /// This expression should have the type given (or some subtype).
280 ExpectHasType(Ty<'tcx>),
282 /// This expression will be cast to the `Ty`.
283 ExpectCastableToType(Ty<'tcx>),
285 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
286 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
287 ExpectRvalueLikeUnsized(Ty<'tcx>),
290 impl<'a, 'tcx> Expectation<'tcx> {
291 // Disregard "castable to" expectations because they
292 // can lead us astray. Consider for example `if cond
293 // {22} else {c} as u8` -- if we propagate the
294 // "castable to u8" constraint to 22, it will pick the
295 // type 22u8, which is overly constrained (c might not
296 // be a u8). In effect, the problem is that the
297 // "castable to" expectation is not the tightest thing
298 // we can say, so we want to drop it in this case.
299 // The tightest thing we can say is "must unify with
300 // else branch". Note that in the case of a "has type"
301 // constraint, this limitation does not hold.
303 // If the expected type is just a type variable, then don't use
304 // an expected type. Otherwise, we might write parts of the type
305 // when checking the 'then' block which are incompatible with the
307 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
309 ExpectHasType(ety) => {
310 let ety = fcx.shallow_resolve(ety);
311 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
313 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
318 /// Provides an expectation for an rvalue expression given an *optional*
319 /// hint, which is not required for type safety (the resulting type might
320 /// be checked higher up, as is the case with `&expr` and `box expr`), but
321 /// is useful in determining the concrete type.
323 /// The primary use case is where the expected type is a fat pointer,
324 /// like `&[isize]`. For example, consider the following statement:
326 /// let x: &[isize] = &[1, 2, 3];
328 /// In this case, the expected type for the `&[1, 2, 3]` expression is
329 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
330 /// expectation `ExpectHasType([isize])`, that would be too strong --
331 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
332 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
333 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
334 /// which still is useful, because it informs integer literals and the like.
335 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
336 /// for examples of where this comes up,.
337 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
338 match fcx.tcx.struct_tail_without_normalization(ty).kind {
339 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
340 _ => ExpectHasType(ty),
344 // Resolves `expected` by a single level if it is a variable. If
345 // there is no expected type or resolution is not possible (e.g.,
346 // no constraints yet present), just returns `None`.
347 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
349 NoExpectation => NoExpectation,
350 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
351 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
352 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
356 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
357 match self.resolve(fcx) {
358 NoExpectation => None,
359 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
363 /// It sometimes happens that we want to turn an expectation into
364 /// a **hard constraint** (i.e., something that must be satisfied
365 /// for the program to type-check). `only_has_type` will return
366 /// such a constraint, if it exists.
367 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
368 match self.resolve(fcx) {
369 ExpectHasType(ty) => Some(ty),
370 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
374 /// Like `only_has_type`, but instead of returning `None` if no
375 /// hard constraint exists, creates a fresh type variable.
376 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
377 self.only_has_type(fcx).unwrap_or_else(|| {
378 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
383 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
390 fn maybe_mut_place(m: hir::Mutability) -> Self {
392 hir::Mutability::Mut => Needs::MutPlace,
393 hir::Mutability::Not => Needs::None,
398 #[derive(Copy, Clone)]
399 pub struct UnsafetyState {
401 pub unsafety: hir::Unsafety,
402 pub unsafe_push_count: u32,
407 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
408 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
411 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
412 use hir::BlockCheckMode;
413 match self.unsafety {
414 // If this unsafe, then if the outer function was already marked as
415 // unsafe we shouldn't attribute the unsafe'ness to the block. This
416 // way the block can be warned about instead of ignoring this
417 // extraneous block (functions are never warned about).
418 hir::Unsafety::Unsafe if self.from_fn => *self,
421 let (unsafety, def, count) = match blk.rules {
422 BlockCheckMode::PushUnsafeBlock(..) => {
423 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
425 BlockCheckMode::PopUnsafeBlock(..) => {
426 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
428 BlockCheckMode::UnsafeBlock(..) => {
429 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
431 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
433 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
439 #[derive(Debug, Copy, Clone)]
445 /// Tracks whether executing a node may exit normally (versus
446 /// return/break/panic, which "diverge", leaving dead code in their
447 /// wake). Tracked semi-automatically (through type variables marked
448 /// as diverging), with some manual adjustments for control-flow
449 /// primitives (approximating a CFG).
450 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
452 /// Potentially unknown, some cases converge,
453 /// others require a CFG to determine them.
456 /// Definitely known to diverge and therefore
457 /// not reach the next sibling or its parent.
459 /// The `Span` points to the expression
460 /// that caused us to diverge
461 /// (e.g. `return`, `break`, etc).
463 /// In some cases (e.g. a `match` expression
464 /// where all arms diverge), we may be
465 /// able to provide a more informative
466 /// message to the user.
467 /// If this is `None`, a default message
468 /// will be generated, which is suitable
470 custom_note: Option<&'static str>,
473 /// Same as `Always` but with a reachability
474 /// warning already emitted.
478 // Convenience impls for combining `Diverges`.
480 impl ops::BitAnd for Diverges {
482 fn bitand(self, other: Self) -> Self {
483 cmp::min(self, other)
487 impl ops::BitOr for Diverges {
489 fn bitor(self, other: Self) -> Self {
490 cmp::max(self, other)
494 impl ops::BitAndAssign for Diverges {
495 fn bitand_assign(&mut self, other: Self) {
496 *self = *self & other;
500 impl ops::BitOrAssign for Diverges {
501 fn bitor_assign(&mut self, other: Self) {
502 *self = *self | other;
507 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
508 fn always(span: Span) -> Diverges {
509 Diverges::Always { span, custom_note: None }
512 fn is_always(self) -> bool {
513 // Enum comparison ignores the
514 // contents of fields, so we just
515 // fill them in with garbage here.
516 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
520 pub struct BreakableCtxt<'tcx> {
523 // this is `null` for loops where break with a value is illegal,
524 // such as `while`, `for`, and `while let`
525 coerce: Option<DynamicCoerceMany<'tcx>>,
528 pub struct EnclosingBreakables<'tcx> {
529 stack: Vec<BreakableCtxt<'tcx>>,
530 by_id: HirIdMap<usize>,
533 impl<'tcx> EnclosingBreakables<'tcx> {
534 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
535 self.opt_find_breakable(target_id).unwrap_or_else(|| {
536 bug!("could not find enclosing breakable with id {}", target_id);
540 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
541 match self.by_id.get(&target_id) {
542 Some(ix) => Some(&mut self.stack[*ix]),
548 pub struct FnCtxt<'a, 'tcx> {
551 /// The parameter environment used for proving trait obligations
552 /// in this function. This can change when we descend into
553 /// closures (as they bring new things into scope), hence it is
554 /// not part of `Inherited` (as of the time of this writing,
555 /// closures do not yet change the environment, but they will
557 param_env: ty::ParamEnv<'tcx>,
559 /// Number of errors that had been reported when we started
560 /// checking this function. On exit, if we find that *more* errors
561 /// have been reported, we will skip regionck and other work that
562 /// expects the types within the function to be consistent.
563 // FIXME(matthewjasper) This should not exist, and it's not correct
564 // if type checking is run in parallel.
565 err_count_on_creation: usize,
567 /// If `Some`, this stores coercion information for returned
568 /// expressions. If `None`, this is in a context where return is
569 /// inappropriate, such as a const expression.
571 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
572 /// can track all the return expressions and then use them to
573 /// compute a useful coercion from the set, similar to a match
574 /// expression or other branching context. You can use methods
575 /// like `expected_ty` to access the declared return type (if
577 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
579 /// First span of a return site that we find. Used in error messages.
580 ret_coercion_span: RefCell<Option<Span>>,
582 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
584 ps: RefCell<UnsafetyState>,
586 /// Whether the last checked node generates a divergence (e.g.,
587 /// `return` will set this to `Always`). In general, when entering
588 /// an expression or other node in the tree, the initial value
589 /// indicates whether prior parts of the containing expression may
590 /// have diverged. It is then typically set to `Maybe` (and the
591 /// old value remembered) for processing the subparts of the
592 /// current expression. As each subpart is processed, they may set
593 /// the flag to `Always`, etc. Finally, at the end, we take the
594 /// result and "union" it with the original value, so that when we
595 /// return the flag indicates if any subpart of the parent
596 /// expression (up to and including this part) has diverged. So,
597 /// if you read it after evaluating a subexpression `X`, the value
598 /// you get indicates whether any subexpression that was
599 /// evaluating up to and including `X` diverged.
601 /// We currently use this flag only for diagnostic purposes:
603 /// - To warn about unreachable code: if, after processing a
604 /// sub-expression but before we have applied the effects of the
605 /// current node, we see that the flag is set to `Always`, we
606 /// can issue a warning. This corresponds to something like
607 /// `foo(return)`; we warn on the `foo()` expression. (We then
608 /// update the flag to `WarnedAlways` to suppress duplicate
609 /// reports.) Similarly, if we traverse to a fresh statement (or
610 /// tail expression) from a `Always` setting, we will issue a
611 /// warning. This corresponds to something like `{return;
612 /// foo();}` or `{return; 22}`, where we would warn on the
615 /// An expression represents dead code if, after checking it,
616 /// the diverges flag is set to something other than `Maybe`.
617 diverges: Cell<Diverges>,
619 /// Whether any child nodes have any type errors.
620 has_errors: Cell<bool>,
622 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
624 inh: &'a Inherited<'a, 'tcx>,
627 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
628 type Target = Inherited<'a, 'tcx>;
629 fn deref(&self) -> &Self::Target {
634 /// Helper type of a temporary returned by `Inherited::build(...)`.
635 /// Necessary because we can't write the following bound:
636 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
637 pub struct InheritedBuilder<'tcx> {
638 infcx: infer::InferCtxtBuilder<'tcx>,
642 impl Inherited<'_, 'tcx> {
643 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
644 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
647 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_owner),
653 impl<'tcx> InheritedBuilder<'tcx> {
654 fn enter<F, R>(&mut self, f: F) -> R
656 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
658 let def_id = self.def_id;
659 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
663 impl Inherited<'a, 'tcx> {
664 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
666 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
667 let body_id = tcx.hir().maybe_body_owned_by(item_id);
670 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
672 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
673 locals: RefCell::new(Default::default()),
674 deferred_sized_obligations: RefCell::new(Vec::new()),
675 deferred_call_resolutions: RefCell::new(Default::default()),
676 deferred_cast_checks: RefCell::new(Vec::new()),
677 deferred_generator_interiors: RefCell::new(Vec::new()),
678 opaque_types: RefCell::new(Default::default()),
679 opaque_types_vars: RefCell::new(Default::default()),
680 implicit_region_bound: None,
685 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
686 debug!("register_predicate({:?})", obligation);
687 if obligation.has_escaping_bound_vars() {
688 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
690 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
693 fn register_predicates<I>(&self, obligations: I)
695 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
697 for obligation in obligations {
698 self.register_predicate(obligation);
702 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
703 self.register_predicates(infer_ok.obligations);
707 fn normalize_associated_types_in<T>(
711 param_env: ty::ParamEnv<'tcx>,
715 T: TypeFoldable<'tcx>,
717 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
718 self.register_infer_ok_obligations(ok)
722 struct CheckItemTypesVisitor<'tcx> {
726 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
727 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
728 check_item_type(self.tcx, i);
730 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
731 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
734 pub fn check_wf_new(tcx: TyCtxt<'_>) {
735 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
736 tcx.hir().krate().par_visit_all_item_likes(&visit);
739 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
740 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
743 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
744 debug_assert!(crate_num == LOCAL_CRATE);
745 tcx.par_body_owners(|body_owner_def_id| {
746 tcx.ensure().typeck_tables_of(body_owner_def_id);
750 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
751 wfcheck::check_item_well_formed(tcx, def_id);
754 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
755 wfcheck::check_trait_item(tcx, def_id);
758 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
759 wfcheck::check_impl_item(tcx, def_id);
762 pub fn provide(providers: &mut Providers<'_>) {
763 method::provide(providers);
764 *providers = Providers {
767 diagnostic_only_typeck_tables_of,
771 check_item_well_formed,
772 check_trait_item_well_formed,
773 check_impl_item_well_formed,
774 check_mod_item_types,
779 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
780 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
783 /// If this `DefId` is a "primary tables entry", returns
784 /// `Some((body_id, header, decl))` with information about
785 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
788 /// If this function returns `Some`, then `typeck_tables(def_id)` will
789 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
790 /// may not succeed. In some cases where this function returns `None`
791 /// (notably closures), `typeck_tables(def_id)` would wind up
792 /// redirecting to the owning function.
796 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
797 match tcx.hir().get(id) {
798 Node::Item(item) => match item.kind {
799 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
800 Some((body, Some(ty), None, None))
802 hir::ItemKind::Fn(ref sig, .., body) => {
803 Some((body, None, Some(&sig.header), Some(&sig.decl)))
807 Node::TraitItem(item) => match item.kind {
808 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
809 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
810 Some((body, None, Some(&sig.header), Some(&sig.decl)))
814 Node::ImplItem(item) => match item.kind {
815 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
816 hir::ImplItemKind::Fn(ref sig, body) => {
817 Some((body, None, Some(&sig.header), Some(&sig.decl)))
821 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
826 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
827 // Closures' tables come from their outermost function,
828 // as they are part of the same "inference environment".
829 let outer_def_id = tcx.closure_base_def_id(def_id);
830 if outer_def_id != def_id {
831 return tcx.has_typeck_tables(outer_def_id);
834 if let Some(def_id) = def_id.as_local() {
835 let id = tcx.hir().local_def_id_to_hir_id(def_id);
836 primary_body_of(tcx, id).is_some()
842 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &DefIdSet {
843 &*tcx.typeck_tables_of(def_id).used_trait_imports
846 /// Inspects the substs of opaque types, replacing any inference variables
847 /// with proper generic parameter from the identity substs.
849 /// This is run after we normalize the function signature, to fix any inference
850 /// variables introduced by the projection of associated types. This ensures that
851 /// any opaque types used in the signature continue to refer to generic parameters,
852 /// allowing them to be considered for defining uses in the function body
854 /// For example, consider this code.
859 /// fn use_it(self) -> Self::MyItem
861 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
862 /// type MyItem = impl Iterator<Item = I>;
863 /// fn use_it(self) -> Self::MyItem {
869 /// When we normalize the signature of `use_it` from the impl block,
870 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
871 /// However, this projection result may contain inference variables, due
872 /// to the way that projection works. We didn't have any inference variables
873 /// in the signature to begin with - leaving them in will cause us to incorrectly
874 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
875 /// variables back to the actual generic parameters, we will correctly see that
876 /// we have a defining use of `MyItem`
877 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
879 T: TypeFoldable<'tcx>,
881 struct FixupFolder<'tcx> {
885 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
886 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
890 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
892 ty::Opaque(def_id, substs) => {
893 debug!("fixup_opaque_types: found type {:?}", ty);
894 // Here, we replace any inference variables that occur within
895 // the substs of an opaque type. By definition, any type occurring
896 // in the substs has a corresponding generic parameter, which is what
897 // we replace it with.
898 // This replacement is only run on the function signature, so any
899 // inference variables that we come across must be the rust of projection
900 // (there's no other way for a user to get inference variables into
901 // a function signature).
902 if ty.needs_infer() {
903 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
904 let old_param = substs[param.index as usize];
905 match old_param.unpack() {
906 GenericArgKind::Type(old_ty) => {
907 if let ty::Infer(_) = old_ty.kind {
908 // Replace inference type with a generic parameter
909 self.tcx.mk_param_from_def(param)
911 old_param.fold_with(self)
914 GenericArgKind::Const(old_const) => {
915 if let ty::ConstKind::Infer(_) = old_const.val {
916 // This should never happen - we currently do not support
917 // 'const projections', e.g.:
918 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
919 // which should be the only way for us to end up with a const inference
920 // variable after projection. If Rust ever gains support for this kind
921 // of projection, this should *probably* be changed to
922 // `self.tcx.mk_param_from_def(param)`
924 "Found infer const: `{:?}` in opaque type: {:?}",
929 old_param.fold_with(self)
932 GenericArgKind::Lifetime(old_region) => {
933 if let RegionKind::ReVar(_) = old_region {
934 self.tcx.mk_param_from_def(param)
936 old_param.fold_with(self)
941 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
942 debug!("fixup_opaque_types: new type: {:?}", new_ty);
948 _ => ty.super_fold_with(self),
953 debug!("fixup_opaque_types({:?})", val);
954 val.fold_with(&mut FixupFolder { tcx })
957 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> {
958 let fallback = move || tcx.type_of(def_id.to_def_id());
959 typeck_tables_of_with_fallback(tcx, def_id, fallback)
962 /// Used only to get `TypeckTables` for type inference during error recovery.
963 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
964 fn diagnostic_only_typeck_tables_of<'tcx>(
967 ) -> &ty::TypeckTables<'tcx> {
968 let fallback = move || {
969 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
970 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
973 typeck_tables_of_with_fallback(tcx, def_id, fallback)
976 fn typeck_tables_of_with_fallback<'tcx>(
979 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
980 ) -> &'tcx ty::TypeckTables<'tcx> {
981 // Closures' tables come from their outermost function,
982 // as they are part of the same "inference environment".
983 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
984 if outer_def_id != def_id {
985 return tcx.typeck_tables_of(outer_def_id);
988 let id = tcx.hir().as_local_hir_id(def_id);
989 let span = tcx.hir().span(id);
991 // Figure out what primary body this item has.
992 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
993 span_bug!(span, "can't type-check body of {:?}", def_id);
995 let body = tcx.hir().body(body_id);
997 let tables = Inherited::build(tcx, def_id).enter(|inh| {
998 let param_env = tcx.param_env(def_id);
999 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1000 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1001 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1007 &hir::Generics::empty(),
1014 check_abi(tcx, span, fn_sig.abi());
1016 // Compute the fty from point of view of inside the fn.
1017 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1018 let fn_sig = inh.normalize_associated_types_in(
1025 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1027 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1030 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1031 let expected_type = body_ty
1032 .and_then(|ty| match ty.kind {
1033 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1036 .unwrap_or_else(fallback);
1037 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1038 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1040 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1041 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1046 // Gather locals in statics (because of block expressions).
1047 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1049 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1051 fcx.write_ty(id, revealed_ty);
1056 // All type checking constraints were added, try to fallback unsolved variables.
1057 fcx.select_obligations_where_possible(false, |_| {});
1058 let mut fallback_has_occurred = false;
1060 // We do fallback in two passes, to try to generate
1061 // better error messages.
1062 // The first time, we do *not* replace opaque types.
1063 for ty in &fcx.unsolved_variables() {
1064 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1066 // We now see if we can make progress. This might
1067 // cause us to unify inference variables for opaque types,
1068 // since we may have unified some other type variables
1069 // during the first phase of fallback.
1070 // This means that we only replace inference variables with their underlying
1071 // opaque types as a last resort.
1073 // In code like this:
1076 // type MyType = impl Copy;
1077 // fn produce() -> MyType { true }
1078 // fn bad_produce() -> MyType { panic!() }
1081 // we want to unify the opaque inference variable in `bad_produce`
1082 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1083 // This will produce a nice error message about conflicting concrete
1084 // types for `MyType`.
1086 // If we had tried to fallback the opaque inference variable to `MyType`,
1087 // we will generate a confusing type-check error that does not explicitly
1088 // refer to opaque types.
1089 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1091 // We now run fallback again, but this time we allow it to replace
1092 // unconstrained opaque type variables, in addition to performing
1093 // other kinds of fallback.
1094 for ty in &fcx.unsolved_variables() {
1095 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1098 // See if we can make any more progress.
1099 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1101 // Even though coercion casts provide type hints, we check casts after fallback for
1102 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1105 // Closure and generator analysis may run after fallback
1106 // because they don't constrain other type variables.
1107 fcx.closure_analyze(body);
1108 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1109 fcx.resolve_generator_interiors(def_id.to_def_id());
1111 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1112 let ty = fcx.normalize_ty(span, ty);
1113 fcx.require_type_is_sized(ty, span, code);
1116 fcx.select_all_obligations_or_error();
1118 if fn_decl.is_some() {
1119 fcx.regionck_fn(id, body);
1121 fcx.regionck_expr(body);
1124 fcx.resolve_type_vars_in_body(body)
1127 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1128 // it will need to hold.
1129 assert_eq!(tables.hir_owner, Some(id.owner));
1134 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1135 if !tcx.sess.target.target.is_abi_supported(abi) {
1140 "The ABI `{}` is not supported for the current target",
1147 struct GatherLocalsVisitor<'a, 'tcx> {
1148 fcx: &'a FnCtxt<'a, 'tcx>,
1149 parent_id: hir::HirId,
1152 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1153 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1156 // Infer the variable's type.
1157 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1158 kind: TypeVariableOriginKind::TypeInference,
1164 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1168 // Take type that the user specified.
1169 self.fcx.locals.borrow_mut().insert(nid, typ);
1176 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1177 type Map = intravisit::ErasedMap<'tcx>;
1179 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1180 NestedVisitorMap::None
1183 // Add explicitly-declared locals.
1184 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1185 let local_ty = match local.ty {
1187 let o_ty = self.fcx.to_ty(&ty);
1189 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1190 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1199 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1201 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1202 ty.hir_id, o_ty, revealed_ty, c_ty
1204 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1206 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1210 self.assign(local.span, local.hir_id, local_ty);
1213 "local variable {:?} is assigned type {}",
1215 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1217 intravisit::walk_local(self, local);
1220 // Add pattern bindings.
1221 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1222 if let PatKind::Binding(_, _, ident, _) = p.kind {
1223 let var_ty = self.assign(p.span, p.hir_id, None);
1225 if !self.fcx.tcx.features().unsized_locals {
1226 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1230 "pattern binding {} is assigned to {} with type {:?}",
1232 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1236 intravisit::walk_pat(self, p);
1239 // Don't descend into the bodies of nested closures.
1242 _: intravisit::FnKind<'tcx>,
1243 _: &'tcx hir::FnDecl<'tcx>,
1251 /// When `check_fn` is invoked on a generator (i.e., a body that
1252 /// includes yield), it returns back some information about the yield
1254 struct GeneratorTypes<'tcx> {
1255 /// Type of generator argument / values returned by `yield`.
1256 resume_ty: Ty<'tcx>,
1258 /// Type of value that is yielded.
1261 /// Types that are captured (see `GeneratorInterior` for more).
1264 /// Indicates if the generator is movable or static (immovable).
1265 movability: hir::Movability,
1268 /// Helper used for fns and closures. Does the grungy work of checking a function
1269 /// body and returns the function context used for that purpose, since in the case of a fn item
1270 /// there is still a bit more to do.
1273 /// * inherited: other fields inherited from the enclosing fn (if any)
1274 fn check_fn<'a, 'tcx>(
1275 inherited: &'a Inherited<'a, 'tcx>,
1276 param_env: ty::ParamEnv<'tcx>,
1277 fn_sig: ty::FnSig<'tcx>,
1278 decl: &'tcx hir::FnDecl<'tcx>,
1280 body: &'tcx hir::Body<'tcx>,
1281 can_be_generator: Option<hir::Movability>,
1282 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1283 let mut fn_sig = fn_sig;
1285 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1287 // Create the function context. This is either derived from scratch or,
1288 // in the case of closures, based on the outer context.
1289 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1290 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1293 let sess = tcx.sess;
1294 let hir = tcx.hir();
1296 let declared_ret_ty = fn_sig.output();
1297 let revealed_ret_ty =
1298 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1299 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1300 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1301 fn_sig = tcx.mk_fn_sig(
1302 fn_sig.inputs().iter().cloned(),
1309 let span = body.value.span;
1311 fn_maybe_err(tcx, span, fn_sig.abi);
1313 if body.generator_kind.is_some() && can_be_generator.is_some() {
1315 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1316 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1318 // Resume type defaults to `()` if the generator has no argument.
1319 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1321 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1324 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
1325 let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1326 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1328 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1329 // (as it's created inside the body itself, not passed in from outside).
1330 let maybe_va_list = if fn_sig.c_variadic {
1331 let span = body.params.last().unwrap().span;
1332 let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
1333 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1335 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1340 // Add formal parameters.
1341 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1342 let inputs_fn = fn_sig.inputs().iter().copied();
1343 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1344 // Check the pattern.
1345 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1347 // Check that argument is Sized.
1348 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1349 // for simple cases like `fn foo(x: Trait)`,
1350 // where we would error once on the parameter as a whole, and once on the binding `x`.
1351 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1352 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1355 fcx.write_ty(param.hir_id, param_ty);
1358 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1360 if let ty::Dynamic(..) = declared_ret_ty.kind {
1361 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1362 // been evaluated so that we have types available for all the nodes being returned, but that
1363 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1364 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1365 // while keeping the current ordering we will ignore the tail expression's type because we
1366 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1367 // because we will trigger "unreachable expression" lints unconditionally.
1368 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1369 // case that a newcomer might make, returning a bare trait, and in that case we populate
1370 // the tail expression's type so that the suggestion will be correct, but ignore all other
1372 fcx.check_expr(&body.value);
1373 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1374 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1376 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1377 fcx.check_return_expr(&body.value);
1380 // We insert the deferred_generator_interiors entry after visiting the body.
1381 // This ensures that all nested generators appear before the entry of this generator.
1382 // resolve_generator_interiors relies on this property.
1383 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1385 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1386 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1388 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1389 Some(GeneratorTypes {
1393 movability: can_be_generator.unwrap(),
1399 // Finalize the return check by taking the LUB of the return types
1400 // we saw and assigning it to the expected return type. This isn't
1401 // really expected to fail, since the coercions would have failed
1402 // earlier when trying to find a LUB.
1404 // However, the behavior around `!` is sort of complex. In the
1405 // event that the `actual_return_ty` comes back as `!`, that
1406 // indicates that the fn either does not return or "returns" only
1407 // values of type `!`. In this case, if there is an expected
1408 // return type that is *not* `!`, that should be ok. But if the
1409 // return type is being inferred, we want to "fallback" to `!`:
1411 // let x = move || panic!();
1413 // To allow for that, I am creating a type variable with diverging
1414 // fallback. This was deemed ever so slightly better than unifying
1415 // the return value with `!` because it allows for the caller to
1416 // make more assumptions about the return type (e.g., they could do
1418 // let y: Option<u32> = Some(x());
1420 // which would then cause this return type to become `u32`, not
1422 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1423 let mut actual_return_ty = coercion.complete(&fcx);
1424 if actual_return_ty.is_never() {
1425 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1426 kind: TypeVariableOriginKind::DivergingFn,
1430 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1432 // Check that the main return type implements the termination trait.
1433 if let Some(term_id) = tcx.lang_items().termination() {
1434 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1435 let main_id = hir.as_local_hir_id(def_id);
1436 if main_id == fn_id {
1437 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1438 let trait_ref = ty::TraitRef::new(term_id, substs);
1439 let return_ty_span = decl.output.span();
1440 let cause = traits::ObligationCause::new(
1443 ObligationCauseCode::MainFunctionType,
1446 inherited.register_predicate(traits::Obligation::new(
1449 trait_ref.without_const().to_predicate(tcx),
1455 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1456 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1457 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1458 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1459 if declared_ret_ty.kind != ty::Never {
1460 sess.span_err(decl.output.span(), "return type should be `!`");
1463 let inputs = fn_sig.inputs();
1464 let span = hir.span(fn_id);
1465 if inputs.len() == 1 {
1466 let arg_is_panic_info = match inputs[0].kind {
1467 ty::Ref(region, ty, mutbl) => match ty.kind {
1468 ty::Adt(ref adt, _) => {
1469 adt.did == panic_info_did
1470 && mutbl == hir::Mutability::Not
1471 && *region != RegionKind::ReStatic
1478 if !arg_is_panic_info {
1479 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1482 if let Node::Item(item) = hir.get(fn_id) {
1483 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1484 if !generics.params.is_empty() {
1485 sess.span_err(span, "should have no type parameters");
1490 let span = sess.source_map().guess_head_span(span);
1491 sess.span_err(span, "function should have one argument");
1494 sess.err("language item required, but not found: `panic_info`");
1499 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1500 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1501 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1502 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1503 if declared_ret_ty.kind != ty::Never {
1504 sess.span_err(decl.output.span(), "return type should be `!`");
1507 let inputs = fn_sig.inputs();
1508 let span = hir.span(fn_id);
1509 if inputs.len() == 1 {
1510 let arg_is_alloc_layout = match inputs[0].kind {
1511 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1515 if !arg_is_alloc_layout {
1516 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1519 if let Node::Item(item) = hir.get(fn_id) {
1520 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1521 if !generics.params.is_empty() {
1524 "`#[alloc_error_handler]` function should have no type \
1531 let span = sess.source_map().guess_head_span(span);
1532 sess.span_err(span, "function should have one argument");
1535 sess.err("language item required, but not found: `alloc_layout`");
1543 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1544 let def_id = tcx.hir().local_def_id(id);
1545 let def = tcx.adt_def(def_id);
1546 def.destructor(tcx); // force the destructor to be evaluated
1547 check_representable(tcx, span, def_id);
1549 if def.repr.simd() {
1550 check_simd(tcx, span, def_id);
1553 check_transparent(tcx, span, def);
1554 check_packed(tcx, span, def);
1557 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1558 let def_id = tcx.hir().local_def_id(id);
1559 let def = tcx.adt_def(def_id);
1560 def.destructor(tcx); // force the destructor to be evaluated
1561 check_representable(tcx, span, def_id);
1562 check_transparent(tcx, span, def);
1563 check_union_fields(tcx, span, def_id);
1564 check_packed(tcx, span, def);
1567 /// When the `#![feature(untagged_unions)]` gate is active,
1568 /// check that the fields of the `union` does not contain fields that need dropping.
1569 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1570 let item_type = tcx.type_of(item_def_id);
1571 if let ty::Adt(def, substs) = item_type.kind {
1572 assert!(def.is_union());
1573 let fields = &def.non_enum_variant().fields;
1574 let param_env = tcx.param_env(item_def_id);
1575 for field in fields {
1576 let field_ty = field.ty(tcx, substs);
1577 // We are currently checking the type this field came from, so it must be local.
1578 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1579 if field_ty.needs_drop(tcx, param_env) {
1584 "unions may not contain fields that need dropping"
1586 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1592 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1597 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1598 /// projections that would result in "inheriting lifetimes".
1599 fn check_opaque<'tcx>(
1602 substs: SubstsRef<'tcx>,
1604 origin: &hir::OpaqueTyOrigin,
1606 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1607 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1610 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1611 /// in "inheriting lifetimes".
1612 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1613 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1615 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1620 struct ProhibitOpaqueVisitor<'tcx> {
1621 opaque_identity_ty: Ty<'tcx>,
1622 generics: &'tcx ty::Generics,
1623 ty: Option<Ty<'tcx>>,
1626 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1627 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1628 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1629 if t != self.opaque_identity_ty && t.super_visit_with(self) {
1636 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1637 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1638 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1639 return *index < self.generics.parent_count as u32;
1642 r.super_visit_with(self)
1645 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1646 if let ty::ConstKind::Unevaluated(..) = c.val {
1647 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1648 // which would violate this check. Even though the particular substitution is not used
1649 // within the const, this should still be fixed.
1652 c.super_visit_with(self)
1656 if let ItemKind::OpaqueTy(hir::OpaqueTy {
1657 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1661 let mut visitor = ProhibitOpaqueVisitor {
1662 opaque_identity_ty: tcx.mk_opaque(
1664 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1666 generics: tcx.generics_of(def_id),
1669 let prohibit_opaque = tcx
1670 .predicates_of(def_id)
1673 .any(|(predicate, _)| predicate.visit_with(&mut visitor));
1675 "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
1676 prohibit_opaque, visitor
1679 if prohibit_opaque {
1680 let is_async = match item.kind {
1681 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1682 hir::OpaqueTyOrigin::AsyncFn => true,
1685 _ => unreachable!(),
1688 let mut err = struct_span_err!(
1692 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1694 if is_async { "async fn" } else { "impl Trait" },
1697 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
1698 if snippet == "Self" {
1699 if let Some(ty) = visitor.ty {
1700 err.span_suggestion(
1702 "consider spelling out the type instead",
1703 format!("{:?}", ty),
1704 Applicability::MaybeIncorrect,
1714 /// Checks that an opaque type does not contain cycles.
1715 fn check_opaque_for_cycles<'tcx>(
1718 substs: SubstsRef<'tcx>,
1720 origin: &hir::OpaqueTyOrigin,
1722 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1724 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1725 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1726 .span_label(span, "recursive `async fn`")
1727 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1731 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1732 err.span_label(span, "expands to a recursive type");
1733 if let ty::Opaque(..) = partially_expanded_type.kind {
1734 err.note("type resolves to itself");
1736 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1743 // Forbid defining intrinsics in Rust code,
1744 // as they must always be defined by the compiler.
1745 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1746 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1747 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1751 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1753 "check_item_type(it.hir_id={}, it.name={})",
1755 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1757 let _indenter = indenter();
1759 // Consts can play a role in type-checking, so they are included here.
1760 hir::ItemKind::Static(..) => {
1761 let def_id = tcx.hir().local_def_id(it.hir_id);
1762 tcx.ensure().typeck_tables_of(def_id);
1763 maybe_check_static_with_link_section(tcx, def_id, it.span);
1765 hir::ItemKind::Const(..) => {
1766 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1768 hir::ItemKind::Enum(ref enum_definition, _) => {
1769 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1771 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1772 hir::ItemKind::Impl { ref items, .. } => {
1773 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1774 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1775 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1776 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1777 let trait_def_id = impl_trait_ref.def_id;
1778 check_on_unimplemented(tcx, trait_def_id, it);
1781 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1782 let def_id = tcx.hir().local_def_id(it.hir_id);
1783 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1785 for item in items.iter() {
1786 let item = tcx.hir().trait_item(item.id);
1787 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1788 let abi = sig.header.abi;
1789 fn_maybe_err(tcx, item.ident.span, abi);
1793 hir::ItemKind::Struct(..) => {
1794 check_struct(tcx, it.hir_id, it.span);
1796 hir::ItemKind::Union(..) => {
1797 check_union(tcx, it.hir_id, it.span);
1799 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1800 let def_id = tcx.hir().local_def_id(it.hir_id);
1802 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1803 check_opaque(tcx, def_id, substs, it.span, &origin);
1805 hir::ItemKind::TyAlias(..) => {
1806 let def_id = tcx.hir().local_def_id(it.hir_id);
1807 let pty_ty = tcx.type_of(def_id);
1808 let generics = tcx.generics_of(def_id);
1809 check_type_params_are_used(tcx, &generics, pty_ty);
1811 hir::ItemKind::ForeignMod(ref m) => {
1812 check_abi(tcx, it.span, m.abi);
1814 if m.abi == Abi::RustIntrinsic {
1815 for item in m.items {
1816 intrinsic::check_intrinsic_type(tcx, item);
1818 } else if m.abi == Abi::PlatformIntrinsic {
1819 for item in m.items {
1820 intrinsic::check_platform_intrinsic_type(tcx, item);
1823 for item in m.items {
1824 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1825 let own_counts = generics.own_counts();
1826 if generics.params.len() - own_counts.lifetimes != 0 {
1827 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1828 (_, 0) => ("type", "types", Some("u32")),
1829 // We don't specify an example value, because we can't generate
1830 // a valid value for any type.
1831 (0, _) => ("const", "consts", None),
1832 _ => ("type or const", "types or consts", None),
1838 "foreign items may not have {} parameters",
1841 .span_label(item.span, &format!("can't have {} parameters", kinds))
1843 // FIXME: once we start storing spans for type arguments, turn this
1844 // into a suggestion.
1846 "replace the {} parameters with concrete {}{}",
1849 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1855 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1856 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1861 _ => { /* nothing to do */ }
1865 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1866 // Only restricted on wasm32 target for now
1867 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1871 // If `#[link_section]` is missing, then nothing to verify
1872 let attrs = tcx.codegen_fn_attrs(id);
1873 if attrs.link_section.is_none() {
1877 // For the wasm32 target statics with `#[link_section]` are placed into custom
1878 // sections of the final output file, but this isn't link custom sections of
1879 // other executable formats. Namely we can only embed a list of bytes,
1880 // nothing with pointers to anything else or relocations. If any relocation
1881 // show up, reject them here.
1882 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1883 // the consumer's responsibility to ensure all bytes that have been read
1884 // have defined values.
1885 match tcx.const_eval_poly(id.to_def_id()) {
1886 Ok(ConstValue::ByRef { alloc, .. }) => {
1887 if alloc.relocations().len() != 0 {
1888 let msg = "statics with a custom `#[link_section]` must be a \
1889 simple list of bytes on the wasm target with no \
1890 extra levels of indirection such as references";
1891 tcx.sess.span_err(span, msg);
1894 Ok(_) => bug!("Matching on non-ByRef static"),
1899 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1900 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1901 // an error would be reported if this fails.
1902 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1905 fn report_forbidden_specialization(
1907 impl_item: &hir::ImplItem<'_>,
1910 let mut err = struct_span_err!(
1914 "`{}` specializes an item from a parent `impl`, but \
1915 that item is not marked `default`",
1918 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1920 match tcx.span_of_impl(parent_impl) {
1922 err.span_label(span, "parent `impl` is here");
1924 "to specialize, `{}` in the parent `impl` must be marked `default`",
1929 err.note(&format!("parent implementation is in crate `{}`", cname));
1936 fn check_specialization_validity<'tcx>(
1938 trait_def: &ty::TraitDef,
1939 trait_item: &ty::AssocItem,
1941 impl_item: &hir::ImplItem<'_>,
1943 let kind = match impl_item.kind {
1944 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1945 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1946 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1947 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1950 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1951 Ok(ancestors) => ancestors,
1954 let mut ancestor_impls = ancestors
1956 .filter_map(|parent| {
1957 if parent.is_from_trait() {
1960 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1965 if ancestor_impls.peek().is_none() {
1966 // No parent, nothing to specialize.
1970 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1972 // Parent impl exists, and contains the parent item we're trying to specialize, but
1973 // doesn't mark it `default`.
1974 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1975 Some(Err(parent_impl.def_id()))
1978 // Parent impl contains item and makes it specializable.
1979 Some(_) => Some(Ok(())),
1981 // Parent impl doesn't mention the item. This means it's inherited from the
1982 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1983 // "defaultness" from the grandparent, else they are final.
1985 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1988 Some(Err(parent_impl.def_id()))
1994 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1995 // item. This is allowed, the item isn't actually getting specialized here.
1996 let result = opt_result.unwrap_or(Ok(()));
1998 if let Err(parent_impl) = result {
1999 report_forbidden_specialization(tcx, impl_item, parent_impl);
2003 fn check_impl_items_against_trait<'tcx>(
2005 full_impl_span: Span,
2006 impl_id: LocalDefId,
2007 impl_trait_ref: ty::TraitRef<'tcx>,
2008 impl_item_refs: &[hir::ImplItemRef<'_>],
2010 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2012 // If the trait reference itself is erroneous (so the compilation is going
2013 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2014 // isn't populated for such impls.
2015 if impl_trait_ref.references_error() {
2019 // Negative impls are not expected to have any items
2020 match tcx.impl_polarity(impl_id) {
2021 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2022 ty::ImplPolarity::Negative => {
2023 if let [first_item_ref, ..] = impl_item_refs {
2024 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2029 "negative impls cannot have any items"
2037 // Locate trait definition and items
2038 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2040 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2042 // Check existing impl methods to see if they are both present in trait
2043 // and compatible with trait signature
2044 for impl_item in impl_items() {
2045 let namespace = impl_item.kind.namespace();
2046 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2047 let ty_trait_item = tcx
2048 .associated_items(impl_trait_ref.def_id)
2049 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2051 // Not compatible, but needed for the error message
2052 tcx.associated_items(impl_trait_ref.def_id)
2053 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2057 // Check that impl definition matches trait definition
2058 if let Some(ty_trait_item) = ty_trait_item {
2059 match impl_item.kind {
2060 hir::ImplItemKind::Const(..) => {
2061 // Find associated const definition.
2062 if ty_trait_item.kind == ty::AssocKind::Const {
2071 let mut err = struct_span_err!(
2075 "item `{}` is an associated const, \
2076 which doesn't match its trait `{}`",
2078 impl_trait_ref.print_only_trait_path()
2080 err.span_label(impl_item.span, "does not match trait");
2081 // We can only get the spans from local trait definition
2082 // Same for E0324 and E0325
2083 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2084 err.span_label(trait_span, "item in trait");
2089 hir::ImplItemKind::Fn(..) => {
2090 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2091 if ty_trait_item.kind == ty::AssocKind::Fn {
2092 compare_impl_method(
2101 let mut err = struct_span_err!(
2105 "item `{}` is an associated method, \
2106 which doesn't match its trait `{}`",
2108 impl_trait_ref.print_only_trait_path()
2110 err.span_label(impl_item.span, "does not match trait");
2111 if let Some(trait_span) = opt_trait_span {
2112 err.span_label(trait_span, "item in trait");
2117 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2118 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2119 if ty_trait_item.kind == ty::AssocKind::Type {
2129 let mut err = struct_span_err!(
2133 "item `{}` is an associated type, \
2134 which doesn't match its trait `{}`",
2136 impl_trait_ref.print_only_trait_path()
2138 err.span_label(impl_item.span, "does not match trait");
2139 if let Some(trait_span) = opt_trait_span {
2140 err.span_label(trait_span, "item in trait");
2147 check_specialization_validity(
2151 impl_id.to_def_id(),
2157 // Check for missing items from trait
2158 let mut missing_items = Vec::new();
2159 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2160 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2161 let is_implemented = ancestors
2162 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2163 .map(|node_item| !node_item.defining_node.is_from_trait())
2166 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2167 if !trait_item.defaultness.has_value() {
2168 missing_items.push(*trait_item);
2174 if !missing_items.is_empty() {
2175 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2179 fn missing_items_err(
2182 missing_items: &[ty::AssocItem],
2183 full_impl_span: Span,
2185 let missing_items_msg = missing_items
2187 .map(|trait_item| trait_item.ident.to_string())
2188 .collect::<Vec<_>>()
2191 let mut err = struct_span_err!(
2195 "not all trait items implemented, missing: `{}`",
2198 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2200 // `Span` before impl block closing brace.
2201 let hi = full_impl_span.hi() - BytePos(1);
2202 // Point at the place right before the closing brace of the relevant `impl` to suggest
2203 // adding the associated item at the end of its body.
2204 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2205 // Obtain the level of indentation ending in `sugg_sp`.
2206 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2207 // Make the whitespace that will make the suggestion have the right indentation.
2208 let padding: String = (0..indentation).map(|_| " ").collect();
2210 for trait_item in missing_items {
2211 let snippet = suggestion_signature(&trait_item, tcx);
2212 let code = format!("{}{}\n{}", padding, snippet, padding);
2213 let msg = format!("implement the missing item: `{}`", snippet);
2214 let appl = Applicability::HasPlaceholders;
2215 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2216 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2217 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2219 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2225 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2226 fn bounds_from_generic_predicates(
2228 predicates: ty::GenericPredicates<'_>,
2229 ) -> (String, String) {
2230 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2231 let mut projections = vec![];
2232 for (predicate, _) in predicates.predicates {
2233 debug!("predicate {:?}", predicate);
2234 match predicate.kind() {
2235 ty::PredicateKind::Trait(trait_predicate, _) => {
2236 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2237 let def_id = trait_predicate.skip_binder().def_id();
2238 if Some(def_id) != tcx.lang_items().sized_trait() {
2239 // Type params are `Sized` by default, do not add that restriction to the list
2240 // if it is a positive requirement.
2241 entry.push(trait_predicate.skip_binder().def_id());
2244 ty::PredicateKind::Projection(projection_pred) => {
2245 projections.push(projection_pred);
2250 let generics = if types.is_empty() {
2257 .filter_map(|t| match t.kind {
2258 ty::Param(_) => Some(t.to_string()),
2259 // Avoid suggesting the following:
2260 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2263 .collect::<Vec<_>>()
2267 let mut where_clauses = vec![];
2268 for (ty, bounds) in types {
2269 for bound in &bounds {
2270 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2273 for projection in &projections {
2274 let p = projection.skip_binder();
2275 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2276 // insert the associated types where they correspond, but for now let's be "lazy" and
2277 // propose this instead of the following valid resugaring:
2278 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2279 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2281 let where_clauses = if where_clauses.is_empty() {
2284 format!(" where {}", where_clauses.join(", "))
2286 (generics, where_clauses)
2289 /// Return placeholder code for the given function.
2290 fn fn_sig_suggestion(
2292 sig: &ty::FnSig<'_>,
2294 predicates: ty::GenericPredicates<'_>,
2295 assoc: &ty::AssocItem,
2302 Some(match ty.kind {
2303 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2304 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2305 let reg = match &format!("{}", reg)[..] {
2306 "'_" | "" => String::new(),
2307 reg => format!("{} ", reg),
2309 if assoc.fn_has_self_parameter {
2311 ty::Param(param) if param.name == kw::SelfUpper => {
2312 format!("&{}{}self", reg, mutability.prefix_str())
2315 _ => format!("self: {}", ty),
2318 format!("_: {:?}", ty)
2322 if assoc.fn_has_self_parameter && i == 0 {
2323 format!("self: {:?}", ty)
2325 format!("_: {:?}", ty)
2330 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2331 .filter_map(|arg| arg)
2332 .collect::<Vec<String>>()
2334 let output = sig.output();
2335 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2337 let unsafety = sig.unsafety.prefix_str();
2338 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2340 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2341 // not be present in the `fn` definition, not will we account for renamed
2342 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2343 // fill in a significant portion of the missing code, and other subsequent
2344 // suggestions can help the user fix the code.
2346 "{}fn {}{}({}){}{} {{ todo!() }}",
2347 unsafety, ident, generics, args, output, where_clauses
2351 /// Return placeholder code for the given associated item.
2352 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2353 /// structured suggestion.
2354 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2356 ty::AssocKind::Fn => {
2357 // We skip the binder here because the binder would deanonymize all
2358 // late-bound regions, and we don't want method signatures to show up
2359 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2360 // regions just fine, showing `fn(&MyType)`.
2363 tcx.fn_sig(assoc.def_id).skip_binder(),
2365 tcx.predicates_of(assoc.def_id),
2369 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2370 // FIXME(type_alias_impl_trait): we should print bounds here too.
2371 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2372 ty::AssocKind::Const => {
2373 let ty = tcx.type_of(assoc.def_id);
2374 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2375 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2380 /// Checks whether a type can be represented in memory. In particular, it
2381 /// identifies types that contain themselves without indirection through a
2382 /// pointer, which would mean their size is unbounded.
2383 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2384 let rty = tcx.type_of(item_def_id);
2386 // Check that it is possible to represent this type. This call identifies
2387 // (1) types that contain themselves and (2) types that contain a different
2388 // recursive type. It is only necessary to throw an error on those that
2389 // contain themselves. For case 2, there must be an inner type that will be
2390 // caught by case 1.
2391 match rty.is_representable(tcx, sp) {
2392 Representability::SelfRecursive(spans) => {
2393 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2395 err.span_label(span, "recursive without indirection");
2400 Representability::Representable | Representability::ContainsRecursive => (),
2405 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2406 let t = tcx.type_of(def_id);
2407 if let ty::Adt(def, substs) = t.kind {
2408 if def.is_struct() {
2409 let fields = &def.non_enum_variant().fields;
2410 if fields.is_empty() {
2411 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2414 let e = fields[0].ty(tcx, substs);
2415 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2416 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2417 .span_label(sp, "SIMD elements must have the same type")
2422 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2423 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2429 "SIMD vector element type should be machine type"
2439 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2440 let repr = def.repr;
2442 for attr in tcx.get_attrs(def.did).iter() {
2443 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2444 if let attr::ReprPacked(pack) = r {
2445 if let Some(repr_pack) = repr.pack {
2446 if pack as u64 != repr_pack.bytes() {
2451 "type has conflicting packed representation hints"
2459 if repr.align.is_some() {
2464 "type has conflicting packed and align representation hints"
2468 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2469 let mut err = struct_span_err!(
2473 "packed type cannot transitively contain a `#[repr(align)]` type"
2476 let hir = tcx.hir();
2477 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2478 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2480 tcx.def_span(def_spans[0].0),
2481 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2485 if def_spans.len() > 2 {
2486 let mut first = true;
2487 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2488 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2489 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2494 "`{}` contains a field of type `{}`",
2495 tcx.type_of(def.did),
2499 format!("...which contains a field of type `{}`", ident)
2513 fn check_packed_inner(
2516 stack: &mut Vec<DefId>,
2517 ) -> Option<Vec<(DefId, Span)>> {
2518 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2519 if def.is_struct() || def.is_union() {
2520 if def.repr.align.is_some() {
2521 return Some(vec![(def.did, DUMMY_SP)]);
2525 for field in &def.non_enum_variant().fields {
2526 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2527 if !stack.contains(&def.did) {
2528 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2529 defs.push((def.did, field.ident.span));
2542 /// Emit an error when encountering more or less than one variant in a transparent enum.
2543 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2544 let variant_spans: Vec<_> = adt
2547 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2549 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2550 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2551 err.span_label(sp, &msg);
2552 if let [start @ .., end] = &*variant_spans {
2553 for variant_span in start {
2554 err.span_label(*variant_span, "");
2556 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2561 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2563 fn bad_non_zero_sized_fields<'tcx>(
2565 adt: &'tcx ty::AdtDef,
2567 field_spans: impl Iterator<Item = Span>,
2570 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2571 let mut err = struct_span_err!(
2575 "{}transparent {} {}",
2576 if adt.is_enum() { "the variant of a " } else { "" },
2580 err.span_label(sp, &msg);
2581 for sp in field_spans {
2582 err.span_label(sp, "this field is non-zero-sized");
2587 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2588 if !adt.repr.transparent() {
2591 let sp = tcx.sess.source_map().guess_head_span(sp);
2593 if adt.is_union() && !tcx.features().transparent_unions {
2595 &tcx.sess.parse_sess,
2596 sym::transparent_unions,
2598 "transparent unions are unstable",
2603 if adt.variants.len() != 1 {
2604 bad_variant_count(tcx, adt, sp, adt.did);
2605 if adt.variants.is_empty() {
2606 // Don't bother checking the fields. No variants (and thus no fields) exist.
2611 // For each field, figure out if it's known to be a ZST and align(1)
2612 let field_infos = adt.all_fields().map(|field| {
2613 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2614 let param_env = tcx.param_env(field.did);
2615 let layout = tcx.layout_of(param_env.and(ty));
2616 // We are currently checking the type this field came from, so it must be local
2617 let span = tcx.hir().span_if_local(field.did).unwrap();
2618 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2619 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2623 let non_zst_fields =
2624 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2625 let non_zst_count = non_zst_fields.clone().count();
2626 if non_zst_count != 1 {
2627 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2629 for (span, zst, align1) in field_infos {
2635 "zero-sized field in transparent {} has alignment larger than 1",
2638 .span_label(span, "has alignment larger than 1")
2644 #[allow(trivial_numeric_casts)]
2645 pub fn check_enum<'tcx>(
2648 vs: &'tcx [hir::Variant<'tcx>],
2651 let def_id = tcx.hir().local_def_id(id);
2652 let def = tcx.adt_def(def_id);
2653 def.destructor(tcx); // force the destructor to be evaluated
2656 let attributes = tcx.get_attrs(def_id.to_def_id());
2657 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2662 "unsupported representation for zero-variant enum"
2664 .span_label(sp, "zero-variant enum")
2669 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2670 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2671 if !tcx.features().repr128 {
2673 &tcx.sess.parse_sess,
2676 "repr with 128-bit type is unstable",
2683 if let Some(ref e) = v.disr_expr {
2684 tcx.ensure().typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2688 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2689 let is_unit = |var: &hir::Variant<'_>| match var.data {
2690 hir::VariantData::Unit(..) => true,
2694 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2695 let has_non_units = vs.iter().any(|var| !is_unit(var));
2696 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2697 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2699 if disr_non_unit || (disr_units && has_non_units) {
2701 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2706 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2707 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2708 // Check for duplicate discriminant values
2709 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2710 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2711 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2712 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2713 let i_span = match variant_i.disr_expr {
2714 Some(ref expr) => tcx.hir().span(expr.hir_id),
2715 None => tcx.hir().span(variant_i_hir_id),
2717 let span = match v.disr_expr {
2718 Some(ref expr) => tcx.hir().span(expr.hir_id),
2725 "discriminant value `{}` already exists",
2728 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2729 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2732 disr_vals.push(discr);
2735 check_representable(tcx, sp, def_id);
2736 check_transparent(tcx, sp, def);
2739 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2744 "expected unit struct, unit variant or constant, found {}{}",
2746 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2751 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2752 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2756 fn item_def_id(&self) -> Option<DefId> {
2760 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2761 // FIXME: refactor this into a method
2762 let node = self.tcx.hir().get(self.body_id);
2763 if let Some(fn_like) = FnLikeNode::from_node(node) {
2766 hir::Constness::NotConst
2770 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2772 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2773 let item_id = tcx.hir().ty_param_owner(hir_id);
2774 let item_def_id = tcx.hir().local_def_id(item_id);
2775 let generics = tcx.generics_of(item_def_id);
2776 let index = generics.param_def_id_to_index[&def_id];
2777 ty::GenericPredicates {
2779 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2780 |predicate| match predicate.kind() {
2781 ty::PredicateKind::Trait(ref data, _)
2782 if data.skip_binder().self_ty().is_param(index) =>
2784 // HACK(eddyb) should get the original `Span`.
2785 let span = tcx.def_span(def_id);
2786 Some((predicate, span))
2794 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2796 Some(def) => infer::EarlyBoundRegion(span, def.name),
2797 None => infer::MiscVariable(span),
2799 Some(self.next_region_var(v))
2802 fn allow_ty_infer(&self) -> bool {
2806 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2807 if let Some(param) = param {
2808 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2813 self.next_ty_var(TypeVariableOrigin {
2814 kind: TypeVariableOriginKind::TypeInference,
2823 param: Option<&ty::GenericParamDef>,
2825 ) -> &'tcx Const<'tcx> {
2826 if let Some(param) = param {
2827 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2832 self.next_const_var(
2834 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2839 fn projected_ty_from_poly_trait_ref(
2843 item_segment: &hir::PathSegment<'_>,
2844 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2846 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2848 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2852 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2861 self.tcx().mk_projection(item_def_id, item_substs)
2864 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2865 if ty.has_escaping_bound_vars() {
2866 ty // FIXME: normalization and escaping regions
2868 self.normalize_associated_types_in(span, &ty)
2872 fn set_tainted_by_errors(&self) {
2873 self.infcx.set_tainted_by_errors()
2876 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2877 self.write_ty(hir_id, ty)
2881 /// Controls whether the arguments are tupled. This is used for the call
2884 /// Tupling means that all call-side arguments are packed into a tuple and
2885 /// passed as a single parameter. For example, if tupling is enabled, this
2888 /// fn f(x: (isize, isize))
2890 /// Can be called as:
2897 #[derive(Clone, Eq, PartialEq)]
2898 enum TupleArgumentsFlag {
2903 /// Controls how we perform fallback for unconstrained
2906 /// Do not fallback type variables to opaque types.
2908 /// Perform all possible kinds of fallback, including
2909 /// turning type variables to opaque types.
2913 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2915 inh: &'a Inherited<'a, 'tcx>,
2916 param_env: ty::ParamEnv<'tcx>,
2917 body_id: hir::HirId,
2918 ) -> FnCtxt<'a, 'tcx> {
2922 err_count_on_creation: inh.tcx.sess.err_count(),
2924 ret_coercion_span: RefCell::new(None),
2925 resume_yield_tys: None,
2926 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2927 diverges: Cell::new(Diverges::Maybe),
2928 has_errors: Cell::new(false),
2929 enclosing_breakables: RefCell::new(EnclosingBreakables {
2931 by_id: Default::default(),
2937 pub fn sess(&self) -> &Session {
2941 pub fn errors_reported_since_creation(&self) -> bool {
2942 self.tcx.sess.err_count() > self.err_count_on_creation
2945 /// Produces warning on the given node, if the current point in the
2946 /// function is unreachable, and there hasn't been another warning.
2947 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2948 // FIXME: Combine these two 'if' expressions into one once
2949 // let chains are implemented
2950 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2951 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2952 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2953 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2954 if !span.is_desugaring(DesugaringKind::CondTemporary)
2955 && !span.is_desugaring(DesugaringKind::Async)
2956 && !orig_span.is_desugaring(DesugaringKind::Await)
2958 self.diverges.set(Diverges::WarnedAlways);
2960 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2962 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2963 let msg = format!("unreachable {}", kind);
2965 .span_label(span, &msg)
2969 .unwrap_or("any code following this expression is unreachable"),
2977 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2978 ObligationCause::new(span, self.body_id, code)
2981 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2982 self.cause(span, ObligationCauseCode::MiscObligation)
2985 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2986 /// version (resolve_vars_if_possible), this version will
2987 /// also select obligations if it seems useful, in an effort
2988 /// to get more type information.
2989 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2990 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2992 // No Infer()? Nothing needs doing.
2993 if !ty.has_infer_types_or_consts() {
2994 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2998 // If `ty` is a type variable, see whether we already know what it is.
2999 ty = self.resolve_vars_if_possible(&ty);
3000 if !ty.has_infer_types_or_consts() {
3001 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3005 // If not, try resolving pending obligations as much as
3006 // possible. This can help substantially when there are
3007 // indirect dependencies that don't seem worth tracking
3009 self.select_obligations_where_possible(false, |_| {});
3010 ty = self.resolve_vars_if_possible(&ty);
3012 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3016 fn record_deferred_call_resolution(
3018 closure_def_id: DefId,
3019 r: DeferredCallResolution<'tcx>,
3021 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3022 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3025 fn remove_deferred_call_resolutions(
3027 closure_def_id: DefId,
3028 ) -> Vec<DeferredCallResolution<'tcx>> {
3029 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3030 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3033 pub fn tag(&self) -> String {
3034 format!("{:p}", self)
3037 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3038 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3039 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3044 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3046 "write_ty({:?}, {:?}) in fcx {}",
3048 self.resolve_vars_if_possible(&ty),
3051 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3053 if ty.references_error() {
3054 self.has_errors.set(true);
3055 self.set_tainted_by_errors();
3059 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3060 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3063 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3064 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3067 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3068 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3069 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3070 self.write_substs(hir_id, method.substs);
3072 // When the method is confirmed, the `method.substs` includes
3073 // parameters from not just the method, but also the impl of
3074 // the method -- in particular, the `Self` type will be fully
3075 // resolved. However, those are not something that the "user
3076 // specified" -- i.e., those types come from the inferred type
3077 // of the receiver, not something the user wrote. So when we
3078 // create the user-substs, we want to replace those earlier
3079 // types with just the types that the user actually wrote --
3080 // that is, those that appear on the *method itself*.
3082 // As an example, if the user wrote something like
3083 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3084 // type of `foo` (possibly adjusted), but we don't want to
3085 // include that. We want just the `[_, u32]` part.
3086 if !method.substs.is_noop() {
3087 let method_generics = self.tcx.generics_of(method.def_id);
3088 if !method_generics.params.is_empty() {
3089 let user_type_annotation = self.infcx.probe(|_| {
3090 let user_substs = UserSubsts {
3091 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3092 let i = param.index as usize;
3093 if i < method_generics.parent_count {
3094 self.infcx.var_for_def(DUMMY_SP, param)
3099 user_self_ty: None, // not relevant here
3102 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3108 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3109 self.write_user_type_annotation(hir_id, user_type_annotation);
3114 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3115 if !substs.is_noop() {
3116 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3118 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3122 /// Given the substs that we just converted from the HIR, try to
3123 /// canonicalize them and store them as user-given substitutions
3124 /// (i.e., substitutions that must be respected by the NLL check).
3126 /// This should be invoked **before any unifications have
3127 /// occurred**, so that annotations like `Vec<_>` are preserved
3129 pub fn write_user_type_annotation_from_substs(
3133 substs: SubstsRef<'tcx>,
3134 user_self_ty: Option<UserSelfTy<'tcx>>,
3137 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3138 user_self_ty={:?} in fcx {}",
3146 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3147 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3149 UserSubsts { substs, user_self_ty },
3151 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3152 self.write_user_type_annotation(hir_id, canonicalized);
3156 pub fn write_user_type_annotation(
3159 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3162 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3164 canonical_user_type_annotation,
3168 if !canonical_user_type_annotation.is_identity() {
3171 .user_provided_types_mut()
3172 .insert(hir_id, canonical_user_type_annotation);
3174 debug!("write_user_type_annotation: skipping identity substs");
3178 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3179 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3185 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3186 Entry::Vacant(entry) => {
3189 Entry::Occupied(mut entry) => {
3190 debug!(" - composing on top of {:?}", entry.get());
3191 match (&entry.get()[..], &adj[..]) {
3192 // Applying any adjustment on top of a NeverToAny
3193 // is a valid NeverToAny adjustment, because it can't
3195 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3197 Adjustment { kind: Adjust::Deref(_), .. },
3198 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3200 Adjustment { kind: Adjust::Deref(_), .. },
3201 .. // Any following adjustments are allowed.
3203 // A reborrow has no effect before a dereference.
3205 // FIXME: currently we never try to compose autoderefs
3206 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3208 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3209 expr, entry.get(), adj)
3211 *entry.get_mut() = adj;
3216 /// Basically whenever we are converting from a type scheme into
3217 /// the fn body space, we always want to normalize associated
3218 /// types as well. This function combines the two.
3219 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3221 T: TypeFoldable<'tcx>,
3223 let value = value.subst(self.tcx, substs);
3224 let result = self.normalize_associated_types_in(span, &value);
3225 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3229 /// As `instantiate_type_scheme`, but for the bounds found in a
3230 /// generic type scheme.
3231 fn instantiate_bounds(
3235 substs: SubstsRef<'tcx>,
3236 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3237 let bounds = self.tcx.predicates_of(def_id);
3238 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3239 let result = bounds.instantiate(self.tcx, substs);
3240 let result = self.normalize_associated_types_in(span, &result);
3242 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3243 bounds, substs, result, spans,
3248 /// Replaces the opaque types from the given value with type variables,
3249 /// and records the `OpaqueTypeMap` for later use during writeback. See
3250 /// `InferCtxt::instantiate_opaque_types` for more details.
3251 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3253 parent_id: hir::HirId,
3257 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3259 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3260 parent_def_id, value
3263 let (value, opaque_type_map) =
3264 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3265 parent_def_id.to_def_id(),
3272 let mut opaque_types = self.opaque_types.borrow_mut();
3273 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3274 for (ty, decl) in opaque_type_map {
3275 let _ = opaque_types.insert(ty, decl);
3276 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3282 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3284 T: TypeFoldable<'tcx>,
3286 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3289 fn normalize_associated_types_in_as_infer_ok<T>(
3293 ) -> InferOk<'tcx, T>
3295 T: TypeFoldable<'tcx>,
3297 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3300 pub fn require_type_meets(
3304 code: traits::ObligationCauseCode<'tcx>,
3307 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3310 pub fn require_type_is_sized(
3314 code: traits::ObligationCauseCode<'tcx>,
3316 if !ty.references_error() {
3317 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3318 self.require_type_meets(ty, span, code, lang_item);
3322 pub fn require_type_is_sized_deferred(
3326 code: traits::ObligationCauseCode<'tcx>,
3328 if !ty.references_error() {
3329 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3333 pub fn register_bound(
3337 cause: traits::ObligationCause<'tcx>,
3339 if !ty.references_error() {
3340 self.fulfillment_cx.borrow_mut().register_bound(
3350 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3351 let t = AstConv::ast_ty_to_ty(self, ast_t);
3352 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3356 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3357 let ty = self.to_ty(ast_ty);
3358 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3360 if Self::can_contain_user_lifetime_bounds(ty) {
3361 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3362 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3363 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3369 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3370 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3371 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3372 self.register_wf_obligation(
3374 self.tcx.hir().span(ast_c.hir_id),
3375 ObligationCauseCode::MiscObligation,
3380 // If the type given by the user has free regions, save it for later, since
3381 // NLL would like to enforce those. Also pass in types that involve
3382 // projections, since those can resolve to `'static` bounds (modulo #54940,
3383 // which hopefully will be fixed by the time you see this comment, dear
3384 // reader, although I have my doubts). Also pass in types with inference
3385 // types, because they may be repeated. Other sorts of things are already
3386 // sufficiently enforced with erased regions. =)
3387 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3389 T: TypeFoldable<'tcx>,
3391 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3394 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3395 match self.tables.borrow().node_types().get(id) {
3397 None if self.is_tainted_by_errors() => self.tcx.types.err,
3400 "no type for node {}: {} in fcx {}",
3402 self.tcx.hir().node_to_string(id),
3409 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3410 pub fn register_wf_obligation(
3412 arg: subst::GenericArg<'tcx>,
3414 code: traits::ObligationCauseCode<'tcx>,
3416 // WF obligations never themselves fail, so no real need to give a detailed cause:
3417 let cause = traits::ObligationCause::new(span, self.body_id, code);
3418 self.register_predicate(traits::Obligation::new(
3421 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3425 /// Registers obligations that all `substs` are well-formed.
3426 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3427 for arg in substs.iter().filter(|arg| {
3428 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3430 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3434 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3435 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3436 /// trait/region obligations.
3438 /// For example, if there is a function:
3441 /// fn foo<'a,T:'a>(...)
3444 /// and a reference:
3450 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3451 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3452 pub fn add_obligations_for_parameters(
3454 cause: traits::ObligationCause<'tcx>,
3455 predicates: ty::InstantiatedPredicates<'tcx>,
3457 assert!(!predicates.has_escaping_bound_vars());
3459 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3461 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3462 self.register_predicate(obligation);
3466 // FIXME(arielb1): use this instead of field.ty everywhere
3467 // Only for fields! Returns <none> for methods>
3468 // Indifferent to privacy flags
3472 field: &'tcx ty::FieldDef,
3473 substs: SubstsRef<'tcx>,
3475 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3478 fn check_casts(&self) {
3479 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3480 for cast in deferred_cast_checks.drain(..) {
3485 fn resolve_generator_interiors(&self, def_id: DefId) {
3486 let mut generators = self.deferred_generator_interiors.borrow_mut();
3487 for (body_id, interior, kind) in generators.drain(..) {
3488 self.select_obligations_where_possible(false, |_| {});
3489 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3493 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3495 // - Unconstrained ints are replaced with `i32`.
3497 // - Unconstrained floats are replaced with with `f64`.
3499 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3500 // is enabled. Otherwise, they are replaced with `()`.
3502 // Fallback becomes very dubious if we have encountered type-checking errors.
3503 // In that case, fallback to Error.
3504 // The return value indicates whether fallback has occurred.
3505 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3506 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3507 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3509 assert!(ty.is_ty_infer());
3510 let fallback = match self.type_is_unconstrained_numeric(ty) {
3511 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3512 UnconstrainedInt => self.tcx.types.i32,
3513 UnconstrainedFloat => self.tcx.types.f64,
3514 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3516 // This type variable was created from the instantiation of an opaque
3517 // type. The fact that we're attempting to perform fallback for it
3518 // means that the function neither constrained it to a concrete
3519 // type, nor to the opaque type itself.
3521 // For example, in this code:
3524 // type MyType = impl Copy;
3525 // fn defining_use() -> MyType { true }
3526 // fn other_use() -> MyType { defining_use() }
3529 // `defining_use` will constrain the instantiated inference
3530 // variable to `bool`, while `other_use` will constrain
3531 // the instantiated inference variable to `MyType`.
3533 // When we process opaque types during writeback, we
3534 // will handle cases like `other_use`, and not count
3535 // them as defining usages
3537 // However, we also need to handle cases like this:
3540 // pub type Foo = impl Copy;
3541 // fn produce() -> Option<Foo> {
3546 // In the above snippet, the inference variable created by
3547 // instantiating `Option<Foo>` will be completely unconstrained.
3548 // We treat this as a non-defining use by making the inference
3549 // variable fall back to the opaque type itself.
3550 if let FallbackMode::All = mode {
3551 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3553 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3565 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3566 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3570 fn select_all_obligations_or_error(&self) {
3571 debug!("select_all_obligations_or_error");
3572 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3573 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3577 /// Select as many obligations as we can at present.
3578 fn select_obligations_where_possible(
3580 fallback_has_occurred: bool,
3581 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3583 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3584 if let Err(mut errors) = result {
3585 mutate_fullfillment_errors(&mut errors);
3586 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3590 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3591 /// returns a type of `&T`, but the actual type we assign to the
3592 /// *expression* is `T`. So this function just peels off the return
3593 /// type by one layer to yield `T`.
3594 fn make_overloaded_place_return_type(
3596 method: MethodCallee<'tcx>,
3597 ) -> ty::TypeAndMut<'tcx> {
3598 // extract method return type, which will be &T;
3599 let ret_ty = method.sig.output();
3601 // method returns &T, but the type as visible to user is T, so deref
3602 ret_ty.builtin_deref(true).unwrap()
3607 expr: &hir::Expr<'_>,
3608 base_expr: &'tcx hir::Expr<'tcx>,
3612 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3613 // FIXME(#18741) -- this is almost but not quite the same as the
3614 // autoderef that normal method probing does. They could likely be
3617 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3618 let mut result = None;
3619 while result.is_none() && autoderef.next().is_some() {
3620 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3622 autoderef.finalize(self);
3626 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3627 /// (and otherwise adjust) `base_expr`, looking for a type which either
3628 /// supports builtin indexing or overloaded indexing.
3629 /// This loop implements one step in that search; the autoderef loop
3630 /// is implemented by `lookup_indexing`.
3633 expr: &hir::Expr<'_>,
3634 base_expr: &hir::Expr<'_>,
3635 autoderef: &Autoderef<'a, 'tcx>,
3638 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3639 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3641 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3643 expr, base_expr, adjusted_ty, index_ty
3646 for &unsize in &[false, true] {
3647 let mut self_ty = adjusted_ty;
3649 // We only unsize arrays here.
3650 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3651 self_ty = self.tcx.mk_slice(element_ty);
3657 // If some lookup succeeds, write callee into table and extract index/element
3658 // type from the method signature.
3659 // If some lookup succeeded, install method in table
3660 let input_ty = self.next_ty_var(TypeVariableOrigin {
3661 kind: TypeVariableOriginKind::AutoDeref,
3662 span: base_expr.span,
3664 let method = self.try_overloaded_place_op(
3672 let result = method.map(|ok| {
3673 debug!("try_index_step: success, using overloaded indexing");
3674 let method = self.register_infer_ok_obligations(ok);
3676 let mut adjustments = autoderef.adjust_steps(self, needs);
3677 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3678 let mutbl = match r_mutbl {
3679 hir::Mutability::Not => AutoBorrowMutability::Not,
3680 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3681 // Indexing can be desugared to a method call,
3682 // so maybe we could use two-phase here.
3683 // See the documentation of AllowTwoPhase for why that's
3684 // not the case today.
3685 allow_two_phase_borrow: AllowTwoPhase::No,
3688 adjustments.push(Adjustment {
3689 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3692 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3696 adjustments.push(Adjustment {
3697 kind: Adjust::Pointer(PointerCast::Unsize),
3698 target: method.sig.inputs()[0],
3701 self.apply_adjustments(base_expr, adjustments);
3703 self.write_method_call(expr.hir_id, method);
3704 (input_ty, self.make_overloaded_place_return_type(method).ty)
3706 if result.is_some() {
3714 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Ident) {
3715 let (tr, name) = match (op, is_mut) {
3716 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3717 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3718 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3719 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3721 (tr, Ident::with_dummy_span(name))
3724 fn try_overloaded_place_op(
3728 arg_tys: &[Ty<'tcx>],
3731 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3732 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3734 // Try Mut first, if needed.
3735 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3736 let method = match (needs, mut_tr) {
3737 (Needs::MutPlace, Some(trait_did)) => {
3738 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3743 // Otherwise, fall back to the immutable version.
3744 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3745 match (method, imm_tr) {
3746 (None, Some(trait_did)) => {
3747 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3749 (method, _) => method,
3753 fn check_method_argument_types(
3756 expr: &'tcx hir::Expr<'tcx>,
3757 method: Result<MethodCallee<'tcx>, ()>,
3758 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3759 tuple_arguments: TupleArgumentsFlag,
3760 expected: Expectation<'tcx>,
3762 let has_error = match method {
3763 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3767 let err_inputs = self.err_args(args_no_rcvr.len());
3769 let err_inputs = match tuple_arguments {
3770 DontTupleArguments => err_inputs,
3771 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3774 self.check_argument_types(
3784 return self.tcx.types.err;
3787 let method = method.unwrap();
3788 // HACK(eddyb) ignore self in the definition (see above).
3789 let expected_arg_tys = self.expected_inputs_for_expected_output(
3792 method.sig.output(),
3793 &method.sig.inputs()[1..],
3795 self.check_argument_types(
3798 &method.sig.inputs()[1..],
3799 &expected_arg_tys[..],
3801 method.sig.c_variadic,
3803 self.tcx.hir().span_if_local(method.def_id),
3808 fn self_type_matches_expected_vid(
3810 trait_ref: ty::PolyTraitRef<'tcx>,
3811 expected_vid: ty::TyVid,
3813 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3815 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3816 trait_ref, self_ty, expected_vid
3818 match self_ty.kind {
3819 ty::Infer(ty::TyVar(found_vid)) => {
3820 // FIXME: consider using `sub_root_var` here so we
3821 // can see through subtyping.
3822 let found_vid = self.root_var(found_vid);
3823 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3824 expected_vid == found_vid
3830 fn obligations_for_self_ty<'b>(
3833 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3836 // FIXME: consider using `sub_root_var` here so we
3837 // can see through subtyping.
3838 let ty_var_root = self.root_var(self_ty);
3840 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3843 self.fulfillment_cx.borrow().pending_obligations()
3848 .pending_obligations()
3850 .filter_map(move |obligation| match obligation.predicate.kind() {
3851 ty::PredicateKind::Projection(ref data) => {
3852 Some((data.to_poly_trait_ref(self.tcx), obligation))
3854 ty::PredicateKind::Trait(ref data, _) => {
3855 Some((data.to_poly_trait_ref(), obligation))
3857 ty::PredicateKind::Subtype(..) => None,
3858 ty::PredicateKind::RegionOutlives(..) => None,
3859 ty::PredicateKind::TypeOutlives(..) => None,
3860 ty::PredicateKind::WellFormed(..) => None,
3861 ty::PredicateKind::ObjectSafe(..) => None,
3862 ty::PredicateKind::ConstEvaluatable(..) => None,
3863 ty::PredicateKind::ConstEquate(..) => None,
3864 // N.B., this predicate is created by breaking down a
3865 // `ClosureType: FnFoo()` predicate, where
3866 // `ClosureType` represents some `Closure`. It can't
3867 // possibly be referring to the current closure,
3868 // because we haven't produced the `Closure` for
3869 // this closure yet; this is exactly why the other
3870 // code is looking for a self type of a unresolved
3871 // inference variable.
3872 ty::PredicateKind::ClosureKind(..) => None,
3874 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3877 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3878 self.obligations_for_self_ty(self_ty)
3879 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3882 /// Generic function that factors out common logic from function calls,
3883 /// method calls and overloaded operators.
3884 fn check_argument_types(
3887 expr: &'tcx hir::Expr<'tcx>,
3888 fn_inputs: &[Ty<'tcx>],
3889 expected_arg_tys: &[Ty<'tcx>],
3890 args: &'tcx [hir::Expr<'tcx>],
3892 tuple_arguments: TupleArgumentsFlag,
3893 def_span: Option<Span>,
3896 // Grab the argument types, supplying fresh type variables
3897 // if the wrong number of arguments were supplied
3898 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3900 // All the input types from the fn signature must outlive the call
3901 // so as to validate implied bounds.
3902 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3903 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3906 let expected_arg_count = fn_inputs.len();
3908 let param_count_error = |expected_count: usize,
3913 let (span, start_span, args) = match &expr.kind {
3914 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3915 hir::ExprKind::MethodCall(path_segment, span, args) => (
3917 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3920 .and_then(|args| args.args.iter().last())
3921 // Account for `foo.bar::<T>()`.
3923 // Skip the closing `>`.
3926 .next_point(tcx.sess.source_map().next_point(arg.span()))
3929 &args[1..], // Skip the receiver.
3931 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3933 let arg_spans = if args.is_empty() {
3935 // ^^^-- supplied 0 arguments
3937 // expected 2 arguments
3938 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3941 // ^^^ - - - supplied 3 arguments
3943 // expected 2 arguments
3944 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3947 let mut err = tcx.sess.struct_span_err_with_code(
3950 "this function takes {}{} but {} {} supplied",
3951 if c_variadic { "at least " } else { "" },
3952 potentially_plural_count(expected_count, "argument"),
3953 potentially_plural_count(arg_count, "argument"),
3954 if arg_count == 1 { "was" } else { "were" }
3956 DiagnosticId::Error(error_code.to_owned()),
3958 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3959 for (i, span) in arg_spans.into_iter().enumerate() {
3962 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3966 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3967 err.span_label(def_s, "defined here");
3970 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3971 // remove closing `)` from the span
3972 let sugg_span = sugg_span.shrink_to_lo();
3973 err.span_suggestion(
3975 "expected the unit value `()`; create it with empty parentheses",
3977 Applicability::MachineApplicable,
3984 if c_variadic { "at least " } else { "" },
3985 potentially_plural_count(expected_count, "argument")
3992 let mut expected_arg_tys = expected_arg_tys.to_vec();
3994 let formal_tys = if tuple_arguments == TupleArguments {
3995 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3996 match tuple_type.kind {
3997 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3998 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3999 expected_arg_tys = vec![];
4000 self.err_args(args.len())
4002 ty::Tuple(arg_types) => {
4003 expected_arg_tys = match expected_arg_tys.get(0) {
4004 Some(&ty) => match ty.kind {
4005 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4010 arg_types.iter().map(|k| k.expect_ty()).collect()
4017 "cannot use call notation; the first type parameter \
4018 for the function trait is neither a tuple nor unit"
4021 expected_arg_tys = vec![];
4022 self.err_args(args.len())
4025 } else if expected_arg_count == supplied_arg_count {
4027 } else if c_variadic {
4028 if supplied_arg_count >= expected_arg_count {
4031 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4032 expected_arg_tys = vec![];
4033 self.err_args(supplied_arg_count)
4036 // is the missing argument of type `()`?
4037 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4038 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4039 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4040 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4044 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4046 expected_arg_tys = vec![];
4047 self.err_args(supplied_arg_count)
4051 "check_argument_types: formal_tys={:?}",
4052 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4055 // If there is no expectation, expect formal_tys.
4056 let expected_arg_tys =
4057 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4059 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4061 // Check the arguments.
4062 // We do this in a pretty awful way: first we type-check any arguments
4063 // that are not closures, then we type-check the closures. This is so
4064 // that we have more information about the types of arguments when we
4065 // type-check the functions. This isn't really the right way to do this.
4066 for &check_closures in &[false, true] {
4067 debug!("check_closures={}", check_closures);
4069 // More awful hacks: before we check argument types, try to do
4070 // an "opportunistic" trait resolution of any trait bounds on
4071 // the call. This helps coercions.
4073 self.select_obligations_where_possible(false, |errors| {
4074 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4075 self.point_at_arg_instead_of_call_if_possible(
4077 &final_arg_types[..],
4084 // For C-variadic functions, we don't have a declared type for all of
4085 // the arguments hence we only do our usual type checking with
4086 // the arguments who's types we do know.
4087 let t = if c_variadic {
4089 } else if tuple_arguments == TupleArguments {
4094 for (i, arg) in args.iter().take(t).enumerate() {
4095 // Warn only for the first loop (the "no closures" one).
4096 // Closure arguments themselves can't be diverging, but
4097 // a previous argument can, e.g., `foo(panic!(), || {})`.
4098 if !check_closures {
4099 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4102 let is_closure = match arg.kind {
4103 ExprKind::Closure(..) => true,
4107 if is_closure != check_closures {
4111 debug!("checking the argument");
4112 let formal_ty = formal_tys[i];
4114 // The special-cased logic below has three functions:
4115 // 1. Provide as good of an expected type as possible.
4116 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4118 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4120 // 2. Coerce to the most detailed type that could be coerced
4121 // to, which is `expected_ty` if `rvalue_hint` returns an
4122 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4123 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4124 // We're processing function arguments so we definitely want to use
4125 // two-phase borrows.
4126 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4127 final_arg_types.push((i, checked_ty, coerce_ty));
4129 // 3. Relate the expected type and the formal one,
4130 // if the expected type was used for the coercion.
4131 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4135 // We also need to make sure we at least write the ty of the other
4136 // arguments which we skipped above.
4138 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4139 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4140 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4143 for arg in args.iter().skip(expected_arg_count) {
4144 let arg_ty = self.check_expr(&arg);
4146 // There are a few types which get autopromoted when passed via varargs
4147 // in C but we just error out instead and require explicit casts.
4148 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4150 ty::Float(ast::FloatTy::F32) => {
4151 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4153 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4154 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4156 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4157 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4160 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4161 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4162 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4170 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4171 vec![self.tcx.types.err; len]
4174 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4175 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4176 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4177 /// can be not easily comparable with predicate type (because of coercion). If the types match
4178 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4179 /// the corresponding argument's expression span instead of the `fn` call path span.
4180 fn point_at_arg_instead_of_call_if_possible(
4182 errors: &mut Vec<traits::FulfillmentError<'_>>,
4183 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4185 args: &'tcx [hir::Expr<'tcx>],
4187 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4188 // the `?` operator.
4189 if call_sp.desugaring_kind().is_some() {
4193 for error in errors {
4194 // Only if the cause is somewhere inside the expression we want try to point at arg.
4195 // Otherwise, it means that the cause is somewhere else and we should not change
4196 // anything because we can break the correct span.
4197 if !call_sp.contains(error.obligation.cause.span) {
4201 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate.kind() {
4202 // Collect the argument position for all arguments that could have caused this
4203 // `FulfillmentError`.
4204 let mut referenced_in = final_arg_types
4206 .map(|&(i, checked_ty, _)| (i, checked_ty))
4207 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4208 .flat_map(|(i, ty)| {
4209 let ty = self.resolve_vars_if_possible(&ty);
4210 // We walk the argument type because the argument's type could have
4211 // been `Option<T>`, but the `FulfillmentError` references `T`.
4212 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4218 .collect::<Vec<_>>();
4220 // Both checked and coerced types could have matched, thus we need to remove
4222 referenced_in.sort();
4223 referenced_in.dedup();
4225 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4226 // We make sure that only *one* argument matches the obligation failure
4227 // and we assign the obligation's span to its expression's.
4228 error.obligation.cause.span = args[ref_in].span;
4229 error.points_at_arg_span = true;
4235 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4236 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4237 /// were caused by them. If they were, we point at the corresponding type argument's span
4238 /// instead of the `fn` call path span.
4239 fn point_at_type_arg_instead_of_call_if_possible(
4241 errors: &mut Vec<traits::FulfillmentError<'_>>,
4242 call_expr: &'tcx hir::Expr<'tcx>,
4244 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4245 if let hir::ExprKind::Path(qpath) = &path.kind {
4246 if let hir::QPath::Resolved(_, path) = &qpath {
4247 for error in errors {
4248 if let ty::PredicateKind::Trait(predicate, _) =
4249 error.obligation.predicate.kind()
4251 // If any of the type arguments in this path segment caused the
4252 // `FullfillmentError`, point at its span (#61860).
4256 .filter_map(|seg| seg.args.as_ref())
4257 .flat_map(|a| a.args.iter())
4259 if let hir::GenericArg::Type(hir_ty) = &arg {
4260 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4263 // Avoid ICE with associated types. As this is best
4264 // effort only, it's ok to ignore the case. It
4265 // would trigger in `is_send::<T::AssocType>();`
4266 // from `typeck-default-trait-impl-assoc-type.rs`.
4268 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4269 let ty = self.resolve_vars_if_possible(&ty);
4270 if ty == predicate.skip_binder().self_ty() {
4271 error.obligation.cause.span = hir_ty.span;
4283 // AST fragment checking
4284 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4288 ast::LitKind::Str(..) => tcx.mk_static_str(),
4289 ast::LitKind::ByteStr(ref v) => {
4290 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4292 ast::LitKind::Byte(_) => tcx.types.u8,
4293 ast::LitKind::Char(_) => tcx.types.char,
4294 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4295 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4296 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4297 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4298 ty::Int(_) | ty::Uint(_) => Some(ty),
4299 ty::Char => Some(tcx.types.u8),
4300 ty::RawPtr(..) => Some(tcx.types.usize),
4301 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4304 opt_ty.unwrap_or_else(|| self.next_int_var())
4306 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4307 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4308 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4309 ty::Float(_) => Some(ty),
4312 opt_ty.unwrap_or_else(|| self.next_float_var())
4314 ast::LitKind::Bool(_) => tcx.types.bool,
4315 ast::LitKind::Err(_) => tcx.types.err,
4319 /// Unifies the output type with the expected type early, for more coercions
4320 /// and forward type information on the input expressions.
4321 fn expected_inputs_for_expected_output(
4324 expected_ret: Expectation<'tcx>,
4325 formal_ret: Ty<'tcx>,
4326 formal_args: &[Ty<'tcx>],
4327 ) -> Vec<Ty<'tcx>> {
4328 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4329 let ret_ty = match expected_ret.only_has_type(self) {
4331 None => return Vec::new(),
4333 let expect_args = self
4334 .fudge_inference_if_ok(|| {
4335 // Attempt to apply a subtyping relationship between the formal
4336 // return type (likely containing type variables if the function
4337 // is polymorphic) and the expected return type.
4338 // No argument expectations are produced if unification fails.
4339 let origin = self.misc(call_span);
4340 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4342 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4343 // to identity so the resulting type is not constrained.
4346 // Process any obligations locally as much as
4347 // we can. We don't care if some things turn
4348 // out unconstrained or ambiguous, as we're
4349 // just trying to get hints here.
4350 self.save_and_restore_in_snapshot_flag(|_| {
4351 let mut fulfill = TraitEngine::new(self.tcx);
4352 for obligation in ok.obligations {
4353 fulfill.register_predicate_obligation(self, obligation);
4355 fulfill.select_where_possible(self)
4359 Err(_) => return Err(()),
4362 // Record all the argument types, with the substitutions
4363 // produced from the above subtyping unification.
4364 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4366 .unwrap_or_default();
4368 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4369 formal_args, formal_ret, expect_args, expected_ret
4374 pub fn check_struct_path(
4378 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4379 let path_span = match *qpath {
4380 QPath::Resolved(_, ref path) => path.span,
4381 QPath::TypeRelative(ref qself, _) => qself.span,
4383 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4384 let variant = match def {
4386 self.set_tainted_by_errors();
4389 Res::Def(DefKind::Variant, _) => match ty.kind {
4390 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4391 _ => bug!("unexpected type: {:?}", ty),
4393 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4394 | Res::SelfTy(..) => match ty.kind {
4395 ty::Adt(adt, substs) if !adt.is_enum() => {
4396 Some((adt.non_enum_variant(), adt.did, substs))
4400 _ => bug!("unexpected definition: {:?}", def),
4403 if let Some((variant, did, substs)) = variant {
4404 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4405 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4407 // Check bounds on type arguments used in the path.
4408 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4410 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4411 self.add_obligations_for_parameters(cause, bounds);
4419 "expected struct, variant or union type, found {}",
4420 ty.sort_string(self.tcx)
4422 .span_label(path_span, "not a struct")
4428 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4429 // The newly resolved definition is written into `type_dependent_defs`.
4430 fn finish_resolving_struct_path(
4435 ) -> (Res, Ty<'tcx>) {
4437 QPath::Resolved(ref maybe_qself, ref path) => {
4438 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4439 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4442 QPath::TypeRelative(ref qself, ref segment) => {
4443 let ty = self.to_ty(qself);
4445 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4451 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4452 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4453 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4455 // Write back the new resolution.
4456 self.write_resolution(hir_id, result);
4458 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4463 /// Resolves an associated value path into a base type and associated constant, or method
4464 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4465 pub fn resolve_ty_and_res_ufcs<'b>(
4467 qpath: &'b QPath<'b>,
4470 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4471 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4472 let (ty, qself, item_segment) = match *qpath {
4473 QPath::Resolved(ref opt_qself, ref path) => {
4476 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4480 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4482 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4483 // Return directly on cache hit. This is useful to avoid doubly reporting
4484 // errors with default match binding modes. See #44614.
4486 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4487 return (def, Some(ty), slice::from_ref(&**item_segment));
4489 let item_name = item_segment.ident;
4490 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4491 let result = match error {
4492 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4493 _ => Err(ErrorReported),
4495 if item_name.name != kw::Invalid {
4496 if let Some(mut e) = self.report_method_error(
4500 SelfSource::QPath(qself),
4510 // Write back the new resolution.
4511 self.write_resolution(hir_id, result);
4513 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4515 slice::from_ref(&**item_segment),
4519 pub fn check_decl_initializer(
4521 local: &'tcx hir::Local<'tcx>,
4522 init: &'tcx hir::Expr<'tcx>,
4524 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4525 // for #42640 (default match binding modes).
4528 let ref_bindings = local.pat.contains_explicit_ref_binding();
4530 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4531 if let Some(m) = ref_bindings {
4532 // Somewhat subtle: if we have a `ref` binding in the pattern,
4533 // we want to avoid introducing coercions for the RHS. This is
4534 // both because it helps preserve sanity and, in the case of
4535 // ref mut, for soundness (issue #23116). In particular, in
4536 // the latter case, we need to be clear that the type of the
4537 // referent for the reference that results is *equal to* the
4538 // type of the place it is referencing, and not some
4539 // supertype thereof.
4540 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4541 self.demand_eqtype(init.span, local_ty, init_ty);
4544 self.check_expr_coercable_to_type(init, local_ty)
4548 /// Type check a `let` statement.
4549 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4550 // Determine and write the type which we'll check the pattern against.
4551 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4552 self.write_ty(local.hir_id, ty);
4554 // Type check the initializer.
4555 if let Some(ref init) = local.init {
4556 let init_ty = self.check_decl_initializer(local, &init);
4557 self.overwrite_local_ty_if_err(local, ty, init_ty);
4560 // Does the expected pattern type originate from an expression and what is the span?
4561 let (origin_expr, ty_span) = match (local.ty, local.init) {
4562 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4563 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4564 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4567 // Type check the pattern. Override if necessary to avoid knock-on errors.
4568 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4569 let pat_ty = self.node_ty(local.pat.hir_id);
4570 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4573 fn overwrite_local_ty_if_err(
4575 local: &'tcx hir::Local<'tcx>,
4579 if ty.references_error() {
4580 // Override the types everywhere with `types.err` to avoid knock on errors.
4581 self.write_ty(local.hir_id, ty);
4582 self.write_ty(local.pat.hir_id, ty);
4583 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4584 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4585 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4589 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4590 err.span_suggestion_short(
4591 span.shrink_to_hi(),
4592 "consider using a semicolon here",
4594 Applicability::MachineApplicable,
4598 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4599 // Don't do all the complex logic below for `DeclItem`.
4601 hir::StmtKind::Item(..) => return,
4602 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4605 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4607 // Hide the outer diverging and `has_errors` flags.
4608 let old_diverges = self.diverges.replace(Diverges::Maybe);
4609 let old_has_errors = self.has_errors.replace(false);
4612 hir::StmtKind::Local(ref l) => {
4613 self.check_decl_local(&l);
4616 hir::StmtKind::Item(_) => {}
4617 hir::StmtKind::Expr(ref expr) => {
4618 // Check with expected type of `()`.
4619 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4620 self.suggest_semicolon_at_end(expr.span, err);
4623 hir::StmtKind::Semi(ref expr) => {
4624 self.check_expr(&expr);
4628 // Combine the diverging and `has_error` flags.
4629 self.diverges.set(self.diverges.get() | old_diverges);
4630 self.has_errors.set(self.has_errors.get() | old_has_errors);
4633 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4634 let unit = self.tcx.mk_unit();
4635 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4637 // if the block produces a `!` value, that can always be
4638 // (effectively) coerced to unit.
4640 self.demand_suptype(blk.span, unit, ty);
4644 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4645 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4646 /// when given code like the following:
4648 /// if false { return 0i32; } else { 1u32 }
4649 /// // ^^^^ point at this instead of the whole `if` expression
4651 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4652 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4653 let arm_spans: Vec<Span> = arms
4656 self.in_progress_tables
4657 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4658 .and_then(|arm_ty| {
4659 if arm_ty.is_never() {
4662 Some(match &arm.body.kind {
4663 // Point at the tail expression when possible.
4664 hir::ExprKind::Block(block, _) => {
4665 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4673 if arm_spans.len() == 1 {
4674 return arm_spans[0];
4680 fn check_block_with_expected(
4682 blk: &'tcx hir::Block<'tcx>,
4683 expected: Expectation<'tcx>,
4686 let mut fcx_ps = self.ps.borrow_mut();
4687 let unsafety_state = fcx_ps.recurse(blk);
4688 replace(&mut *fcx_ps, unsafety_state)
4691 // In some cases, blocks have just one exit, but other blocks
4692 // can be targeted by multiple breaks. This can happen both
4693 // with labeled blocks as well as when we desugar
4694 // a `try { ... }` expression.
4698 // 'a: { if true { break 'a Err(()); } Ok(()) }
4700 // Here we would wind up with two coercions, one from
4701 // `Err(())` and the other from the tail expression
4702 // `Ok(())`. If the tail expression is omitted, that's a
4703 // "forced unit" -- unless the block diverges, in which
4704 // case we can ignore the tail expression (e.g., `'a: {
4705 // break 'a 22; }` would not force the type of the block
4707 let tail_expr = blk.expr.as_ref();
4708 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4709 let coerce = if blk.targeted_by_break {
4710 CoerceMany::new(coerce_to_ty)
4712 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4713 Some(e) => slice::from_ref(e),
4716 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4719 let prev_diverges = self.diverges.get();
4720 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4722 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4723 for s in blk.stmts {
4727 // check the tail expression **without** holding the
4728 // `enclosing_breakables` lock below.
4729 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4731 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4732 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4733 let coerce = ctxt.coerce.as_mut().unwrap();
4734 if let Some(tail_expr_ty) = tail_expr_ty {
4735 let tail_expr = tail_expr.unwrap();
4736 let span = self.get_expr_coercion_span(tail_expr);
4737 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4738 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4740 // Subtle: if there is no explicit tail expression,
4741 // that is typically equivalent to a tail expression
4742 // of `()` -- except if the block diverges. In that
4743 // case, there is no value supplied from the tail
4744 // expression (assuming there are no other breaks,
4745 // this implies that the type of the block will be
4748 // #41425 -- label the implicit `()` as being the
4749 // "found type" here, rather than the "expected type".
4750 if !self.diverges.get().is_always() {
4751 // #50009 -- Do not point at the entire fn block span, point at the return type
4752 // span, as it is the cause of the requirement, and
4753 // `consider_hint_about_removing_semicolon` will point at the last expression
4754 // if it were a relevant part of the error. This improves usability in editors
4755 // that highlight errors inline.
4756 let mut sp = blk.span;
4757 let mut fn_span = None;
4758 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4759 let ret_sp = decl.output.span();
4760 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4761 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4762 // output would otherwise be incorrect and even misleading. Make sure
4763 // the span we're aiming at correspond to a `fn` body.
4764 if block_sp == blk.span {
4766 fn_span = Some(ident.span);
4770 coerce.coerce_forced_unit(
4774 if let Some(expected_ty) = expected.only_has_type(self) {
4775 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4777 if let Some(fn_span) = fn_span {
4780 "implicitly returns `()` as its body has no tail or `return` \
4792 // If we can break from the block, then the block's exit is always reachable
4793 // (... as long as the entry is reachable) - regardless of the tail of the block.
4794 self.diverges.set(prev_diverges);
4797 let mut ty = ctxt.coerce.unwrap().complete(self);
4799 if self.has_errors.get() || ty.references_error() {
4800 ty = self.tcx.types.err
4803 self.write_ty(blk.hir_id, ty);
4805 *self.ps.borrow_mut() = prev;
4809 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4810 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4812 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4813 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4814 let body = self.tcx.hir().body(body_id);
4815 if let ExprKind::Block(block, _) = &body.value.kind {
4816 return Some(block.span);
4824 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4825 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4826 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4827 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4830 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4831 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4833 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4834 // This is less than ideal, it will not suggest a return type span on any
4835 // method called `main`, regardless of whether it is actually the entry point,
4836 // but it will still present it as the reason for the expected type.
4837 Some((&sig.decl, ident, ident.name != sym::main))
4839 Node::TraitItem(&hir::TraitItem {
4841 kind: hir::TraitItemKind::Fn(ref sig, ..),
4843 }) => Some((&sig.decl, ident, true)),
4844 Node::ImplItem(&hir::ImplItem {
4846 kind: hir::ImplItemKind::Fn(ref sig, ..),
4848 }) => Some((&sig.decl, ident, false)),
4853 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4854 /// suggestion can be made, `None` otherwise.
4855 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4856 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4857 // `while` before reaching it, as block tail returns are not available in them.
4858 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4859 let parent = self.tcx.hir().get(blk_id);
4860 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4864 /// On implicit return expressions with mismatched types, provides the following suggestions:
4866 /// - Points out the method's return type as the reason for the expected type.
4867 /// - Possible missing semicolon.
4868 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4869 pub fn suggest_mismatched_types_on_tail(
4871 err: &mut DiagnosticBuilder<'_>,
4872 expr: &'tcx hir::Expr<'tcx>,
4878 let expr = expr.peel_drop_temps();
4879 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4880 let mut pointing_at_return_type = false;
4881 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4882 pointing_at_return_type =
4883 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4885 pointing_at_return_type
4888 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4889 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4891 /// fn foo(x: usize) -> usize { x }
4892 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4896 err: &mut DiagnosticBuilder<'_>,
4897 expr: &hir::Expr<'_>,
4901 let hir = self.tcx.hir();
4902 let (def_id, sig) = match found.kind {
4903 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4904 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4908 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4909 let sig = self.normalize_associated_types_in(expr.span, &sig);
4910 if self.can_coerce(sig.output(), expected) {
4911 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4912 (String::new(), Applicability::MachineApplicable)
4914 ("...".to_string(), Applicability::HasPlaceholders)
4916 let mut msg = "call this function";
4917 match hir.get_if_local(def_id) {
4919 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4920 | Node::ImplItem(hir::ImplItem {
4921 kind: hir::ImplItemKind::Fn(_, body_id), ..
4923 | Node::TraitItem(hir::TraitItem {
4924 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4928 let body = hir.body(*body_id);
4932 .map(|param| match ¶m.pat.kind {
4933 hir::PatKind::Binding(_, _, ident, None)
4934 if ident.name != kw::SelfLower =>
4938 _ => "_".to_string(),
4940 .collect::<Vec<_>>()
4943 Some(Node::Expr(hir::Expr {
4944 kind: ExprKind::Closure(_, _, body_id, _, _),
4945 span: full_closure_span,
4948 if *full_closure_span == expr.span {
4951 msg = "call this closure";
4952 let body = hir.body(*body_id);
4956 .map(|param| match ¶m.pat.kind {
4957 hir::PatKind::Binding(_, _, ident, None)
4958 if ident.name != kw::SelfLower =>
4962 _ => "_".to_string(),
4964 .collect::<Vec<_>>()
4967 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4968 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4969 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
4970 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4971 msg = "instantiate this tuple variant";
4973 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
4974 msg = "instantiate this tuple struct";
4979 Some(Node::ForeignItem(hir::ForeignItem {
4980 kind: hir::ForeignItemKind::Fn(_, idents, _),
4986 if ident.name != kw::SelfLower {
4992 .collect::<Vec<_>>()
4995 Some(Node::TraitItem(hir::TraitItem {
4996 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5002 if ident.name != kw::SelfLower {
5008 .collect::<Vec<_>>()
5013 err.span_suggestion_verbose(
5014 expr.span.shrink_to_hi(),
5015 &format!("use parentheses to {}", msg),
5016 format!("({})", sugg_call),
5024 pub fn suggest_deref_ref_or_into(
5026 err: &mut DiagnosticBuilder<'_>,
5027 expr: &hir::Expr<'_>,
5031 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5032 err.span_suggestion(sp, msg, suggestion, applicability);
5033 } else if let (ty::FnDef(def_id, ..), true) =
5034 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5036 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5037 let sp = self.sess().source_map().guess_head_span(sp);
5038 err.span_label(sp, &format!("{} defined here", found));
5040 } else if !self.check_for_cast(err, expr, found, expected) {
5041 let is_struct_pat_shorthand_field =
5042 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5043 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5044 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5045 let mut suggestions = iter::repeat(&expr_text)
5046 .zip(methods.iter())
5047 .filter_map(|(receiver, method)| {
5048 let method_call = format!(".{}()", method.ident);
5049 if receiver.ends_with(&method_call) {
5050 None // do not suggest code that is already there (#53348)
5052 let method_call_list = [".to_vec()", ".to_string()"];
5053 let sugg = if receiver.ends_with(".clone()")
5054 && method_call_list.contains(&method_call.as_str())
5056 let max_len = receiver.rfind('.').unwrap();
5057 format!("{}{}", &receiver[..max_len], method_call)
5059 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5060 format!("({}){}", receiver, method_call)
5062 format!("{}{}", receiver, method_call)
5065 Some(if is_struct_pat_shorthand_field {
5066 format!("{}: {}", receiver, sugg)
5073 if suggestions.peek().is_some() {
5074 err.span_suggestions(
5076 "try using a conversion method",
5078 Applicability::MaybeIncorrect,
5085 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5086 /// in the heap by calling `Box::new()`.
5087 fn suggest_boxing_when_appropriate(
5089 err: &mut DiagnosticBuilder<'_>,
5090 expr: &hir::Expr<'_>,
5094 if self.tcx.hir().is_const_context(expr.hir_id) {
5095 // Do not suggest `Box::new` in const context.
5098 if !expected.is_box() || found.is_box() {
5101 let boxed_found = self.tcx.mk_box(found);
5102 if let (true, Ok(snippet)) = (
5103 self.can_coerce(boxed_found, expected),
5104 self.sess().source_map().span_to_snippet(expr.span),
5106 err.span_suggestion(
5108 "store this in the heap by calling `Box::new`",
5109 format!("Box::new({})", snippet),
5110 Applicability::MachineApplicable,
5113 "for more on the distinction between the stack and the heap, read \
5114 https://doc.rust-lang.org/book/ch15-01-box.html, \
5115 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5116 https://doc.rust-lang.org/std/boxed/index.html",
5121 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5122 fn suggest_calling_boxed_future_when_appropriate(
5124 err: &mut DiagnosticBuilder<'_>,
5125 expr: &hir::Expr<'_>,
5131 if self.tcx.hir().is_const_context(expr.hir_id) {
5132 // Do not suggest `Box::new` in const context.
5135 let pin_did = self.tcx.lang_items().pin_type();
5136 match expected.kind {
5137 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5138 // This guards the `unwrap` and `mk_box` below.
5139 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5142 let boxed_found = self.tcx.mk_box(found);
5143 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5144 if let (true, Ok(snippet)) = (
5145 self.can_coerce(new_found, expected),
5146 self.sess().source_map().span_to_snippet(expr.span),
5149 ty::Adt(def, _) if def.is_box() => {
5150 err.help("use `Box::pin`");
5153 err.span_suggestion(
5155 "you need to pin and box this expression",
5156 format!("Box::pin({})", snippet),
5157 Applicability::MachineApplicable,
5167 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5171 /// bar_that_returns_u32()
5175 /// This routine checks if the return expression in a block would make sense on its own as a
5176 /// statement and the return type has been left as default or has been specified as `()`. If so,
5177 /// it suggests adding a semicolon.
5178 fn suggest_missing_semicolon(
5180 err: &mut DiagnosticBuilder<'_>,
5181 expression: &'tcx hir::Expr<'tcx>,
5185 if expected.is_unit() {
5186 // `BlockTailExpression` only relevant if the tail expr would be
5187 // useful on its own.
5188 match expression.kind {
5190 | ExprKind::MethodCall(..)
5191 | ExprKind::Loop(..)
5192 | ExprKind::Match(..)
5193 | ExprKind::Block(..) => {
5194 err.span_suggestion(
5195 cause_span.shrink_to_hi(),
5196 "try adding a semicolon",
5198 Applicability::MachineApplicable,
5206 /// A possible error is to forget to add a return type that is needed:
5210 /// bar_that_returns_u32()
5214 /// This routine checks if the return type is left as default, the method is not part of an
5215 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5217 fn suggest_missing_return_type(
5219 err: &mut DiagnosticBuilder<'_>,
5220 fn_decl: &hir::FnDecl<'_>,
5225 // Only suggest changing the return type for methods that
5226 // haven't set a return type at all (and aren't `fn main()` or an impl).
5227 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5228 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5229 err.span_suggestion(
5231 "try adding a return type",
5232 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5233 Applicability::MachineApplicable,
5237 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5238 err.span_label(span, "possibly return type missing here?");
5241 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5242 // `fn main()` must return `()`, do not suggest changing return type
5243 err.span_label(span, "expected `()` because of default return type");
5246 // expectation was caused by something else, not the default return
5247 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5248 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5249 // Only point to return type if the expected type is the return type, as if they
5250 // are not, the expectation must have been caused by something else.
5251 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5253 let ty = AstConv::ast_ty_to_ty(self, ty);
5254 debug!("suggest_missing_return_type: return type {:?}", ty);
5255 debug!("suggest_missing_return_type: expected type {:?}", ty);
5256 if ty.kind == expected.kind {
5257 err.span_label(sp, format!("expected `{}` because of return type", expected));
5265 /// A possible error is to forget to add `.await` when using futures:
5268 /// async fn make_u32() -> u32 {
5272 /// fn take_u32(x: u32) {}
5274 /// async fn foo() {
5275 /// let x = make_u32();
5280 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5281 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5282 /// `.await` to the tail of the expression.
5283 fn suggest_missing_await(
5285 err: &mut DiagnosticBuilder<'_>,
5286 expr: &hir::Expr<'_>,
5290 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5291 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5292 // body isn't `async`.
5293 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5294 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5295 let body = self.tcx().hir().body(body_id);
5296 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5298 // Check for `Future` implementations by constructing a predicate to
5299 // prove: `<T as Future>::Output == U`
5300 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5301 let item_def_id = self
5303 .associated_items(future_trait)
5304 .in_definition_order()
5308 // `<T as Future>::Output`
5309 let projection_ty = ty::ProjectionTy {
5313 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5319 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5323 .to_predicate(self.tcx);
5324 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5326 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5328 if self.infcx.predicate_may_hold(&obligation) {
5329 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5330 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5331 err.span_suggestion(
5333 "consider using `.await` here",
5334 format!("{}.await", code),
5335 Applicability::MaybeIncorrect,
5338 debug!("suggest_missing_await: no snippet for {:?}", sp);
5341 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5347 /// A common error is to add an extra semicolon:
5350 /// fn foo() -> usize {
5355 /// This routine checks if the final statement in a block is an
5356 /// expression with an explicit semicolon whose type is compatible
5357 /// with `expected_ty`. If so, it suggests removing the semicolon.
5358 fn consider_hint_about_removing_semicolon(
5360 blk: &'tcx hir::Block<'tcx>,
5361 expected_ty: Ty<'tcx>,
5362 err: &mut DiagnosticBuilder<'_>,
5364 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5365 err.span_suggestion(
5367 "consider removing this semicolon",
5369 Applicability::MachineApplicable,
5374 fn could_remove_semicolon(
5376 blk: &'tcx hir::Block<'tcx>,
5377 expected_ty: Ty<'tcx>,
5379 // Be helpful when the user wrote `{... expr;}` and
5380 // taking the `;` off is enough to fix the error.
5381 let last_stmt = blk.stmts.last()?;
5382 let last_expr = match last_stmt.kind {
5383 hir::StmtKind::Semi(ref e) => e,
5386 let last_expr_ty = self.node_ty(last_expr.hir_id);
5387 if matches!(last_expr_ty.kind, ty::Error)
5388 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5392 let original_span = original_sp(last_stmt.span, blk.span);
5393 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5396 // Instantiates the given path, which must refer to an item with the given
5397 // number of type parameters and type.
5398 pub fn instantiate_value_path(
5400 segments: &[hir::PathSegment<'_>],
5401 self_ty: Option<Ty<'tcx>>,
5405 ) -> (Ty<'tcx>, Res) {
5407 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5408 segments, self_ty, res, hir_id,
5413 let path_segs = match res {
5414 Res::Local(_) | Res::SelfCtor(_) => vec![],
5415 Res::Def(kind, def_id) => {
5416 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5418 _ => bug!("instantiate_value_path on {:?}", res),
5421 let mut user_self_ty = None;
5422 let mut is_alias_variant_ctor = false;
5424 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5425 if let Some(self_ty) = self_ty {
5426 let adt_def = self_ty.ty_adt_def().unwrap();
5427 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5428 is_alias_variant_ctor = true;
5431 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5432 let container = tcx.associated_item(def_id).container;
5433 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5435 ty::TraitContainer(trait_did) => {
5436 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5438 ty::ImplContainer(impl_def_id) => {
5439 if segments.len() == 1 {
5440 // `<T>::assoc` will end up here, and so
5441 // can `T::assoc`. It this came from an
5442 // inherent impl, we need to record the
5443 // `T` for posterity (see `UserSelfTy` for
5445 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5446 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5454 // Now that we have categorized what space the parameters for each
5455 // segment belong to, let's sort out the parameters that the user
5456 // provided (if any) into their appropriate spaces. We'll also report
5457 // errors if type parameters are provided in an inappropriate place.
5459 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5460 let generics_has_err = AstConv::prohibit_generics(
5462 segments.iter().enumerate().filter_map(|(index, seg)| {
5463 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5471 if let Res::Local(hid) = res {
5472 let ty = self.local_ty(span, hid).decl_ty;
5473 let ty = self.normalize_associated_types_in(span, &ty);
5474 self.write_ty(hir_id, ty);
5478 if generics_has_err {
5479 // Don't try to infer type parameters when prohibited generic arguments were given.
5480 user_self_ty = None;
5483 // Now we have to compare the types that the user *actually*
5484 // provided against the types that were *expected*. If the user
5485 // did not provide any types, then we want to substitute inference
5486 // variables. If the user provided some types, we may still need
5487 // to add defaults. If the user provided *too many* types, that's
5490 let mut infer_args_for_err = FxHashSet::default();
5491 for &PathSeg(def_id, index) in &path_segs {
5492 let seg = &segments[index];
5493 let generics = tcx.generics_of(def_id);
5494 // Argument-position `impl Trait` is treated as a normal generic
5495 // parameter internally, but we don't allow users to specify the
5496 // parameter's value explicitly, so we have to do some error-
5498 if let GenericArgCountResult {
5499 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5501 } = AstConv::check_generic_arg_count_for_call(
5502 tcx, span, &generics, &seg, false, // `is_method_call`
5504 infer_args_for_err.insert(index);
5505 self.set_tainted_by_errors(); // See issue #53251.
5509 let has_self = path_segs
5511 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5514 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5515 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5517 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5518 let variant = adt_def.non_enum_variant();
5519 let ctor_def_id = variant.ctor_def_id.unwrap();
5521 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5526 let mut err = tcx.sess.struct_span_err(
5528 "the `Self` constructor can only be used with tuple or unit structs",
5530 if let Some(adt_def) = ty.ty_adt_def() {
5531 match adt_def.adt_kind() {
5533 err.help("did you mean to use one of the enum's variants?");
5535 AdtKind::Struct | AdtKind::Union => {
5536 err.span_suggestion(
5538 "use curly brackets",
5539 String::from("Self { /* fields */ }"),
5540 Applicability::HasPlaceholders,
5547 return (tcx.types.err, res);
5553 let def_id = res.def_id();
5555 // The things we are substituting into the type should not contain
5556 // escaping late-bound regions, and nor should the base type scheme.
5557 let ty = tcx.type_of(def_id);
5559 let arg_count = GenericArgCountResult {
5560 explicit_late_bound: ExplicitLateBound::No,
5561 correct: if infer_args_for_err.is_empty() {
5564 Err(GenericArgCountMismatch::default())
5568 let substs = self_ctor_substs.unwrap_or_else(|| {
5569 AstConv::create_substs_for_generic_args(
5576 // Provide the generic args, and whether types should be inferred.
5578 if let Some(&PathSeg(_, index)) =
5579 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5581 // If we've encountered an `impl Trait`-related error, we're just
5582 // going to infer the arguments for better error messages.
5583 if !infer_args_for_err.contains(&index) {
5584 // Check whether the user has provided generic arguments.
5585 if let Some(ref data) = segments[index].args {
5586 return (Some(data), segments[index].infer_args);
5589 return (None, segments[index].infer_args);
5594 // Provide substitutions for parameters for which (valid) arguments have been provided.
5595 |param, arg| match (¶m.kind, arg) {
5596 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5597 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5599 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5600 self.to_ty(ty).into()
5602 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5603 self.to_const(&ct.value).into()
5605 _ => unreachable!(),
5607 // Provide substitutions for parameters for which arguments are inferred.
5608 |substs, param, infer_args| {
5610 GenericParamDefKind::Lifetime => {
5611 self.re_infer(Some(param), span).unwrap().into()
5613 GenericParamDefKind::Type { has_default, .. } => {
5614 if !infer_args && has_default {
5615 // If we have a default, then we it doesn't matter that we're not
5616 // inferring the type arguments: we provide the default where any
5618 let default = tcx.type_of(param.def_id);
5621 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5625 // If no type arguments were provided, we have to infer them.
5626 // This case also occurs as a result of some malformed input, e.g.
5627 // a lifetime argument being given instead of a type parameter.
5628 // Using inference instead of `Error` gives better error messages.
5629 self.var_for_def(span, param)
5632 GenericParamDefKind::Const => {
5633 // FIXME(const_generics:defaults)
5634 // No const parameters were provided, we have to infer them.
5635 self.var_for_def(span, param)
5641 assert!(!substs.has_escaping_bound_vars());
5642 assert!(!ty.has_escaping_bound_vars());
5644 // First, store the "user substs" for later.
5645 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5647 self.add_required_obligations(span, def_id, &substs);
5649 // Substitute the values for the type parameters into the type of
5650 // the referenced item.
5651 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5653 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5654 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5655 // is inherent, there is no `Self` parameter; instead, the impl needs
5656 // type parameters, which we can infer by unifying the provided `Self`
5657 // with the substituted impl type.
5658 // This also occurs for an enum variant on a type alias.
5659 let ty = tcx.type_of(impl_def_id);
5661 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5662 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5663 Ok(ok) => self.register_infer_ok_obligations(ok),
5665 self.tcx.sess.delay_span_bug(
5668 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5677 self.check_rustc_args_require_const(def_id, hir_id, span);
5679 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5680 self.write_substs(hir_id, substs);
5682 (ty_substituted, res)
5685 /// Add all the obligations that are required, substituting and normalized appropriately.
5686 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5687 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5689 for (i, mut obligation) in traits::predicates_for_generics(
5690 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5696 // This makes the error point at the bound, but we want to point at the argument
5697 if let Some(span) = spans.get(i) {
5698 obligation.cause.code = traits::BindingObligation(def_id, *span);
5700 self.register_predicate(obligation);
5704 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5705 // We're only interested in functions tagged with
5706 // #[rustc_args_required_const], so ignore anything that's not.
5707 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5711 // If our calling expression is indeed the function itself, we're good!
5712 // If not, generate an error that this can only be called directly.
5713 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5714 if let ExprKind::Call(ref callee, ..) = expr.kind {
5715 if callee.hir_id == hir_id {
5721 self.tcx.sess.span_err(
5723 "this function can only be invoked directly, not through a function pointer",
5727 /// Resolves `typ` by a single level if `typ` is a type variable.
5728 /// If no resolution is possible, then an error is reported.
5729 /// Numeric inference variables may be left unresolved.
5730 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5731 let ty = self.resolve_vars_with_obligations(ty);
5732 if !ty.is_ty_var() {
5735 if !self.is_tainted_by_errors() {
5736 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5737 .note("type must be known at this point")
5740 self.demand_suptype(sp, self.tcx.types.err, ty);
5745 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5748 ctxt: BreakableCtxt<'tcx>,
5750 ) -> (BreakableCtxt<'tcx>, R) {
5753 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5754 index = enclosing_breakables.stack.len();
5755 enclosing_breakables.by_id.insert(id, index);
5756 enclosing_breakables.stack.push(ctxt);
5760 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5761 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5762 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5763 enclosing_breakables.stack.pop().expect("missing breakable context")
5768 /// Instantiate a QueryResponse in a probe context, without a
5769 /// good ObligationCause.
5770 fn probe_instantiate_query_response(
5773 original_values: &OriginalQueryValues<'tcx>,
5774 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5775 ) -> InferResult<'tcx, Ty<'tcx>> {
5776 self.instantiate_query_response_and_region_obligations(
5777 &traits::ObligationCause::misc(span, self.body_id),
5784 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5785 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5786 let mut contained_in_place = false;
5788 while let hir::Node::Expr(parent_expr) =
5789 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5791 match &parent_expr.kind {
5792 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5793 if lhs.hir_id == expr_id {
5794 contained_in_place = true;
5800 expr_id = parent_expr.hir_id;
5807 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5808 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5810 assert_eq!(generics.parent, None);
5812 if generics.own_counts().types == 0 {
5816 let mut params_used = BitSet::new_empty(generics.params.len());
5818 if ty.references_error() {
5819 // If there is already another error, do not emit
5820 // an error for not using a type parameter.
5821 assert!(tcx.sess.has_errors());
5825 for leaf in ty.walk() {
5826 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5827 if let ty::Param(param) = leaf_ty.kind {
5828 debug!("found use of ty param {:?}", param);
5829 params_used.insert(param.index);
5834 for param in &generics.params {
5835 if !params_used.contains(param.index) {
5836 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5837 let span = tcx.def_span(param.def_id);
5842 "type parameter `{}` is unused",
5845 .span_label(span, "unused type parameter")
5852 fn fatally_break_rust(sess: &Session) {
5853 let handler = sess.diagnostic();
5854 handler.span_bug_no_panic(
5856 "It looks like you're trying to break rust; would you like some ICE?",
5858 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5859 handler.note_without_error(
5860 "we would appreciate a joke overview: \
5861 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5863 handler.note_without_error(&format!(
5864 "rustc {} running on {}",
5865 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5866 config::host_triple(),
5870 fn potentially_plural_count(count: usize, word: &str) -> String {
5871 format!("{} {}{}", count, word, pluralize!(count))