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);
757 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
758 wfcheck::check_item_well_formed(tcx, def_id.expect_local());
761 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
762 wfcheck::check_trait_item(tcx, def_id.expect_local());
765 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
766 wfcheck::check_impl_item(tcx, def_id.expect_local());
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.expect_local()));
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.expect_local());
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 let revealed_ret_ty =
1309 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1310 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1311 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1312 fn_sig = tcx.mk_fn_sig(
1313 fn_sig.inputs().iter().cloned(),
1320 let span = body.value.span;
1322 fn_maybe_err(tcx, span, fn_sig.abi);
1324 if body.generator_kind.is_some() && can_be_generator.is_some() {
1326 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1327 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1329 // Resume type defaults to `()` if the generator has no argument.
1330 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1332 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1335 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id());
1336 let outer_hir_id = hir.as_local_hir_id(outer_def_id.expect_local());
1337 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1339 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1340 // (as it's created inside the body itself, not passed in from outside).
1341 let maybe_va_list = if fn_sig.c_variadic {
1342 let va_list_did = tcx.require_lang_item(
1343 lang_items::VaListTypeLangItem,
1344 Some(body.params.last().unwrap().span),
1346 let region = tcx.mk_region(ty::ReScope(region::Scope {
1347 id: body.value.hir_id.local_id,
1348 data: region::ScopeData::CallSite,
1351 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1356 // Add formal parameters.
1357 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1358 let inputs_fn = fn_sig.inputs().iter().copied();
1359 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1360 // Check the pattern.
1361 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1363 // Check that argument is Sized.
1364 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1365 // for simple cases like `fn foo(x: Trait)`,
1366 // where we would error once on the parameter as a whole, and once on the binding `x`.
1367 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1368 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1371 fcx.write_ty(param.hir_id, param_ty);
1374 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1376 if let ty::Dynamic(..) = declared_ret_ty.kind {
1377 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1378 // been evaluated so that we have types available for all the nodes being returned, but that
1379 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1380 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1381 // while keeping the current ordering we will ignore the tail expression's type because we
1382 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1383 // because we will trigger "unreachable expression" lints unconditionally.
1384 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1385 // case that a newcomer might make, returning a bare trait, and in that case we populate
1386 // the tail expression's type so that the suggestion will be correct, but ignore all other
1388 fcx.check_expr(&body.value);
1389 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1390 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1392 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1393 fcx.check_return_expr(&body.value);
1396 // We insert the deferred_generator_interiors entry after visiting the body.
1397 // This ensures that all nested generators appear before the entry of this generator.
1398 // resolve_generator_interiors relies on this property.
1399 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1401 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1402 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1404 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1405 Some(GeneratorTypes {
1409 movability: can_be_generator.unwrap(),
1415 // Finalize the return check by taking the LUB of the return types
1416 // we saw and assigning it to the expected return type. This isn't
1417 // really expected to fail, since the coercions would have failed
1418 // earlier when trying to find a LUB.
1420 // However, the behavior around `!` is sort of complex. In the
1421 // event that the `actual_return_ty` comes back as `!`, that
1422 // indicates that the fn either does not return or "returns" only
1423 // values of type `!`. In this case, if there is an expected
1424 // return type that is *not* `!`, that should be ok. But if the
1425 // return type is being inferred, we want to "fallback" to `!`:
1427 // let x = move || panic!();
1429 // To allow for that, I am creating a type variable with diverging
1430 // fallback. This was deemed ever so slightly better than unifying
1431 // the return value with `!` because it allows for the caller to
1432 // make more assumptions about the return type (e.g., they could do
1434 // let y: Option<u32> = Some(x());
1436 // which would then cause this return type to become `u32`, not
1438 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1439 let mut actual_return_ty = coercion.complete(&fcx);
1440 if actual_return_ty.is_never() {
1441 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1442 kind: TypeVariableOriginKind::DivergingFn,
1446 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1448 // Check that the main return type implements the termination trait.
1449 if let Some(term_id) = tcx.lang_items().termination() {
1450 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1451 let main_id = hir.as_local_hir_id(def_id.expect_local());
1452 if main_id == fn_id {
1453 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1454 let trait_ref = ty::TraitRef::new(term_id, substs);
1455 let return_ty_span = decl.output.span();
1456 let cause = traits::ObligationCause::new(
1459 ObligationCauseCode::MainFunctionType,
1462 inherited.register_predicate(traits::Obligation::new(
1465 trait_ref.without_const().to_predicate(),
1471 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1472 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1473 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1474 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1475 if declared_ret_ty.kind != ty::Never {
1476 sess.span_err(decl.output.span(), "return type should be `!`");
1479 let inputs = fn_sig.inputs();
1480 let span = hir.span(fn_id);
1481 if inputs.len() == 1 {
1482 let arg_is_panic_info = match inputs[0].kind {
1483 ty::Ref(region, ty, mutbl) => match ty.kind {
1484 ty::Adt(ref adt, _) => {
1485 adt.did == panic_info_did
1486 && mutbl == hir::Mutability::Not
1487 && *region != RegionKind::ReStatic
1494 if !arg_is_panic_info {
1495 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1498 if let Node::Item(item) = hir.get(fn_id) {
1499 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1500 if !generics.params.is_empty() {
1501 sess.span_err(span, "should have no type parameters");
1506 let span = sess.source_map().guess_head_span(span);
1507 sess.span_err(span, "function should have one argument");
1510 sess.err("language item required, but not found: `panic_info`");
1515 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1516 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1517 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1518 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1519 if declared_ret_ty.kind != ty::Never {
1520 sess.span_err(decl.output.span(), "return type should be `!`");
1523 let inputs = fn_sig.inputs();
1524 let span = hir.span(fn_id);
1525 if inputs.len() == 1 {
1526 let arg_is_alloc_layout = match inputs[0].kind {
1527 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1531 if !arg_is_alloc_layout {
1532 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1535 if let Node::Item(item) = hir.get(fn_id) {
1536 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1537 if !generics.params.is_empty() {
1540 "`#[alloc_error_handler]` function should have no type \
1547 let span = sess.source_map().guess_head_span(span);
1548 sess.span_err(span, "function should have one argument");
1551 sess.err("language item required, but not found: `alloc_layout`");
1559 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1560 let def_id = tcx.hir().local_def_id(id);
1561 let def = tcx.adt_def(def_id);
1562 def.destructor(tcx); // force the destructor to be evaluated
1563 check_representable(tcx, span, def_id);
1565 if def.repr.simd() {
1566 check_simd(tcx, span, def_id);
1569 check_transparent(tcx, span, def);
1570 check_packed(tcx, span, def);
1573 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1574 let def_id = tcx.hir().local_def_id(id);
1575 let def = tcx.adt_def(def_id);
1576 def.destructor(tcx); // force the destructor to be evaluated
1577 check_representable(tcx, span, def_id);
1578 check_transparent(tcx, span, def);
1579 check_union_fields(tcx, span, def_id);
1580 check_packed(tcx, span, def);
1583 /// When the `#![feature(untagged_unions)]` gate is active,
1584 /// check that the fields of the `union` does not contain fields that need dropping.
1585 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1586 let item_type = tcx.type_of(item_def_id);
1587 if let ty::Adt(def, substs) = item_type.kind {
1588 assert!(def.is_union());
1589 let fields = &def.non_enum_variant().fields;
1590 let param_env = tcx.param_env(item_def_id);
1591 for field in fields {
1592 let field_ty = field.ty(tcx, substs);
1593 // We are currently checking the type this field came from, so it must be local.
1594 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1595 if field_ty.needs_drop(tcx, param_env) {
1600 "unions may not contain fields that need dropping"
1602 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1608 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1613 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1614 /// projections that would result in "inheriting lifetimes".
1615 fn check_opaque<'tcx>(
1618 substs: SubstsRef<'tcx>,
1620 origin: &hir::OpaqueTyOrigin,
1622 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1623 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1626 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1627 /// in "inheriting lifetimes".
1628 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1629 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1631 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1636 struct ProhibitOpaqueVisitor<'tcx> {
1637 opaque_identity_ty: Ty<'tcx>,
1638 generics: &'tcx ty::Generics,
1641 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1642 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1643 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1644 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1647 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1648 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1649 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1650 return *index < self.generics.parent_count as u32;
1653 r.super_visit_with(self)
1657 let prohibit_opaque = match item.kind {
1658 ItemKind::OpaqueTy(hir::OpaqueTy {
1659 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1662 let mut visitor = ProhibitOpaqueVisitor {
1663 opaque_identity_ty: tcx.mk_opaque(
1665 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1667 generics: tcx.generics_of(def_id),
1669 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1671 tcx.predicates_of(def_id)
1674 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1679 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1680 if prohibit_opaque {
1681 let is_async = match item.kind {
1682 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1683 hir::OpaqueTyOrigin::AsyncFn => true,
1686 _ => unreachable!(),
1692 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1694 if is_async { "async fn" } else { "impl Trait" },
1700 /// Checks that an opaque type does not contain cycles.
1701 fn check_opaque_for_cycles<'tcx>(
1704 substs: SubstsRef<'tcx>,
1706 origin: &hir::OpaqueTyOrigin,
1708 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1710 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1711 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1712 .span_label(span, "recursive `async fn`")
1713 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1717 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1718 err.span_label(span, "expands to a recursive type");
1719 if let ty::Opaque(..) = partially_expanded_type.kind {
1720 err.note("type resolves to itself");
1722 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1729 // Forbid defining intrinsics in Rust code,
1730 // as they must always be defined by the compiler.
1731 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1732 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1733 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1737 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1739 "check_item_type(it.hir_id={}, it.name={})",
1741 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1743 let _indenter = indenter();
1745 // Consts can play a role in type-checking, so they are included here.
1746 hir::ItemKind::Static(..) => {
1747 let def_id = tcx.hir().local_def_id(it.hir_id);
1748 tcx.typeck_tables_of(def_id);
1749 maybe_check_static_with_link_section(tcx, def_id, it.span);
1751 hir::ItemKind::Const(..) => {
1752 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1754 hir::ItemKind::Enum(ref enum_definition, _) => {
1755 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1757 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1758 hir::ItemKind::Impl { ref items, .. } => {
1759 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1760 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1761 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1762 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1763 let trait_def_id = impl_trait_ref.def_id;
1764 check_on_unimplemented(tcx, trait_def_id, it);
1767 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1768 let def_id = tcx.hir().local_def_id(it.hir_id);
1769 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1771 for item in items.iter() {
1772 let item = tcx.hir().trait_item(item.id);
1773 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1774 let abi = sig.header.abi;
1775 fn_maybe_err(tcx, item.ident.span, abi);
1779 hir::ItemKind::Struct(..) => {
1780 check_struct(tcx, it.hir_id, it.span);
1782 hir::ItemKind::Union(..) => {
1783 check_union(tcx, it.hir_id, it.span);
1785 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1786 let def_id = tcx.hir().local_def_id(it.hir_id);
1788 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1789 check_opaque(tcx, def_id, substs, it.span, &origin);
1791 hir::ItemKind::TyAlias(..) => {
1792 let def_id = tcx.hir().local_def_id(it.hir_id);
1793 let pty_ty = tcx.type_of(def_id);
1794 let generics = tcx.generics_of(def_id);
1795 check_type_params_are_used(tcx, &generics, pty_ty);
1797 hir::ItemKind::ForeignMod(ref m) => {
1798 check_abi(tcx, it.span, m.abi);
1800 if m.abi == Abi::RustIntrinsic {
1801 for item in m.items {
1802 intrinsic::check_intrinsic_type(tcx, item);
1804 } else if m.abi == Abi::PlatformIntrinsic {
1805 for item in m.items {
1806 intrinsic::check_platform_intrinsic_type(tcx, item);
1809 for item in m.items {
1810 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1811 let own_counts = generics.own_counts();
1812 if generics.params.len() - own_counts.lifetimes != 0 {
1813 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1814 (_, 0) => ("type", "types", Some("u32")),
1815 // We don't specify an example value, because we can't generate
1816 // a valid value for any type.
1817 (0, _) => ("const", "consts", None),
1818 _ => ("type or const", "types or consts", None),
1824 "foreign items may not have {} parameters",
1827 .span_label(item.span, &format!("can't have {} parameters", kinds))
1829 // FIXME: once we start storing spans for type arguments, turn this
1830 // into a suggestion.
1832 "replace the {} parameters with concrete {}{}",
1835 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1841 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1842 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1847 _ => { /* nothing to do */ }
1851 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
1852 // Only restricted on wasm32 target for now
1853 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1857 // If `#[link_section]` is missing, then nothing to verify
1858 let attrs = tcx.codegen_fn_attrs(id);
1859 if attrs.link_section.is_none() {
1863 // For the wasm32 target statics with `#[link_section]` are placed into custom
1864 // sections of the final output file, but this isn't link custom sections of
1865 // other executable formats. Namely we can only embed a list of bytes,
1866 // nothing with pointers to anything else or relocations. If any relocation
1867 // show up, reject them here.
1868 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1869 // the consumer's responsibility to ensure all bytes that have been read
1870 // have defined values.
1871 match tcx.const_eval_poly(id.to_def_id()) {
1872 Ok(ConstValue::ByRef { alloc, .. }) => {
1873 if alloc.relocations().len() != 0 {
1874 let msg = "statics with a custom `#[link_section]` must be a \
1875 simple list of bytes on the wasm target with no \
1876 extra levels of indirection such as references";
1877 tcx.sess.span_err(span, msg);
1880 Ok(_) => bug!("Matching on non-ByRef static"),
1885 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1886 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1887 // an error would be reported if this fails.
1888 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
1891 fn report_forbidden_specialization(
1893 impl_item: &hir::ImplItem<'_>,
1896 let mut err = struct_span_err!(
1900 "`{}` specializes an item from a parent `impl`, but \
1901 that item is not marked `default`",
1904 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1906 match tcx.span_of_impl(parent_impl) {
1908 err.span_label(span, "parent `impl` is here");
1910 "to specialize, `{}` in the parent `impl` must be marked `default`",
1915 err.note(&format!("parent implementation is in crate `{}`", cname));
1922 fn check_specialization_validity<'tcx>(
1924 trait_def: &ty::TraitDef,
1925 trait_item: &ty::AssocItem,
1927 impl_item: &hir::ImplItem<'_>,
1929 let kind = match impl_item.kind {
1930 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1931 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
1932 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1933 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1936 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1937 Ok(ancestors) => ancestors,
1940 let mut ancestor_impls = ancestors
1942 .filter_map(|parent| {
1943 if parent.is_from_trait() {
1946 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1951 if ancestor_impls.peek().is_none() {
1952 // No parent, nothing to specialize.
1956 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1958 // Parent impl exists, and contains the parent item we're trying to specialize, but
1959 // doesn't mark it `default`.
1960 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1961 Some(Err(parent_impl.def_id()))
1964 // Parent impl contains item and makes it specializable.
1965 Some(_) => Some(Ok(())),
1967 // Parent impl doesn't mention the item. This means it's inherited from the
1968 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1969 // "defaultness" from the grandparent, else they are final.
1971 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1974 Some(Err(parent_impl.def_id()))
1980 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1981 // item. This is allowed, the item isn't actually getting specialized here.
1982 let result = opt_result.unwrap_or(Ok(()));
1984 if let Err(parent_impl) = result {
1985 report_forbidden_specialization(tcx, impl_item, parent_impl);
1989 fn check_impl_items_against_trait<'tcx>(
1991 full_impl_span: Span,
1992 impl_id: LocalDefId,
1993 impl_trait_ref: ty::TraitRef<'tcx>,
1994 impl_item_refs: &[hir::ImplItemRef<'_>],
1996 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1998 // If the trait reference itself is erroneous (so the compilation is going
1999 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2000 // isn't populated for such impls.
2001 if impl_trait_ref.references_error() {
2005 // Negative impls are not expected to have any items
2006 match tcx.impl_polarity(impl_id) {
2007 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2008 ty::ImplPolarity::Negative => {
2009 if let [first_item_ref, ..] = impl_item_refs {
2010 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2015 "negative impls cannot have any items"
2023 // Locate trait definition and items
2024 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2026 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2028 // Check existing impl methods to see if they are both present in trait
2029 // and compatible with trait signature
2030 for impl_item in impl_items() {
2031 let namespace = impl_item.kind.namespace();
2032 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2033 let ty_trait_item = tcx
2034 .associated_items(impl_trait_ref.def_id)
2035 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2037 // Not compatible, but needed for the error message
2038 tcx.associated_items(impl_trait_ref.def_id)
2039 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2043 // Check that impl definition matches trait definition
2044 if let Some(ty_trait_item) = ty_trait_item {
2045 match impl_item.kind {
2046 hir::ImplItemKind::Const(..) => {
2047 // Find associated const definition.
2048 if ty_trait_item.kind == ty::AssocKind::Const {
2057 let mut err = struct_span_err!(
2061 "item `{}` is an associated const, \
2062 which doesn't match its trait `{}`",
2064 impl_trait_ref.print_only_trait_path()
2066 err.span_label(impl_item.span, "does not match trait");
2067 // We can only get the spans from local trait definition
2068 // Same for E0324 and E0325
2069 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2070 err.span_label(trait_span, "item in trait");
2075 hir::ImplItemKind::Fn(..) => {
2076 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2077 if ty_trait_item.kind == ty::AssocKind::Fn {
2078 compare_impl_method(
2087 let mut err = struct_span_err!(
2091 "item `{}` is an associated method, \
2092 which doesn't match its trait `{}`",
2094 impl_trait_ref.print_only_trait_path()
2096 err.span_label(impl_item.span, "does not match trait");
2097 if let Some(trait_span) = opt_trait_span {
2098 err.span_label(trait_span, "item in trait");
2103 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2104 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2105 if ty_trait_item.kind == ty::AssocKind::Type {
2115 let mut err = struct_span_err!(
2119 "item `{}` is an associated type, \
2120 which doesn't match its trait `{}`",
2122 impl_trait_ref.print_only_trait_path()
2124 err.span_label(impl_item.span, "does not match trait");
2125 if let Some(trait_span) = opt_trait_span {
2126 err.span_label(trait_span, "item in trait");
2133 check_specialization_validity(
2137 impl_id.to_def_id(),
2143 // Check for missing items from trait
2144 let mut missing_items = Vec::new();
2145 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2146 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2147 let is_implemented = ancestors
2148 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2149 .map(|node_item| !node_item.defining_node.is_from_trait())
2152 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2153 if !trait_item.defaultness.has_value() {
2154 missing_items.push(*trait_item);
2160 if !missing_items.is_empty() {
2161 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2165 fn missing_items_err(
2168 missing_items: &[ty::AssocItem],
2169 full_impl_span: Span,
2171 let missing_items_msg = missing_items
2173 .map(|trait_item| trait_item.ident.to_string())
2174 .collect::<Vec<_>>()
2177 let mut err = struct_span_err!(
2181 "not all trait items implemented, missing: `{}`",
2184 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2186 // `Span` before impl block closing brace.
2187 let hi = full_impl_span.hi() - BytePos(1);
2188 // Point at the place right before the closing brace of the relevant `impl` to suggest
2189 // adding the associated item at the end of its body.
2190 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2191 // Obtain the level of indentation ending in `sugg_sp`.
2192 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2193 // Make the whitespace that will make the suggestion have the right indentation.
2194 let padding: String = (0..indentation).map(|_| " ").collect();
2196 for trait_item in missing_items {
2197 let snippet = suggestion_signature(&trait_item, tcx);
2198 let code = format!("{}{}\n{}", padding, snippet, padding);
2199 let msg = format!("implement the missing item: `{}`", snippet);
2200 let appl = Applicability::HasPlaceholders;
2201 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2202 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2203 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2205 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2211 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2212 fn bounds_from_generic_predicates(
2214 predicates: ty::GenericPredicates<'_>,
2215 ) -> (String, String) {
2216 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2217 let mut projections = vec![];
2218 for (predicate, _) in predicates.predicates {
2219 debug!("predicate {:?}", predicate);
2221 ty::Predicate::Trait(trait_predicate, _) => {
2222 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2223 let def_id = trait_predicate.skip_binder().def_id();
2224 if Some(def_id) != tcx.lang_items().sized_trait() {
2225 // Type params are `Sized` by default, do not add that restriction to the list
2226 // if it is a positive requirement.
2227 entry.push(trait_predicate.skip_binder().def_id());
2230 ty::Predicate::Projection(projection_pred) => {
2231 projections.push(projection_pred);
2236 let generics = if types.is_empty() {
2243 .filter_map(|t| match t.kind {
2244 ty::Param(_) => Some(t.to_string()),
2245 // Avoid suggesting the following:
2246 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2249 .collect::<Vec<_>>()
2253 let mut where_clauses = vec![];
2254 for (ty, bounds) in types {
2255 for bound in &bounds {
2256 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2259 for projection in &projections {
2260 let p = projection.skip_binder();
2261 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2262 // insert the associated types where they correspond, but for now let's be "lazy" and
2263 // propose this instead of the following valid resugaring:
2264 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2265 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2267 let where_clauses = if where_clauses.is_empty() {
2270 format!(" where {}", where_clauses.join(", "))
2272 (generics, where_clauses)
2275 /// Return placeholder code for the given function.
2276 fn fn_sig_suggestion(
2278 sig: &ty::FnSig<'_>,
2280 predicates: ty::GenericPredicates<'_>,
2281 assoc: &ty::AssocItem,
2288 Some(match ty.kind {
2289 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2290 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2291 let reg = match &format!("{}", reg)[..] {
2292 "'_" | "" => String::new(),
2293 reg => format!("{} ", reg),
2295 if assoc.fn_has_self_parameter {
2297 ty::Param(param) if param.name == kw::SelfUpper => {
2298 format!("&{}{}self", reg, mutability.prefix_str())
2301 _ => format!("self: {}", ty),
2304 format!("_: {:?}", ty)
2308 if assoc.fn_has_self_parameter && i == 0 {
2309 format!("self: {:?}", ty)
2311 format!("_: {:?}", ty)
2316 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2317 .filter_map(|arg| arg)
2318 .collect::<Vec<String>>()
2320 let output = sig.output();
2321 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2323 let unsafety = sig.unsafety.prefix_str();
2324 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2326 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2327 // not be present in the `fn` definition, not will we account for renamed
2328 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2329 // fill in a significant portion of the missing code, and other subsequent
2330 // suggestions can help the user fix the code.
2332 "{}fn {}{}({}){}{} {{ todo!() }}",
2333 unsafety, ident, generics, args, output, where_clauses
2337 /// Return placeholder code for the given associated item.
2338 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2339 /// structured suggestion.
2340 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2342 ty::AssocKind::Fn => {
2343 // We skip the binder here because the binder would deanonymize all
2344 // late-bound regions, and we don't want method signatures to show up
2345 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2346 // regions just fine, showing `fn(&MyType)`.
2349 tcx.fn_sig(assoc.def_id).skip_binder(),
2351 tcx.predicates_of(assoc.def_id),
2355 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2356 // FIXME(type_alias_impl_trait): we should print bounds here too.
2357 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2358 ty::AssocKind::Const => {
2359 let ty = tcx.type_of(assoc.def_id);
2360 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2361 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2366 /// Checks whether a type can be represented in memory. In particular, it
2367 /// identifies types that contain themselves without indirection through a
2368 /// pointer, which would mean their size is unbounded.
2369 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2370 let rty = tcx.type_of(item_def_id);
2372 // Check that it is possible to represent this type. This call identifies
2373 // (1) types that contain themselves and (2) types that contain a different
2374 // recursive type. It is only necessary to throw an error on those that
2375 // contain themselves. For case 2, there must be an inner type that will be
2376 // caught by case 1.
2377 match rty.is_representable(tcx, sp) {
2378 Representability::SelfRecursive(spans) => {
2379 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id());
2381 err.span_label(span, "recursive without indirection");
2386 Representability::Representable | Representability::ContainsRecursive => (),
2391 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2392 let t = tcx.type_of(def_id);
2393 if let ty::Adt(def, substs) = t.kind {
2394 if def.is_struct() {
2395 let fields = &def.non_enum_variant().fields;
2396 if fields.is_empty() {
2397 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2400 let e = fields[0].ty(tcx, substs);
2401 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2402 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2403 .span_label(sp, "SIMD elements must have the same type")
2408 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2409 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2415 "SIMD vector element type should be machine type"
2425 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2426 let repr = def.repr;
2428 for attr in tcx.get_attrs(def.did).iter() {
2429 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2430 if let attr::ReprPacked(pack) = r {
2431 if let Some(repr_pack) = repr.pack {
2432 if pack as u64 != repr_pack.bytes() {
2437 "type has conflicting packed representation hints"
2445 if repr.align.is_some() {
2450 "type has conflicting packed and align representation hints"
2454 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2455 let mut err = struct_span_err!(
2459 "packed type cannot transitively contain a `#[repr(align)]` type"
2462 let hir = tcx.hir();
2463 let hir_id = hir.as_local_hir_id(def_spans[0].0.expect_local());
2464 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2466 tcx.def_span(def_spans[0].0),
2467 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2471 if def_spans.len() > 2 {
2472 let mut first = true;
2473 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2474 let hir_id = hir.as_local_hir_id(adt_def.expect_local());
2475 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2480 "`{}` contains a field of type `{}`",
2481 tcx.type_of(def.did),
2485 format!("...which contains a field of type `{}`", ident)
2499 fn check_packed_inner(
2502 stack: &mut Vec<DefId>,
2503 ) -> Option<Vec<(DefId, Span)>> {
2504 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2505 if def.is_struct() || def.is_union() {
2506 if def.repr.align.is_some() {
2507 return Some(vec![(def.did, DUMMY_SP)]);
2511 for field in &def.non_enum_variant().fields {
2512 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2513 if !stack.contains(&def.did) {
2514 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2515 defs.push((def.did, field.ident.span));
2528 /// Emit an error when encountering more or less than one variant in a transparent enum.
2529 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2530 let variant_spans: Vec<_> = adt
2533 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2535 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2536 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2537 err.span_label(sp, &msg);
2538 if let [start @ .., end] = &*variant_spans {
2539 for variant_span in start {
2540 err.span_label(*variant_span, "");
2542 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2547 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2549 fn bad_non_zero_sized_fields<'tcx>(
2551 adt: &'tcx ty::AdtDef,
2553 field_spans: impl Iterator<Item = Span>,
2556 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2557 let mut err = struct_span_err!(
2561 "{}transparent {} {}",
2562 if adt.is_enum() { "the variant of a " } else { "" },
2566 err.span_label(sp, &msg);
2567 for sp in field_spans {
2568 err.span_label(sp, "this field is non-zero-sized");
2573 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2574 if !adt.repr.transparent() {
2577 let sp = tcx.sess.source_map().guess_head_span(sp);
2579 if adt.is_union() && !tcx.features().transparent_unions {
2581 &tcx.sess.parse_sess,
2582 sym::transparent_unions,
2584 "transparent unions are unstable",
2589 if adt.variants.len() != 1 {
2590 bad_variant_count(tcx, adt, sp, adt.did);
2591 if adt.variants.is_empty() {
2592 // Don't bother checking the fields. No variants (and thus no fields) exist.
2597 // For each field, figure out if it's known to be a ZST and align(1)
2598 let field_infos = adt.all_fields().map(|field| {
2599 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2600 let param_env = tcx.param_env(field.did);
2601 let layout = tcx.layout_of(param_env.and(ty));
2602 // We are currently checking the type this field came from, so it must be local
2603 let span = tcx.hir().span_if_local(field.did).unwrap();
2604 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2605 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2609 let non_zst_fields =
2610 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2611 let non_zst_count = non_zst_fields.clone().count();
2612 if non_zst_count != 1 {
2613 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2615 for (span, zst, align1) in field_infos {
2621 "zero-sized field in transparent {} has alignment larger than 1",
2624 .span_label(span, "has alignment larger than 1")
2630 #[allow(trivial_numeric_casts)]
2631 pub fn check_enum<'tcx>(
2634 vs: &'tcx [hir::Variant<'tcx>],
2637 let def_id = tcx.hir().local_def_id(id);
2638 let def = tcx.adt_def(def_id);
2639 def.destructor(tcx); // force the destructor to be evaluated
2642 let attributes = tcx.get_attrs(def_id.to_def_id());
2643 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2648 "unsupported representation for zero-variant enum"
2650 .span_label(sp, "zero-variant enum")
2655 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2656 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2657 if !tcx.features().repr128 {
2659 &tcx.sess.parse_sess,
2662 "repr with 128-bit type is unstable",
2669 if let Some(ref e) = v.disr_expr {
2670 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2674 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2675 let is_unit = |var: &hir::Variant<'_>| match var.data {
2676 hir::VariantData::Unit(..) => true,
2680 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2681 let has_non_units = vs.iter().any(|var| !is_unit(var));
2682 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2683 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2685 if disr_non_unit || (disr_units && has_non_units) {
2687 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2692 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2693 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2694 // Check for duplicate discriminant values
2695 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2696 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2697 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2698 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2699 let i_span = match variant_i.disr_expr {
2700 Some(ref expr) => tcx.hir().span(expr.hir_id),
2701 None => tcx.hir().span(variant_i_hir_id),
2703 let span = match v.disr_expr {
2704 Some(ref expr) => tcx.hir().span(expr.hir_id),
2711 "discriminant value `{}` already exists",
2714 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2715 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2718 disr_vals.push(discr);
2721 check_representable(tcx, sp, def_id);
2722 check_transparent(tcx, sp, def);
2725 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2730 "expected unit struct, unit variant or constant, found {}{}",
2732 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2737 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2738 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2742 fn item_def_id(&self) -> Option<DefId> {
2746 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2747 // FIXME: refactor this into a method
2748 let node = self.tcx.hir().get(self.body_id);
2749 if let Some(fn_like) = FnLikeNode::from_node(node) {
2752 hir::Constness::NotConst
2756 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2758 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2759 let item_id = tcx.hir().ty_param_owner(hir_id);
2760 let item_def_id = tcx.hir().local_def_id(item_id);
2761 let generics = tcx.generics_of(item_def_id);
2762 let index = generics.param_def_id_to_index[&def_id];
2763 ty::GenericPredicates {
2765 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2766 |&predicate| match predicate {
2767 ty::Predicate::Trait(ref data, _)
2768 if data.skip_binder().self_ty().is_param(index) =>
2770 // HACK(eddyb) should get the original `Span`.
2771 let span = tcx.def_span(def_id);
2772 Some((predicate, span))
2780 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2782 Some(def) => infer::EarlyBoundRegion(span, def.name),
2783 None => infer::MiscVariable(span),
2785 Some(self.next_region_var(v))
2788 fn allow_ty_infer(&self) -> bool {
2792 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2793 if let Some(param) = param {
2794 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2799 self.next_ty_var(TypeVariableOrigin {
2800 kind: TypeVariableOriginKind::TypeInference,
2809 param: Option<&ty::GenericParamDef>,
2811 ) -> &'tcx Const<'tcx> {
2812 if let Some(param) = param {
2813 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2818 self.next_const_var(
2820 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2825 fn projected_ty_from_poly_trait_ref(
2829 item_segment: &hir::PathSegment<'_>,
2830 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2832 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2834 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2838 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2847 self.tcx().mk_projection(item_def_id, item_substs)
2850 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2851 if ty.has_escaping_bound_vars() {
2852 ty // FIXME: normalization and escaping regions
2854 self.normalize_associated_types_in(span, &ty)
2858 fn set_tainted_by_errors(&self) {
2859 self.infcx.set_tainted_by_errors()
2862 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2863 self.write_ty(hir_id, ty)
2867 /// Controls whether the arguments are tupled. This is used for the call
2870 /// Tupling means that all call-side arguments are packed into a tuple and
2871 /// passed as a single parameter. For example, if tupling is enabled, this
2874 /// fn f(x: (isize, isize))
2876 /// Can be called as:
2883 #[derive(Clone, Eq, PartialEq)]
2884 enum TupleArgumentsFlag {
2889 /// Controls how we perform fallback for unconstrained
2892 /// Do not fallback type variables to opaque types.
2894 /// Perform all possible kinds of fallback, including
2895 /// turning type variables to opaque types.
2899 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2901 inh: &'a Inherited<'a, 'tcx>,
2902 param_env: ty::ParamEnv<'tcx>,
2903 body_id: hir::HirId,
2904 ) -> FnCtxt<'a, 'tcx> {
2908 err_count_on_creation: inh.tcx.sess.err_count(),
2910 ret_coercion_span: RefCell::new(None),
2911 resume_yield_tys: None,
2912 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2913 diverges: Cell::new(Diverges::Maybe),
2914 has_errors: Cell::new(false),
2915 enclosing_breakables: RefCell::new(EnclosingBreakables {
2917 by_id: Default::default(),
2923 pub fn sess(&self) -> &Session {
2927 pub fn errors_reported_since_creation(&self) -> bool {
2928 self.tcx.sess.err_count() > self.err_count_on_creation
2931 /// Produces warning on the given node, if the current point in the
2932 /// function is unreachable, and there hasn't been another warning.
2933 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2934 // FIXME: Combine these two 'if' expressions into one once
2935 // let chains are implemented
2936 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2937 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2938 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2939 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2940 if !span.is_desugaring(DesugaringKind::CondTemporary)
2941 && !span.is_desugaring(DesugaringKind::Async)
2942 && !orig_span.is_desugaring(DesugaringKind::Await)
2944 self.diverges.set(Diverges::WarnedAlways);
2946 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2948 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2949 let msg = format!("unreachable {}", kind);
2951 .span_label(span, &msg)
2955 .unwrap_or("any code following this expression is unreachable"),
2963 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2964 ObligationCause::new(span, self.body_id, code)
2967 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2968 self.cause(span, ObligationCauseCode::MiscObligation)
2971 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2972 /// version (resolve_vars_if_possible), this version will
2973 /// also select obligations if it seems useful, in an effort
2974 /// to get more type information.
2975 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2976 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2978 // No Infer()? Nothing needs doing.
2979 if !ty.has_infer_types_or_consts() {
2980 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2984 // If `ty` is a type variable, see whether we already know what it is.
2985 ty = self.resolve_vars_if_possible(&ty);
2986 if !ty.has_infer_types_or_consts() {
2987 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2991 // If not, try resolving pending obligations as much as
2992 // possible. This can help substantially when there are
2993 // indirect dependencies that don't seem worth tracking
2995 self.select_obligations_where_possible(false, |_| {});
2996 ty = self.resolve_vars_if_possible(&ty);
2998 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3002 fn record_deferred_call_resolution(
3004 closure_def_id: DefId,
3005 r: DeferredCallResolution<'tcx>,
3007 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3008 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3011 fn remove_deferred_call_resolutions(
3013 closure_def_id: DefId,
3014 ) -> Vec<DeferredCallResolution<'tcx>> {
3015 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3016 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3019 pub fn tag(&self) -> String {
3020 format!("{:p}", self)
3023 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3024 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3025 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3030 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3032 "write_ty({:?}, {:?}) in fcx {}",
3034 self.resolve_vars_if_possible(&ty),
3037 self.tables.borrow_mut().node_types_mut().insert(id, ty);
3039 if ty.references_error() {
3040 self.has_errors.set(true);
3041 self.set_tainted_by_errors();
3045 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3046 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3049 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3050 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3053 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3054 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3055 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3056 self.write_substs(hir_id, method.substs);
3058 // When the method is confirmed, the `method.substs` includes
3059 // parameters from not just the method, but also the impl of
3060 // the method -- in particular, the `Self` type will be fully
3061 // resolved. However, those are not something that the "user
3062 // specified" -- i.e., those types come from the inferred type
3063 // of the receiver, not something the user wrote. So when we
3064 // create the user-substs, we want to replace those earlier
3065 // types with just the types that the user actually wrote --
3066 // that is, those that appear on the *method itself*.
3068 // As an example, if the user wrote something like
3069 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3070 // type of `foo` (possibly adjusted), but we don't want to
3071 // include that. We want just the `[_, u32]` part.
3072 if !method.substs.is_noop() {
3073 let method_generics = self.tcx.generics_of(method.def_id);
3074 if !method_generics.params.is_empty() {
3075 let user_type_annotation = self.infcx.probe(|_| {
3076 let user_substs = UserSubsts {
3077 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3078 let i = param.index as usize;
3079 if i < method_generics.parent_count {
3080 self.infcx.var_for_def(DUMMY_SP, param)
3085 user_self_ty: None, // not relevant here
3088 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3094 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3095 self.write_user_type_annotation(hir_id, user_type_annotation);
3100 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3101 if !substs.is_noop() {
3102 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3104 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3108 /// Given the substs that we just converted from the HIR, try to
3109 /// canonicalize them and store them as user-given substitutions
3110 /// (i.e., substitutions that must be respected by the NLL check).
3112 /// This should be invoked **before any unifications have
3113 /// occurred**, so that annotations like `Vec<_>` are preserved
3115 pub fn write_user_type_annotation_from_substs(
3119 substs: SubstsRef<'tcx>,
3120 user_self_ty: Option<UserSelfTy<'tcx>>,
3123 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3124 user_self_ty={:?} in fcx {}",
3132 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3133 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3135 UserSubsts { substs, user_self_ty },
3137 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3138 self.write_user_type_annotation(hir_id, canonicalized);
3142 pub fn write_user_type_annotation(
3145 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3148 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3150 canonical_user_type_annotation,
3154 if !canonical_user_type_annotation.is_identity() {
3157 .user_provided_types_mut()
3158 .insert(hir_id, canonical_user_type_annotation);
3160 debug!("write_user_type_annotation: skipping identity substs");
3164 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3165 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3171 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3172 Entry::Vacant(entry) => {
3175 Entry::Occupied(mut entry) => {
3176 debug!(" - composing on top of {:?}", entry.get());
3177 match (&entry.get()[..], &adj[..]) {
3178 // Applying any adjustment on top of a NeverToAny
3179 // is a valid NeverToAny adjustment, because it can't
3181 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3183 Adjustment { kind: Adjust::Deref(_), .. },
3184 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3186 Adjustment { kind: Adjust::Deref(_), .. },
3187 .. // Any following adjustments are allowed.
3189 // A reborrow has no effect before a dereference.
3191 // FIXME: currently we never try to compose autoderefs
3192 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3194 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3195 expr, entry.get(), adj)
3197 *entry.get_mut() = adj;
3202 /// Basically whenever we are converting from a type scheme into
3203 /// the fn body space, we always want to normalize associated
3204 /// types as well. This function combines the two.
3205 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3207 T: TypeFoldable<'tcx>,
3209 let value = value.subst(self.tcx, substs);
3210 let result = self.normalize_associated_types_in(span, &value);
3211 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3215 /// As `instantiate_type_scheme`, but for the bounds found in a
3216 /// generic type scheme.
3217 fn instantiate_bounds(
3221 substs: SubstsRef<'tcx>,
3222 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3223 let bounds = self.tcx.predicates_of(def_id);
3224 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3225 let result = bounds.instantiate(self.tcx, substs);
3226 let result = self.normalize_associated_types_in(span, &result);
3228 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3229 bounds, substs, result, spans,
3234 /// Replaces the opaque types from the given value with type variables,
3235 /// and records the `OpaqueTypeMap` for later use during writeback. See
3236 /// `InferCtxt::instantiate_opaque_types` for more details.
3237 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3239 parent_id: hir::HirId,
3243 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3245 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3246 parent_def_id, value
3249 let (value, opaque_type_map) =
3250 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3251 parent_def_id.to_def_id(),
3258 let mut opaque_types = self.opaque_types.borrow_mut();
3259 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3260 for (ty, decl) in opaque_type_map {
3261 let _ = opaque_types.insert(ty, decl);
3262 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3268 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3270 T: TypeFoldable<'tcx>,
3272 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3275 fn normalize_associated_types_in_as_infer_ok<T>(
3279 ) -> InferOk<'tcx, T>
3281 T: TypeFoldable<'tcx>,
3283 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3286 pub fn require_type_meets(
3290 code: traits::ObligationCauseCode<'tcx>,
3293 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3296 pub fn require_type_is_sized(
3300 code: traits::ObligationCauseCode<'tcx>,
3302 if !ty.references_error() {
3303 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
3304 self.require_type_meets(ty, span, code, lang_item);
3308 pub fn require_type_is_sized_deferred(
3312 code: traits::ObligationCauseCode<'tcx>,
3314 if !ty.references_error() {
3315 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3319 pub fn register_bound(
3323 cause: traits::ObligationCause<'tcx>,
3325 if !ty.references_error() {
3326 self.fulfillment_cx.borrow_mut().register_bound(
3336 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3337 let t = AstConv::ast_ty_to_ty(self, ast_t);
3338 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3342 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3343 let ty = self.to_ty(ast_ty);
3344 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3346 if Self::can_contain_user_lifetime_bounds(ty) {
3347 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3348 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3349 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3355 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3356 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3357 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3359 // HACK(eddyb) emulate what a `WellFormedConst` obligation would do.
3360 // This code should be replaced with the proper WF handling ASAP.
3361 if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
3362 assert!(promoted.is_none());
3364 // HACK(eddyb) let's hope these are always empty.
3365 // let obligations = self.nominal_obligations(def_id, substs);
3366 // self.out.extend(obligations);
3368 let cause = traits::ObligationCause::new(
3369 self.tcx.def_span(const_def_id.to_def_id()),
3371 traits::MiscObligation,
3373 self.register_predicate(traits::Obligation::new(
3376 ty::Predicate::ConstEvaluatable(def_id, substs),
3383 // If the type given by the user has free regions, save it for later, since
3384 // NLL would like to enforce those. Also pass in types that involve
3385 // projections, since those can resolve to `'static` bounds (modulo #54940,
3386 // which hopefully will be fixed by the time you see this comment, dear
3387 // reader, although I have my doubts). Also pass in types with inference
3388 // types, because they may be repeated. Other sorts of things are already
3389 // sufficiently enforced with erased regions. =)
3390 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3392 T: TypeFoldable<'tcx>,
3394 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3397 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3398 match self.tables.borrow().node_types().get(id) {
3400 None if self.is_tainted_by_errors() => self.tcx.types.err,
3403 "no type for node {}: {} in fcx {}",
3405 self.tcx.hir().node_to_string(id),
3412 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3413 /// outlive the region `r`.
3414 pub fn register_wf_obligation(
3418 code: traits::ObligationCauseCode<'tcx>,
3420 // WF obligations never themselves fail, so no real need to give a detailed cause:
3421 let cause = traits::ObligationCause::new(span, self.body_id, code);
3422 self.register_predicate(traits::Obligation::new(
3425 ty::Predicate::WellFormed(ty),
3429 /// Registers obligations that all types appearing in `substs` are well-formed.
3430 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3431 for ty in substs.types() {
3432 if !ty.references_error() {
3433 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3438 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3439 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3440 /// trait/region obligations.
3442 /// For example, if there is a function:
3445 /// fn foo<'a,T:'a>(...)
3448 /// and a reference:
3454 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3455 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3456 pub fn add_obligations_for_parameters(
3458 cause: traits::ObligationCause<'tcx>,
3459 predicates: &ty::InstantiatedPredicates<'tcx>,
3461 assert!(!predicates.has_escaping_bound_vars());
3463 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3465 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3466 self.register_predicate(obligation);
3470 // FIXME(arielb1): use this instead of field.ty everywhere
3471 // Only for fields! Returns <none> for methods>
3472 // Indifferent to privacy flags
3476 field: &'tcx ty::FieldDef,
3477 substs: SubstsRef<'tcx>,
3479 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3482 fn check_casts(&self) {
3483 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3484 for cast in deferred_cast_checks.drain(..) {
3489 fn resolve_generator_interiors(&self, def_id: DefId) {
3490 let mut generators = self.deferred_generator_interiors.borrow_mut();
3491 for (body_id, interior, kind) in generators.drain(..) {
3492 self.select_obligations_where_possible(false, |_| {});
3493 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3497 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3499 // - Unconstrained ints are replaced with `i32`.
3501 // - Unconstrained floats are replaced with with `f64`.
3503 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3504 // is enabled. Otherwise, they are replaced with `()`.
3506 // Fallback becomes very dubious if we have encountered type-checking errors.
3507 // In that case, fallback to Error.
3508 // The return value indicates whether fallback has occurred.
3509 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3510 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3511 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3513 assert!(ty.is_ty_infer());
3514 let fallback = match self.type_is_unconstrained_numeric(ty) {
3515 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3516 UnconstrainedInt => self.tcx.types.i32,
3517 UnconstrainedFloat => self.tcx.types.f64,
3518 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3520 // This type variable was created from the instantiation of an opaque
3521 // type. The fact that we're attempting to perform fallback for it
3522 // means that the function neither constrained it to a concrete
3523 // type, nor to the opaque type itself.
3525 // For example, in this code:
3528 // type MyType = impl Copy;
3529 // fn defining_use() -> MyType { true }
3530 // fn other_use() -> MyType { defining_use() }
3533 // `defining_use` will constrain the instantiated inference
3534 // variable to `bool`, while `other_use` will constrain
3535 // the instantiated inference variable to `MyType`.
3537 // When we process opaque types during writeback, we
3538 // will handle cases like `other_use`, and not count
3539 // them as defining usages
3541 // However, we also need to handle cases like this:
3544 // pub type Foo = impl Copy;
3545 // fn produce() -> Option<Foo> {
3550 // In the above snippet, the inference variable created by
3551 // instantiating `Option<Foo>` will be completely unconstrained.
3552 // We treat this as a non-defining use by making the inference
3553 // variable fall back to the opaque type itself.
3554 if let FallbackMode::All = mode {
3555 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3557 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3569 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3570 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3574 fn select_all_obligations_or_error(&self) {
3575 debug!("select_all_obligations_or_error");
3576 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3577 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3581 /// Select as many obligations as we can at present.
3582 fn select_obligations_where_possible(
3584 fallback_has_occurred: bool,
3585 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3587 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3588 if let Err(mut errors) = result {
3589 mutate_fullfillment_errors(&mut errors);
3590 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3594 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3595 /// returns a type of `&T`, but the actual type we assign to the
3596 /// *expression* is `T`. So this function just peels off the return
3597 /// type by one layer to yield `T`.
3598 fn make_overloaded_place_return_type(
3600 method: MethodCallee<'tcx>,
3601 ) -> ty::TypeAndMut<'tcx> {
3602 // extract method return type, which will be &T;
3603 let ret_ty = method.sig.output();
3605 // method returns &T, but the type as visible to user is T, so deref
3606 ret_ty.builtin_deref(true).unwrap()
3611 expr: &hir::Expr<'_>,
3612 base_expr: &'tcx hir::Expr<'tcx>,
3616 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3617 // FIXME(#18741) -- this is almost but not quite the same as the
3618 // autoderef that normal method probing does. They could likely be
3621 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3622 let mut result = None;
3623 while result.is_none() && autoderef.next().is_some() {
3624 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3626 autoderef.finalize(self);
3630 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3631 /// (and otherwise adjust) `base_expr`, looking for a type which either
3632 /// supports builtin indexing or overloaded indexing.
3633 /// This loop implements one step in that search; the autoderef loop
3634 /// is implemented by `lookup_indexing`.
3637 expr: &hir::Expr<'_>,
3638 base_expr: &hir::Expr<'_>,
3639 autoderef: &Autoderef<'a, 'tcx>,
3642 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3643 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3645 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3647 expr, base_expr, adjusted_ty, index_ty
3650 for &unsize in &[false, true] {
3651 let mut self_ty = adjusted_ty;
3653 // We only unsize arrays here.
3654 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3655 self_ty = self.tcx.mk_slice(element_ty);
3661 // If some lookup succeeds, write callee into table and extract index/element
3662 // type from the method signature.
3663 // If some lookup succeeded, install method in table
3664 let input_ty = self.next_ty_var(TypeVariableOrigin {
3665 kind: TypeVariableOriginKind::AutoDeref,
3666 span: base_expr.span,
3668 let method = self.try_overloaded_place_op(
3676 let result = method.map(|ok| {
3677 debug!("try_index_step: success, using overloaded indexing");
3678 let method = self.register_infer_ok_obligations(ok);
3680 let mut adjustments = autoderef.adjust_steps(self, needs);
3681 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3682 let mutbl = match r_mutbl {
3683 hir::Mutability::Not => AutoBorrowMutability::Not,
3684 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3685 // Indexing can be desugared to a method call,
3686 // so maybe we could use two-phase here.
3687 // See the documentation of AllowTwoPhase for why that's
3688 // not the case today.
3689 allow_two_phase_borrow: AllowTwoPhase::No,
3692 adjustments.push(Adjustment {
3693 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3696 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3700 adjustments.push(Adjustment {
3701 kind: Adjust::Pointer(PointerCast::Unsize),
3702 target: method.sig.inputs()[0],
3705 self.apply_adjustments(base_expr, adjustments);
3707 self.write_method_call(expr.hir_id, method);
3708 (input_ty, self.make_overloaded_place_return_type(method).ty)
3710 if result.is_some() {
3718 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3719 let (tr, name) = match (op, is_mut) {
3720 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3721 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3722 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3723 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3725 (tr, ast::Ident::with_dummy_span(name))
3728 fn try_overloaded_place_op(
3732 arg_tys: &[Ty<'tcx>],
3735 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3736 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3738 // Try Mut first, if needed.
3739 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3740 let method = match (needs, mut_tr) {
3741 (Needs::MutPlace, Some(trait_did)) => {
3742 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3747 // Otherwise, fall back to the immutable version.
3748 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3749 match (method, imm_tr) {
3750 (None, Some(trait_did)) => {
3751 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3753 (method, _) => method,
3757 fn check_method_argument_types(
3760 expr: &'tcx hir::Expr<'tcx>,
3761 method: Result<MethodCallee<'tcx>, ()>,
3762 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3763 tuple_arguments: TupleArgumentsFlag,
3764 expected: Expectation<'tcx>,
3766 let has_error = match method {
3767 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3771 let err_inputs = self.err_args(args_no_rcvr.len());
3773 let err_inputs = match tuple_arguments {
3774 DontTupleArguments => err_inputs,
3775 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3778 self.check_argument_types(
3788 return self.tcx.types.err;
3791 let method = method.unwrap();
3792 // HACK(eddyb) ignore self in the definition (see above).
3793 let expected_arg_tys = self.expected_inputs_for_expected_output(
3796 method.sig.output(),
3797 &method.sig.inputs()[1..],
3799 self.check_argument_types(
3802 &method.sig.inputs()[1..],
3803 &expected_arg_tys[..],
3805 method.sig.c_variadic,
3807 self.tcx.hir().span_if_local(method.def_id),
3812 fn self_type_matches_expected_vid(
3814 trait_ref: ty::PolyTraitRef<'tcx>,
3815 expected_vid: ty::TyVid,
3817 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3819 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3820 trait_ref, self_ty, expected_vid
3822 match self_ty.kind {
3823 ty::Infer(ty::TyVar(found_vid)) => {
3824 // FIXME: consider using `sub_root_var` here so we
3825 // can see through subtyping.
3826 let found_vid = self.root_var(found_vid);
3827 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3828 expected_vid == found_vid
3834 fn obligations_for_self_ty<'b>(
3837 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3840 // FIXME: consider using `sub_root_var` here so we
3841 // can see through subtyping.
3842 let ty_var_root = self.root_var(self_ty);
3844 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3847 self.fulfillment_cx.borrow().pending_obligations()
3852 .pending_obligations()
3854 .filter_map(move |obligation| match obligation.predicate {
3855 ty::Predicate::Projection(ref data) => {
3856 Some((data.to_poly_trait_ref(self.tcx), obligation))
3858 ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
3859 ty::Predicate::Subtype(..) => None,
3860 ty::Predicate::RegionOutlives(..) => None,
3861 ty::Predicate::TypeOutlives(..) => None,
3862 ty::Predicate::WellFormed(..) => None,
3863 ty::Predicate::ObjectSafe(..) => None,
3864 ty::Predicate::ConstEvaluatable(..) => None,
3865 // N.B., this predicate is created by breaking down a
3866 // `ClosureType: FnFoo()` predicate, where
3867 // `ClosureType` represents some `Closure`. It can't
3868 // possibly be referring to the current closure,
3869 // because we haven't produced the `Closure` for
3870 // this closure yet; this is exactly why the other
3871 // code is looking for a self type of a unresolved
3872 // inference variable.
3873 ty::Predicate::ClosureKind(..) => None,
3875 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3878 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3879 self.obligations_for_self_ty(self_ty)
3880 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3883 /// Generic function that factors out common logic from function calls,
3884 /// method calls and overloaded operators.
3885 fn check_argument_types(
3888 expr: &'tcx hir::Expr<'tcx>,
3889 fn_inputs: &[Ty<'tcx>],
3890 expected_arg_tys: &[Ty<'tcx>],
3891 args: &'tcx [hir::Expr<'tcx>],
3893 tuple_arguments: TupleArgumentsFlag,
3894 def_span: Option<Span>,
3897 // Grab the argument types, supplying fresh type variables
3898 // if the wrong number of arguments were supplied
3899 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3901 // All the input types from the fn signature must outlive the call
3902 // so as to validate implied bounds.
3903 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3904 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3907 let expected_arg_count = fn_inputs.len();
3909 let param_count_error = |expected_count: usize,
3914 let (span, start_span, args) = match &expr.kind {
3915 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3916 hir::ExprKind::MethodCall(path_segment, span, args) => (
3918 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3921 .and_then(|args| args.args.iter().last())
3922 // Account for `foo.bar::<T>()`.
3924 // Skip the closing `>`.
3927 .next_point(tcx.sess.source_map().next_point(arg.span()))
3930 &args[1..], // Skip the receiver.
3932 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3934 let arg_spans = if args.is_empty() {
3936 // ^^^-- supplied 0 arguments
3938 // expected 2 arguments
3939 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3942 // ^^^ - - - supplied 3 arguments
3944 // expected 2 arguments
3945 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3948 let mut err = tcx.sess.struct_span_err_with_code(
3951 "this function takes {}{} but {} {} supplied",
3952 if c_variadic { "at least " } else { "" },
3953 potentially_plural_count(expected_count, "argument"),
3954 potentially_plural_count(arg_count, "argument"),
3955 if arg_count == 1 { "was" } else { "were" }
3957 DiagnosticId::Error(error_code.to_owned()),
3959 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3960 for (i, span) in arg_spans.into_iter().enumerate() {
3963 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3967 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3968 err.span_label(def_s, "defined here");
3971 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3972 // remove closing `)` from the span
3973 let sugg_span = sugg_span.shrink_to_lo();
3974 err.span_suggestion(
3976 "expected the unit value `()`; create it with empty parentheses",
3978 Applicability::MachineApplicable,
3985 if c_variadic { "at least " } else { "" },
3986 potentially_plural_count(expected_count, "argument")
3993 let mut expected_arg_tys = expected_arg_tys.to_vec();
3995 let formal_tys = if tuple_arguments == TupleArguments {
3996 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3997 match tuple_type.kind {
3998 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3999 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4000 expected_arg_tys = vec![];
4001 self.err_args(args.len())
4003 ty::Tuple(arg_types) => {
4004 expected_arg_tys = match expected_arg_tys.get(0) {
4005 Some(&ty) => match ty.kind {
4006 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4011 arg_types.iter().map(|k| k.expect_ty()).collect()
4018 "cannot use call notation; the first type parameter \
4019 for the function trait is neither a tuple nor unit"
4022 expected_arg_tys = vec![];
4023 self.err_args(args.len())
4026 } else if expected_arg_count == supplied_arg_count {
4028 } else if c_variadic {
4029 if supplied_arg_count >= expected_arg_count {
4032 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4033 expected_arg_tys = vec![];
4034 self.err_args(supplied_arg_count)
4037 // is the missing argument of type `()`?
4038 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4039 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4040 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4041 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4045 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4047 expected_arg_tys = vec![];
4048 self.err_args(supplied_arg_count)
4052 "check_argument_types: formal_tys={:?}",
4053 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4056 // If there is no expectation, expect formal_tys.
4057 let expected_arg_tys =
4058 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4060 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4062 // Check the arguments.
4063 // We do this in a pretty awful way: first we type-check any arguments
4064 // that are not closures, then we type-check the closures. This is so
4065 // that we have more information about the types of arguments when we
4066 // type-check the functions. This isn't really the right way to do this.
4067 for &check_closures in &[false, true] {
4068 debug!("check_closures={}", check_closures);
4070 // More awful hacks: before we check argument types, try to do
4071 // an "opportunistic" vtable resolution of any trait bounds on
4072 // the call. This helps coercions.
4074 self.select_obligations_where_possible(false, |errors| {
4075 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4076 self.point_at_arg_instead_of_call_if_possible(
4078 &final_arg_types[..],
4085 // For C-variadic functions, we don't have a declared type for all of
4086 // the arguments hence we only do our usual type checking with
4087 // the arguments who's types we do know.
4088 let t = if c_variadic {
4090 } else if tuple_arguments == TupleArguments {
4095 for (i, arg) in args.iter().take(t).enumerate() {
4096 // Warn only for the first loop (the "no closures" one).
4097 // Closure arguments themselves can't be diverging, but
4098 // a previous argument can, e.g., `foo(panic!(), || {})`.
4099 if !check_closures {
4100 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4103 let is_closure = match arg.kind {
4104 ExprKind::Closure(..) => true,
4108 if is_closure != check_closures {
4112 debug!("checking the argument");
4113 let formal_ty = formal_tys[i];
4115 // The special-cased logic below has three functions:
4116 // 1. Provide as good of an expected type as possible.
4117 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4119 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4121 // 2. Coerce to the most detailed type that could be coerced
4122 // to, which is `expected_ty` if `rvalue_hint` returns an
4123 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4124 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4125 // We're processing function arguments so we definitely want to use
4126 // two-phase borrows.
4127 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4128 final_arg_types.push((i, checked_ty, coerce_ty));
4130 // 3. Relate the expected type and the formal one,
4131 // if the expected type was used for the coercion.
4132 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4136 // We also need to make sure we at least write the ty of the other
4137 // arguments which we skipped above.
4139 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4140 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4141 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4144 for arg in args.iter().skip(expected_arg_count) {
4145 let arg_ty = self.check_expr(&arg);
4147 // There are a few types which get autopromoted when passed via varargs
4148 // in C but we just error out instead and require explicit casts.
4149 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4151 ty::Float(ast::FloatTy::F32) => {
4152 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4154 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4155 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4157 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4158 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4161 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4162 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4163 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4171 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4172 vec![self.tcx.types.err; len]
4175 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4176 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4177 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4178 /// can be not easily comparable with predicate type (because of coercion). If the types match
4179 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4180 /// the corresponding argument's expression span instead of the `fn` call path span.
4181 fn point_at_arg_instead_of_call_if_possible(
4183 errors: &mut Vec<traits::FulfillmentError<'_>>,
4184 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4186 args: &'tcx [hir::Expr<'tcx>],
4188 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4189 // the `?` operator.
4190 if call_sp.desugaring_kind().is_some() {
4194 for error in errors {
4195 // Only if the cause is somewhere inside the expression we want try to point at arg.
4196 // Otherwise, it means that the cause is somewhere else and we should not change
4197 // anything because we can break the correct span.
4198 if !call_sp.contains(error.obligation.cause.span) {
4202 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4203 // Collect the argument position for all arguments that could have caused this
4204 // `FulfillmentError`.
4205 let mut referenced_in = final_arg_types
4207 .map(|&(i, checked_ty, _)| (i, checked_ty))
4208 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4209 .flat_map(|(i, ty)| {
4210 let ty = self.resolve_vars_if_possible(&ty);
4211 // We walk the argument type because the argument's type could have
4212 // been `Option<T>`, but the `FulfillmentError` references `T`.
4213 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4219 .collect::<Vec<_>>();
4221 // Both checked and coerced types could have matched, thus we need to remove
4223 referenced_in.sort();
4224 referenced_in.dedup();
4226 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4227 // We make sure that only *one* argument matches the obligation failure
4228 // and we assign the obligation's span to its expression's.
4229 error.obligation.cause.span = args[ref_in].span;
4230 error.points_at_arg_span = true;
4236 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4237 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4238 /// were caused by them. If they were, we point at the corresponding type argument's span
4239 /// instead of the `fn` call path span.
4240 fn point_at_type_arg_instead_of_call_if_possible(
4242 errors: &mut Vec<traits::FulfillmentError<'_>>,
4243 call_expr: &'tcx hir::Expr<'tcx>,
4245 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4246 if let hir::ExprKind::Path(qpath) = &path.kind {
4247 if let hir::QPath::Resolved(_, path) = &qpath {
4248 for error in errors {
4249 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4250 // If any of the type arguments in this path segment caused the
4251 // `FullfillmentError`, point at its span (#61860).
4255 .filter_map(|seg| seg.args.as_ref())
4256 .flat_map(|a| a.args.iter())
4258 if let hir::GenericArg::Type(hir_ty) = &arg {
4259 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4262 // Avoid ICE with associated types. As this is best
4263 // effort only, it's ok to ignore the case. It
4264 // would trigger in `is_send::<T::AssocType>();`
4265 // from `typeck-default-trait-impl-assoc-type.rs`.
4267 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4268 let ty = self.resolve_vars_if_possible(&ty);
4269 if ty == predicate.skip_binder().self_ty() {
4270 error.obligation.cause.span = hir_ty.span;
4282 // AST fragment checking
4283 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4287 ast::LitKind::Str(..) => tcx.mk_static_str(),
4288 ast::LitKind::ByteStr(ref v) => {
4289 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4291 ast::LitKind::Byte(_) => tcx.types.u8,
4292 ast::LitKind::Char(_) => tcx.types.char,
4293 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4294 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4295 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4296 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4297 ty::Int(_) | ty::Uint(_) => Some(ty),
4298 ty::Char => Some(tcx.types.u8),
4299 ty::RawPtr(..) => Some(tcx.types.usize),
4300 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4303 opt_ty.unwrap_or_else(|| self.next_int_var())
4305 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4306 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4307 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4308 ty::Float(_) => Some(ty),
4311 opt_ty.unwrap_or_else(|| self.next_float_var())
4313 ast::LitKind::Bool(_) => tcx.types.bool,
4314 ast::LitKind::Err(_) => tcx.types.err,
4318 /// Unifies the output type with the expected type early, for more coercions
4319 /// and forward type information on the input expressions.
4320 fn expected_inputs_for_expected_output(
4323 expected_ret: Expectation<'tcx>,
4324 formal_ret: Ty<'tcx>,
4325 formal_args: &[Ty<'tcx>],
4326 ) -> Vec<Ty<'tcx>> {
4327 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4328 let ret_ty = match expected_ret.only_has_type(self) {
4330 None => return Vec::new(),
4332 let expect_args = self
4333 .fudge_inference_if_ok(|| {
4334 // Attempt to apply a subtyping relationship between the formal
4335 // return type (likely containing type variables if the function
4336 // is polymorphic) and the expected return type.
4337 // No argument expectations are produced if unification fails.
4338 let origin = self.misc(call_span);
4339 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4341 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4342 // to identity so the resulting type is not constrained.
4345 // Process any obligations locally as much as
4346 // we can. We don't care if some things turn
4347 // out unconstrained or ambiguous, as we're
4348 // just trying to get hints here.
4349 self.save_and_restore_in_snapshot_flag(|_| {
4350 let mut fulfill = TraitEngine::new(self.tcx);
4351 for obligation in ok.obligations {
4352 fulfill.register_predicate_obligation(self, obligation);
4354 fulfill.select_where_possible(self)
4358 Err(_) => return Err(()),
4361 // Record all the argument types, with the substitutions
4362 // produced from the above subtyping unification.
4363 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4365 .unwrap_or_default();
4367 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4368 formal_args, formal_ret, expect_args, expected_ret
4373 pub fn check_struct_path(
4377 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4378 let path_span = match *qpath {
4379 QPath::Resolved(_, ref path) => path.span,
4380 QPath::TypeRelative(ref qself, _) => qself.span,
4382 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4383 let variant = match def {
4385 self.set_tainted_by_errors();
4388 Res::Def(DefKind::Variant, _) => match ty.kind {
4389 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4390 _ => bug!("unexpected type: {:?}", ty),
4392 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4393 | Res::SelfTy(..) => match ty.kind {
4394 ty::Adt(adt, substs) if !adt.is_enum() => {
4395 Some((adt.non_enum_variant(), adt.did, substs))
4399 _ => bug!("unexpected definition: {:?}", def),
4402 if let Some((variant, did, substs)) = variant {
4403 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4404 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4406 // Check bounds on type arguments used in the path.
4407 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4409 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4410 self.add_obligations_for_parameters(cause, &bounds);
4418 "expected struct, variant or union type, found {}",
4419 ty.sort_string(self.tcx)
4421 .span_label(path_span, "not a struct")
4427 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4428 // The newly resolved definition is written into `type_dependent_defs`.
4429 fn finish_resolving_struct_path(
4434 ) -> (Res, Ty<'tcx>) {
4436 QPath::Resolved(ref maybe_qself, ref path) => {
4437 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4438 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4441 QPath::TypeRelative(ref qself, ref segment) => {
4442 let ty = self.to_ty(qself);
4444 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4450 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4451 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4452 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4454 // Write back the new resolution.
4455 self.write_resolution(hir_id, result);
4457 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4462 /// Resolves an associated value path into a base type and associated constant, or method
4463 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4464 pub fn resolve_ty_and_res_ufcs<'b>(
4466 qpath: &'b QPath<'b>,
4469 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4470 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4471 let (ty, qself, item_segment) = match *qpath {
4472 QPath::Resolved(ref opt_qself, ref path) => {
4475 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4479 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4481 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4482 // Return directly on cache hit. This is useful to avoid doubly reporting
4483 // errors with default match binding modes. See #44614.
4485 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4486 return (def, Some(ty), slice::from_ref(&**item_segment));
4488 let item_name = item_segment.ident;
4489 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4490 let result = match error {
4491 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4492 _ => Err(ErrorReported),
4494 if item_name.name != kw::Invalid {
4495 self.report_method_error(
4499 SelfSource::QPath(qself),
4503 .map(|mut e| e.emit());
4508 // Write back the new resolution.
4509 self.write_resolution(hir_id, result);
4511 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4513 slice::from_ref(&**item_segment),
4517 pub fn check_decl_initializer(
4519 local: &'tcx hir::Local<'tcx>,
4520 init: &'tcx hir::Expr<'tcx>,
4522 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4523 // for #42640 (default match binding modes).
4526 let ref_bindings = local.pat.contains_explicit_ref_binding();
4528 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4529 if let Some(m) = ref_bindings {
4530 // Somewhat subtle: if we have a `ref` binding in the pattern,
4531 // we want to avoid introducing coercions for the RHS. This is
4532 // both because it helps preserve sanity and, in the case of
4533 // ref mut, for soundness (issue #23116). In particular, in
4534 // the latter case, we need to be clear that the type of the
4535 // referent for the reference that results is *equal to* the
4536 // type of the place it is referencing, and not some
4537 // supertype thereof.
4538 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4539 self.demand_eqtype(init.span, local_ty, init_ty);
4542 self.check_expr_coercable_to_type(init, local_ty)
4546 /// Type check a `let` statement.
4547 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4548 // Determine and write the type which we'll check the pattern against.
4549 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4550 self.write_ty(local.hir_id, ty);
4552 // Type check the initializer.
4553 if let Some(ref init) = local.init {
4554 let init_ty = self.check_decl_initializer(local, &init);
4555 self.overwrite_local_ty_if_err(local, ty, init_ty);
4558 // Does the expected pattern type originate from an expression and what is the span?
4559 let (origin_expr, ty_span) = match (local.ty, local.init) {
4560 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4561 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4562 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4565 // Type check the pattern. Override if necessary to avoid knock-on errors.
4566 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4567 let pat_ty = self.node_ty(local.pat.hir_id);
4568 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4571 fn overwrite_local_ty_if_err(
4573 local: &'tcx hir::Local<'tcx>,
4577 if ty.references_error() {
4578 // Override the types everywhere with `types.err` to avoid knock on errors.
4579 self.write_ty(local.hir_id, ty);
4580 self.write_ty(local.pat.hir_id, ty);
4581 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4582 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4583 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4587 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4588 err.span_suggestion_short(
4589 span.shrink_to_hi(),
4590 "consider using a semicolon here",
4592 Applicability::MachineApplicable,
4596 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4597 // Don't do all the complex logic below for `DeclItem`.
4599 hir::StmtKind::Item(..) => return,
4600 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4603 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4605 // Hide the outer diverging and `has_errors` flags.
4606 let old_diverges = self.diverges.replace(Diverges::Maybe);
4607 let old_has_errors = self.has_errors.replace(false);
4610 hir::StmtKind::Local(ref l) => {
4611 self.check_decl_local(&l);
4614 hir::StmtKind::Item(_) => {}
4615 hir::StmtKind::Expr(ref expr) => {
4616 // Check with expected type of `()`.
4617 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4618 self.suggest_semicolon_at_end(expr.span, err);
4621 hir::StmtKind::Semi(ref expr) => {
4622 self.check_expr(&expr);
4626 // Combine the diverging and `has_error` flags.
4627 self.diverges.set(self.diverges.get() | old_diverges);
4628 self.has_errors.set(self.has_errors.get() | old_has_errors);
4631 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4632 let unit = self.tcx.mk_unit();
4633 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4635 // if the block produces a `!` value, that can always be
4636 // (effectively) coerced to unit.
4638 self.demand_suptype(blk.span, unit, ty);
4642 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4643 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4644 /// when given code like the following:
4646 /// if false { return 0i32; } else { 1u32 }
4647 /// // ^^^^ point at this instead of the whole `if` expression
4649 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4650 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4651 let arm_spans: Vec<Span> = arms
4654 self.in_progress_tables
4655 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4656 .and_then(|arm_ty| {
4657 if arm_ty.is_never() {
4660 Some(match &arm.body.kind {
4661 // Point at the tail expression when possible.
4662 hir::ExprKind::Block(block, _) => {
4663 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4671 if arm_spans.len() == 1 {
4672 return arm_spans[0];
4678 fn check_block_with_expected(
4680 blk: &'tcx hir::Block<'tcx>,
4681 expected: Expectation<'tcx>,
4684 let mut fcx_ps = self.ps.borrow_mut();
4685 let unsafety_state = fcx_ps.recurse(blk);
4686 replace(&mut *fcx_ps, unsafety_state)
4689 // In some cases, blocks have just one exit, but other blocks
4690 // can be targeted by multiple breaks. This can happen both
4691 // with labeled blocks as well as when we desugar
4692 // a `try { ... }` expression.
4696 // 'a: { if true { break 'a Err(()); } Ok(()) }
4698 // Here we would wind up with two coercions, one from
4699 // `Err(())` and the other from the tail expression
4700 // `Ok(())`. If the tail expression is omitted, that's a
4701 // "forced unit" -- unless the block diverges, in which
4702 // case we can ignore the tail expression (e.g., `'a: {
4703 // break 'a 22; }` would not force the type of the block
4705 let tail_expr = blk.expr.as_ref();
4706 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4707 let coerce = if blk.targeted_by_break {
4708 CoerceMany::new(coerce_to_ty)
4710 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4711 Some(e) => slice::from_ref(e),
4714 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4717 let prev_diverges = self.diverges.get();
4718 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4720 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4721 for s in blk.stmts {
4725 // check the tail expression **without** holding the
4726 // `enclosing_breakables` lock below.
4727 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4729 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4730 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4731 let coerce = ctxt.coerce.as_mut().unwrap();
4732 if let Some(tail_expr_ty) = tail_expr_ty {
4733 let tail_expr = tail_expr.unwrap();
4734 let span = self.get_expr_coercion_span(tail_expr);
4735 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4736 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4738 // Subtle: if there is no explicit tail expression,
4739 // that is typically equivalent to a tail expression
4740 // of `()` -- except if the block diverges. In that
4741 // case, there is no value supplied from the tail
4742 // expression (assuming there are no other breaks,
4743 // this implies that the type of the block will be
4746 // #41425 -- label the implicit `()` as being the
4747 // "found type" here, rather than the "expected type".
4748 if !self.diverges.get().is_always() {
4749 // #50009 -- Do not point at the entire fn block span, point at the return type
4750 // span, as it is the cause of the requirement, and
4751 // `consider_hint_about_removing_semicolon` will point at the last expression
4752 // if it were a relevant part of the error. This improves usability in editors
4753 // that highlight errors inline.
4754 let mut sp = blk.span;
4755 let mut fn_span = None;
4756 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4757 let ret_sp = decl.output.span();
4758 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4759 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4760 // output would otherwise be incorrect and even misleading. Make sure
4761 // the span we're aiming at correspond to a `fn` body.
4762 if block_sp == blk.span {
4764 fn_span = Some(ident.span);
4768 coerce.coerce_forced_unit(
4772 if let Some(expected_ty) = expected.only_has_type(self) {
4773 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4775 if let Some(fn_span) = fn_span {
4778 "implicitly returns `()` as its body has no tail or `return` \
4790 // If we can break from the block, then the block's exit is always reachable
4791 // (... as long as the entry is reachable) - regardless of the tail of the block.
4792 self.diverges.set(prev_diverges);
4795 let mut ty = ctxt.coerce.unwrap().complete(self);
4797 if self.has_errors.get() || ty.references_error() {
4798 ty = self.tcx.types.err
4801 self.write_ty(blk.hir_id, ty);
4803 *self.ps.borrow_mut() = prev;
4807 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4808 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4810 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4811 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4812 let body = self.tcx.hir().body(body_id);
4813 if let ExprKind::Block(block, _) = &body.value.kind {
4814 return Some(block.span);
4822 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4823 fn get_parent_fn_decl(
4826 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
4827 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4828 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4831 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4832 fn get_node_fn_decl(
4835 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
4837 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4838 // This is less than ideal, it will not suggest a return type span on any
4839 // method called `main`, regardless of whether it is actually the entry point,
4840 // but it will still present it as the reason for the expected type.
4841 Some((&sig.decl, ident, ident.name != sym::main))
4843 Node::TraitItem(&hir::TraitItem {
4845 kind: hir::TraitItemKind::Fn(ref sig, ..),
4847 }) => Some((&sig.decl, ident, true)),
4848 Node::ImplItem(&hir::ImplItem {
4850 kind: hir::ImplItemKind::Fn(ref sig, ..),
4852 }) => Some((&sig.decl, ident, false)),
4857 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4858 /// suggestion can be made, `None` otherwise.
4859 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4860 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4861 // `while` before reaching it, as block tail returns are not available in them.
4862 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4863 let parent = self.tcx.hir().get(blk_id);
4864 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4868 /// On implicit return expressions with mismatched types, provides the following suggestions:
4870 /// - Points out the method's return type as the reason for the expected type.
4871 /// - Possible missing semicolon.
4872 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4873 pub fn suggest_mismatched_types_on_tail(
4875 err: &mut DiagnosticBuilder<'_>,
4876 expr: &'tcx hir::Expr<'tcx>,
4882 let expr = expr.peel_drop_temps();
4883 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4884 let mut pointing_at_return_type = false;
4885 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4886 pointing_at_return_type =
4887 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4889 pointing_at_return_type
4892 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4893 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4895 /// fn foo(x: usize) -> usize { x }
4896 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4900 err: &mut DiagnosticBuilder<'_>,
4901 expr: &hir::Expr<'_>,
4905 let hir = self.tcx.hir();
4906 let (def_id, sig) = match found.kind {
4907 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4908 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4912 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4913 let sig = self.normalize_associated_types_in(expr.span, &sig);
4914 if self.can_coerce(sig.output(), expected) {
4915 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4916 (String::new(), Applicability::MachineApplicable)
4918 ("...".to_string(), Applicability::HasPlaceholders)
4920 let mut msg = "call this function";
4921 match hir.get_if_local(def_id) {
4923 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4924 | Node::ImplItem(hir::ImplItem {
4925 kind: hir::ImplItemKind::Fn(_, body_id), ..
4927 | Node::TraitItem(hir::TraitItem {
4928 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4932 let body = hir.body(*body_id);
4936 .map(|param| match ¶m.pat.kind {
4937 hir::PatKind::Binding(_, _, ident, None)
4938 if ident.name != kw::SelfLower =>
4942 _ => "_".to_string(),
4944 .collect::<Vec<_>>()
4947 Some(Node::Expr(hir::Expr {
4948 kind: ExprKind::Closure(_, _, body_id, _, _),
4949 span: full_closure_span,
4952 if *full_closure_span == expr.span {
4955 msg = "call this closure";
4956 let body = hir.body(*body_id);
4960 .map(|param| match ¶m.pat.kind {
4961 hir::PatKind::Binding(_, _, ident, None)
4962 if ident.name != kw::SelfLower =>
4966 _ => "_".to_string(),
4968 .collect::<Vec<_>>()
4971 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4972 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4975 .map(|def_id| hir.as_local_hir_id(def_id))
4976 .and_then(|hir_id| hir.def_kind(hir_id))
4978 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4979 msg = "instantiate this tuple variant";
4981 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4982 msg = "instantiate this tuple struct";
4987 Some(Node::ForeignItem(hir::ForeignItem {
4988 kind: hir::ForeignItemKind::Fn(_, idents, _),
4994 if ident.name != kw::SelfLower {
5000 .collect::<Vec<_>>()
5003 Some(Node::TraitItem(hir::TraitItem {
5004 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5010 if ident.name != kw::SelfLower {
5016 .collect::<Vec<_>>()
5021 err.span_suggestion_verbose(
5022 expr.span.shrink_to_hi(),
5023 &format!("use parentheses to {}", msg),
5024 format!("({})", sugg_call),
5032 pub fn suggest_ref_or_into(
5034 err: &mut DiagnosticBuilder<'_>,
5035 expr: &hir::Expr<'_>,
5039 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
5040 err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable);
5041 } else if let (ty::FnDef(def_id, ..), true) =
5042 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5044 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5045 let sp = self.sess().source_map().guess_head_span(sp);
5046 err.span_label(sp, &format!("{} defined here", found));
5048 } else if !self.check_for_cast(err, expr, found, expected) {
5049 let is_struct_pat_shorthand_field =
5050 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5051 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5052 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5053 let mut suggestions = iter::repeat(&expr_text)
5054 .zip(methods.iter())
5055 .filter_map(|(receiver, method)| {
5056 let method_call = format!(".{}()", method.ident);
5057 if receiver.ends_with(&method_call) {
5058 None // do not suggest code that is already there (#53348)
5060 let method_call_list = [".to_vec()", ".to_string()"];
5061 let sugg = if receiver.ends_with(".clone()")
5062 && method_call_list.contains(&method_call.as_str())
5064 let max_len = receiver.rfind('.').unwrap();
5065 format!("{}{}", &receiver[..max_len], method_call)
5067 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5068 format!("({}){}", receiver, method_call)
5070 format!("{}{}", receiver, method_call)
5073 Some(if is_struct_pat_shorthand_field {
5074 format!("{}: {}", receiver, sugg)
5081 if suggestions.peek().is_some() {
5082 err.span_suggestions(
5084 "try using a conversion method",
5086 Applicability::MaybeIncorrect,
5093 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5094 /// in the heap by calling `Box::new()`.
5095 fn suggest_boxing_when_appropriate(
5097 err: &mut DiagnosticBuilder<'_>,
5098 expr: &hir::Expr<'_>,
5102 if self.tcx.hir().is_const_context(expr.hir_id) {
5103 // Do not suggest `Box::new` in const context.
5106 if !expected.is_box() || found.is_box() {
5109 let boxed_found = self.tcx.mk_box(found);
5110 if let (true, Ok(snippet)) = (
5111 self.can_coerce(boxed_found, expected),
5112 self.sess().source_map().span_to_snippet(expr.span),
5114 err.span_suggestion(
5116 "store this in the heap by calling `Box::new`",
5117 format!("Box::new({})", snippet),
5118 Applicability::MachineApplicable,
5121 "for more on the distinction between the stack and the heap, read \
5122 https://doc.rust-lang.org/book/ch15-01-box.html, \
5123 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5124 https://doc.rust-lang.org/std/boxed/index.html",
5129 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5130 fn suggest_calling_boxed_future_when_appropriate(
5132 err: &mut DiagnosticBuilder<'_>,
5133 expr: &hir::Expr<'_>,
5139 if self.tcx.hir().is_const_context(expr.hir_id) {
5140 // Do not suggest `Box::new` in const context.
5143 let pin_did = self.tcx.lang_items().pin_type();
5144 match expected.kind {
5145 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5146 // This guards the `unwrap` and `mk_box` below.
5147 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5150 let boxed_found = self.tcx.mk_box(found);
5151 let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap();
5152 if let (true, Ok(snippet)) = (
5153 self.can_coerce(new_found, expected),
5154 self.sess().source_map().span_to_snippet(expr.span),
5157 ty::Adt(def, _) if def.is_box() => {
5158 err.help("use `Box::pin`");
5161 err.span_suggestion(
5163 "you need to pin and box this expression",
5164 format!("Box::pin({})", snippet),
5165 Applicability::MachineApplicable,
5175 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5179 /// bar_that_returns_u32()
5183 /// This routine checks if the return expression in a block would make sense on its own as a
5184 /// statement and the return type has been left as default or has been specified as `()`. If so,
5185 /// it suggests adding a semicolon.
5186 fn suggest_missing_semicolon(
5188 err: &mut DiagnosticBuilder<'_>,
5189 expression: &'tcx hir::Expr<'tcx>,
5193 if expected.is_unit() {
5194 // `BlockTailExpression` only relevant if the tail expr would be
5195 // useful on its own.
5196 match expression.kind {
5198 | ExprKind::MethodCall(..)
5199 | ExprKind::Loop(..)
5200 | ExprKind::Match(..)
5201 | ExprKind::Block(..) => {
5202 err.span_suggestion(
5203 cause_span.shrink_to_hi(),
5204 "try adding a semicolon",
5206 Applicability::MachineApplicable,
5214 /// A possible error is to forget to add a return type that is needed:
5218 /// bar_that_returns_u32()
5222 /// This routine checks if the return type is left as default, the method is not part of an
5223 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5225 fn suggest_missing_return_type(
5227 err: &mut DiagnosticBuilder<'_>,
5228 fn_decl: &hir::FnDecl<'_>,
5233 // Only suggest changing the return type for methods that
5234 // haven't set a return type at all (and aren't `fn main()` or an impl).
5235 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5236 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5237 err.span_suggestion(
5239 "try adding a return type",
5240 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5241 Applicability::MachineApplicable,
5245 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5246 err.span_label(span, "possibly return type missing here?");
5249 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5250 // `fn main()` must return `()`, do not suggest changing return type
5251 err.span_label(span, "expected `()` because of default return type");
5254 // expectation was caused by something else, not the default return
5255 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5256 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5257 // Only point to return type if the expected type is the return type, as if they
5258 // are not, the expectation must have been caused by something else.
5259 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5261 let ty = AstConv::ast_ty_to_ty(self, ty);
5262 debug!("suggest_missing_return_type: return type {:?}", ty);
5263 debug!("suggest_missing_return_type: expected type {:?}", ty);
5264 if ty.kind == expected.kind {
5265 err.span_label(sp, format!("expected `{}` because of return type", expected));
5273 /// A possible error is to forget to add `.await` when using futures:
5276 /// async fn make_u32() -> u32 {
5280 /// fn take_u32(x: u32) {}
5282 /// async fn foo() {
5283 /// let x = make_u32();
5288 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5289 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5290 /// `.await` to the tail of the expression.
5291 fn suggest_missing_await(
5293 err: &mut DiagnosticBuilder<'_>,
5294 expr: &hir::Expr<'_>,
5298 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5299 // body isn't `async`.
5300 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5301 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5302 let body = self.tcx().hir().body(body_id);
5303 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5305 // Check for `Future` implementations by constructing a predicate to
5306 // prove: `<T as Future>::Output == U`
5307 let future_trait = self.tcx.lang_items().future_trait().unwrap();
5308 let item_def_id = self
5310 .associated_items(future_trait)
5311 .in_definition_order()
5316 ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5317 // `<T as Future>::Output`
5318 projection_ty: ty::ProjectionTy {
5320 substs: self.tcx.mk_substs_trait(
5322 self.fresh_substs_for_item(sp, item_def_id),
5329 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5330 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5331 if self.infcx.predicate_may_hold(&obligation) {
5332 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5333 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5334 err.span_suggestion(
5336 "consider using `.await` here",
5337 format!("{}.await", code),
5338 Applicability::MaybeIncorrect,
5341 debug!("suggest_missing_await: no snippet for {:?}", sp);
5344 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5350 /// A common error is to add an extra semicolon:
5353 /// fn foo() -> usize {
5358 /// This routine checks if the final statement in a block is an
5359 /// expression with an explicit semicolon whose type is compatible
5360 /// with `expected_ty`. If so, it suggests removing the semicolon.
5361 fn consider_hint_about_removing_semicolon(
5363 blk: &'tcx hir::Block<'tcx>,
5364 expected_ty: Ty<'tcx>,
5365 err: &mut DiagnosticBuilder<'_>,
5367 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5368 err.span_suggestion(
5370 "consider removing this semicolon",
5372 Applicability::MachineApplicable,
5377 fn could_remove_semicolon(
5379 blk: &'tcx hir::Block<'tcx>,
5380 expected_ty: Ty<'tcx>,
5382 // Be helpful when the user wrote `{... expr;}` and
5383 // taking the `;` off is enough to fix the error.
5384 let last_stmt = blk.stmts.last()?;
5385 let last_expr = match last_stmt.kind {
5386 hir::StmtKind::Semi(ref e) => e,
5389 let last_expr_ty = self.node_ty(last_expr.hir_id);
5390 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5393 let original_span = original_sp(last_stmt.span, blk.span);
5394 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5397 // Instantiates the given path, which must refer to an item with the given
5398 // number of type parameters and type.
5399 pub fn instantiate_value_path(
5401 segments: &[hir::PathSegment<'_>],
5402 self_ty: Option<Ty<'tcx>>,
5406 ) -> (Ty<'tcx>, Res) {
5408 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5409 segments, self_ty, res, hir_id,
5414 let path_segs = match res {
5415 Res::Local(_) | Res::SelfCtor(_) => vec![],
5416 Res::Def(kind, def_id) => {
5417 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5419 _ => bug!("instantiate_value_path on {:?}", res),
5422 let mut user_self_ty = None;
5423 let mut is_alias_variant_ctor = false;
5425 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5426 if let Some(self_ty) = self_ty {
5427 let adt_def = self_ty.ty_adt_def().unwrap();
5428 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5429 is_alias_variant_ctor = true;
5432 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5433 let container = tcx.associated_item(def_id).container;
5434 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5436 ty::TraitContainer(trait_did) => {
5437 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5439 ty::ImplContainer(impl_def_id) => {
5440 if segments.len() == 1 {
5441 // `<T>::assoc` will end up here, and so
5442 // can `T::assoc`. It this came from an
5443 // inherent impl, we need to record the
5444 // `T` for posterity (see `UserSelfTy` for
5446 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5447 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5455 // Now that we have categorized what space the parameters for each
5456 // segment belong to, let's sort out the parameters that the user
5457 // provided (if any) into their appropriate spaces. We'll also report
5458 // errors if type parameters are provided in an inappropriate place.
5460 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5461 let generics_has_err = AstConv::prohibit_generics(
5463 segments.iter().enumerate().filter_map(|(index, seg)| {
5464 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5472 if let Res::Local(hid) = res {
5473 let ty = self.local_ty(span, hid).decl_ty;
5474 let ty = self.normalize_associated_types_in(span, &ty);
5475 self.write_ty(hir_id, ty);
5479 if generics_has_err {
5480 // Don't try to infer type parameters when prohibited generic arguments were given.
5481 user_self_ty = None;
5484 // Now we have to compare the types that the user *actually*
5485 // provided against the types that were *expected*. If the user
5486 // did not provide any types, then we want to substitute inference
5487 // variables. If the user provided some types, we may still need
5488 // to add defaults. If the user provided *too many* types, that's
5491 let mut infer_args_for_err = FxHashSet::default();
5492 for &PathSeg(def_id, index) in &path_segs {
5493 let seg = &segments[index];
5494 let generics = tcx.generics_of(def_id);
5495 // Argument-position `impl Trait` is treated as a normal generic
5496 // parameter internally, but we don't allow users to specify the
5497 // parameter's value explicitly, so we have to do some error-
5499 if let Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }) =
5500 AstConv::check_generic_arg_count_for_call(
5501 tcx, span, &generics, &seg, false, // `is_method_call`
5504 infer_args_for_err.insert(index);
5505 self.set_tainted_by_errors(); // See issue #53251.
5509 let has_self = path_segs
5511 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5514 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5515 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5517 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5518 let variant = adt_def.non_enum_variant();
5519 let ctor_def_id = variant.ctor_def_id.unwrap();
5521 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5526 let mut err = tcx.sess.struct_span_err(
5528 "the `Self` constructor can only be used with tuple or unit structs",
5530 if let Some(adt_def) = ty.ty_adt_def() {
5531 match adt_def.adt_kind() {
5533 err.help("did you mean to use one of the enum's variants?");
5535 AdtKind::Struct | AdtKind::Union => {
5536 err.span_suggestion(
5538 "use curly brackets",
5539 String::from("Self { /* fields */ }"),
5540 Applicability::HasPlaceholders,
5547 return (tcx.types.err, res);
5553 let def_id = res.def_id();
5555 // The things we are substituting into the type should not contain
5556 // escaping late-bound regions, and nor should the base type scheme.
5557 let ty = tcx.type_of(def_id);
5559 let substs = self_ctor_substs.unwrap_or_else(|| {
5560 AstConv::create_substs_for_generic_args(
5566 infer_args_for_err.is_empty(),
5567 // Provide the generic args, and whether types should be inferred.
5569 if let Some(&PathSeg(_, index)) =
5570 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5572 // If we've encountered an `impl Trait`-related error, we're just
5573 // going to infer the arguments for better error messages.
5574 if !infer_args_for_err.contains(&index) {
5575 // Check whether the user has provided generic arguments.
5576 if let Some(ref data) = segments[index].args {
5577 return (Some(data), segments[index].infer_args);
5580 return (None, segments[index].infer_args);
5585 // Provide substitutions for parameters for which (valid) arguments have been provided.
5586 |param, arg| match (¶m.kind, arg) {
5587 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5588 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5590 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5591 self.to_ty(ty).into()
5593 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5594 self.to_const(&ct.value).into()
5596 _ => unreachable!(),
5598 // Provide substitutions for parameters for which arguments are inferred.
5599 |substs, param, infer_args| {
5601 GenericParamDefKind::Lifetime => {
5602 self.re_infer(Some(param), span).unwrap().into()
5604 GenericParamDefKind::Type { has_default, .. } => {
5605 if !infer_args && has_default {
5606 // If we have a default, then we it doesn't matter that we're not
5607 // inferring the type arguments: we provide the default where any
5609 let default = tcx.type_of(param.def_id);
5612 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5616 // If no type arguments were provided, we have to infer them.
5617 // This case also occurs as a result of some malformed input, e.g.
5618 // a lifetime argument being given instead of a type parameter.
5619 // Using inference instead of `Error` gives better error messages.
5620 self.var_for_def(span, param)
5623 GenericParamDefKind::Const => {
5624 // FIXME(const_generics:defaults)
5625 // No const parameters were provided, we have to infer them.
5626 self.var_for_def(span, param)
5632 assert!(!substs.has_escaping_bound_vars());
5633 assert!(!ty.has_escaping_bound_vars());
5635 // First, store the "user substs" for later.
5636 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5638 self.add_required_obligations(span, def_id, &substs);
5640 // Substitute the values for the type parameters into the type of
5641 // the referenced item.
5642 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5644 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5645 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5646 // is inherent, there is no `Self` parameter; instead, the impl needs
5647 // type parameters, which we can infer by unifying the provided `Self`
5648 // with the substituted impl type.
5649 // This also occurs for an enum variant on a type alias.
5650 let ty = tcx.type_of(impl_def_id);
5652 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5653 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5654 Ok(ok) => self.register_infer_ok_obligations(ok),
5656 self.tcx.sess.delay_span_bug(
5659 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5668 self.check_rustc_args_require_const(def_id, hir_id, span);
5670 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5671 self.write_substs(hir_id, substs);
5673 (ty_substituted, res)
5676 /// Add all the obligations that are required, substituting and normalized appropriately.
5677 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5678 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5680 for (i, mut obligation) in traits::predicates_for_generics(
5681 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5688 // This makes the error point at the bound, but we want to point at the argument
5689 if let Some(span) = spans.get(i) {
5690 obligation.cause.code = traits::BindingObligation(def_id, *span);
5692 self.register_predicate(obligation);
5696 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5697 // We're only interested in functions tagged with
5698 // #[rustc_args_required_const], so ignore anything that's not.
5699 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5703 // If our calling expression is indeed the function itself, we're good!
5704 // If not, generate an error that this can only be called directly.
5705 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5706 if let ExprKind::Call(ref callee, ..) = expr.kind {
5707 if callee.hir_id == hir_id {
5713 self.tcx.sess.span_err(
5715 "this function can only be invoked directly, not through a function pointer",
5719 /// Resolves `typ` by a single level if `typ` is a type variable.
5720 /// If no resolution is possible, then an error is reported.
5721 /// Numeric inference variables may be left unresolved.
5722 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5723 let ty = self.resolve_vars_with_obligations(ty);
5724 if !ty.is_ty_var() {
5727 if !self.is_tainted_by_errors() {
5728 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5729 .note("type must be known at this point")
5732 self.demand_suptype(sp, self.tcx.types.err, ty);
5737 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5740 ctxt: BreakableCtxt<'tcx>,
5742 ) -> (BreakableCtxt<'tcx>, R) {
5745 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5746 index = enclosing_breakables.stack.len();
5747 enclosing_breakables.by_id.insert(id, index);
5748 enclosing_breakables.stack.push(ctxt);
5752 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5753 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5754 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5755 enclosing_breakables.stack.pop().expect("missing breakable context")
5760 /// Instantiate a QueryResponse in a probe context, without a
5761 /// good ObligationCause.
5762 fn probe_instantiate_query_response(
5765 original_values: &OriginalQueryValues<'tcx>,
5766 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5767 ) -> InferResult<'tcx, Ty<'tcx>> {
5768 self.instantiate_query_response_and_region_obligations(
5769 &traits::ObligationCause::misc(span, self.body_id),
5776 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5777 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5778 let mut contained_in_place = false;
5780 while let hir::Node::Expr(parent_expr) =
5781 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5783 match &parent_expr.kind {
5784 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5785 if lhs.hir_id == expr_id {
5786 contained_in_place = true;
5792 expr_id = parent_expr.hir_id;
5799 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5800 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5802 assert_eq!(generics.parent, None);
5804 if generics.own_counts().types == 0 {
5808 let mut params_used = BitSet::new_empty(generics.params.len());
5810 if ty.references_error() {
5811 // If there is already another error, do not emit
5812 // an error for not using a type parameter.
5813 assert!(tcx.sess.has_errors());
5817 for leaf in ty.walk() {
5818 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5819 if let ty::Param(param) = leaf_ty.kind {
5820 debug!("found use of ty param {:?}", param);
5821 params_used.insert(param.index);
5826 for param in &generics.params {
5827 if !params_used.contains(param.index) {
5828 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5829 let span = tcx.def_span(param.def_id);
5834 "type parameter `{}` is unused",
5837 .span_label(span, "unused type parameter")
5844 fn fatally_break_rust(sess: &Session) {
5845 let handler = sess.diagnostic();
5846 handler.span_bug_no_panic(
5848 "It looks like you're trying to break rust; would you like some ICE?",
5850 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5851 handler.note_without_error(
5852 "we would appreciate a joke overview: \
5853 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5855 handler.note_without_error(&format!(
5856 "rustc {} running on {}",
5857 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5858 config::host_triple(),
5862 fn potentially_plural_count(count: usize, word: &str) -> String {
5863 format!("{} {}{}", count, word, pluralize!(count))