1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
80 mod generator_interior;
90 use crate::astconv::{AstConv, GenericArgCountMismatch, PathSeg};
92 use rustc_ast::util::parser::ExprPrecedence;
93 use rustc_attr as attr;
94 use rustc_data_structures::captures::Captures;
95 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
96 use rustc_errors::ErrorReported;
97 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
99 use rustc_hir::def::{CtorOf, DefKind, Res};
100 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
101 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
102 use rustc_hir::itemlikevisit::ItemLikeVisitor;
103 use rustc_hir::lang_items;
104 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
105 use rustc_index::bit_set::BitSet;
106 use rustc_index::vec::Idx;
107 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
108 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
109 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
110 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
111 use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
112 use rustc_middle::hir::map::blocks::FnLikeNode;
113 use rustc_middle::middle::region;
114 use rustc_middle::mir::interpret::ConstValue;
115 use rustc_middle::ty::adjustment::{
116 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
118 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
119 use rustc_middle::ty::query::Providers;
120 use rustc_middle::ty::subst::{
121 GenericArgKind, InternalSubsts, Subst, SubstsRef, 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);
668 let implicit_region_bound = body_id.map(|body_id| {
669 let body = tcx.hir().body(body_id);
670 tcx.mk_region(ty::ReScope(region::Scope {
671 id: body.value.hir_id.local_id,
672 data: region::ScopeData::CallSite,
677 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
679 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
680 locals: RefCell::new(Default::default()),
681 deferred_sized_obligations: RefCell::new(Vec::new()),
682 deferred_call_resolutions: RefCell::new(Default::default()),
683 deferred_cast_checks: RefCell::new(Vec::new()),
684 deferred_generator_interiors: RefCell::new(Vec::new()),
685 opaque_types: RefCell::new(Default::default()),
686 opaque_types_vars: RefCell::new(Default::default()),
687 implicit_region_bound,
692 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
693 debug!("register_predicate({:?})", obligation);
694 if obligation.has_escaping_bound_vars() {
695 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
697 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
700 fn register_predicates<I>(&self, obligations: I)
702 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
704 for obligation in obligations {
705 self.register_predicate(obligation);
709 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
710 self.register_predicates(infer_ok.obligations);
714 fn normalize_associated_types_in<T>(
718 param_env: ty::ParamEnv<'tcx>,
722 T: TypeFoldable<'tcx>,
724 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
725 self.register_infer_ok_obligations(ok)
729 struct CheckItemTypesVisitor<'tcx> {
733 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
734 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
735 check_item_type(self.tcx, i);
737 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
738 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
741 pub fn check_wf_new(tcx: TyCtxt<'_>) {
742 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
743 tcx.hir().krate().par_visit_all_item_likes(&visit);
746 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
747 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
750 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
751 debug_assert!(crate_num == LOCAL_CRATE);
752 tcx.par_body_owners(|body_owner_def_id| {
753 tcx.ensure().typeck_tables_of(body_owner_def_id.to_def_id());
757 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
758 wfcheck::check_item_well_formed(tcx, def_id);
761 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
762 wfcheck::check_trait_item(tcx, def_id);
765 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
766 wfcheck::check_impl_item(tcx, def_id);
769 pub fn provide(providers: &mut Providers<'_>) {
770 method::provide(providers);
771 *providers = Providers {
774 diagnostic_only_typeck_tables_of,
778 check_item_well_formed,
779 check_trait_item_well_formed,
780 check_impl_item_well_formed,
781 check_mod_item_types,
786 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
787 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
790 /// If this `DefId` is a "primary tables entry", returns
791 /// `Some((body_id, header, decl))` with information about
792 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
795 /// If this function returns `Some`, then `typeck_tables(def_id)` will
796 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
797 /// may not succeed. In some cases where this function returns `None`
798 /// (notably closures), `typeck_tables(def_id)` would wind up
799 /// redirecting to the owning function.
803 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
804 match tcx.hir().get(id) {
805 Node::Item(item) => match item.kind {
806 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
807 Some((body, Some(ty), None, None))
809 hir::ItemKind::Fn(ref sig, .., body) => {
810 Some((body, None, Some(&sig.header), Some(&sig.decl)))
814 Node::TraitItem(item) => match item.kind {
815 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
816 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
817 Some((body, None, Some(&sig.header), Some(&sig.decl)))
821 Node::ImplItem(item) => match item.kind {
822 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
823 hir::ImplItemKind::Fn(ref sig, body) => {
824 Some((body, None, Some(&sig.header), Some(&sig.decl)))
828 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
833 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
834 // Closures' tables come from their outermost function,
835 // as they are part of the same "inference environment".
836 let outer_def_id = tcx.closure_base_def_id(def_id);
837 if outer_def_id != def_id {
838 return tcx.has_typeck_tables(outer_def_id);
841 // FIXME(#71104) Should really be using just `as_local_hir_id` but
842 // some `LocalDefId` do not seem to have a corresponding HirId.
844 def_id.as_local().and_then(|def_id| tcx.hir().opt_local_def_id_to_hir_id(def_id))
846 primary_body_of(tcx, id).is_some()
852 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
853 &*tcx.typeck_tables_of(def_id).used_trait_imports
856 /// Inspects the substs of opaque types, replacing any inference variables
857 /// with proper generic parameter from the identity substs.
859 /// This is run after we normalize the function signature, to fix any inference
860 /// variables introduced by the projection of associated types. This ensures that
861 /// any opaque types used in the signature continue to refer to generic parameters,
862 /// allowing them to be considered for defining uses in the function body
864 /// For example, consider this code.
869 /// fn use_it(self) -> Self::MyItem
871 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
872 /// type MyItem = impl Iterator<Item = I>;
873 /// fn use_it(self) -> Self::MyItem {
879 /// When we normalize the signature of `use_it` from the impl block,
880 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
881 /// However, this projection result may contain inference variables, due
882 /// to the way that projection works. We didn't have any inference variables
883 /// in the signature to begin with - leaving them in will cause us to incorrectly
884 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
885 /// variables back to the actual generic parameters, we will correctly see that
886 /// we have a defining use of `MyItem`
887 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
889 T: TypeFoldable<'tcx>,
891 struct FixupFolder<'tcx> {
895 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
896 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
900 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
902 ty::Opaque(def_id, substs) => {
903 debug!("fixup_opaque_types: found type {:?}", ty);
904 // Here, we replace any inference variables that occur within
905 // the substs of an opaque type. By definition, any type occurring
906 // in the substs has a corresponding generic parameter, which is what
907 // we replace it with.
908 // This replacement is only run on the function signature, so any
909 // inference variables that we come across must be the rust of projection
910 // (there's no other way for a user to get inference variables into
911 // a function signature).
912 if ty.needs_infer() {
913 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
914 let old_param = substs[param.index as usize];
915 match old_param.unpack() {
916 GenericArgKind::Type(old_ty) => {
917 if let ty::Infer(_) = old_ty.kind {
918 // Replace inference type with a generic parameter
919 self.tcx.mk_param_from_def(param)
921 old_param.fold_with(self)
924 GenericArgKind::Const(old_const) => {
925 if let ty::ConstKind::Infer(_) = old_const.val {
926 // This should never happen - we currently do not support
927 // 'const projections', e.g.:
928 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
929 // which should be the only way for us to end up with a const inference
930 // variable after projection. If Rust ever gains support for this kind
931 // of projection, this should *probably* be changed to
932 // `self.tcx.mk_param_from_def(param)`
934 "Found infer const: `{:?}` in opaque type: {:?}",
939 old_param.fold_with(self)
942 GenericArgKind::Lifetime(old_region) => {
943 if let RegionKind::ReVar(_) = old_region {
944 self.tcx.mk_param_from_def(param)
946 old_param.fold_with(self)
951 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
952 debug!("fixup_opaque_types: new type: {:?}", new_ty);
958 _ => ty.super_fold_with(self),
963 debug!("fixup_opaque_types({:?})", val);
964 val.fold_with(&mut FixupFolder { tcx })
967 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &ty::TypeckTables<'tcx> {
968 let fallback = move || tcx.type_of(def_id);
969 typeck_tables_of_with_fallback(tcx, def_id, fallback)
972 /// Used only to get `TypeckTables` for type inference during error recovery.
973 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
974 fn diagnostic_only_typeck_tables_of<'tcx>(
977 ) -> &ty::TypeckTables<'tcx> {
978 assert!(def_id.is_local());
979 let fallback = move || {
980 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id).unwrap());
981 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
984 typeck_tables_of_with_fallback(tcx, def_id, fallback)
987 fn typeck_tables_of_with_fallback<'tcx>(
990 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
991 ) -> &'tcx ty::TypeckTables<'tcx> {
992 // Closures' tables come from their outermost function,
993 // as they are part of the same "inference environment".
994 let outer_def_id = tcx.closure_base_def_id(def_id);
995 if outer_def_id != def_id {
996 return tcx.typeck_tables_of(outer_def_id);
999 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
1000 let span = tcx.hir().span(id);
1002 // Figure out what primary body this item has.
1003 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
1004 span_bug!(span, "can't type-check body of {:?}", def_id);
1006 let body = tcx.hir().body(body_id);
1008 let tables = Inherited::build(tcx, def_id.expect_local()).enter(|inh| {
1009 let param_env = tcx.param_env(def_id);
1010 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1011 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1012 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1018 &hir::Generics::empty(),
1025 check_abi(tcx, span, fn_sig.abi());
1027 // Compute the fty from point of view of inside the fn.
1028 let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
1029 let fn_sig = inh.normalize_associated_types_in(
1036 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1038 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1041 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1042 let expected_type = body_ty
1043 .and_then(|ty| match ty.kind {
1044 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1047 .unwrap_or_else(fallback);
1048 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1049 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1051 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1052 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1057 // Gather locals in statics (because of block expressions).
1058 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1060 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1062 fcx.write_ty(id, revealed_ty);
1067 // All type checking constraints were added, try to fallback unsolved variables.
1068 fcx.select_obligations_where_possible(false, |_| {});
1069 let mut fallback_has_occurred = false;
1071 // We do fallback in two passes, to try to generate
1072 // better error messages.
1073 // The first time, we do *not* replace opaque types.
1074 for ty in &fcx.unsolved_variables() {
1075 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1077 // We now see if we can make progress. This might
1078 // cause us to unify inference variables for opaque types,
1079 // since we may have unified some other type variables
1080 // during the first phase of fallback.
1081 // This means that we only replace inference variables with their underlying
1082 // opaque types as a last resort.
1084 // In code like this:
1087 // type MyType = impl Copy;
1088 // fn produce() -> MyType { true }
1089 // fn bad_produce() -> MyType { panic!() }
1092 // we want to unify the opaque inference variable in `bad_produce`
1093 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1094 // This will produce a nice error message about conflicting concrete
1095 // types for `MyType`.
1097 // If we had tried to fallback the opaque inference variable to `MyType`,
1098 // we will generate a confusing type-check error that does not explicitly
1099 // refer to opaque types.
1100 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1102 // We now run fallback again, but this time we allow it to replace
1103 // unconstrained opaque type variables, in addition to performing
1104 // other kinds of fallback.
1105 for ty in &fcx.unsolved_variables() {
1106 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1109 // See if we can make any more progress.
1110 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1112 // Even though coercion casts provide type hints, we check casts after fallback for
1113 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1116 // Closure and generator analysis may run after fallback
1117 // because they don't constrain other type variables.
1118 fcx.closure_analyze(body);
1119 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1120 fcx.resolve_generator_interiors(def_id);
1122 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1123 let ty = fcx.normalize_ty(span, ty);
1124 fcx.require_type_is_sized(ty, span, code);
1127 fcx.select_all_obligations_or_error();
1129 if fn_decl.is_some() {
1130 fcx.regionck_fn(id, body);
1132 fcx.regionck_expr(body);
1135 fcx.resolve_type_vars_in_body(body)
1138 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1139 // it will need to hold.
1140 assert_eq!(tables.hir_owner, Some(id.owner));
1145 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1146 if !tcx.sess.target.target.is_abi_supported(abi) {
1151 "The ABI `{}` is not supported for the current target",
1158 struct GatherLocalsVisitor<'a, 'tcx> {
1159 fcx: &'a FnCtxt<'a, 'tcx>,
1160 parent_id: hir::HirId,
1163 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1164 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1167 // Infer the variable's type.
1168 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1169 kind: TypeVariableOriginKind::TypeInference,
1175 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1179 // Take type that the user specified.
1180 self.fcx.locals.borrow_mut().insert(nid, typ);
1187 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1188 type Map = intravisit::ErasedMap<'tcx>;
1190 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1191 NestedVisitorMap::None
1194 // Add explicitly-declared locals.
1195 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1196 let local_ty = match local.ty {
1198 let o_ty = self.fcx.to_ty(&ty);
1200 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1201 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1210 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1212 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1213 ty.hir_id, o_ty, revealed_ty, c_ty
1215 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1217 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1221 self.assign(local.span, local.hir_id, local_ty);
1224 "local variable {:?} is assigned type {}",
1226 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1228 intravisit::walk_local(self, local);
1231 // Add pattern bindings.
1232 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1233 if let PatKind::Binding(_, _, ident, _) = p.kind {
1234 let var_ty = self.assign(p.span, p.hir_id, None);
1236 if !self.fcx.tcx.features().unsized_locals {
1237 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1241 "pattern binding {} is assigned to {} with type {:?}",
1243 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1247 intravisit::walk_pat(self, p);
1250 // Don't descend into the bodies of nested closures.
1253 _: intravisit::FnKind<'tcx>,
1254 _: &'tcx hir::FnDecl<'tcx>,
1262 /// When `check_fn` is invoked on a generator (i.e., a body that
1263 /// includes yield), it returns back some information about the yield
1265 struct GeneratorTypes<'tcx> {
1266 /// Type of generator argument / values returned by `yield`.
1267 resume_ty: Ty<'tcx>,
1269 /// Type of value that is yielded.
1272 /// Types that are captured (see `GeneratorInterior` for more).
1275 /// Indicates if the generator is movable or static (immovable).
1276 movability: hir::Movability,
1279 /// Helper used for fns and closures. Does the grungy work of checking a function
1280 /// body and returns the function context used for that purpose, since in the case of a fn item
1281 /// there is still a bit more to do.
1284 /// * inherited: other fields inherited from the enclosing fn (if any)
1285 fn check_fn<'a, 'tcx>(
1286 inherited: &'a Inherited<'a, 'tcx>,
1287 param_env: ty::ParamEnv<'tcx>,
1288 fn_sig: ty::FnSig<'tcx>,
1289 decl: &'tcx hir::FnDecl<'tcx>,
1291 body: &'tcx hir::Body<'tcx>,
1292 can_be_generator: Option<hir::Movability>,
1293 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1294 let mut fn_sig = fn_sig;
1296 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1298 // Create the function context. This is either derived from scratch or,
1299 // in the case of closures, based on the outer context.
1300 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1301 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1304 let sess = tcx.sess;
1305 let hir = tcx.hir();
1307 let declared_ret_ty = fn_sig.output();
1308 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1309 let revealed_ret_ty =
1310 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1311 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1312 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1313 fn_sig = tcx.mk_fn_sig(
1314 fn_sig.inputs().iter().cloned(),
1321 let span = body.value.span;
1323 fn_maybe_err(tcx, span, fn_sig.abi);
1325 if body.generator_kind.is_some() && can_be_generator.is_some() {
1327 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1328 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1330 // Resume type defaults to `()` if the generator has no argument.
1331 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1333 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1336 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
1337 let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap();
1338 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1340 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1341 // (as it's created inside the body itself, not passed in from outside).
1342 let maybe_va_list = if fn_sig.c_variadic {
1343 let va_list_did = tcx.require_lang_item(
1344 lang_items::VaListTypeLangItem,
1345 Some(body.params.last().unwrap().span),
1347 let region = tcx.mk_region(ty::ReScope(region::Scope {
1348 id: body.value.hir_id.local_id,
1349 data: region::ScopeData::CallSite,
1352 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1357 // Add formal parameters.
1358 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1359 let inputs_fn = fn_sig.inputs().iter().copied();
1360 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1361 // Check the pattern.
1362 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1364 // Check that argument is Sized.
1365 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1366 // for simple cases like `fn foo(x: Trait)`,
1367 // where we would error once on the parameter as a whole, and once on the binding `x`.
1368 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1369 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1372 fcx.write_ty(param.hir_id, param_ty);
1375 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1377 fcx.check_return_expr(&body.value);
1379 // We insert the deferred_generator_interiors entry after visiting the body.
1380 // This ensures that all nested generators appear before the entry of this generator.
1381 // resolve_generator_interiors relies on this property.
1382 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1384 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1385 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1387 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1388 Some(GeneratorTypes {
1392 movability: can_be_generator.unwrap(),
1398 // Finalize the return check by taking the LUB of the return types
1399 // we saw and assigning it to the expected return type. This isn't
1400 // really expected to fail, since the coercions would have failed
1401 // earlier when trying to find a LUB.
1403 // However, the behavior around `!` is sort of complex. In the
1404 // event that the `actual_return_ty` comes back as `!`, that
1405 // indicates that the fn either does not return or "returns" only
1406 // values of type `!`. In this case, if there is an expected
1407 // return type that is *not* `!`, that should be ok. But if the
1408 // return type is being inferred, we want to "fallback" to `!`:
1410 // let x = move || panic!();
1412 // To allow for that, I am creating a type variable with diverging
1413 // fallback. This was deemed ever so slightly better than unifying
1414 // the return value with `!` because it allows for the caller to
1415 // make more assumptions about the return type (e.g., they could do
1417 // let y: Option<u32> = Some(x());
1419 // which would then cause this return type to become `u32`, not
1421 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1422 let mut actual_return_ty = coercion.complete(&fcx);
1423 if actual_return_ty.is_never() {
1424 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1425 kind: TypeVariableOriginKind::DivergingFn,
1429 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1431 // Check that the main return type implements the termination trait.
1432 if let Some(term_id) = tcx.lang_items().termination() {
1433 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1434 let main_id = hir.as_local_hir_id(def_id).unwrap();
1435 if main_id == fn_id {
1436 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1437 let trait_ref = ty::TraitRef::new(term_id, substs);
1438 let return_ty_span = decl.output.span();
1439 let cause = traits::ObligationCause::new(
1442 ObligationCauseCode::MainFunctionType,
1445 inherited.register_predicate(traits::Obligation::new(
1448 trait_ref.without_const().to_predicate(),
1454 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1455 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1456 if panic_impl_did == hir.local_def_id(fn_id) {
1457 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1458 if declared_ret_ty.kind != ty::Never {
1459 sess.span_err(decl.output.span(), "return type should be `!`");
1462 let inputs = fn_sig.inputs();
1463 let span = hir.span(fn_id);
1464 if inputs.len() == 1 {
1465 let arg_is_panic_info = match inputs[0].kind {
1466 ty::Ref(region, ty, mutbl) => match ty.kind {
1467 ty::Adt(ref adt, _) => {
1468 adt.did == panic_info_did
1469 && mutbl == hir::Mutability::Not
1470 && *region != RegionKind::ReStatic
1477 if !arg_is_panic_info {
1478 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1481 if let Node::Item(item) = hir.get(fn_id) {
1482 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1483 if !generics.params.is_empty() {
1484 sess.span_err(span, "should have no type parameters");
1489 let span = sess.source_map().guess_head_span(span);
1490 sess.span_err(span, "function should have one argument");
1493 sess.err("language item required, but not found: `panic_info`");
1498 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1499 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1500 if alloc_error_handler_did == hir.local_def_id(fn_id) {
1501 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1502 if declared_ret_ty.kind != ty::Never {
1503 sess.span_err(decl.output.span(), "return type should be `!`");
1506 let inputs = fn_sig.inputs();
1507 let span = hir.span(fn_id);
1508 if inputs.len() == 1 {
1509 let arg_is_alloc_layout = match inputs[0].kind {
1510 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1514 if !arg_is_alloc_layout {
1515 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1518 if let Node::Item(item) = hir.get(fn_id) {
1519 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1520 if !generics.params.is_empty() {
1523 "`#[alloc_error_handler]` function should have no type \
1530 let span = sess.source_map().guess_head_span(span);
1531 sess.span_err(span, "function should have one argument");
1534 sess.err("language item required, but not found: `alloc_layout`");
1542 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1543 let def_id = tcx.hir().local_def_id(id);
1544 let def = tcx.adt_def(def_id);
1545 def.destructor(tcx); // force the destructor to be evaluated
1546 check_representable(tcx, span, def_id);
1548 if def.repr.simd() {
1549 check_simd(tcx, span, def_id);
1552 check_transparent(tcx, span, def_id);
1553 check_packed(tcx, span, def_id);
1556 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1557 let def_id = tcx.hir().local_def_id(id);
1558 let def = tcx.adt_def(def_id);
1559 def.destructor(tcx); // force the destructor to be evaluated
1560 check_representable(tcx, span, def_id);
1561 check_transparent(tcx, span, def_id);
1562 check_union_fields(tcx, span, def_id);
1563 check_packed(tcx, span, def_id);
1566 /// When the `#![feature(untagged_unions)]` gate is active,
1567 /// check that the fields of the `union` does not contain fields that need dropping.
1568 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1569 let item_type = tcx.type_of(item_def_id);
1570 if let ty::Adt(def, substs) = item_type.kind {
1571 assert!(def.is_union());
1572 let fields = &def.non_enum_variant().fields;
1573 let param_env = tcx.param_env(item_def_id);
1574 for field in fields {
1575 let field_ty = field.ty(tcx, substs);
1576 // We are currently checking the type this field came from, so it must be local.
1577 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1578 if field_ty.needs_drop(tcx, param_env) {
1583 "unions may not contain fields that need dropping"
1585 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1591 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1596 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1597 /// projections that would result in "inheriting lifetimes".
1598 fn check_opaque<'tcx>(
1601 substs: SubstsRef<'tcx>,
1603 origin: &hir::OpaqueTyOrigin,
1605 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1606 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1609 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1610 /// in "inheriting lifetimes".
1611 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span: Span) {
1613 tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
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,
1625 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1626 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1627 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1628 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1631 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1632 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1633 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1634 return *index < self.generics.parent_count as u32;
1637 r.super_visit_with(self)
1641 let prohibit_opaque = match item.kind {
1642 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. })
1643 | ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1644 let mut visitor = ProhibitOpaqueVisitor {
1645 opaque_identity_ty: tcx
1646 .mk_opaque(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1647 generics: tcx.generics_of(def_id),
1649 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1651 tcx.predicates_of(def_id)
1654 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1659 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1660 if prohibit_opaque {
1661 let is_async = match item.kind {
1662 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1663 hir::OpaqueTyOrigin::AsyncFn => true,
1666 _ => unreachable!(),
1672 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1674 if is_async { "async fn" } else { "impl Trait" },
1680 /// Checks that an opaque type does not contain cycles.
1681 fn check_opaque_for_cycles<'tcx>(
1684 substs: SubstsRef<'tcx>,
1686 origin: &hir::OpaqueTyOrigin,
1688 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1689 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1690 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1691 .span_label(span, "recursive `async fn`")
1692 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1696 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1697 err.span_label(span, "expands to a recursive type");
1698 if let ty::Opaque(..) = partially_expanded_type.kind {
1699 err.note("type resolves to itself");
1701 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1708 // Forbid defining intrinsics in Rust code,
1709 // as they must always be defined by the compiler.
1710 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1711 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1712 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1716 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1718 "check_item_type(it.hir_id={}, it.name={})",
1720 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1722 let _indenter = indenter();
1724 // Consts can play a role in type-checking, so they are included here.
1725 hir::ItemKind::Static(..) => {
1726 let def_id = tcx.hir().local_def_id(it.hir_id);
1727 tcx.typeck_tables_of(def_id);
1728 maybe_check_static_with_link_section(tcx, def_id, it.span);
1730 hir::ItemKind::Const(..) => {
1731 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1733 hir::ItemKind::Enum(ref enum_definition, _) => {
1734 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1736 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1737 hir::ItemKind::Impl { ref items, .. } => {
1738 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1739 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1740 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1741 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1742 let trait_def_id = impl_trait_ref.def_id;
1743 check_on_unimplemented(tcx, trait_def_id, it);
1746 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1747 let def_id = tcx.hir().local_def_id(it.hir_id);
1748 check_on_unimplemented(tcx, def_id, it);
1750 for item in items.iter() {
1751 let item = tcx.hir().trait_item(item.id);
1752 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1753 let abi = sig.header.abi;
1754 fn_maybe_err(tcx, item.ident.span, abi);
1758 hir::ItemKind::Struct(..) => {
1759 check_struct(tcx, it.hir_id, it.span);
1761 hir::ItemKind::Union(..) => {
1762 check_union(tcx, it.hir_id, it.span);
1764 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1765 let def_id = tcx.hir().local_def_id(it.hir_id);
1767 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1768 check_opaque(tcx, def_id, substs, it.span, &origin);
1770 hir::ItemKind::TyAlias(..) => {
1771 let def_id = tcx.hir().local_def_id(it.hir_id);
1772 let pty_ty = tcx.type_of(def_id);
1773 let generics = tcx.generics_of(def_id);
1774 check_type_params_are_used(tcx, &generics, pty_ty);
1776 hir::ItemKind::ForeignMod(ref m) => {
1777 check_abi(tcx, it.span, m.abi);
1779 if m.abi == Abi::RustIntrinsic {
1780 for item in m.items {
1781 intrinsic::check_intrinsic_type(tcx, item);
1783 } else if m.abi == Abi::PlatformIntrinsic {
1784 for item in m.items {
1785 intrinsic::check_platform_intrinsic_type(tcx, item);
1788 for item in m.items {
1789 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1790 let own_counts = generics.own_counts();
1791 if generics.params.len() - own_counts.lifetimes != 0 {
1792 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1793 (_, 0) => ("type", "types", Some("u32")),
1794 // We don't specify an example value, because we can't generate
1795 // a valid value for any type.
1796 (0, _) => ("const", "consts", None),
1797 _ => ("type or const", "types or consts", None),
1803 "foreign items may not have {} parameters",
1806 .span_label(item.span, &format!("can't have {} parameters", kinds))
1808 // FIXME: once we start storing spans for type arguments, turn this
1809 // into a suggestion.
1811 "replace the {} parameters with concrete {}{}",
1814 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1820 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1821 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1826 _ => { /* nothing to do */ }
1830 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1831 // Only restricted on wasm32 target for now
1832 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1836 // If `#[link_section]` is missing, then nothing to verify
1837 let attrs = tcx.codegen_fn_attrs(id);
1838 if attrs.link_section.is_none() {
1842 // For the wasm32 target statics with `#[link_section]` are placed into custom
1843 // sections of the final output file, but this isn't link custom sections of
1844 // other executable formats. Namely we can only embed a list of bytes,
1845 // nothing with pointers to anything else or relocations. If any relocation
1846 // show up, reject them here.
1847 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1848 // the consumer's responsibility to ensure all bytes that have been read
1849 // have defined values.
1850 match tcx.const_eval_poly(id) {
1851 Ok(ConstValue::ByRef { alloc, .. }) => {
1852 if alloc.relocations().len() != 0 {
1853 let msg = "statics with a custom `#[link_section]` must be a \
1854 simple list of bytes on the wasm target with no \
1855 extra levels of indirection such as references";
1856 tcx.sess.span_err(span, msg);
1859 Ok(_) => bug!("Matching on non-ByRef static"),
1864 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1865 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1866 // an error would be reported if this fails.
1867 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1870 fn report_forbidden_specialization(
1872 impl_item: &hir::ImplItem<'_>,
1875 let mut err = struct_span_err!(
1879 "`{}` specializes an item from a parent `impl`, but \
1880 that item is not marked `default`",
1883 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1885 match tcx.span_of_impl(parent_impl) {
1887 err.span_label(span, "parent `impl` is here");
1889 "to specialize, `{}` in the parent `impl` must be marked `default`",
1894 err.note(&format!("parent implementation is in crate `{}`", cname));
1901 fn check_specialization_validity<'tcx>(
1903 trait_def: &ty::TraitDef,
1904 trait_item: &ty::AssocItem,
1906 impl_item: &hir::ImplItem<'_>,
1908 let kind = match impl_item.kind {
1909 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1910 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1911 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1912 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1915 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1916 Ok(ancestors) => ancestors,
1919 let mut ancestor_impls = ancestors
1921 .filter_map(|parent| {
1922 if parent.is_from_trait() {
1925 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1930 if ancestor_impls.peek().is_none() {
1931 // No parent, nothing to specialize.
1935 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1937 // Parent impl exists, and contains the parent item we're trying to specialize, but
1938 // doesn't mark it `default`.
1939 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1940 Some(Err(parent_impl.def_id()))
1943 // Parent impl contains item and makes it specializable.
1944 Some(_) => Some(Ok(())),
1946 // Parent impl doesn't mention the item. This means it's inherited from the
1947 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1948 // "defaultness" from the grandparent, else they are final.
1950 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1953 Some(Err(parent_impl.def_id()))
1959 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1960 // item. This is allowed, the item isn't actually getting specialized here.
1961 let result = opt_result.unwrap_or(Ok(()));
1963 if let Err(parent_impl) = result {
1964 report_forbidden_specialization(tcx, impl_item, parent_impl);
1968 fn check_impl_items_against_trait<'tcx>(
1970 full_impl_span: Span,
1972 impl_trait_ref: ty::TraitRef<'tcx>,
1973 impl_item_refs: &[hir::ImplItemRef<'_>],
1975 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1977 // If the trait reference itself is erroneous (so the compilation is going
1978 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1979 // isn't populated for such impls.
1980 if impl_trait_ref.references_error() {
1984 // Negative impls are not expected to have any items
1985 match tcx.impl_polarity(impl_id) {
1986 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
1987 ty::ImplPolarity::Negative => {
1988 if let [first_item_ref, ..] = impl_item_refs {
1989 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
1994 "negative impls cannot have any items"
2002 // Locate trait definition and items
2003 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2005 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2007 // Check existing impl methods to see if they are both present in trait
2008 // and compatible with trait signature
2009 for impl_item in impl_items() {
2010 let namespace = impl_item.kind.namespace();
2011 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2012 let ty_trait_item = tcx
2013 .associated_items(impl_trait_ref.def_id)
2014 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2016 // Not compatible, but needed for the error message
2017 tcx.associated_items(impl_trait_ref.def_id)
2018 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2022 // Check that impl definition matches trait definition
2023 if let Some(ty_trait_item) = ty_trait_item {
2024 match impl_item.kind {
2025 hir::ImplItemKind::Const(..) => {
2026 // Find associated const definition.
2027 if ty_trait_item.kind == ty::AssocKind::Const {
2036 let mut err = struct_span_err!(
2040 "item `{}` is an associated const, \
2041 which doesn't match its trait `{}`",
2043 impl_trait_ref.print_only_trait_path()
2045 err.span_label(impl_item.span, "does not match trait");
2046 // We can only get the spans from local trait definition
2047 // Same for E0324 and E0325
2048 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2049 err.span_label(trait_span, "item in trait");
2054 hir::ImplItemKind::Fn(..) => {
2055 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2056 if ty_trait_item.kind == ty::AssocKind::Fn {
2057 compare_impl_method(
2066 let mut err = struct_span_err!(
2070 "item `{}` is an associated method, \
2071 which doesn't match its trait `{}`",
2073 impl_trait_ref.print_only_trait_path()
2075 err.span_label(impl_item.span, "does not match trait");
2076 if let Some(trait_span) = opt_trait_span {
2077 err.span_label(trait_span, "item in trait");
2082 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2083 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2084 if ty_trait_item.kind == ty::AssocKind::Type {
2094 let mut err = struct_span_err!(
2098 "item `{}` is an associated type, \
2099 which doesn't match its trait `{}`",
2101 impl_trait_ref.print_only_trait_path()
2103 err.span_label(impl_item.span, "does not match trait");
2104 if let Some(trait_span) = opt_trait_span {
2105 err.span_label(trait_span, "item in trait");
2112 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
2116 // Check for missing items from trait
2117 let mut missing_items = Vec::new();
2118 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) {
2119 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2120 let is_implemented = ancestors
2121 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2122 .map(|node_item| !node_item.defining_node.is_from_trait())
2125 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2126 if !trait_item.defaultness.has_value() {
2127 missing_items.push(*trait_item);
2133 if !missing_items.is_empty() {
2134 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2138 fn missing_items_err(
2141 missing_items: &[ty::AssocItem],
2142 full_impl_span: Span,
2144 let missing_items_msg = missing_items
2146 .map(|trait_item| trait_item.ident.to_string())
2147 .collect::<Vec<_>>()
2150 let mut err = struct_span_err!(
2154 "not all trait items implemented, missing: `{}`",
2157 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2159 // `Span` before impl block closing brace.
2160 let hi = full_impl_span.hi() - BytePos(1);
2161 // Point at the place right before the closing brace of the relevant `impl` to suggest
2162 // adding the associated item at the end of its body.
2163 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2164 // Obtain the level of indentation ending in `sugg_sp`.
2165 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2166 // Make the whitespace that will make the suggestion have the right indentation.
2167 let padding: String = (0..indentation).map(|_| " ").collect();
2169 for trait_item in missing_items {
2170 let snippet = suggestion_signature(&trait_item, tcx);
2171 let code = format!("{}{}\n{}", padding, snippet, padding);
2172 let msg = format!("implement the missing item: `{}`", snippet);
2173 let appl = Applicability::HasPlaceholders;
2174 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2175 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2176 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2178 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2184 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2185 fn bounds_from_generic_predicates(
2187 predicates: ty::GenericPredicates<'_>,
2188 ) -> (String, String) {
2189 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2190 let mut projections = vec![];
2191 for (predicate, _) in predicates.predicates {
2192 debug!("predicate {:?}", predicate);
2194 ty::Predicate::Trait(trait_predicate, _) => {
2195 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2196 let def_id = trait_predicate.skip_binder().def_id();
2197 if Some(def_id) != tcx.lang_items().sized_trait() {
2198 // Type params are `Sized` by default, do not add that restriction to the list
2199 // if it is a positive requirement.
2200 entry.push(trait_predicate.skip_binder().def_id());
2203 ty::Predicate::Projection(projection_pred) => {
2204 projections.push(projection_pred);
2209 let generics = if types.is_empty() {
2216 .filter_map(|t| match t.kind {
2217 ty::Param(_) => Some(t.to_string()),
2218 // Avoid suggesting the following:
2219 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2222 .collect::<Vec<_>>()
2226 let mut where_clauses = vec![];
2227 for (ty, bounds) in types {
2228 for bound in &bounds {
2229 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2232 for projection in &projections {
2233 let p = projection.skip_binder();
2234 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2235 // insert the associated types where they correspond, but for now let's be "lazy" and
2236 // propose this instead of the following valid resugaring:
2237 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2238 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2240 let where_clauses = if where_clauses.is_empty() {
2243 format!(" where {}", where_clauses.join(", "))
2245 (generics, where_clauses)
2248 /// Return placeholder code for the given function.
2249 fn fn_sig_suggestion(
2251 sig: &ty::FnSig<'_>,
2253 predicates: ty::GenericPredicates<'_>,
2254 assoc: &ty::AssocItem,
2261 Some(match ty.kind {
2262 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2263 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2264 let reg = match &format!("{}", reg)[..] {
2265 "'_" | "" => String::new(),
2266 reg => format!("{} ", reg),
2268 if assoc.fn_has_self_parameter {
2270 ty::Param(param) if param.name == kw::SelfUpper => {
2271 format!("&{}{}self", reg, mutability.prefix_str())
2274 _ => format!("self: {}", ty),
2277 format!("_: {:?}", ty)
2281 if assoc.fn_has_self_parameter && i == 0 {
2282 format!("self: {:?}", ty)
2284 format!("_: {:?}", ty)
2289 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2290 .filter_map(|arg| arg)
2291 .collect::<Vec<String>>()
2293 let output = sig.output();
2294 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2296 let unsafety = sig.unsafety.prefix_str();
2297 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2299 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2300 // not be present in the `fn` definition, not will we account for renamed
2301 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2302 // fill in a significant portion of the missing code, and other subsequent
2303 // suggestions can help the user fix the code.
2305 "{}fn {}{}({}){}{} {{ todo!() }}",
2306 unsafety, ident, generics, args, output, where_clauses
2310 /// Return placeholder code for the given associated item.
2311 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2312 /// structured suggestion.
2313 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2315 ty::AssocKind::Fn => {
2316 // We skip the binder here because the binder would deanonymize all
2317 // late-bound regions, and we don't want method signatures to show up
2318 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2319 // regions just fine, showing `fn(&MyType)`.
2322 tcx.fn_sig(assoc.def_id).skip_binder(),
2324 tcx.predicates_of(assoc.def_id),
2328 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2329 // FIXME(type_alias_impl_trait): we should print bounds here too.
2330 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2331 ty::AssocKind::Const => {
2332 let ty = tcx.type_of(assoc.def_id);
2333 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2334 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2339 /// Checks whether a type can be represented in memory. In particular, it
2340 /// identifies types that contain themselves without indirection through a
2341 /// pointer, which would mean their size is unbounded.
2342 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
2343 let rty = tcx.type_of(item_def_id);
2345 // Check that it is possible to represent this type. This call identifies
2346 // (1) types that contain themselves and (2) types that contain a different
2347 // recursive type. It is only necessary to throw an error on those that
2348 // contain themselves. For case 2, there must be an inner type that will be
2349 // caught by case 1.
2350 match rty.is_representable(tcx, sp) {
2351 Representability::SelfRecursive(spans) => {
2352 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id);
2354 err.span_label(span, "recursive without indirection");
2359 Representability::Representable | Representability::ContainsRecursive => (),
2364 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2365 let t = tcx.type_of(def_id);
2366 if let ty::Adt(def, substs) = t.kind {
2367 if def.is_struct() {
2368 let fields = &def.non_enum_variant().fields;
2369 if fields.is_empty() {
2370 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2373 let e = fields[0].ty(tcx, substs);
2374 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2375 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2376 .span_label(sp, "SIMD elements must have the same type")
2381 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2382 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2388 "SIMD vector element type should be machine type"
2398 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2399 let repr = tcx.adt_def(def_id).repr;
2401 for attr in tcx.get_attrs(def_id).iter() {
2402 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2403 if let attr::ReprPacked(pack) = r {
2404 if let Some(repr_pack) = repr.pack {
2405 if pack as u64 != repr_pack.bytes() {
2410 "type has conflicting packed representation hints"
2418 if repr.align.is_some() {
2423 "type has conflicting packed and align representation hints"
2427 if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) {
2428 let mut err = struct_span_err!(
2432 "packed type cannot transitively contain a `#[repr(align)]` type"
2435 let hir = tcx.hir();
2436 if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) {
2437 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2439 tcx.def_span(def_spans[0].0),
2440 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2445 if def_spans.len() > 2 {
2446 let mut first = true;
2447 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2448 if let Some(hir_id) = hir.as_local_hir_id(*adt_def) {
2449 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2454 "`{}` contains a field of type `{}`",
2455 tcx.type_of(def_id),
2459 format!("...which contains a field of type `{}`", ident)
2474 fn check_packed_inner(
2477 stack: &mut Vec<DefId>,
2478 ) -> Option<Vec<(DefId, Span)>> {
2479 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2480 if def.is_struct() || def.is_union() {
2481 if def.repr.align.is_some() {
2482 return Some(vec![(def.did, DUMMY_SP)]);
2486 for field in &def.non_enum_variant().fields {
2487 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2488 if !stack.contains(&def.did) {
2489 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2490 defs.push((def.did, field.ident.span));
2503 /// Emit an error when encountering more or less than one variant in a transparent enum.
2504 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2505 let variant_spans: Vec<_> = adt
2508 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2510 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2511 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2512 err.span_label(sp, &msg);
2513 if let [start @ .., end] = &*variant_spans {
2514 for variant_span in start {
2515 err.span_label(*variant_span, "");
2517 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2522 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2524 fn bad_non_zero_sized_fields<'tcx>(
2526 adt: &'tcx ty::AdtDef,
2528 field_spans: impl Iterator<Item = Span>,
2531 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2532 let mut err = struct_span_err!(
2536 "{}transparent {} {}",
2537 if adt.is_enum() { "the variant of a " } else { "" },
2541 err.span_label(sp, &msg);
2542 for sp in field_spans {
2543 err.span_label(sp, "this field is non-zero-sized");
2548 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2549 let adt = tcx.adt_def(def_id);
2550 if !adt.repr.transparent() {
2553 let sp = tcx.sess.source_map().guess_head_span(sp);
2555 if adt.is_union() && !tcx.features().transparent_unions {
2557 &tcx.sess.parse_sess,
2558 sym::transparent_unions,
2560 "transparent unions are unstable",
2565 if adt.variants.len() != 1 {
2566 bad_variant_count(tcx, adt, sp, def_id);
2567 if adt.variants.is_empty() {
2568 // Don't bother checking the fields. No variants (and thus no fields) exist.
2573 // For each field, figure out if it's known to be a ZST and align(1)
2574 let field_infos = adt.all_fields().map(|field| {
2575 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2576 let param_env = tcx.param_env(field.did);
2577 let layout = tcx.layout_of(param_env.and(ty));
2578 // We are currently checking the type this field came from, so it must be local
2579 let span = tcx.hir().span_if_local(field.did).unwrap();
2580 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2581 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2585 let non_zst_fields =
2586 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2587 let non_zst_count = non_zst_fields.clone().count();
2588 if non_zst_count != 1 {
2589 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2591 for (span, zst, align1) in field_infos {
2597 "zero-sized field in transparent {} has alignment larger than 1",
2600 .span_label(span, "has alignment larger than 1")
2606 #[allow(trivial_numeric_casts)]
2607 pub fn check_enum<'tcx>(
2610 vs: &'tcx [hir::Variant<'tcx>],
2613 let def_id = tcx.hir().local_def_id(id);
2614 let def = tcx.adt_def(def_id);
2615 def.destructor(tcx); // force the destructor to be evaluated
2618 let attributes = tcx.get_attrs(def_id);
2619 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2624 "unsupported representation for zero-variant enum"
2626 .span_label(sp, "zero-variant enum")
2631 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2632 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2633 if !tcx.features().repr128 {
2635 &tcx.sess.parse_sess,
2638 "repr with 128-bit type is unstable",
2645 if let Some(ref e) = v.disr_expr {
2646 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2650 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2651 let is_unit = |var: &hir::Variant<'_>| match var.data {
2652 hir::VariantData::Unit(..) => true,
2656 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2657 let has_non_units = vs.iter().any(|var| !is_unit(var));
2658 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2659 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2661 if disr_non_unit || (disr_units && has_non_units) {
2663 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2668 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2669 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2670 // Check for duplicate discriminant values
2671 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2672 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2673 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2674 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2675 let i_span = match variant_i.disr_expr {
2676 Some(ref expr) => tcx.hir().span(expr.hir_id),
2677 None => tcx.hir().span(variant_i_hir_id),
2679 let span = match v.disr_expr {
2680 Some(ref expr) => tcx.hir().span(expr.hir_id),
2687 "discriminant value `{}` already exists",
2690 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2691 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2694 disr_vals.push(discr);
2697 check_representable(tcx, sp, def_id);
2698 check_transparent(tcx, sp, def_id);
2701 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2706 "expected unit struct, unit variant or constant, found {}{}",
2708 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2713 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2714 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2718 fn item_def_id(&self) -> Option<DefId> {
2722 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2723 // FIXME: refactor this into a method
2724 let node = self.tcx.hir().get(self.body_id);
2725 if let Some(fn_like) = FnLikeNode::from_node(node) {
2728 hir::Constness::NotConst
2732 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2734 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2735 let item_id = tcx.hir().ty_param_owner(hir_id);
2736 let item_def_id = tcx.hir().local_def_id(item_id);
2737 let generics = tcx.generics_of(item_def_id);
2738 let index = generics.param_def_id_to_index[&def_id];
2739 ty::GenericPredicates {
2741 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2742 |&predicate| match predicate {
2743 ty::Predicate::Trait(ref data, _)
2744 if data.skip_binder().self_ty().is_param(index) =>
2746 // HACK(eddyb) should get the original `Span`.
2747 let span = tcx.def_span(def_id);
2748 Some((predicate, span))
2756 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2758 Some(def) => infer::EarlyBoundRegion(span, def.name),
2759 None => infer::MiscVariable(span),
2761 Some(self.next_region_var(v))
2764 fn allow_ty_infer(&self) -> bool {
2768 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2769 if let Some(param) = param {
2770 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2775 self.next_ty_var(TypeVariableOrigin {
2776 kind: TypeVariableOriginKind::TypeInference,
2785 param: Option<&ty::GenericParamDef>,
2787 ) -> &'tcx Const<'tcx> {
2788 if let Some(param) = param {
2789 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2794 self.next_const_var(
2796 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2801 fn projected_ty_from_poly_trait_ref(
2805 item_segment: &hir::PathSegment<'_>,
2806 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2808 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2810 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2814 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2823 self.tcx().mk_projection(item_def_id, item_substs)
2826 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2827 if ty.has_escaping_bound_vars() {
2828 ty // FIXME: normalization and escaping regions
2830 self.normalize_associated_types_in(span, &ty)
2834 fn set_tainted_by_errors(&self) {
2835 self.infcx.set_tainted_by_errors()
2838 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2839 self.write_ty(hir_id, ty)
2843 /// Controls whether the arguments are tupled. This is used for the call
2846 /// Tupling means that all call-side arguments are packed into a tuple and
2847 /// passed as a single parameter. For example, if tupling is enabled, this
2850 /// fn f(x: (isize, isize))
2852 /// Can be called as:
2859 #[derive(Clone, Eq, PartialEq)]
2860 enum TupleArgumentsFlag {
2865 /// Controls how we perform fallback for unconstrained
2868 /// Do not fallback type variables to opaque types.
2870 /// Perform all possible kinds of fallback, including
2871 /// turning type variables to opaque types.
2875 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2877 inh: &'a Inherited<'a, 'tcx>,
2878 param_env: ty::ParamEnv<'tcx>,
2879 body_id: hir::HirId,
2880 ) -> FnCtxt<'a, 'tcx> {
2884 err_count_on_creation: inh.tcx.sess.err_count(),
2886 ret_coercion_span: RefCell::new(None),
2887 resume_yield_tys: None,
2888 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2889 diverges: Cell::new(Diverges::Maybe),
2890 has_errors: Cell::new(false),
2891 enclosing_breakables: RefCell::new(EnclosingBreakables {
2893 by_id: Default::default(),
2899 pub fn sess(&self) -> &Session {
2903 pub fn errors_reported_since_creation(&self) -> bool {
2904 self.tcx.sess.err_count() > self.err_count_on_creation
2907 /// Produces warning on the given node, if the current point in the
2908 /// function is unreachable, and there hasn't been another warning.
2909 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2910 // FIXME: Combine these two 'if' expressions into one once
2911 // let chains are implemented
2912 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2913 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2914 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2915 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2916 if !span.is_desugaring(DesugaringKind::CondTemporary)
2917 && !span.is_desugaring(DesugaringKind::Async)
2918 && !orig_span.is_desugaring(DesugaringKind::Await)
2920 self.diverges.set(Diverges::WarnedAlways);
2922 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2924 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2925 let msg = format!("unreachable {}", kind);
2927 .span_label(span, &msg)
2931 .unwrap_or("any code following this expression is unreachable"),
2939 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2940 ObligationCause::new(span, self.body_id, code)
2943 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2944 self.cause(span, ObligationCauseCode::MiscObligation)
2947 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2948 /// version (resolve_vars_if_possible), this version will
2949 /// also select obligations if it seems useful, in an effort
2950 /// to get more type information.
2951 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2952 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2954 // No Infer()? Nothing needs doing.
2955 if !ty.has_infer_types_or_consts() {
2956 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2960 // If `ty` is a type variable, see whether we already know what it is.
2961 ty = self.resolve_vars_if_possible(&ty);
2962 if !ty.has_infer_types_or_consts() {
2963 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2967 // If not, try resolving pending obligations as much as
2968 // possible. This can help substantially when there are
2969 // indirect dependencies that don't seem worth tracking
2971 self.select_obligations_where_possible(false, |_| {});
2972 ty = self.resolve_vars_if_possible(&ty);
2974 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2978 fn record_deferred_call_resolution(
2980 closure_def_id: DefId,
2981 r: DeferredCallResolution<'tcx>,
2983 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2984 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2987 fn remove_deferred_call_resolutions(
2989 closure_def_id: DefId,
2990 ) -> Vec<DeferredCallResolution<'tcx>> {
2991 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2992 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2995 pub fn tag(&self) -> String {
2996 format!("{:p}", self)
2999 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3000 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3001 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3006 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3008 "write_ty({:?}, {:?}) in fcx {}",
3010 self.resolve_vars_if_possible(&ty),
3013 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3015 if ty.references_error() {
3016 self.has_errors.set(true);
3017 self.set_tainted_by_errors();
3021 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3022 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3025 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3026 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3029 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3030 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3031 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3032 self.write_substs(hir_id, method.substs);
3034 // When the method is confirmed, the `method.substs` includes
3035 // parameters from not just the method, but also the impl of
3036 // the method -- in particular, the `Self` type will be fully
3037 // resolved. However, those are not something that the "user
3038 // specified" -- i.e., those types come from the inferred type
3039 // of the receiver, not something the user wrote. So when we
3040 // create the user-substs, we want to replace those earlier
3041 // types with just the types that the user actually wrote --
3042 // that is, those that appear on the *method itself*.
3044 // As an example, if the user wrote something like
3045 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3046 // type of `foo` (possibly adjusted), but we don't want to
3047 // include that. We want just the `[_, u32]` part.
3048 if !method.substs.is_noop() {
3049 let method_generics = self.tcx.generics_of(method.def_id);
3050 if !method_generics.params.is_empty() {
3051 let user_type_annotation = self.infcx.probe(|_| {
3052 let user_substs = UserSubsts {
3053 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3054 let i = param.index as usize;
3055 if i < method_generics.parent_count {
3056 self.infcx.var_for_def(DUMMY_SP, param)
3061 user_self_ty: None, // not relevant here
3064 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3070 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3071 self.write_user_type_annotation(hir_id, user_type_annotation);
3076 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3077 if !substs.is_noop() {
3078 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3080 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3084 /// Given the substs that we just converted from the HIR, try to
3085 /// canonicalize them and store them as user-given substitutions
3086 /// (i.e., substitutions that must be respected by the NLL check).
3088 /// This should be invoked **before any unifications have
3089 /// occurred**, so that annotations like `Vec<_>` are preserved
3091 pub fn write_user_type_annotation_from_substs(
3095 substs: SubstsRef<'tcx>,
3096 user_self_ty: Option<UserSelfTy<'tcx>>,
3099 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3100 user_self_ty={:?} in fcx {}",
3108 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3109 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3111 UserSubsts { substs, user_self_ty },
3113 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3114 self.write_user_type_annotation(hir_id, canonicalized);
3118 pub fn write_user_type_annotation(
3121 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3124 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3126 canonical_user_type_annotation,
3130 if !canonical_user_type_annotation.is_identity() {
3133 .user_provided_types_mut()
3134 .insert(hir_id, canonical_user_type_annotation);
3136 debug!("write_user_type_annotation: skipping identity substs");
3140 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3141 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3147 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3148 Entry::Vacant(entry) => {
3151 Entry::Occupied(mut entry) => {
3152 debug!(" - composing on top of {:?}", entry.get());
3153 match (&entry.get()[..], &adj[..]) {
3154 // Applying any adjustment on top of a NeverToAny
3155 // is a valid NeverToAny adjustment, because it can't
3157 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3159 Adjustment { kind: Adjust::Deref(_), .. },
3160 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3162 Adjustment { kind: Adjust::Deref(_), .. },
3163 .. // Any following adjustments are allowed.
3165 // A reborrow has no effect before a dereference.
3167 // FIXME: currently we never try to compose autoderefs
3168 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3170 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3171 expr, entry.get(), adj)
3173 *entry.get_mut() = adj;
3178 /// Basically whenever we are converting from a type scheme into
3179 /// the fn body space, we always want to normalize associated
3180 /// types as well. This function combines the two.
3181 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3183 T: TypeFoldable<'tcx>,
3185 let value = value.subst(self.tcx, substs);
3186 let result = self.normalize_associated_types_in(span, &value);
3187 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3191 /// As `instantiate_type_scheme`, but for the bounds found in a
3192 /// generic type scheme.
3193 fn instantiate_bounds(
3197 substs: SubstsRef<'tcx>,
3198 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3199 let bounds = self.tcx.predicates_of(def_id);
3200 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3201 let result = bounds.instantiate(self.tcx, substs);
3202 let result = self.normalize_associated_types_in(span, &result);
3204 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3205 bounds, substs, result, spans,
3210 /// Replaces the opaque types from the given value with type variables,
3211 /// and records the `OpaqueTypeMap` for later use during writeback. See
3212 /// `InferCtxt::instantiate_opaque_types` for more details.
3213 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3215 parent_id: hir::HirId,
3219 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3221 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3222 parent_def_id, value
3225 let (value, opaque_type_map) =
3226 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3234 let mut opaque_types = self.opaque_types.borrow_mut();
3235 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3236 for (ty, decl) in opaque_type_map {
3237 let _ = opaque_types.insert(ty, decl);
3238 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3244 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3246 T: TypeFoldable<'tcx>,
3248 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3251 fn normalize_associated_types_in_as_infer_ok<T>(
3255 ) -> InferOk<'tcx, T>
3257 T: TypeFoldable<'tcx>,
3259 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3262 pub fn require_type_meets(
3266 code: traits::ObligationCauseCode<'tcx>,
3269 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3272 pub fn require_type_is_sized(
3276 code: traits::ObligationCauseCode<'tcx>,
3278 if !ty.references_error() {
3279 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
3280 self.require_type_meets(ty, span, code, lang_item);
3284 pub fn require_type_is_sized_deferred(
3288 code: traits::ObligationCauseCode<'tcx>,
3290 if !ty.references_error() {
3291 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3295 pub fn register_bound(
3299 cause: traits::ObligationCause<'tcx>,
3301 if !ty.references_error() {
3302 self.fulfillment_cx.borrow_mut().register_bound(
3312 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3313 let t = AstConv::ast_ty_to_ty(self, ast_t);
3314 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3318 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3319 let ty = self.to_ty(ast_ty);
3320 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3322 if Self::can_contain_user_lifetime_bounds(ty) {
3323 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3324 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3325 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3331 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3332 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local();
3333 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3335 // HACK(eddyb) emulate what a `WellFormedConst` obligation would do.
3336 // This code should be replaced with the proper WF handling ASAP.
3337 if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
3338 assert!(promoted.is_none());
3340 // HACK(eddyb) let's hope these are always empty.
3341 // let obligations = self.nominal_obligations(def_id, substs);
3342 // self.out.extend(obligations);
3344 let cause = traits::ObligationCause::new(
3345 self.tcx.def_span(const_def_id.to_def_id()),
3347 traits::MiscObligation,
3349 self.register_predicate(traits::Obligation::new(
3352 ty::Predicate::ConstEvaluatable(def_id, substs),
3359 // If the type given by the user has free regions, save it for later, since
3360 // NLL would like to enforce those. Also pass in types that involve
3361 // projections, since those can resolve to `'static` bounds (modulo #54940,
3362 // which hopefully will be fixed by the time you see this comment, dear
3363 // reader, although I have my doubts). Also pass in types with inference
3364 // types, because they may be repeated. Other sorts of things are already
3365 // sufficiently enforced with erased regions. =)
3366 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3368 T: TypeFoldable<'tcx>,
3370 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3373 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3374 match self.tables.borrow().node_types().get(id) {
3376 None if self.is_tainted_by_errors() => self.tcx.types.err,
3379 "no type for node {}: {} in fcx {}",
3381 self.tcx.hir().node_to_string(id),
3388 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3389 /// outlive the region `r`.
3390 pub fn register_wf_obligation(
3394 code: traits::ObligationCauseCode<'tcx>,
3396 // WF obligations never themselves fail, so no real need to give a detailed cause:
3397 let cause = traits::ObligationCause::new(span, self.body_id, code);
3398 self.register_predicate(traits::Obligation::new(
3401 ty::Predicate::WellFormed(ty),
3405 /// Registers obligations that all types appearing in `substs` are well-formed.
3406 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3407 for ty in substs.types() {
3408 if !ty.references_error() {
3409 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3414 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3415 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3416 /// trait/region obligations.
3418 /// For example, if there is a function:
3421 /// fn foo<'a,T:'a>(...)
3424 /// and a reference:
3430 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3431 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3432 pub fn add_obligations_for_parameters(
3434 cause: traits::ObligationCause<'tcx>,
3435 predicates: &ty::InstantiatedPredicates<'tcx>,
3437 assert!(!predicates.has_escaping_bound_vars());
3439 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3441 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3442 self.register_predicate(obligation);
3446 // FIXME(arielb1): use this instead of field.ty everywhere
3447 // Only for fields! Returns <none> for methods>
3448 // Indifferent to privacy flags
3452 field: &'tcx ty::FieldDef,
3453 substs: SubstsRef<'tcx>,
3455 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3458 fn check_casts(&self) {
3459 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3460 for cast in deferred_cast_checks.drain(..) {
3465 fn resolve_generator_interiors(&self, def_id: DefId) {
3466 let mut generators = self.deferred_generator_interiors.borrow_mut();
3467 for (body_id, interior, kind) in generators.drain(..) {
3468 self.select_obligations_where_possible(false, |_| {});
3469 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3473 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3475 // - Unconstrained ints are replaced with `i32`.
3477 // - Unconstrained floats are replaced with with `f64`.
3479 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3480 // is enabled. Otherwise, they are replaced with `()`.
3482 // Fallback becomes very dubious if we have encountered type-checking errors.
3483 // In that case, fallback to Error.
3484 // The return value indicates whether fallback has occurred.
3485 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3486 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3487 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3489 assert!(ty.is_ty_infer());
3490 let fallback = match self.type_is_unconstrained_numeric(ty) {
3491 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3492 UnconstrainedInt => self.tcx.types.i32,
3493 UnconstrainedFloat => self.tcx.types.f64,
3494 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3496 // This type variable was created from the instantiation of an opaque
3497 // type. The fact that we're attempting to perform fallback for it
3498 // means that the function neither constrained it to a concrete
3499 // type, nor to the opaque type itself.
3501 // For example, in this code:
3504 // type MyType = impl Copy;
3505 // fn defining_use() -> MyType { true }
3506 // fn other_use() -> MyType { defining_use() }
3509 // `defining_use` will constrain the instantiated inference
3510 // variable to `bool`, while `other_use` will constrain
3511 // the instantiated inference variable to `MyType`.
3513 // When we process opaque types during writeback, we
3514 // will handle cases like `other_use`, and not count
3515 // them as defining usages
3517 // However, we also need to handle cases like this:
3520 // pub type Foo = impl Copy;
3521 // fn produce() -> Option<Foo> {
3526 // In the above snippet, the inference variable created by
3527 // instantiating `Option<Foo>` will be completely unconstrained.
3528 // We treat this as a non-defining use by making the inference
3529 // variable fall back to the opaque type itself.
3530 if let FallbackMode::All = mode {
3531 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3533 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3545 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3546 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3550 fn select_all_obligations_or_error(&self) {
3551 debug!("select_all_obligations_or_error");
3552 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3553 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3557 /// Select as many obligations as we can at present.
3558 fn select_obligations_where_possible(
3560 fallback_has_occurred: bool,
3561 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3563 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3564 if let Err(mut errors) = result {
3565 mutate_fullfillment_errors(&mut errors);
3566 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3570 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3571 /// returns a type of `&T`, but the actual type we assign to the
3572 /// *expression* is `T`. So this function just peels off the return
3573 /// type by one layer to yield `T`.
3574 fn make_overloaded_place_return_type(
3576 method: MethodCallee<'tcx>,
3577 ) -> ty::TypeAndMut<'tcx> {
3578 // extract method return type, which will be &T;
3579 let ret_ty = method.sig.output();
3581 // method returns &T, but the type as visible to user is T, so deref
3582 ret_ty.builtin_deref(true).unwrap()
3587 expr: &hir::Expr<'_>,
3588 base_expr: &'tcx hir::Expr<'tcx>,
3592 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3593 // FIXME(#18741) -- this is almost but not quite the same as the
3594 // autoderef that normal method probing does. They could likely be
3597 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3598 let mut result = None;
3599 while result.is_none() && autoderef.next().is_some() {
3600 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3602 autoderef.finalize(self);
3606 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3607 /// (and otherwise adjust) `base_expr`, looking for a type which either
3608 /// supports builtin indexing or overloaded indexing.
3609 /// This loop implements one step in that search; the autoderef loop
3610 /// is implemented by `lookup_indexing`.
3613 expr: &hir::Expr<'_>,
3614 base_expr: &hir::Expr<'_>,
3615 autoderef: &Autoderef<'a, 'tcx>,
3618 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3619 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3621 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3623 expr, base_expr, adjusted_ty, index_ty
3626 for &unsize in &[false, true] {
3627 let mut self_ty = adjusted_ty;
3629 // We only unsize arrays here.
3630 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3631 self_ty = self.tcx.mk_slice(element_ty);
3637 // If some lookup succeeds, write callee into table and extract index/element
3638 // type from the method signature.
3639 // If some lookup succeeded, install method in table
3640 let input_ty = self.next_ty_var(TypeVariableOrigin {
3641 kind: TypeVariableOriginKind::AutoDeref,
3642 span: base_expr.span,
3644 let method = self.try_overloaded_place_op(
3652 let result = method.map(|ok| {
3653 debug!("try_index_step: success, using overloaded indexing");
3654 let method = self.register_infer_ok_obligations(ok);
3656 let mut adjustments = autoderef.adjust_steps(self, needs);
3657 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3658 let mutbl = match r_mutbl {
3659 hir::Mutability::Not => AutoBorrowMutability::Not,
3660 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3661 // Indexing can be desugared to a method call,
3662 // so maybe we could use two-phase here.
3663 // See the documentation of AllowTwoPhase for why that's
3664 // not the case today.
3665 allow_two_phase_borrow: AllowTwoPhase::No,
3668 adjustments.push(Adjustment {
3669 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3672 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3676 adjustments.push(Adjustment {
3677 kind: Adjust::Pointer(PointerCast::Unsize),
3678 target: method.sig.inputs()[0],
3681 self.apply_adjustments(base_expr, adjustments);
3683 self.write_method_call(expr.hir_id, method);
3684 (input_ty, self.make_overloaded_place_return_type(method).ty)
3686 if result.is_some() {
3694 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3695 let (tr, name) = match (op, is_mut) {
3696 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3697 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3698 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3699 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3701 (tr, ast::Ident::with_dummy_span(name))
3704 fn try_overloaded_place_op(
3708 arg_tys: &[Ty<'tcx>],
3711 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3712 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3714 // Try Mut first, if needed.
3715 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3716 let method = match (needs, mut_tr) {
3717 (Needs::MutPlace, Some(trait_did)) => {
3718 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3723 // Otherwise, fall back to the immutable version.
3724 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3725 match (method, imm_tr) {
3726 (None, Some(trait_did)) => {
3727 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3729 (method, _) => method,
3733 fn check_method_argument_types(
3736 expr: &'tcx hir::Expr<'tcx>,
3737 method: Result<MethodCallee<'tcx>, ()>,
3738 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3739 tuple_arguments: TupleArgumentsFlag,
3740 expected: Expectation<'tcx>,
3742 let has_error = match method {
3743 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3747 let err_inputs = self.err_args(args_no_rcvr.len());
3749 let err_inputs = match tuple_arguments {
3750 DontTupleArguments => err_inputs,
3751 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3754 self.check_argument_types(
3764 return self.tcx.types.err;
3767 let method = method.unwrap();
3768 // HACK(eddyb) ignore self in the definition (see above).
3769 let expected_arg_tys = self.expected_inputs_for_expected_output(
3772 method.sig.output(),
3773 &method.sig.inputs()[1..],
3775 self.check_argument_types(
3778 &method.sig.inputs()[1..],
3779 &expected_arg_tys[..],
3781 method.sig.c_variadic,
3783 self.tcx.hir().span_if_local(method.def_id),
3788 fn self_type_matches_expected_vid(
3790 trait_ref: ty::PolyTraitRef<'tcx>,
3791 expected_vid: ty::TyVid,
3793 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3795 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3796 trait_ref, self_ty, expected_vid
3798 match self_ty.kind {
3799 ty::Infer(ty::TyVar(found_vid)) => {
3800 // FIXME: consider using `sub_root_var` here so we
3801 // can see through subtyping.
3802 let found_vid = self.root_var(found_vid);
3803 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3804 expected_vid == found_vid
3810 fn obligations_for_self_ty<'b>(
3813 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3816 // FIXME: consider using `sub_root_var` here so we
3817 // can see through subtyping.
3818 let ty_var_root = self.root_var(self_ty);
3820 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3823 self.fulfillment_cx.borrow().pending_obligations()
3828 .pending_obligations()
3830 .filter_map(move |obligation| match obligation.predicate {
3831 ty::Predicate::Projection(ref data) => {
3832 Some((data.to_poly_trait_ref(self.tcx), obligation))
3834 ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
3835 ty::Predicate::Subtype(..) => None,
3836 ty::Predicate::RegionOutlives(..) => None,
3837 ty::Predicate::TypeOutlives(..) => None,
3838 ty::Predicate::WellFormed(..) => None,
3839 ty::Predicate::ObjectSafe(..) => None,
3840 ty::Predicate::ConstEvaluatable(..) => None,
3841 // N.B., this predicate is created by breaking down a
3842 // `ClosureType: FnFoo()` predicate, where
3843 // `ClosureType` represents some `Closure`. It can't
3844 // possibly be referring to the current closure,
3845 // because we haven't produced the `Closure` for
3846 // this closure yet; this is exactly why the other
3847 // code is looking for a self type of a unresolved
3848 // inference variable.
3849 ty::Predicate::ClosureKind(..) => None,
3851 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3854 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3855 self.obligations_for_self_ty(self_ty)
3856 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3859 /// Generic function that factors out common logic from function calls,
3860 /// method calls and overloaded operators.
3861 fn check_argument_types(
3864 expr: &'tcx hir::Expr<'tcx>,
3865 fn_inputs: &[Ty<'tcx>],
3866 expected_arg_tys: &[Ty<'tcx>],
3867 args: &'tcx [hir::Expr<'tcx>],
3869 tuple_arguments: TupleArgumentsFlag,
3870 def_span: Option<Span>,
3873 // Grab the argument types, supplying fresh type variables
3874 // if the wrong number of arguments were supplied
3875 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3877 // All the input types from the fn signature must outlive the call
3878 // so as to validate implied bounds.
3879 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3880 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3883 let expected_arg_count = fn_inputs.len();
3885 let param_count_error = |expected_count: usize,
3890 let (span, start_span, args) = match &expr.kind {
3891 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3892 hir::ExprKind::MethodCall(path_segment, span, args) => (
3894 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3897 .and_then(|args| args.args.iter().last())
3898 // Account for `foo.bar::<T>()`.
3900 // Skip the closing `>`.
3903 .next_point(tcx.sess.source_map().next_point(arg.span()))
3906 &args[1..], // Skip the receiver.
3908 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3910 let arg_spans = if args.is_empty() {
3912 // ^^^-- supplied 0 arguments
3914 // expected 2 arguments
3915 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3918 // ^^^ - - - supplied 3 arguments
3920 // expected 2 arguments
3921 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3924 let mut err = tcx.sess.struct_span_err_with_code(
3927 "this function takes {}{} but {} {} supplied",
3928 if c_variadic { "at least " } else { "" },
3929 potentially_plural_count(expected_count, "argument"),
3930 potentially_plural_count(arg_count, "argument"),
3931 if arg_count == 1 { "was" } else { "were" }
3933 DiagnosticId::Error(error_code.to_owned()),
3935 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3936 for (i, span) in arg_spans.into_iter().enumerate() {
3939 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3943 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3944 err.span_label(def_s, "defined here");
3947 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3948 // remove closing `)` from the span
3949 let sugg_span = sugg_span.shrink_to_lo();
3950 err.span_suggestion(
3952 "expected the unit value `()`; create it with empty parentheses",
3954 Applicability::MachineApplicable,
3961 if c_variadic { "at least " } else { "" },
3962 potentially_plural_count(expected_count, "argument")
3969 let mut expected_arg_tys = expected_arg_tys.to_vec();
3971 let formal_tys = if tuple_arguments == TupleArguments {
3972 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3973 match tuple_type.kind {
3974 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3975 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3976 expected_arg_tys = vec![];
3977 self.err_args(args.len())
3979 ty::Tuple(arg_types) => {
3980 expected_arg_tys = match expected_arg_tys.get(0) {
3981 Some(&ty) => match ty.kind {
3982 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3987 arg_types.iter().map(|k| k.expect_ty()).collect()
3994 "cannot use call notation; the first type parameter \
3995 for the function trait is neither a tuple nor unit"
3998 expected_arg_tys = vec![];
3999 self.err_args(args.len())
4002 } else if expected_arg_count == supplied_arg_count {
4004 } else if c_variadic {
4005 if supplied_arg_count >= expected_arg_count {
4008 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4009 expected_arg_tys = vec![];
4010 self.err_args(supplied_arg_count)
4013 // is the missing argument of type `()`?
4014 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4015 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4016 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4017 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4021 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4023 expected_arg_tys = vec![];
4024 self.err_args(supplied_arg_count)
4028 "check_argument_types: formal_tys={:?}",
4029 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4032 // If there is no expectation, expect formal_tys.
4033 let expected_arg_tys =
4034 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4036 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4038 // Check the arguments.
4039 // We do this in a pretty awful way: first we type-check any arguments
4040 // that are not closures, then we type-check the closures. This is so
4041 // that we have more information about the types of arguments when we
4042 // type-check the functions. This isn't really the right way to do this.
4043 for &check_closures in &[false, true] {
4044 debug!("check_closures={}", check_closures);
4046 // More awful hacks: before we check argument types, try to do
4047 // an "opportunistic" vtable resolution of any trait bounds on
4048 // the call. This helps coercions.
4050 self.select_obligations_where_possible(false, |errors| {
4051 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4052 self.point_at_arg_instead_of_call_if_possible(
4054 &final_arg_types[..],
4061 // For C-variadic functions, we don't have a declared type for all of
4062 // the arguments hence we only do our usual type checking with
4063 // the arguments who's types we do know.
4064 let t = if c_variadic {
4066 } else if tuple_arguments == TupleArguments {
4071 for (i, arg) in args.iter().take(t).enumerate() {
4072 // Warn only for the first loop (the "no closures" one).
4073 // Closure arguments themselves can't be diverging, but
4074 // a previous argument can, e.g., `foo(panic!(), || {})`.
4075 if !check_closures {
4076 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4079 let is_closure = match arg.kind {
4080 ExprKind::Closure(..) => true,
4084 if is_closure != check_closures {
4088 debug!("checking the argument");
4089 let formal_ty = formal_tys[i];
4091 // The special-cased logic below has three functions:
4092 // 1. Provide as good of an expected type as possible.
4093 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4095 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4097 // 2. Coerce to the most detailed type that could be coerced
4098 // to, which is `expected_ty` if `rvalue_hint` returns an
4099 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4100 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4101 // We're processing function arguments so we definitely want to use
4102 // two-phase borrows.
4103 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4104 final_arg_types.push((i, checked_ty, coerce_ty));
4106 // 3. Relate the expected type and the formal one,
4107 // if the expected type was used for the coercion.
4108 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4112 // We also need to make sure we at least write the ty of the other
4113 // arguments which we skipped above.
4115 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4116 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4117 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4120 for arg in args.iter().skip(expected_arg_count) {
4121 let arg_ty = self.check_expr(&arg);
4123 // There are a few types which get autopromoted when passed via varargs
4124 // in C but we just error out instead and require explicit casts.
4125 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4127 ty::Float(ast::FloatTy::F32) => {
4128 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4130 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
4131 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4133 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
4134 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4137 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4138 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4139 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4147 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4148 vec![self.tcx.types.err; len]
4151 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4152 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4153 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4154 /// can be not easily comparable with predicate type (because of coercion). If the types match
4155 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4156 /// the corresponding argument's expression span instead of the `fn` call path span.
4157 fn point_at_arg_instead_of_call_if_possible(
4159 errors: &mut Vec<traits::FulfillmentError<'_>>,
4160 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4162 args: &'tcx [hir::Expr<'tcx>],
4164 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4165 // the `?` operator.
4166 if call_sp.desugaring_kind().is_some() {
4170 for error in errors {
4171 // Only if the cause is somewhere inside the expression we want try to point at arg.
4172 // Otherwise, it means that the cause is somewhere else and we should not change
4173 // anything because we can break the correct span.
4174 if !call_sp.contains(error.obligation.cause.span) {
4178 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4179 // Collect the argument position for all arguments that could have caused this
4180 // `FulfillmentError`.
4181 let mut referenced_in = final_arg_types
4183 .map(|&(i, checked_ty, _)| (i, checked_ty))
4184 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4185 .flat_map(|(i, ty)| {
4186 let ty = self.resolve_vars_if_possible(&ty);
4187 // We walk the argument type because the argument's type could have
4188 // been `Option<T>`, but the `FulfillmentError` references `T`.
4189 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4195 .collect::<Vec<_>>();
4197 // Both checked and coerced types could have matched, thus we need to remove
4199 referenced_in.sort();
4200 referenced_in.dedup();
4202 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4203 // We make sure that only *one* argument matches the obligation failure
4204 // and we assign the obligation's span to its expression's.
4205 error.obligation.cause.span = args[ref_in].span;
4206 error.points_at_arg_span = true;
4212 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4213 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4214 /// were caused by them. If they were, we point at the corresponding type argument's span
4215 /// instead of the `fn` call path span.
4216 fn point_at_type_arg_instead_of_call_if_possible(
4218 errors: &mut Vec<traits::FulfillmentError<'_>>,
4219 call_expr: &'tcx hir::Expr<'tcx>,
4221 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4222 if let hir::ExprKind::Path(qpath) = &path.kind {
4223 if let hir::QPath::Resolved(_, path) = &qpath {
4224 for error in errors {
4225 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4226 // If any of the type arguments in this path segment caused the
4227 // `FullfillmentError`, point at its span (#61860).
4231 .filter_map(|seg| seg.args.as_ref())
4232 .flat_map(|a| a.args.iter())
4234 if let hir::GenericArg::Type(hir_ty) = &arg {
4235 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4238 // Avoid ICE with associated types. As this is best
4239 // effort only, it's ok to ignore the case. It
4240 // would trigger in `is_send::<T::AssocType>();`
4241 // from `typeck-default-trait-impl-assoc-type.rs`.
4243 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4244 let ty = self.resolve_vars_if_possible(&ty);
4245 if ty == predicate.skip_binder().self_ty() {
4246 error.obligation.cause.span = hir_ty.span;
4258 // AST fragment checking
4259 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4263 ast::LitKind::Str(..) => tcx.mk_static_str(),
4264 ast::LitKind::ByteStr(ref v) => {
4265 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4267 ast::LitKind::Byte(_) => tcx.types.u8,
4268 ast::LitKind::Char(_) => tcx.types.char,
4269 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4270 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4271 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4272 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4273 ty::Int(_) | ty::Uint(_) => Some(ty),
4274 ty::Char => Some(tcx.types.u8),
4275 ty::RawPtr(..) => Some(tcx.types.usize),
4276 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4279 opt_ty.unwrap_or_else(|| self.next_int_var())
4281 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4282 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4283 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4284 ty::Float(_) => Some(ty),
4287 opt_ty.unwrap_or_else(|| self.next_float_var())
4289 ast::LitKind::Bool(_) => tcx.types.bool,
4290 ast::LitKind::Err(_) => tcx.types.err,
4294 /// Unifies the output type with the expected type early, for more coercions
4295 /// and forward type information on the input expressions.
4296 fn expected_inputs_for_expected_output(
4299 expected_ret: Expectation<'tcx>,
4300 formal_ret: Ty<'tcx>,
4301 formal_args: &[Ty<'tcx>],
4302 ) -> Vec<Ty<'tcx>> {
4303 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4304 let ret_ty = match expected_ret.only_has_type(self) {
4306 None => return Vec::new(),
4308 let expect_args = self
4309 .fudge_inference_if_ok(|| {
4310 // Attempt to apply a subtyping relationship between the formal
4311 // return type (likely containing type variables if the function
4312 // is polymorphic) and the expected return type.
4313 // No argument expectations are produced if unification fails.
4314 let origin = self.misc(call_span);
4315 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4317 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4318 // to identity so the resulting type is not constrained.
4321 // Process any obligations locally as much as
4322 // we can. We don't care if some things turn
4323 // out unconstrained or ambiguous, as we're
4324 // just trying to get hints here.
4325 self.save_and_restore_in_snapshot_flag(|_| {
4326 let mut fulfill = TraitEngine::new(self.tcx);
4327 for obligation in ok.obligations {
4328 fulfill.register_predicate_obligation(self, obligation);
4330 fulfill.select_where_possible(self)
4334 Err(_) => return Err(()),
4337 // Record all the argument types, with the substitutions
4338 // produced from the above subtyping unification.
4339 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4341 .unwrap_or_default();
4343 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4344 formal_args, formal_ret, expect_args, expected_ret
4349 pub fn check_struct_path(
4353 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4354 let path_span = match *qpath {
4355 QPath::Resolved(_, ref path) => path.span,
4356 QPath::TypeRelative(ref qself, _) => qself.span,
4358 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4359 let variant = match def {
4361 self.set_tainted_by_errors();
4364 Res::Def(DefKind::Variant, _) => match ty.kind {
4365 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4366 _ => bug!("unexpected type: {:?}", ty),
4368 Res::Def(DefKind::Struct, _)
4369 | Res::Def(DefKind::Union, _)
4370 | Res::Def(DefKind::TyAlias, _)
4371 | Res::Def(DefKind::AssocTy, _)
4372 | Res::SelfTy(..) => match ty.kind {
4373 ty::Adt(adt, substs) if !adt.is_enum() => {
4374 Some((adt.non_enum_variant(), adt.did, substs))
4378 _ => bug!("unexpected definition: {:?}", def),
4381 if let Some((variant, did, substs)) = variant {
4382 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4383 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4385 // Check bounds on type arguments used in the path.
4386 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4388 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4389 self.add_obligations_for_parameters(cause, &bounds);
4397 "expected struct, variant or union type, found {}",
4398 ty.sort_string(self.tcx)
4400 .span_label(path_span, "not a struct")
4406 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4407 // The newly resolved definition is written into `type_dependent_defs`.
4408 fn finish_resolving_struct_path(
4413 ) -> (Res, Ty<'tcx>) {
4415 QPath::Resolved(ref maybe_qself, ref path) => {
4416 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4417 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4420 QPath::TypeRelative(ref qself, ref segment) => {
4421 let ty = self.to_ty(qself);
4423 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4429 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4430 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4431 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4433 // Write back the new resolution.
4434 self.write_resolution(hir_id, result);
4436 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4441 /// Resolves an associated value path into a base type and associated constant, or method
4442 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4443 pub fn resolve_ty_and_res_ufcs<'b>(
4445 qpath: &'b QPath<'b>,
4448 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4449 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4450 let (ty, qself, item_segment) = match *qpath {
4451 QPath::Resolved(ref opt_qself, ref path) => {
4454 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4458 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4460 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4461 // Return directly on cache hit. This is useful to avoid doubly reporting
4462 // errors with default match binding modes. See #44614.
4464 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4465 return (def, Some(ty), slice::from_ref(&**item_segment));
4467 let item_name = item_segment.ident;
4468 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4469 let result = match error {
4470 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4471 _ => Err(ErrorReported),
4473 if item_name.name != kw::Invalid {
4474 self.report_method_error(
4478 SelfSource::QPath(qself),
4482 .map(|mut e| e.emit());
4487 // Write back the new resolution.
4488 self.write_resolution(hir_id, result);
4490 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4492 slice::from_ref(&**item_segment),
4496 pub fn check_decl_initializer(
4498 local: &'tcx hir::Local<'tcx>,
4499 init: &'tcx hir::Expr<'tcx>,
4501 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4502 // for #42640 (default match binding modes).
4505 let ref_bindings = local.pat.contains_explicit_ref_binding();
4507 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4508 if let Some(m) = ref_bindings {
4509 // Somewhat subtle: if we have a `ref` binding in the pattern,
4510 // we want to avoid introducing coercions for the RHS. This is
4511 // both because it helps preserve sanity and, in the case of
4512 // ref mut, for soundness (issue #23116). In particular, in
4513 // the latter case, we need to be clear that the type of the
4514 // referent for the reference that results is *equal to* the
4515 // type of the place it is referencing, and not some
4516 // supertype thereof.
4517 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4518 self.demand_eqtype(init.span, local_ty, init_ty);
4521 self.check_expr_coercable_to_type(init, local_ty)
4525 /// Type check a `let` statement.
4526 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4527 // Determine and write the type which we'll check the pattern against.
4528 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4529 self.write_ty(local.hir_id, ty);
4531 // Type check the initializer.
4532 if let Some(ref init) = local.init {
4533 let init_ty = self.check_decl_initializer(local, &init);
4534 self.overwrite_local_ty_if_err(local, ty, init_ty);
4537 // Does the expected pattern type originate from an expression and what is the span?
4538 let (origin_expr, ty_span) = match (local.ty, local.init) {
4539 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4540 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4541 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4544 // Type check the pattern. Override if necessary to avoid knock-on errors.
4545 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4546 let pat_ty = self.node_ty(local.pat.hir_id);
4547 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4550 fn overwrite_local_ty_if_err(
4552 local: &'tcx hir::Local<'tcx>,
4556 if ty.references_error() {
4557 // Override the types everywhere with `types.err` to avoid knock on errors.
4558 self.write_ty(local.hir_id, ty);
4559 self.write_ty(local.pat.hir_id, ty);
4560 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4561 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4562 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4566 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4567 err.span_suggestion_short(
4568 span.shrink_to_hi(),
4569 "consider using a semicolon here",
4571 Applicability::MachineApplicable,
4575 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4576 // Don't do all the complex logic below for `DeclItem`.
4578 hir::StmtKind::Item(..) => return,
4579 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4582 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4584 // Hide the outer diverging and `has_errors` flags.
4585 let old_diverges = self.diverges.replace(Diverges::Maybe);
4586 let old_has_errors = self.has_errors.replace(false);
4589 hir::StmtKind::Local(ref l) => {
4590 self.check_decl_local(&l);
4593 hir::StmtKind::Item(_) => {}
4594 hir::StmtKind::Expr(ref expr) => {
4595 // Check with expected type of `()`.
4596 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4597 self.suggest_semicolon_at_end(expr.span, err);
4600 hir::StmtKind::Semi(ref expr) => {
4601 self.check_expr(&expr);
4605 // Combine the diverging and `has_error` flags.
4606 self.diverges.set(self.diverges.get() | old_diverges);
4607 self.has_errors.set(self.has_errors.get() | old_has_errors);
4610 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4611 let unit = self.tcx.mk_unit();
4612 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4614 // if the block produces a `!` value, that can always be
4615 // (effectively) coerced to unit.
4617 self.demand_suptype(blk.span, unit, ty);
4621 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4622 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4623 /// when given code like the following:
4625 /// if false { return 0i32; } else { 1u32 }
4626 /// // ^^^^ point at this instead of the whole `if` expression
4628 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4629 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4630 let arm_spans: Vec<Span> = arms
4633 self.in_progress_tables
4634 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4635 .and_then(|arm_ty| {
4636 if arm_ty.is_never() {
4639 Some(match &arm.body.kind {
4640 // Point at the tail expression when possible.
4641 hir::ExprKind::Block(block, _) => {
4642 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4650 if arm_spans.len() == 1 {
4651 return arm_spans[0];
4657 fn check_block_with_expected(
4659 blk: &'tcx hir::Block<'tcx>,
4660 expected: Expectation<'tcx>,
4663 let mut fcx_ps = self.ps.borrow_mut();
4664 let unsafety_state = fcx_ps.recurse(blk);
4665 replace(&mut *fcx_ps, unsafety_state)
4668 // In some cases, blocks have just one exit, but other blocks
4669 // can be targeted by multiple breaks. This can happen both
4670 // with labeled blocks as well as when we desugar
4671 // a `try { ... }` expression.
4675 // 'a: { if true { break 'a Err(()); } Ok(()) }
4677 // Here we would wind up with two coercions, one from
4678 // `Err(())` and the other from the tail expression
4679 // `Ok(())`. If the tail expression is omitted, that's a
4680 // "forced unit" -- unless the block diverges, in which
4681 // case we can ignore the tail expression (e.g., `'a: {
4682 // break 'a 22; }` would not force the type of the block
4684 let tail_expr = blk.expr.as_ref();
4685 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4686 let coerce = if blk.targeted_by_break {
4687 CoerceMany::new(coerce_to_ty)
4689 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4690 Some(e) => slice::from_ref(e),
4693 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4696 let prev_diverges = self.diverges.get();
4697 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4699 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4700 for s in blk.stmts {
4704 // check the tail expression **without** holding the
4705 // `enclosing_breakables` lock below.
4706 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4708 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4709 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4710 let coerce = ctxt.coerce.as_mut().unwrap();
4711 if let Some(tail_expr_ty) = tail_expr_ty {
4712 let tail_expr = tail_expr.unwrap();
4713 let span = self.get_expr_coercion_span(tail_expr);
4714 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4715 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4717 // Subtle: if there is no explicit tail expression,
4718 // that is typically equivalent to a tail expression
4719 // of `()` -- except if the block diverges. In that
4720 // case, there is no value supplied from the tail
4721 // expression (assuming there are no other breaks,
4722 // this implies that the type of the block will be
4725 // #41425 -- label the implicit `()` as being the
4726 // "found type" here, rather than the "expected type".
4727 if !self.diverges.get().is_always() {
4728 // #50009 -- Do not point at the entire fn block span, point at the return type
4729 // span, as it is the cause of the requirement, and
4730 // `consider_hint_about_removing_semicolon` will point at the last expression
4731 // if it were a relevant part of the error. This improves usability in editors
4732 // that highlight errors inline.
4733 let mut sp = blk.span;
4734 let mut fn_span = None;
4735 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4736 let ret_sp = decl.output.span();
4737 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4738 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4739 // output would otherwise be incorrect and even misleading. Make sure
4740 // the span we're aiming at correspond to a `fn` body.
4741 if block_sp == blk.span {
4743 fn_span = Some(ident.span);
4747 coerce.coerce_forced_unit(
4751 if let Some(expected_ty) = expected.only_has_type(self) {
4752 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4754 if let Some(fn_span) = fn_span {
4757 "implicitly returns `()` as its body has no tail or `return` \
4769 // If we can break from the block, then the block's exit is always reachable
4770 // (... as long as the entry is reachable) - regardless of the tail of the block.
4771 self.diverges.set(prev_diverges);
4774 let mut ty = ctxt.coerce.unwrap().complete(self);
4776 if self.has_errors.get() || ty.references_error() {
4777 ty = self.tcx.types.err
4780 self.write_ty(blk.hir_id, ty);
4782 *self.ps.borrow_mut() = prev;
4786 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4787 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4789 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4790 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4791 let body = self.tcx.hir().body(body_id);
4792 if let ExprKind::Block(block, _) = &body.value.kind {
4793 return Some(block.span);
4801 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4802 fn get_parent_fn_decl(
4805 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
4806 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4807 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4810 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4811 fn get_node_fn_decl(
4814 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
4816 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4817 // This is less than ideal, it will not suggest a return type span on any
4818 // method called `main`, regardless of whether it is actually the entry point,
4819 // but it will still present it as the reason for the expected type.
4820 Some((&sig.decl, ident, ident.name != sym::main))
4822 Node::TraitItem(&hir::TraitItem {
4824 kind: hir::TraitItemKind::Fn(ref sig, ..),
4826 }) => Some((&sig.decl, ident, true)),
4827 Node::ImplItem(&hir::ImplItem {
4829 kind: hir::ImplItemKind::Fn(ref sig, ..),
4831 }) => Some((&sig.decl, ident, false)),
4836 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4837 /// suggestion can be made, `None` otherwise.
4838 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4839 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4840 // `while` before reaching it, as block tail returns are not available in them.
4841 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4842 let parent = self.tcx.hir().get(blk_id);
4843 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4847 /// On implicit return expressions with mismatched types, provides the following suggestions:
4849 /// - Points out the method's return type as the reason for the expected type.
4850 /// - Possible missing semicolon.
4851 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4852 pub fn suggest_mismatched_types_on_tail(
4854 err: &mut DiagnosticBuilder<'_>,
4855 expr: &'tcx hir::Expr<'tcx>,
4861 let expr = expr.peel_drop_temps();
4862 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4863 let mut pointing_at_return_type = false;
4864 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4865 pointing_at_return_type =
4866 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4868 pointing_at_return_type
4871 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4872 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4874 /// fn foo(x: usize) -> usize { x }
4875 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4879 err: &mut DiagnosticBuilder<'_>,
4880 expr: &hir::Expr<'_>,
4884 let hir = self.tcx.hir();
4885 let (def_id, sig) = match found.kind {
4886 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4887 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4891 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4892 let sig = self.normalize_associated_types_in(expr.span, &sig);
4893 if self.can_coerce(sig.output(), expected) {
4894 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4895 (String::new(), Applicability::MachineApplicable)
4897 ("...".to_string(), Applicability::HasPlaceholders)
4899 let mut msg = "call this function";
4900 match hir.get_if_local(def_id) {
4901 Some(Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. }))
4902 | Some(Node::ImplItem(hir::ImplItem {
4903 kind: hir::ImplItemKind::Fn(_, body_id),
4906 | Some(Node::TraitItem(hir::TraitItem {
4907 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4910 let body = hir.body(*body_id);
4914 .map(|param| match ¶m.pat.kind {
4915 hir::PatKind::Binding(_, _, ident, None)
4916 if ident.name != kw::SelfLower =>
4920 _ => "_".to_string(),
4922 .collect::<Vec<_>>()
4925 Some(Node::Expr(hir::Expr {
4926 kind: ExprKind::Closure(_, _, body_id, _, _),
4927 span: full_closure_span,
4930 if *full_closure_span == expr.span {
4933 msg = "call this closure";
4934 let body = hir.body(*body_id);
4938 .map(|param| match ¶m.pat.kind {
4939 hir::PatKind::Binding(_, _, ident, None)
4940 if ident.name != kw::SelfLower =>
4944 _ => "_".to_string(),
4946 .collect::<Vec<_>>()
4949 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4950 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4951 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4952 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4953 msg = "instantiate this tuple variant";
4955 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4956 msg = "instantiate this tuple struct";
4961 Some(Node::ForeignItem(hir::ForeignItem {
4962 kind: hir::ForeignItemKind::Fn(_, idents, _),
4968 if ident.name != kw::SelfLower {
4974 .collect::<Vec<_>>()
4977 Some(Node::TraitItem(hir::TraitItem {
4978 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
4984 if ident.name != kw::SelfLower {
4990 .collect::<Vec<_>>()
4995 err.span_suggestion_verbose(
4996 expr.span.shrink_to_hi(),
4997 &format!("use parentheses to {}", msg),
4998 format!("({})", sugg_call),
5006 pub fn suggest_ref_or_into(
5008 err: &mut DiagnosticBuilder<'_>,
5009 expr: &hir::Expr<'_>,
5013 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
5014 err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable);
5015 } else if let (ty::FnDef(def_id, ..), true) =
5016 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5018 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5019 let sp = self.sess().source_map().guess_head_span(sp);
5020 err.span_label(sp, &format!("{} defined here", found));
5022 } else if !self.check_for_cast(err, expr, found, expected) {
5023 let is_struct_pat_shorthand_field =
5024 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5025 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5026 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5027 let mut suggestions = iter::repeat(&expr_text)
5028 .zip(methods.iter())
5029 .filter_map(|(receiver, method)| {
5030 let method_call = format!(".{}()", method.ident);
5031 if receiver.ends_with(&method_call) {
5032 None // do not suggest code that is already there (#53348)
5034 let method_call_list = [".to_vec()", ".to_string()"];
5035 let sugg = if receiver.ends_with(".clone()")
5036 && method_call_list.contains(&method_call.as_str())
5038 let max_len = receiver.rfind('.').unwrap();
5039 format!("{}{}", &receiver[..max_len], method_call)
5041 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5042 format!("({}){}", receiver, method_call)
5044 format!("{}{}", receiver, method_call)
5047 Some(if is_struct_pat_shorthand_field {
5048 format!("{}: {}", receiver, sugg)
5055 if suggestions.peek().is_some() {
5056 err.span_suggestions(
5058 "try using a conversion method",
5060 Applicability::MaybeIncorrect,
5067 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5068 /// in the heap by calling `Box::new()`.
5069 fn suggest_boxing_when_appropriate(
5071 err: &mut DiagnosticBuilder<'_>,
5072 expr: &hir::Expr<'_>,
5076 if self.tcx.hir().is_const_context(expr.hir_id) {
5077 // Do not suggest `Box::new` in const context.
5080 if !expected.is_box() || found.is_box() {
5083 let boxed_found = self.tcx.mk_box(found);
5084 if let (true, Ok(snippet)) = (
5085 self.can_coerce(boxed_found, expected),
5086 self.sess().source_map().span_to_snippet(expr.span),
5088 err.span_suggestion(
5090 "store this in the heap by calling `Box::new`",
5091 format!("Box::new({})", snippet),
5092 Applicability::MachineApplicable,
5095 "for more on the distinction between the stack and the heap, read \
5096 https://doc.rust-lang.org/book/ch15-01-box.html, \
5097 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5098 https://doc.rust-lang.org/std/boxed/index.html",
5103 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5104 fn suggest_calling_boxed_future_when_appropriate(
5106 err: &mut DiagnosticBuilder<'_>,
5107 expr: &hir::Expr<'_>,
5113 if self.tcx.hir().is_const_context(expr.hir_id) {
5114 // Do not suggest `Box::new` in const context.
5117 let pin_did = self.tcx.lang_items().pin_type();
5118 match expected.kind {
5119 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5120 // This guards the `unwrap` and `mk_box` below.
5121 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5124 let boxed_found = self.tcx.mk_box(found);
5125 let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap();
5126 if let (true, Ok(snippet)) = (
5127 self.can_coerce(new_found, expected),
5128 self.sess().source_map().span_to_snippet(expr.span),
5131 ty::Adt(def, _) if def.is_box() => {
5132 err.help("use `Box::pin`");
5135 err.span_suggestion(
5137 "you need to pin and box this expression",
5138 format!("Box::pin({})", snippet),
5139 Applicability::MachineApplicable,
5149 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5153 /// bar_that_returns_u32()
5157 /// This routine checks if the return expression in a block would make sense on its own as a
5158 /// statement and the return type has been left as default or has been specified as `()`. If so,
5159 /// it suggests adding a semicolon.
5160 fn suggest_missing_semicolon(
5162 err: &mut DiagnosticBuilder<'_>,
5163 expression: &'tcx hir::Expr<'tcx>,
5167 if expected.is_unit() {
5168 // `BlockTailExpression` only relevant if the tail expr would be
5169 // useful on its own.
5170 match expression.kind {
5172 | ExprKind::MethodCall(..)
5173 | ExprKind::Loop(..)
5174 | ExprKind::Match(..)
5175 | ExprKind::Block(..) => {
5176 err.span_suggestion(
5177 cause_span.shrink_to_hi(),
5178 "try adding a semicolon",
5180 Applicability::MachineApplicable,
5188 /// A possible error is to forget to add a return type that is needed:
5192 /// bar_that_returns_u32()
5196 /// This routine checks if the return type is left as default, the method is not part of an
5197 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5199 fn suggest_missing_return_type(
5201 err: &mut DiagnosticBuilder<'_>,
5202 fn_decl: &hir::FnDecl<'_>,
5207 // Only suggest changing the return type for methods that
5208 // haven't set a return type at all (and aren't `fn main()` or an impl).
5209 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5210 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5211 err.span_suggestion(
5213 "try adding a return type",
5214 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5215 Applicability::MachineApplicable,
5219 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5220 err.span_label(span, "possibly return type missing here?");
5223 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5224 // `fn main()` must return `()`, do not suggest changing return type
5225 err.span_label(span, "expected `()` because of default return type");
5228 // expectation was caused by something else, not the default return
5229 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5230 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5231 // Only point to return type if the expected type is the return type, as if they
5232 // are not, the expectation must have been caused by something else.
5233 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5235 let ty = AstConv::ast_ty_to_ty(self, ty);
5236 debug!("suggest_missing_return_type: return type {:?}", ty);
5237 debug!("suggest_missing_return_type: expected type {:?}", ty);
5238 if ty.kind == expected.kind {
5239 err.span_label(sp, format!("expected `{}` because of return type", expected));
5247 /// A possible error is to forget to add `.await` when using futures:
5250 /// async fn make_u32() -> u32 {
5254 /// fn take_u32(x: u32) {}
5256 /// async fn foo() {
5257 /// let x = make_u32();
5262 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5263 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5264 /// `.await` to the tail of the expression.
5265 fn suggest_missing_await(
5267 err: &mut DiagnosticBuilder<'_>,
5268 expr: &hir::Expr<'_>,
5272 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5273 // body isn't `async`.
5274 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5275 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5276 let body = self.tcx().hir().body(body_id);
5277 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5279 // Check for `Future` implementations by constructing a predicate to
5280 // prove: `<T as Future>::Output == U`
5281 let future_trait = self.tcx.lang_items().future_trait().unwrap();
5282 let item_def_id = self
5284 .associated_items(future_trait)
5285 .in_definition_order()
5290 ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5291 // `<T as Future>::Output`
5292 projection_ty: ty::ProjectionTy {
5294 substs: self.tcx.mk_substs_trait(
5296 self.fresh_substs_for_item(sp, item_def_id),
5303 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5304 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5305 if self.infcx.predicate_may_hold(&obligation) {
5306 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5307 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5308 err.span_suggestion(
5310 "consider using `.await` here",
5311 format!("{}.await", code),
5312 Applicability::MaybeIncorrect,
5315 debug!("suggest_missing_await: no snippet for {:?}", sp);
5318 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5324 /// A common error is to add an extra semicolon:
5327 /// fn foo() -> usize {
5332 /// This routine checks if the final statement in a block is an
5333 /// expression with an explicit semicolon whose type is compatible
5334 /// with `expected_ty`. If so, it suggests removing the semicolon.
5335 fn consider_hint_about_removing_semicolon(
5337 blk: &'tcx hir::Block<'tcx>,
5338 expected_ty: Ty<'tcx>,
5339 err: &mut DiagnosticBuilder<'_>,
5341 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5342 err.span_suggestion(
5344 "consider removing this semicolon",
5346 Applicability::MachineApplicable,
5351 fn could_remove_semicolon(
5353 blk: &'tcx hir::Block<'tcx>,
5354 expected_ty: Ty<'tcx>,
5356 // Be helpful when the user wrote `{... expr;}` and
5357 // taking the `;` off is enough to fix the error.
5358 let last_stmt = blk.stmts.last()?;
5359 let last_expr = match last_stmt.kind {
5360 hir::StmtKind::Semi(ref e) => e,
5363 let last_expr_ty = self.node_ty(last_expr.hir_id);
5364 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5367 let original_span = original_sp(last_stmt.span, blk.span);
5368 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5371 // Instantiates the given path, which must refer to an item with the given
5372 // number of type parameters and type.
5373 pub fn instantiate_value_path(
5375 segments: &[hir::PathSegment<'_>],
5376 self_ty: Option<Ty<'tcx>>,
5380 ) -> (Ty<'tcx>, Res) {
5382 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5383 segments, self_ty, res, hir_id,
5388 let path_segs = match res {
5389 Res::Local(_) | Res::SelfCtor(_) => vec![],
5390 Res::Def(kind, def_id) => {
5391 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5393 _ => bug!("instantiate_value_path on {:?}", res),
5396 let mut user_self_ty = None;
5397 let mut is_alias_variant_ctor = false;
5399 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5400 if let Some(self_ty) = self_ty {
5401 let adt_def = self_ty.ty_adt_def().unwrap();
5402 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5403 is_alias_variant_ctor = true;
5406 Res::Def(DefKind::AssocFn, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
5407 let container = tcx.associated_item(def_id).container;
5408 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5410 ty::TraitContainer(trait_did) => {
5411 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5413 ty::ImplContainer(impl_def_id) => {
5414 if segments.len() == 1 {
5415 // `<T>::assoc` will end up here, and so
5416 // can `T::assoc`. It this came from an
5417 // inherent impl, we need to record the
5418 // `T` for posterity (see `UserSelfTy` for
5420 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5421 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5429 // Now that we have categorized what space the parameters for each
5430 // segment belong to, let's sort out the parameters that the user
5431 // provided (if any) into their appropriate spaces. We'll also report
5432 // errors if type parameters are provided in an inappropriate place.
5434 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5435 let generics_has_err = AstConv::prohibit_generics(
5437 segments.iter().enumerate().filter_map(|(index, seg)| {
5438 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5446 if let Res::Local(hid) = res {
5447 let ty = self.local_ty(span, hid).decl_ty;
5448 let ty = self.normalize_associated_types_in(span, &ty);
5449 self.write_ty(hir_id, ty);
5453 if generics_has_err {
5454 // Don't try to infer type parameters when prohibited generic arguments were given.
5455 user_self_ty = None;
5458 // Now we have to compare the types that the user *actually*
5459 // provided against the types that were *expected*. If the user
5460 // did not provide any types, then we want to substitute inference
5461 // variables. If the user provided some types, we may still need
5462 // to add defaults. If the user provided *too many* types, that's
5465 let mut infer_args_for_err = FxHashSet::default();
5466 for &PathSeg(def_id, index) in &path_segs {
5467 let seg = &segments[index];
5468 let generics = tcx.generics_of(def_id);
5469 // Argument-position `impl Trait` is treated as a normal generic
5470 // parameter internally, but we don't allow users to specify the
5471 // parameter's value explicitly, so we have to do some error-
5473 if let Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }) =
5474 AstConv::check_generic_arg_count_for_call(
5475 tcx, span, &generics, &seg, false, // `is_method_call`
5478 infer_args_for_err.insert(index);
5479 self.set_tainted_by_errors(); // See issue #53251.
5483 let has_self = path_segs
5485 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5488 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5489 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5491 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5492 let variant = adt_def.non_enum_variant();
5493 let ctor_def_id = variant.ctor_def_id.unwrap();
5495 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5500 let mut err = tcx.sess.struct_span_err(
5502 "the `Self` constructor can only be used with tuple or unit structs",
5504 if let Some(adt_def) = ty.ty_adt_def() {
5505 match adt_def.adt_kind() {
5507 err.help("did you mean to use one of the enum's variants?");
5509 AdtKind::Struct | AdtKind::Union => {
5510 err.span_suggestion(
5512 "use curly brackets",
5513 String::from("Self { /* fields */ }"),
5514 Applicability::HasPlaceholders,
5521 return (tcx.types.err, res);
5527 let def_id = res.def_id();
5529 // The things we are substituting into the type should not contain
5530 // escaping late-bound regions, and nor should the base type scheme.
5531 let ty = tcx.type_of(def_id);
5533 let substs = self_ctor_substs.unwrap_or_else(|| {
5534 AstConv::create_substs_for_generic_args(
5540 infer_args_for_err.is_empty(),
5541 // Provide the generic args, and whether types should be inferred.
5543 if let Some(&PathSeg(_, index)) =
5544 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5546 // If we've encountered an `impl Trait`-related error, we're just
5547 // going to infer the arguments for better error messages.
5548 if !infer_args_for_err.contains(&index) {
5549 // Check whether the user has provided generic arguments.
5550 if let Some(ref data) = segments[index].args {
5551 return (Some(data), segments[index].infer_args);
5554 return (None, segments[index].infer_args);
5559 // Provide substitutions for parameters for which (valid) arguments have been provided.
5560 |param, arg| match (¶m.kind, arg) {
5561 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5562 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5564 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5565 self.to_ty(ty).into()
5567 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5568 self.to_const(&ct.value).into()
5570 _ => unreachable!(),
5572 // Provide substitutions for parameters for which arguments are inferred.
5573 |substs, param, infer_args| {
5575 GenericParamDefKind::Lifetime => {
5576 self.re_infer(Some(param), span).unwrap().into()
5578 GenericParamDefKind::Type { has_default, .. } => {
5579 if !infer_args && has_default {
5580 // If we have a default, then we it doesn't matter that we're not
5581 // inferring the type arguments: we provide the default where any
5583 let default = tcx.type_of(param.def_id);
5586 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5590 // If no type arguments were provided, we have to infer them.
5591 // This case also occurs as a result of some malformed input, e.g.
5592 // a lifetime argument being given instead of a type parameter.
5593 // Using inference instead of `Error` gives better error messages.
5594 self.var_for_def(span, param)
5597 GenericParamDefKind::Const => {
5598 // FIXME(const_generics:defaults)
5599 // No const parameters were provided, we have to infer them.
5600 self.var_for_def(span, param)
5606 assert!(!substs.has_escaping_bound_vars());
5607 assert!(!ty.has_escaping_bound_vars());
5609 // First, store the "user substs" for later.
5610 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5612 self.add_required_obligations(span, def_id, &substs);
5614 // Substitute the values for the type parameters into the type of
5615 // the referenced item.
5616 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5618 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5619 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5620 // is inherent, there is no `Self` parameter; instead, the impl needs
5621 // type parameters, which we can infer by unifying the provided `Self`
5622 // with the substituted impl type.
5623 // This also occurs for an enum variant on a type alias.
5624 let ty = tcx.type_of(impl_def_id);
5626 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5627 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5628 Ok(ok) => self.register_infer_ok_obligations(ok),
5630 self.tcx.sess.delay_span_bug(
5633 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5642 self.check_rustc_args_require_const(def_id, hir_id, span);
5644 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5645 self.write_substs(hir_id, substs);
5647 (ty_substituted, res)
5650 /// Add all the obligations that are required, substituting and normalized appropriately.
5651 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5652 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5654 for (i, mut obligation) in traits::predicates_for_generics(
5655 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5662 // This makes the error point at the bound, but we want to point at the argument
5663 if let Some(span) = spans.get(i) {
5664 obligation.cause.code = traits::BindingObligation(def_id, *span);
5666 self.register_predicate(obligation);
5670 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5671 // We're only interested in functions tagged with
5672 // #[rustc_args_required_const], so ignore anything that's not.
5673 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5677 // If our calling expression is indeed the function itself, we're good!
5678 // If not, generate an error that this can only be called directly.
5679 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5680 if let ExprKind::Call(ref callee, ..) = expr.kind {
5681 if callee.hir_id == hir_id {
5687 self.tcx.sess.span_err(
5689 "this function can only be invoked directly, not through a function pointer",
5693 /// Resolves `typ` by a single level if `typ` is a type variable.
5694 /// If no resolution is possible, then an error is reported.
5695 /// Numeric inference variables may be left unresolved.
5696 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5697 let ty = self.resolve_vars_with_obligations(ty);
5698 if !ty.is_ty_var() {
5701 if !self.is_tainted_by_errors() {
5702 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5703 .note("type must be known at this point")
5706 self.demand_suptype(sp, self.tcx.types.err, ty);
5711 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5714 ctxt: BreakableCtxt<'tcx>,
5716 ) -> (BreakableCtxt<'tcx>, R) {
5719 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5720 index = enclosing_breakables.stack.len();
5721 enclosing_breakables.by_id.insert(id, index);
5722 enclosing_breakables.stack.push(ctxt);
5726 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5727 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5728 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5729 enclosing_breakables.stack.pop().expect("missing breakable context")
5734 /// Instantiate a QueryResponse in a probe context, without a
5735 /// good ObligationCause.
5736 fn probe_instantiate_query_response(
5739 original_values: &OriginalQueryValues<'tcx>,
5740 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5741 ) -> InferResult<'tcx, Ty<'tcx>> {
5742 self.instantiate_query_response_and_region_obligations(
5743 &traits::ObligationCause::misc(span, self.body_id),
5750 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5751 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5752 let mut contained_in_place = false;
5754 while let hir::Node::Expr(parent_expr) =
5755 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5757 match &parent_expr.kind {
5758 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5759 if lhs.hir_id == expr_id {
5760 contained_in_place = true;
5766 expr_id = parent_expr.hir_id;
5773 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5774 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5776 assert_eq!(generics.parent, None);
5778 if generics.own_counts().types == 0 {
5782 let mut params_used = BitSet::new_empty(generics.params.len());
5784 if ty.references_error() {
5785 // If there is already another error, do not emit
5786 // an error for not using a type parameter.
5787 assert!(tcx.sess.has_errors());
5791 for leaf in ty.walk() {
5792 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5793 if let ty::Param(param) = leaf_ty.kind {
5794 debug!("found use of ty param {:?}", param);
5795 params_used.insert(param.index);
5800 for param in &generics.params {
5801 if !params_used.contains(param.index) {
5802 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5803 let span = tcx.def_span(param.def_id);
5808 "type parameter `{}` is unused",
5811 .span_label(span, "unused type parameter")
5818 fn fatally_break_rust(sess: &Session) {
5819 let handler = sess.diagnostic();
5820 handler.span_bug_no_panic(
5822 "It looks like you're trying to break rust; would you like some ICE?",
5824 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5825 handler.note_without_error(
5826 "we would appreciate a joke overview: \
5827 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5829 handler.note_without_error(&format!(
5830 "rustc {} running on {}",
5831 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5832 config::host_triple(),
5836 fn potentially_plural_count(count: usize, word: &str) -> String {
5837 format!("{} {}{}", count, word, pluralize!(count))