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;
157 use crate::TypeAndSubsts;
159 use self::autoderef::Autoderef;
160 use self::callee::DeferredCallResolution;
161 use self::coercion::{CoerceMany, DynamicCoerceMany};
162 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
163 use self::method::{MethodCallee, SelfSource};
164 pub use self::Expectation::*;
165 use self::TupleArgumentsFlag::*;
168 macro_rules! type_error_struct {
169 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
170 if $typ.references_error() {
171 $session.diagnostic().struct_dummy()
173 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
178 /// The type of a local binding, including the revealed type for anon types.
179 #[derive(Copy, Clone, Debug)]
180 pub struct LocalTy<'tcx> {
182 revealed_ty: Ty<'tcx>,
185 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
186 #[derive(Copy, Clone)]
187 struct MaybeInProgressTables<'a, 'tcx> {
188 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
191 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
192 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
193 match self.maybe_tables {
194 Some(tables) => tables.borrow(),
195 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
199 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
200 match self.maybe_tables {
201 Some(tables) => tables.borrow_mut(),
202 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
207 /// Closures defined within the function. For example:
210 /// bar(move|| { ... })
213 /// Here, the function `foo()` and the closure passed to
214 /// `bar()` will each have their own `FnCtxt`, but they will
215 /// share the inherited fields.
216 pub struct Inherited<'a, 'tcx> {
217 infcx: InferCtxt<'a, 'tcx>,
219 tables: MaybeInProgressTables<'a, 'tcx>,
221 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
223 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
225 // Some additional `Sized` obligations badly affect type inference.
226 // These obligations are added in a later stage of typeck.
227 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
229 // When we process a call like `c()` where `c` is a closure type,
230 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
231 // `FnOnce` closure. In that case, we defer full resolution of the
232 // call until upvar inference can kick in and make the
233 // decision. We keep these deferred resolutions grouped by the
234 // def-id of the closure, so that once we decide, we can easily go
235 // back and process them.
236 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
238 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
240 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
242 // Opaque types found in explicit return types and their
243 // associated fresh inference variable. Writeback resolves these
244 // variables to get the concrete type, which can be used to
245 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
246 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
248 /// A map from inference variables created from opaque
249 /// type instantiations (`ty::Infer`) to the actual opaque
250 /// type (`ty::Opaque`). Used during fallback to map unconstrained
251 /// opaque type inference variables to their corresponding
253 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
255 /// Each type parameter has an implicit region bound that
256 /// indicates it must outlive at least the function body (the user
257 /// may specify stronger requirements). This field indicates the
258 /// region of the callee. If it is `None`, then the parameter
259 /// environment is for an item or something where the "callee" is
261 implicit_region_bound: Option<ty::Region<'tcx>>,
263 body_id: Option<hir::BodyId>,
266 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
267 type Target = InferCtxt<'a, 'tcx>;
268 fn deref(&self) -> &Self::Target {
273 /// When type-checking an expression, we propagate downward
274 /// whatever type hint we are able in the form of an `Expectation`.
275 #[derive(Copy, Clone, Debug)]
276 pub enum Expectation<'tcx> {
277 /// We know nothing about what type this expression should have.
280 /// This expression should have the type given (or some subtype).
281 ExpectHasType(Ty<'tcx>),
283 /// This expression will be cast to the `Ty`.
284 ExpectCastableToType(Ty<'tcx>),
286 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
287 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
288 ExpectRvalueLikeUnsized(Ty<'tcx>),
291 impl<'a, 'tcx> Expectation<'tcx> {
292 // Disregard "castable to" expectations because they
293 // can lead us astray. Consider for example `if cond
294 // {22} else {c} as u8` -- if we propagate the
295 // "castable to u8" constraint to 22, it will pick the
296 // type 22u8, which is overly constrained (c might not
297 // be a u8). In effect, the problem is that the
298 // "castable to" expectation is not the tightest thing
299 // we can say, so we want to drop it in this case.
300 // The tightest thing we can say is "must unify with
301 // else branch". Note that in the case of a "has type"
302 // constraint, this limitation does not hold.
304 // If the expected type is just a type variable, then don't use
305 // an expected type. Otherwise, we might write parts of the type
306 // when checking the 'then' block which are incompatible with the
308 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
310 ExpectHasType(ety) => {
311 let ety = fcx.shallow_resolve(ety);
312 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
314 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
319 /// Provides an expectation for an rvalue expression given an *optional*
320 /// hint, which is not required for type safety (the resulting type might
321 /// be checked higher up, as is the case with `&expr` and `box expr`), but
322 /// is useful in determining the concrete type.
324 /// The primary use case is where the expected type is a fat pointer,
325 /// like `&[isize]`. For example, consider the following statement:
327 /// let x: &[isize] = &[1, 2, 3];
329 /// In this case, the expected type for the `&[1, 2, 3]` expression is
330 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
331 /// expectation `ExpectHasType([isize])`, that would be too strong --
332 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
333 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
334 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
335 /// which still is useful, because it informs integer literals and the like.
336 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
337 /// for examples of where this comes up,.
338 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
339 match fcx.tcx.struct_tail_without_normalization(ty).kind {
340 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
341 _ => ExpectHasType(ty),
345 // Resolves `expected` by a single level if it is a variable. If
346 // there is no expected type or resolution is not possible (e.g.,
347 // no constraints yet present), just returns `None`.
348 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
350 NoExpectation => NoExpectation,
351 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
352 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
353 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
357 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
358 match self.resolve(fcx) {
359 NoExpectation => None,
360 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
364 /// It sometimes happens that we want to turn an expectation into
365 /// a **hard constraint** (i.e., something that must be satisfied
366 /// for the program to type-check). `only_has_type` will return
367 /// such a constraint, if it exists.
368 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
369 match self.resolve(fcx) {
370 ExpectHasType(ty) => Some(ty),
371 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
375 /// Like `only_has_type`, but instead of returning `None` if no
376 /// hard constraint exists, creates a fresh type variable.
377 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
378 self.only_has_type(fcx).unwrap_or_else(|| {
379 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
384 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
391 fn maybe_mut_place(m: hir::Mutability) -> Self {
393 hir::Mutability::Mut => Needs::MutPlace,
394 hir::Mutability::Not => Needs::None,
399 #[derive(Copy, Clone)]
400 pub struct UnsafetyState {
402 pub unsafety: hir::Unsafety,
403 pub unsafe_push_count: u32,
408 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
409 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
412 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
413 use hir::BlockCheckMode;
414 match self.unsafety {
415 // If this unsafe, then if the outer function was already marked as
416 // unsafe we shouldn't attribute the unsafe'ness to the block. This
417 // way the block can be warned about instead of ignoring this
418 // extraneous block (functions are never warned about).
419 hir::Unsafety::Unsafe if self.from_fn => *self,
422 let (unsafety, def, count) = match blk.rules {
423 BlockCheckMode::PushUnsafeBlock(..) => {
424 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
426 BlockCheckMode::PopUnsafeBlock(..) => {
427 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
429 BlockCheckMode::UnsafeBlock(..) => {
430 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
432 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
434 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
440 #[derive(Debug, Copy, Clone)]
446 /// Tracks whether executing a node may exit normally (versus
447 /// return/break/panic, which "diverge", leaving dead code in their
448 /// wake). Tracked semi-automatically (through type variables marked
449 /// as diverging), with some manual adjustments for control-flow
450 /// primitives (approximating a CFG).
451 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
453 /// Potentially unknown, some cases converge,
454 /// others require a CFG to determine them.
457 /// Definitely known to diverge and therefore
458 /// not reach the next sibling or its parent.
460 /// The `Span` points to the expression
461 /// that caused us to diverge
462 /// (e.g. `return`, `break`, etc).
464 /// In some cases (e.g. a `match` expression
465 /// where all arms diverge), we may be
466 /// able to provide a more informative
467 /// message to the user.
468 /// If this is `None`, a default message
469 /// will be generated, which is suitable
471 custom_note: Option<&'static str>,
474 /// Same as `Always` but with a reachability
475 /// warning already emitted.
479 // Convenience impls for combining `Diverges`.
481 impl ops::BitAnd for Diverges {
483 fn bitand(self, other: Self) -> Self {
484 cmp::min(self, other)
488 impl ops::BitOr for Diverges {
490 fn bitor(self, other: Self) -> Self {
491 cmp::max(self, other)
495 impl ops::BitAndAssign for Diverges {
496 fn bitand_assign(&mut self, other: Self) {
497 *self = *self & other;
501 impl ops::BitOrAssign for Diverges {
502 fn bitor_assign(&mut self, other: Self) {
503 *self = *self | other;
508 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
509 fn always(span: Span) -> Diverges {
510 Diverges::Always { span, custom_note: None }
513 fn is_always(self) -> bool {
514 // Enum comparison ignores the
515 // contents of fields, so we just
516 // fill them in with garbage here.
517 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
521 pub struct BreakableCtxt<'tcx> {
524 // this is `null` for loops where break with a value is illegal,
525 // such as `while`, `for`, and `while let`
526 coerce: Option<DynamicCoerceMany<'tcx>>,
529 pub struct EnclosingBreakables<'tcx> {
530 stack: Vec<BreakableCtxt<'tcx>>,
531 by_id: HirIdMap<usize>,
534 impl<'tcx> EnclosingBreakables<'tcx> {
535 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
536 self.opt_find_breakable(target_id).unwrap_or_else(|| {
537 bug!("could not find enclosing breakable with id {}", target_id);
541 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
542 match self.by_id.get(&target_id) {
543 Some(ix) => Some(&mut self.stack[*ix]),
549 pub struct FnCtxt<'a, 'tcx> {
552 /// The parameter environment used for proving trait obligations
553 /// in this function. This can change when we descend into
554 /// closures (as they bring new things into scope), hence it is
555 /// not part of `Inherited` (as of the time of this writing,
556 /// closures do not yet change the environment, but they will
558 param_env: ty::ParamEnv<'tcx>,
560 /// Number of errors that had been reported when we started
561 /// checking this function. On exit, if we find that *more* errors
562 /// have been reported, we will skip regionck and other work that
563 /// expects the types within the function to be consistent.
564 // FIXME(matthewjasper) This should not exist, and it's not correct
565 // if type checking is run in parallel.
566 err_count_on_creation: usize,
568 /// If `Some`, this stores coercion information for returned
569 /// expressions. If `None`, this is in a context where return is
570 /// inappropriate, such as a const expression.
572 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
573 /// can track all the return expressions and then use them to
574 /// compute a useful coercion from the set, similar to a match
575 /// expression or other branching context. You can use methods
576 /// like `expected_ty` to access the declared return type (if
578 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
580 /// First span of a return site that we find. Used in error messages.
581 ret_coercion_span: RefCell<Option<Span>>,
583 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
585 ps: RefCell<UnsafetyState>,
587 /// Whether the last checked node generates a divergence (e.g.,
588 /// `return` will set this to `Always`). In general, when entering
589 /// an expression or other node in the tree, the initial value
590 /// indicates whether prior parts of the containing expression may
591 /// have diverged. It is then typically set to `Maybe` (and the
592 /// old value remembered) for processing the subparts of the
593 /// current expression. As each subpart is processed, they may set
594 /// the flag to `Always`, etc. Finally, at the end, we take the
595 /// result and "union" it with the original value, so that when we
596 /// return the flag indicates if any subpart of the parent
597 /// expression (up to and including this part) has diverged. So,
598 /// if you read it after evaluating a subexpression `X`, the value
599 /// you get indicates whether any subexpression that was
600 /// evaluating up to and including `X` diverged.
602 /// We currently use this flag only for diagnostic purposes:
604 /// - To warn about unreachable code: if, after processing a
605 /// sub-expression but before we have applied the effects of the
606 /// current node, we see that the flag is set to `Always`, we
607 /// can issue a warning. This corresponds to something like
608 /// `foo(return)`; we warn on the `foo()` expression. (We then
609 /// update the flag to `WarnedAlways` to suppress duplicate
610 /// reports.) Similarly, if we traverse to a fresh statement (or
611 /// tail expression) from a `Always` setting, we will issue a
612 /// warning. This corresponds to something like `{return;
613 /// foo();}` or `{return; 22}`, where we would warn on the
616 /// An expression represents dead code if, after checking it,
617 /// the diverges flag is set to something other than `Maybe`.
618 diverges: Cell<Diverges>,
620 /// Whether any child nodes have any type errors.
621 has_errors: Cell<bool>,
623 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
625 inh: &'a Inherited<'a, 'tcx>,
628 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
629 type Target = Inherited<'a, 'tcx>;
630 fn deref(&self) -> &Self::Target {
635 /// Helper type of a temporary returned by `Inherited::build(...)`.
636 /// Necessary because we can't write the following bound:
637 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
638 pub struct InheritedBuilder<'tcx> {
639 infcx: infer::InferCtxtBuilder<'tcx>,
643 impl Inherited<'_, 'tcx> {
644 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
645 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
648 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_owner),
654 impl<'tcx> InheritedBuilder<'tcx> {
655 fn enter<F, R>(&mut self, f: F) -> R
657 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
659 let def_id = self.def_id;
660 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
664 impl Inherited<'a, 'tcx> {
665 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
667 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
668 let body_id = tcx.hir().maybe_body_owned_by(item_id);
669 let implicit_region_bound = body_id.map(|body_id| {
670 let body = tcx.hir().body(body_id);
671 tcx.mk_region(ty::ReScope(region::Scope {
672 id: body.value.hir_id.local_id,
673 data: region::ScopeData::CallSite,
678 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
680 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
681 locals: RefCell::new(Default::default()),
682 deferred_sized_obligations: RefCell::new(Vec::new()),
683 deferred_call_resolutions: RefCell::new(Default::default()),
684 deferred_cast_checks: RefCell::new(Vec::new()),
685 deferred_generator_interiors: RefCell::new(Vec::new()),
686 opaque_types: RefCell::new(Default::default()),
687 opaque_types_vars: RefCell::new(Default::default()),
688 implicit_region_bound,
693 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
694 debug!("register_predicate({:?})", obligation);
695 if obligation.has_escaping_bound_vars() {
696 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
698 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
701 fn register_predicates<I>(&self, obligations: I)
703 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
705 for obligation in obligations {
706 self.register_predicate(obligation);
710 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
711 self.register_predicates(infer_ok.obligations);
715 fn normalize_associated_types_in<T>(
719 param_env: ty::ParamEnv<'tcx>,
723 T: TypeFoldable<'tcx>,
725 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
726 self.register_infer_ok_obligations(ok)
730 struct CheckItemTypesVisitor<'tcx> {
734 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
735 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
736 check_item_type(self.tcx, i);
738 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
739 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
742 pub fn check_wf_new(tcx: TyCtxt<'_>) {
743 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
744 tcx.hir().krate().par_visit_all_item_likes(&visit);
747 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
748 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
751 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
752 debug_assert!(crate_num == LOCAL_CRATE);
753 tcx.par_body_owners(|body_owner_def_id| {
754 tcx.ensure().typeck_tables_of(body_owner_def_id.to_def_id());
758 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
759 wfcheck::check_item_well_formed(tcx, def_id);
762 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
763 wfcheck::check_trait_item(tcx, def_id);
766 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
767 wfcheck::check_impl_item(tcx, def_id);
770 pub fn provide(providers: &mut Providers<'_>) {
771 method::provide(providers);
772 *providers = Providers {
775 diagnostic_only_typeck_tables_of,
779 check_item_well_formed,
780 check_trait_item_well_formed,
781 check_impl_item_well_formed,
782 check_mod_item_types,
787 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
788 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
791 /// If this `DefId` is a "primary tables entry", returns
792 /// `Some((body_id, header, decl))` with information about
793 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
796 /// If this function returns `Some`, then `typeck_tables(def_id)` will
797 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
798 /// may not succeed. In some cases where this function returns `None`
799 /// (notably closures), `typeck_tables(def_id)` would wind up
800 /// redirecting to the owning function.
804 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
805 match tcx.hir().get(id) {
806 Node::Item(item) => match item.kind {
807 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
808 Some((body, Some(ty), None, None))
810 hir::ItemKind::Fn(ref sig, .., body) => {
811 Some((body, None, Some(&sig.header), Some(&sig.decl)))
815 Node::TraitItem(item) => match item.kind {
816 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
817 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
818 Some((body, None, Some(&sig.header), Some(&sig.decl)))
822 Node::ImplItem(item) => match item.kind {
823 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
824 hir::ImplItemKind::Fn(ref sig, body) => {
825 Some((body, None, Some(&sig.header), Some(&sig.decl)))
829 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
834 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
835 // Closures' tables come from their outermost function,
836 // as they are part of the same "inference environment".
837 let outer_def_id = tcx.closure_base_def_id(def_id);
838 if outer_def_id != def_id {
839 return tcx.has_typeck_tables(outer_def_id);
842 if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
843 primary_body_of(tcx, id).is_some()
849 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
850 &*tcx.typeck_tables_of(def_id).used_trait_imports
853 /// Inspects the substs of opaque types, replacing any inference variables
854 /// with proper generic parameter from the identity substs.
856 /// This is run after we normalize the function signature, to fix any inference
857 /// variables introduced by the projection of associated types. This ensures that
858 /// any opaque types used in the signature continue to refer to generic parameters,
859 /// allowing them to be considered for defining uses in the function body
861 /// For example, consider this code.
866 /// fn use_it(self) -> Self::MyItem
868 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
869 /// type MyItem = impl Iterator<Item = I>;
870 /// fn use_it(self) -> Self::MyItem {
876 /// When we normalize the signature of `use_it` from the impl block,
877 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
878 /// However, this projection result may contain inference variables, due
879 /// to the way that projection works. We didn't have any inference variables
880 /// in the signature to begin with - leaving them in will cause us to incorrectly
881 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
882 /// variables back to the actual generic parameters, we will correctly see that
883 /// we have a defining use of `MyItem`
884 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
886 T: TypeFoldable<'tcx>,
888 struct FixupFolder<'tcx> {
892 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
893 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
897 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
899 ty::Opaque(def_id, substs) => {
900 debug!("fixup_opaque_types: found type {:?}", ty);
901 // Here, we replace any inference variables that occur within
902 // the substs of an opaque type. By definition, any type occurring
903 // in the substs has a corresponding generic parameter, which is what
904 // we replace it with.
905 // This replacement is only run on the function signature, so any
906 // inference variables that we come across must be the rust of projection
907 // (there's no other way for a user to get inference variables into
908 // a function signature).
909 if ty.needs_infer() {
910 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
911 let old_param = substs[param.index as usize];
912 match old_param.unpack() {
913 GenericArgKind::Type(old_ty) => {
914 if let ty::Infer(_) = old_ty.kind {
915 // Replace inference type with a generic parameter
916 self.tcx.mk_param_from_def(param)
918 old_param.fold_with(self)
921 GenericArgKind::Const(old_const) => {
922 if let ty::ConstKind::Infer(_) = old_const.val {
923 // This should never happen - we currently do not support
924 // 'const projections', e.g.:
925 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
926 // which should be the only way for us to end up with a const inference
927 // variable after projection. If Rust ever gains support for this kind
928 // of projection, this should *probably* be changed to
929 // `self.tcx.mk_param_from_def(param)`
931 "Found infer const: `{:?}` in opaque type: {:?}",
936 old_param.fold_with(self)
939 GenericArgKind::Lifetime(old_region) => {
940 if let RegionKind::ReVar(_) = old_region {
941 self.tcx.mk_param_from_def(param)
943 old_param.fold_with(self)
948 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
949 debug!("fixup_opaque_types: new type: {:?}", new_ty);
955 _ => ty.super_fold_with(self),
960 debug!("fixup_opaque_types({:?})", val);
961 val.fold_with(&mut FixupFolder { tcx })
964 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &ty::TypeckTables<'tcx> {
965 let fallback = move || tcx.type_of(def_id);
966 typeck_tables_of_with_fallback(tcx, def_id, fallback)
969 /// Used only to get `TypeckTables` for type inference during error recovery.
970 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
971 fn diagnostic_only_typeck_tables_of<'tcx>(
974 ) -> &ty::TypeckTables<'tcx> {
975 assert!(def_id.is_local());
976 let fallback = move || {
977 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id).unwrap());
978 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
981 typeck_tables_of_with_fallback(tcx, def_id, fallback)
984 fn typeck_tables_of_with_fallback<'tcx>(
987 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
988 ) -> &'tcx ty::TypeckTables<'tcx> {
989 // Closures' tables come from their outermost function,
990 // as they are part of the same "inference environment".
991 let outer_def_id = tcx.closure_base_def_id(def_id);
992 if outer_def_id != def_id {
993 return tcx.typeck_tables_of(outer_def_id);
996 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
997 let span = tcx.hir().span(id);
999 // Figure out what primary body this item has.
1000 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
1001 span_bug!(span, "can't type-check body of {:?}", def_id);
1003 let body = tcx.hir().body(body_id);
1005 let tables = Inherited::build(tcx, def_id.expect_local()).enter(|inh| {
1006 let param_env = tcx.param_env(def_id);
1007 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1008 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1009 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1015 &hir::Generics::empty(),
1022 check_abi(tcx, span, fn_sig.abi());
1024 // Compute the fty from point of view of inside the fn.
1025 let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
1026 let fn_sig = inh.normalize_associated_types_in(
1033 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1035 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1038 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1039 let expected_type = body_ty
1040 .and_then(|ty| match ty.kind {
1041 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1044 .unwrap_or_else(fallback);
1045 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1046 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1048 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1049 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1054 // Gather locals in statics (because of block expressions).
1055 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1057 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1059 fcx.write_ty(id, revealed_ty);
1064 // All type checking constraints were added, try to fallback unsolved variables.
1065 fcx.select_obligations_where_possible(false, |_| {});
1066 let mut fallback_has_occurred = false;
1068 // We do fallback in two passes, to try to generate
1069 // better error messages.
1070 // The first time, we do *not* replace opaque types.
1071 for ty in &fcx.unsolved_variables() {
1072 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1074 // We now see if we can make progress. This might
1075 // cause us to unify inference variables for opaque types,
1076 // since we may have unified some other type variables
1077 // during the first phase of fallback.
1078 // This means that we only replace inference variables with their underlying
1079 // opaque types as a last resort.
1081 // In code like this:
1084 // type MyType = impl Copy;
1085 // fn produce() -> MyType { true }
1086 // fn bad_produce() -> MyType { panic!() }
1089 // we want to unify the opaque inference variable in `bad_produce`
1090 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1091 // This will produce a nice error message about conflicting concrete
1092 // types for `MyType`.
1094 // If we had tried to fallback the opaque inference variable to `MyType`,
1095 // we will generate a confusing type-check error that does not explicitly
1096 // refer to opaque types.
1097 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1099 // We now run fallback again, but this time we allow it to replace
1100 // unconstrained opaque type variables, in addition to performing
1101 // other kinds of fallback.
1102 for ty in &fcx.unsolved_variables() {
1103 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1106 // See if we can make any more progress.
1107 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1109 // Even though coercion casts provide type hints, we check casts after fallback for
1110 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1113 // Closure and generator analysis may run after fallback
1114 // because they don't constrain other type variables.
1115 fcx.closure_analyze(body);
1116 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1117 fcx.resolve_generator_interiors(def_id);
1119 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1120 let ty = fcx.normalize_ty(span, ty);
1121 fcx.require_type_is_sized(ty, span, code);
1124 fcx.select_all_obligations_or_error();
1126 if fn_decl.is_some() {
1127 fcx.regionck_fn(id, body);
1129 fcx.regionck_expr(body);
1132 fcx.resolve_type_vars_in_body(body)
1135 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1136 // it will need to hold.
1137 assert_eq!(tables.hir_owner, Some(id.owner));
1142 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1143 if !tcx.sess.target.target.is_abi_supported(abi) {
1148 "The ABI `{}` is not supported for the current target",
1155 struct GatherLocalsVisitor<'a, 'tcx> {
1156 fcx: &'a FnCtxt<'a, 'tcx>,
1157 parent_id: hir::HirId,
1160 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1161 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1164 // Infer the variable's type.
1165 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1166 kind: TypeVariableOriginKind::TypeInference,
1172 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1176 // Take type that the user specified.
1177 self.fcx.locals.borrow_mut().insert(nid, typ);
1184 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1185 type Map = intravisit::ErasedMap<'tcx>;
1187 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1188 NestedVisitorMap::None
1191 // Add explicitly-declared locals.
1192 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1193 let local_ty = match local.ty {
1195 let o_ty = self.fcx.to_ty(&ty);
1197 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1198 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1207 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1209 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1210 ty.hir_id, o_ty, revealed_ty, c_ty
1212 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1214 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1218 self.assign(local.span, local.hir_id, local_ty);
1221 "local variable {:?} is assigned type {}",
1223 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1225 intravisit::walk_local(self, local);
1228 // Add pattern bindings.
1229 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1230 if let PatKind::Binding(_, _, ident, _) = p.kind {
1231 let var_ty = self.assign(p.span, p.hir_id, None);
1233 if !self.fcx.tcx.features().unsized_locals {
1234 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1238 "pattern binding {} is assigned to {} with type {:?}",
1240 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1244 intravisit::walk_pat(self, p);
1247 // Don't descend into the bodies of nested closures.
1250 _: intravisit::FnKind<'tcx>,
1251 _: &'tcx hir::FnDecl<'tcx>,
1259 /// When `check_fn` is invoked on a generator (i.e., a body that
1260 /// includes yield), it returns back some information about the yield
1262 struct GeneratorTypes<'tcx> {
1263 /// Type of generator argument / values returned by `yield`.
1264 resume_ty: Ty<'tcx>,
1266 /// Type of value that is yielded.
1269 /// Types that are captured (see `GeneratorInterior` for more).
1272 /// Indicates if the generator is movable or static (immovable).
1273 movability: hir::Movability,
1276 /// Helper used for fns and closures. Does the grungy work of checking a function
1277 /// body and returns the function context used for that purpose, since in the case of a fn item
1278 /// there is still a bit more to do.
1281 /// * inherited: other fields inherited from the enclosing fn (if any)
1282 fn check_fn<'a, 'tcx>(
1283 inherited: &'a Inherited<'a, 'tcx>,
1284 param_env: ty::ParamEnv<'tcx>,
1285 fn_sig: ty::FnSig<'tcx>,
1286 decl: &'tcx hir::FnDecl<'tcx>,
1288 body: &'tcx hir::Body<'tcx>,
1289 can_be_generator: Option<hir::Movability>,
1290 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1291 let mut fn_sig = fn_sig;
1293 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1295 // Create the function context. This is either derived from scratch or,
1296 // in the case of closures, based on the outer context.
1297 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1298 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1301 let sess = tcx.sess;
1302 let hir = tcx.hir();
1304 let declared_ret_ty = fn_sig.output();
1305 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1306 let revealed_ret_ty =
1307 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1308 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1309 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1310 fn_sig = tcx.mk_fn_sig(
1311 fn_sig.inputs().iter().cloned(),
1318 let span = body.value.span;
1320 fn_maybe_err(tcx, span, fn_sig.abi);
1322 if body.generator_kind.is_some() && can_be_generator.is_some() {
1324 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1325 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1327 // Resume type defaults to `()` if the generator has no argument.
1328 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1330 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1333 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
1334 let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap();
1335 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1337 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1338 // (as it's created inside the body itself, not passed in from outside).
1339 let maybe_va_list = if fn_sig.c_variadic {
1340 let va_list_did = tcx.require_lang_item(
1341 lang_items::VaListTypeLangItem,
1342 Some(body.params.last().unwrap().span),
1344 let region = tcx.mk_region(ty::ReScope(region::Scope {
1345 id: body.value.hir_id.local_id,
1346 data: region::ScopeData::CallSite,
1349 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1354 // Add formal parameters.
1355 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1356 let inputs_fn = fn_sig.inputs().iter().copied();
1357 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1358 // Check the pattern.
1359 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1361 // Check that argument is Sized.
1362 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1363 // for simple cases like `fn foo(x: Trait)`,
1364 // where we would error once on the parameter as a whole, and once on the binding `x`.
1365 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1366 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1369 fcx.write_ty(param.hir_id, param_ty);
1372 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1374 fcx.check_return_expr(&body.value);
1376 // We insert the deferred_generator_interiors entry after visiting the body.
1377 // This ensures that all nested generators appear before the entry of this generator.
1378 // resolve_generator_interiors relies on this property.
1379 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1381 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1382 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1384 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1385 Some(GeneratorTypes {
1389 movability: can_be_generator.unwrap(),
1395 // Finalize the return check by taking the LUB of the return types
1396 // we saw and assigning it to the expected return type. This isn't
1397 // really expected to fail, since the coercions would have failed
1398 // earlier when trying to find a LUB.
1400 // However, the behavior around `!` is sort of complex. In the
1401 // event that the `actual_return_ty` comes back as `!`, that
1402 // indicates that the fn either does not return or "returns" only
1403 // values of type `!`. In this case, if there is an expected
1404 // return type that is *not* `!`, that should be ok. But if the
1405 // return type is being inferred, we want to "fallback" to `!`:
1407 // let x = move || panic!();
1409 // To allow for that, I am creating a type variable with diverging
1410 // fallback. This was deemed ever so slightly better than unifying
1411 // the return value with `!` because it allows for the caller to
1412 // make more assumptions about the return type (e.g., they could do
1414 // let y: Option<u32> = Some(x());
1416 // which would then cause this return type to become `u32`, not
1418 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1419 let mut actual_return_ty = coercion.complete(&fcx);
1420 if actual_return_ty.is_never() {
1421 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1422 kind: TypeVariableOriginKind::DivergingFn,
1426 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1428 // Check that the main return type implements the termination trait.
1429 if let Some(term_id) = tcx.lang_items().termination() {
1430 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1431 let main_id = hir.as_local_hir_id(def_id).unwrap();
1432 if main_id == fn_id {
1433 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1434 let trait_ref = ty::TraitRef::new(term_id, substs);
1435 let return_ty_span = decl.output.span();
1436 let cause = traits::ObligationCause::new(
1439 ObligationCauseCode::MainFunctionType,
1442 inherited.register_predicate(traits::Obligation::new(
1445 trait_ref.without_const().to_predicate(),
1451 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1452 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1453 if panic_impl_did == hir.local_def_id(fn_id) {
1454 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1455 if declared_ret_ty.kind != ty::Never {
1456 sess.span_err(decl.output.span(), "return type should be `!`");
1459 let inputs = fn_sig.inputs();
1460 let span = hir.span(fn_id);
1461 if inputs.len() == 1 {
1462 let arg_is_panic_info = match inputs[0].kind {
1463 ty::Ref(region, ty, mutbl) => match ty.kind {
1464 ty::Adt(ref adt, _) => {
1465 adt.did == panic_info_did
1466 && mutbl == hir::Mutability::Not
1467 && *region != RegionKind::ReStatic
1474 if !arg_is_panic_info {
1475 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1478 if let Node::Item(item) = hir.get(fn_id) {
1479 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1480 if !generics.params.is_empty() {
1481 sess.span_err(span, "should have no type parameters");
1486 let span = sess.source_map().guess_head_span(span);
1487 sess.span_err(span, "function should have one argument");
1490 sess.err("language item required, but not found: `panic_info`");
1495 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1496 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1497 if alloc_error_handler_did == hir.local_def_id(fn_id) {
1498 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1499 if declared_ret_ty.kind != ty::Never {
1500 sess.span_err(decl.output.span(), "return type should be `!`");
1503 let inputs = fn_sig.inputs();
1504 let span = hir.span(fn_id);
1505 if inputs.len() == 1 {
1506 let arg_is_alloc_layout = match inputs[0].kind {
1507 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1511 if !arg_is_alloc_layout {
1512 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1515 if let Node::Item(item) = hir.get(fn_id) {
1516 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1517 if !generics.params.is_empty() {
1520 "`#[alloc_error_handler]` function should have no type \
1527 let span = sess.source_map().guess_head_span(span);
1528 sess.span_err(span, "function should have one argument");
1531 sess.err("language item required, but not found: `alloc_layout`");
1539 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1540 let def_id = tcx.hir().local_def_id(id);
1541 let def = tcx.adt_def(def_id);
1542 def.destructor(tcx); // force the destructor to be evaluated
1543 check_representable(tcx, span, def_id);
1545 if def.repr.simd() {
1546 check_simd(tcx, span, def_id);
1549 check_transparent(tcx, span, def_id);
1550 check_packed(tcx, span, def_id);
1553 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1554 let def_id = tcx.hir().local_def_id(id);
1555 let def = tcx.adt_def(def_id);
1556 def.destructor(tcx); // force the destructor to be evaluated
1557 check_representable(tcx, span, def_id);
1558 check_transparent(tcx, span, def_id);
1559 check_union_fields(tcx, span, def_id);
1560 check_packed(tcx, span, def_id);
1563 /// When the `#![feature(untagged_unions)]` gate is active,
1564 /// check that the fields of the `union` does not contain fields that need dropping.
1565 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1566 let item_type = tcx.type_of(item_def_id);
1567 if let ty::Adt(def, substs) = item_type.kind {
1568 assert!(def.is_union());
1569 let fields = &def.non_enum_variant().fields;
1570 let param_env = tcx.param_env(item_def_id);
1571 for field in fields {
1572 let field_ty = field.ty(tcx, substs);
1573 // We are currently checking the type this field came from, so it must be local.
1574 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1575 if field_ty.needs_drop(tcx, param_env) {
1580 "unions may not contain fields that need dropping"
1582 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1588 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1593 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1594 /// projections that would result in "inheriting lifetimes".
1595 fn check_opaque<'tcx>(
1598 substs: SubstsRef<'tcx>,
1600 origin: &hir::OpaqueTyOrigin,
1602 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1603 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1606 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1607 /// in "inheriting lifetimes".
1608 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span: Span) {
1610 tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1612 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1617 struct ProhibitOpaqueVisitor<'tcx> {
1618 opaque_identity_ty: Ty<'tcx>,
1619 generics: &'tcx ty::Generics,
1622 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1623 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1624 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1625 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1628 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1629 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1630 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1631 return *index < self.generics.parent_count as u32;
1634 r.super_visit_with(self)
1638 let prohibit_opaque = match item.kind {
1639 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. })
1640 | ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1641 let mut visitor = ProhibitOpaqueVisitor {
1642 opaque_identity_ty: tcx
1643 .mk_opaque(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1644 generics: tcx.generics_of(def_id),
1646 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1648 tcx.predicates_of(def_id)
1651 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1656 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1657 if prohibit_opaque {
1658 let is_async = match item.kind {
1659 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1660 hir::OpaqueTyOrigin::AsyncFn => true,
1663 _ => unreachable!(),
1669 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1671 if is_async { "async fn" } else { "impl Trait" },
1677 /// Checks that an opaque type does not contain cycles.
1678 fn check_opaque_for_cycles<'tcx>(
1681 substs: SubstsRef<'tcx>,
1683 origin: &hir::OpaqueTyOrigin,
1685 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1686 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1687 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1688 .span_label(span, "recursive `async fn`")
1689 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1693 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1694 err.span_label(span, "expands to a recursive type");
1695 if let ty::Opaque(..) = partially_expanded_type.kind {
1696 err.note("type resolves to itself");
1698 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1705 // Forbid defining intrinsics in Rust code,
1706 // as they must always be defined by the compiler.
1707 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1708 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1709 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1713 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1715 "check_item_type(it.hir_id={}, it.name={})",
1717 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1719 let _indenter = indenter();
1721 // Consts can play a role in type-checking, so they are included here.
1722 hir::ItemKind::Static(..) => {
1723 let def_id = tcx.hir().local_def_id(it.hir_id);
1724 tcx.typeck_tables_of(def_id);
1725 maybe_check_static_with_link_section(tcx, def_id, it.span);
1727 hir::ItemKind::Const(..) => {
1728 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1730 hir::ItemKind::Enum(ref enum_definition, _) => {
1731 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1733 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1734 hir::ItemKind::Impl { ref items, .. } => {
1735 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1736 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1737 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1738 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1739 let trait_def_id = impl_trait_ref.def_id;
1740 check_on_unimplemented(tcx, trait_def_id, it);
1743 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1744 let def_id = tcx.hir().local_def_id(it.hir_id);
1745 check_on_unimplemented(tcx, def_id, it);
1747 for item in items.iter() {
1748 let item = tcx.hir().trait_item(item.id);
1749 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1750 let abi = sig.header.abi;
1751 fn_maybe_err(tcx, item.ident.span, abi);
1755 hir::ItemKind::Struct(..) => {
1756 check_struct(tcx, it.hir_id, it.span);
1758 hir::ItemKind::Union(..) => {
1759 check_union(tcx, it.hir_id, it.span);
1761 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1762 let def_id = tcx.hir().local_def_id(it.hir_id);
1764 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1765 check_opaque(tcx, def_id, substs, it.span, &origin);
1767 hir::ItemKind::TyAlias(..) => {
1768 let def_id = tcx.hir().local_def_id(it.hir_id);
1769 let pty_ty = tcx.type_of(def_id);
1770 let generics = tcx.generics_of(def_id);
1771 check_type_params_are_used(tcx, &generics, pty_ty);
1773 hir::ItemKind::ForeignMod(ref m) => {
1774 check_abi(tcx, it.span, m.abi);
1776 if m.abi == Abi::RustIntrinsic {
1777 for item in m.items {
1778 intrinsic::check_intrinsic_type(tcx, item);
1780 } else if m.abi == Abi::PlatformIntrinsic {
1781 for item in m.items {
1782 intrinsic::check_platform_intrinsic_type(tcx, item);
1785 for item in m.items {
1786 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1787 let own_counts = generics.own_counts();
1788 if generics.params.len() - own_counts.lifetimes != 0 {
1789 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1790 (_, 0) => ("type", "types", Some("u32")),
1791 // We don't specify an example value, because we can't generate
1792 // a valid value for any type.
1793 (0, _) => ("const", "consts", None),
1794 _ => ("type or const", "types or consts", None),
1800 "foreign items may not have {} parameters",
1803 .span_label(item.span, &format!("can't have {} parameters", kinds))
1805 // FIXME: once we start storing spans for type arguments, turn this
1806 // into a suggestion.
1808 "replace the {} parameters with concrete {}{}",
1811 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1817 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1818 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1823 _ => { /* nothing to do */ }
1827 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1828 // Only restricted on wasm32 target for now
1829 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1833 // If `#[link_section]` is missing, then nothing to verify
1834 let attrs = tcx.codegen_fn_attrs(id);
1835 if attrs.link_section.is_none() {
1839 // For the wasm32 target statics with `#[link_section]` are placed into custom
1840 // sections of the final output file, but this isn't link custom sections of
1841 // other executable formats. Namely we can only embed a list of bytes,
1842 // nothing with pointers to anything else or relocations. If any relocation
1843 // show up, reject them here.
1844 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1845 // the consumer's responsibility to ensure all bytes that have been read
1846 // have defined values.
1847 match tcx.const_eval_poly(id) {
1848 Ok(ConstValue::ByRef { alloc, .. }) => {
1849 if alloc.relocations().len() != 0 {
1850 let msg = "statics with a custom `#[link_section]` must be a \
1851 simple list of bytes on the wasm target with no \
1852 extra levels of indirection such as references";
1853 tcx.sess.span_err(span, msg);
1856 Ok(_) => bug!("Matching on non-ByRef static"),
1861 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1862 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1863 // an error would be reported if this fails.
1864 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1867 fn report_forbidden_specialization(
1869 impl_item: &hir::ImplItem<'_>,
1872 let mut err = struct_span_err!(
1876 "`{}` specializes an item from a parent `impl`, but \
1877 that item is not marked `default`",
1880 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1882 match tcx.span_of_impl(parent_impl) {
1884 err.span_label(span, "parent `impl` is here");
1886 "to specialize, `{}` in the parent `impl` must be marked `default`",
1891 err.note(&format!("parent implementation is in crate `{}`", cname));
1898 fn check_specialization_validity<'tcx>(
1900 trait_def: &ty::TraitDef,
1901 trait_item: &ty::AssocItem,
1903 impl_item: &hir::ImplItem<'_>,
1905 let kind = match impl_item.kind {
1906 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1907 hir::ImplItemKind::Fn(..) => ty::AssocKind::Method,
1908 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1909 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1912 let ancestors = match trait_def.ancestors(tcx, impl_id) {
1913 Ok(ancestors) => ancestors,
1916 let mut ancestor_impls = ancestors
1918 .filter_map(|parent| {
1919 if parent.is_from_trait() {
1922 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1927 if ancestor_impls.peek().is_none() {
1928 // No parent, nothing to specialize.
1932 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1934 // Parent impl exists, and contains the parent item we're trying to specialize, but
1935 // doesn't mark it `default`.
1936 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1937 Some(Err(parent_impl.def_id()))
1940 // Parent impl contains item and makes it specializable.
1941 Some(_) => Some(Ok(())),
1943 // Parent impl doesn't mention the item. This means it's inherited from the
1944 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1945 // "defaultness" from the grandparent, else they are final.
1947 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
1950 Some(Err(parent_impl.def_id()))
1956 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
1957 // item. This is allowed, the item isn't actually getting specialized here.
1958 let result = opt_result.unwrap_or(Ok(()));
1960 if let Err(parent_impl) = result {
1961 report_forbidden_specialization(tcx, impl_item, parent_impl);
1965 fn check_impl_items_against_trait<'tcx>(
1967 full_impl_span: Span,
1969 impl_trait_ref: ty::TraitRef<'tcx>,
1970 impl_item_refs: &[hir::ImplItemRef<'_>],
1972 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1974 // If the trait reference itself is erroneous (so the compilation is going
1975 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1976 // isn't populated for such impls.
1977 if impl_trait_ref.references_error() {
1981 // Negative impls are not expected to have any items
1982 match tcx.impl_polarity(impl_id) {
1983 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
1984 ty::ImplPolarity::Negative => {
1985 if let [first_item_ref, ..] = impl_item_refs {
1986 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
1991 "negative impls cannot have any items"
1999 // Locate trait definition and items
2000 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2002 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2004 // Check existing impl methods to see if they are both present in trait
2005 // and compatible with trait signature
2006 for impl_item in impl_items() {
2007 let namespace = impl_item.kind.namespace();
2008 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2009 let ty_trait_item = tcx
2010 .associated_items(impl_trait_ref.def_id)
2011 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2013 // Not compatible, but needed for the error message
2014 tcx.associated_items(impl_trait_ref.def_id)
2015 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2019 // Check that impl definition matches trait definition
2020 if let Some(ty_trait_item) = ty_trait_item {
2021 match impl_item.kind {
2022 hir::ImplItemKind::Const(..) => {
2023 // Find associated const definition.
2024 if ty_trait_item.kind == ty::AssocKind::Const {
2033 let mut err = struct_span_err!(
2037 "item `{}` is an associated const, \
2038 which doesn't match its trait `{}`",
2040 impl_trait_ref.print_only_trait_path()
2042 err.span_label(impl_item.span, "does not match trait");
2043 // We can only get the spans from local trait definition
2044 // Same for E0324 and E0325
2045 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2046 err.span_label(trait_span, "item in trait");
2051 hir::ImplItemKind::Fn(..) => {
2052 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2053 if ty_trait_item.kind == ty::AssocKind::Method {
2054 compare_impl_method(
2063 let mut err = struct_span_err!(
2067 "item `{}` is an associated method, \
2068 which doesn't match its trait `{}`",
2070 impl_trait_ref.print_only_trait_path()
2072 err.span_label(impl_item.span, "does not match trait");
2073 if let Some(trait_span) = opt_trait_span {
2074 err.span_label(trait_span, "item in trait");
2079 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2080 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2081 if ty_trait_item.kind == ty::AssocKind::Type {
2091 let mut err = struct_span_err!(
2095 "item `{}` is an associated type, \
2096 which doesn't match its trait `{}`",
2098 impl_trait_ref.print_only_trait_path()
2100 err.span_label(impl_item.span, "does not match trait");
2101 if let Some(trait_span) = opt_trait_span {
2102 err.span_label(trait_span, "item in trait");
2109 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
2113 // Check for missing items from trait
2114 let mut missing_items = Vec::new();
2115 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) {
2116 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2117 let is_implemented = ancestors
2118 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2119 .map(|node_item| !node_item.defining_node.is_from_trait())
2122 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2123 if !trait_item.defaultness.has_value() {
2124 missing_items.push(*trait_item);
2130 if !missing_items.is_empty() {
2131 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2135 fn missing_items_err(
2138 missing_items: &[ty::AssocItem],
2139 full_impl_span: Span,
2141 let missing_items_msg = missing_items
2143 .map(|trait_item| trait_item.ident.to_string())
2144 .collect::<Vec<_>>()
2147 let mut err = struct_span_err!(
2151 "not all trait items implemented, missing: `{}`",
2154 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2156 // `Span` before impl block closing brace.
2157 let hi = full_impl_span.hi() - BytePos(1);
2158 // Point at the place right before the closing brace of the relevant `impl` to suggest
2159 // adding the associated item at the end of its body.
2160 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2161 // Obtain the level of indentation ending in `sugg_sp`.
2162 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2163 // Make the whitespace that will make the suggestion have the right indentation.
2164 let padding: String = (0..indentation).map(|_| " ").collect();
2166 for trait_item in missing_items {
2167 let snippet = suggestion_signature(&trait_item, tcx);
2168 let code = format!("{}{}\n{}", padding, snippet, padding);
2169 let msg = format!("implement the missing item: `{}`", snippet);
2170 let appl = Applicability::HasPlaceholders;
2171 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2172 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2173 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2175 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2181 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2182 fn bounds_from_generic_predicates(
2184 predicates: ty::GenericPredicates<'_>,
2185 ) -> (String, String) {
2186 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2187 let mut projections = vec![];
2188 for (predicate, _) in predicates.predicates {
2189 debug!("predicate {:?}", predicate);
2191 ty::Predicate::Trait(trait_predicate, _) => {
2192 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2193 let def_id = trait_predicate.skip_binder().def_id();
2194 if Some(def_id) != tcx.lang_items().sized_trait() {
2195 // Type params are `Sized` by default, do not add that restriction to the list
2196 // if it is a positive requirement.
2197 entry.push(trait_predicate.skip_binder().def_id());
2200 ty::Predicate::Projection(projection_pred) => {
2201 projections.push(projection_pred);
2206 let generics = if types.is_empty() {
2213 .filter_map(|t| match t.kind {
2214 ty::Param(_) => Some(t.to_string()),
2215 // Avoid suggesting the following:
2216 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2219 .collect::<Vec<_>>()
2223 let mut where_clauses = vec![];
2224 for (ty, bounds) in types {
2225 for bound in &bounds {
2226 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2229 for projection in &projections {
2230 let p = projection.skip_binder();
2231 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2232 // insert the associated types where they correspond, but for now let's be "lazy" and
2233 // propose this instead of the following valid resugaring:
2234 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2235 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2237 let where_clauses = if where_clauses.is_empty() {
2240 format!(" where {}", where_clauses.join(", "))
2242 (generics, where_clauses)
2245 /// Return placeholder code for the given function.
2246 fn fn_sig_suggestion(
2248 sig: &ty::FnSig<'_>,
2250 predicates: ty::GenericPredicates<'_>,
2256 Some(match ty.kind {
2257 ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
2258 ty::Ref(reg, ref_ty, mutability) => {
2259 let reg = match &format!("{}", reg)[..] {
2260 "'_" | "" => String::new(),
2261 reg => format!("{} ", reg),
2264 ty::Param(param) if param.name == kw::SelfUpper => {
2265 format!("&{}{}self", reg, mutability.prefix_str())
2267 _ => format!("_: {:?}", ty),
2270 _ => format!("_: {:?}", ty),
2273 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2274 .filter_map(|arg| arg)
2275 .collect::<Vec<String>>()
2277 let output = sig.output();
2278 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2280 let unsafety = sig.unsafety.prefix_str();
2281 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2283 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2284 // not be present in the `fn` definition, not will we account for renamed
2285 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2286 // fill in a significant portion of the missing code, and other subsequent
2287 // suggestions can help the user fix the code.
2289 "{}fn {}{}({}){}{} {{ todo!() }}",
2290 unsafety, ident, generics, args, output, where_clauses
2294 /// Return placeholder code for the given associated item.
2295 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2296 /// structured suggestion.
2297 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2299 ty::AssocKind::Method => {
2300 // We skip the binder here because the binder would deanonymize all
2301 // late-bound regions, and we don't want method signatures to show up
2302 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2303 // regions just fine, showing `fn(&MyType)`.
2306 tcx.fn_sig(assoc.def_id).skip_binder(),
2308 tcx.predicates_of(assoc.def_id),
2311 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2312 // FIXME(type_alias_impl_trait): we should print bounds here too.
2313 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2314 ty::AssocKind::Const => {
2315 let ty = tcx.type_of(assoc.def_id);
2316 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2317 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2322 /// Checks whether a type can be represented in memory. In particular, it
2323 /// identifies types that contain themselves without indirection through a
2324 /// pointer, which would mean their size is unbounded.
2325 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
2326 let rty = tcx.type_of(item_def_id);
2328 // Check that it is possible to represent this type. This call identifies
2329 // (1) types that contain themselves and (2) types that contain a different
2330 // recursive type. It is only necessary to throw an error on those that
2331 // contain themselves. For case 2, there must be an inner type that will be
2332 // caught by case 1.
2333 match rty.is_representable(tcx, sp) {
2334 Representability::SelfRecursive(spans) => {
2335 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id);
2337 err.span_label(span, "recursive without indirection");
2342 Representability::Representable | Representability::ContainsRecursive => (),
2347 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2348 let t = tcx.type_of(def_id);
2349 if let ty::Adt(def, substs) = t.kind {
2350 if def.is_struct() {
2351 let fields = &def.non_enum_variant().fields;
2352 if fields.is_empty() {
2353 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2356 let e = fields[0].ty(tcx, substs);
2357 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2358 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2359 .span_label(sp, "SIMD elements must have the same type")
2364 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2365 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2371 "SIMD vector element type should be machine type"
2381 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2382 let repr = tcx.adt_def(def_id).repr;
2384 for attr in tcx.get_attrs(def_id).iter() {
2385 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2386 if let attr::ReprPacked(pack) = r {
2387 if let Some(repr_pack) = repr.pack {
2388 if pack as u64 != repr_pack.bytes() {
2393 "type has conflicting packed representation hints"
2401 if repr.align.is_some() {
2406 "type has conflicting packed and align representation hints"
2410 if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) {
2411 let mut err = struct_span_err!(
2415 "packed type cannot transitively contain a `#[repr(align)]` type"
2418 let hir = tcx.hir();
2419 if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) {
2420 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2422 tcx.def_span(def_spans[0].0),
2423 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2428 if def_spans.len() > 2 {
2429 let mut first = true;
2430 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2431 if let Some(hir_id) = hir.as_local_hir_id(*adt_def) {
2432 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2437 "`{}` contains a field of type `{}`",
2438 tcx.type_of(def_id),
2442 format!("...which contains a field of type `{}`", ident)
2457 fn check_packed_inner(
2460 stack: &mut Vec<DefId>,
2461 ) -> Option<Vec<(DefId, Span)>> {
2462 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2463 if def.is_struct() || def.is_union() {
2464 if def.repr.align.is_some() {
2465 return Some(vec![(def.did, DUMMY_SP)]);
2469 for field in &def.non_enum_variant().fields {
2470 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2471 if !stack.contains(&def.did) {
2472 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2473 defs.push((def.did, field.ident.span));
2486 /// Emit an error when encountering more or less than one variant in a transparent enum.
2487 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2488 let variant_spans: Vec<_> = adt
2491 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2493 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2494 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2495 err.span_label(sp, &msg);
2496 if let [start @ .., end] = &*variant_spans {
2497 for variant_span in start {
2498 err.span_label(*variant_span, "");
2500 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2505 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2507 fn bad_non_zero_sized_fields<'tcx>(
2509 adt: &'tcx ty::AdtDef,
2511 field_spans: impl Iterator<Item = Span>,
2514 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2515 let mut err = struct_span_err!(
2519 "{}transparent {} {}",
2520 if adt.is_enum() { "the variant of a " } else { "" },
2524 err.span_label(sp, &msg);
2525 for sp in field_spans {
2526 err.span_label(sp, "this field is non-zero-sized");
2531 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2532 let adt = tcx.adt_def(def_id);
2533 if !adt.repr.transparent() {
2536 let sp = tcx.sess.source_map().guess_head_span(sp);
2538 if adt.is_union() && !tcx.features().transparent_unions {
2540 &tcx.sess.parse_sess,
2541 sym::transparent_unions,
2543 "transparent unions are unstable",
2548 if adt.variants.len() != 1 {
2549 bad_variant_count(tcx, adt, sp, def_id);
2550 if adt.variants.is_empty() {
2551 // Don't bother checking the fields. No variants (and thus no fields) exist.
2556 // For each field, figure out if it's known to be a ZST and align(1)
2557 let field_infos = adt.all_fields().map(|field| {
2558 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2559 let param_env = tcx.param_env(field.did);
2560 let layout = tcx.layout_of(param_env.and(ty));
2561 // We are currently checking the type this field came from, so it must be local
2562 let span = tcx.hir().span_if_local(field.did).unwrap();
2563 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2564 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2568 let non_zst_fields =
2569 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2570 let non_zst_count = non_zst_fields.clone().count();
2571 if non_zst_count != 1 {
2572 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2574 for (span, zst, align1) in field_infos {
2580 "zero-sized field in transparent {} has alignment larger than 1",
2583 .span_label(span, "has alignment larger than 1")
2589 #[allow(trivial_numeric_casts)]
2590 pub fn check_enum<'tcx>(
2593 vs: &'tcx [hir::Variant<'tcx>],
2596 let def_id = tcx.hir().local_def_id(id);
2597 let def = tcx.adt_def(def_id);
2598 def.destructor(tcx); // force the destructor to be evaluated
2601 let attributes = tcx.get_attrs(def_id);
2602 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2607 "unsupported representation for zero-variant enum"
2609 .span_label(sp, "zero-variant enum")
2614 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2615 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2616 if !tcx.features().repr128 {
2618 &tcx.sess.parse_sess,
2621 "repr with 128-bit type is unstable",
2628 if let Some(ref e) = v.disr_expr {
2629 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2633 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2634 let is_unit = |var: &hir::Variant<'_>| match var.data {
2635 hir::VariantData::Unit(..) => true,
2639 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2640 let has_non_units = vs.iter().any(|var| !is_unit(var));
2641 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2642 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2644 if disr_non_unit || (disr_units && has_non_units) {
2646 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2651 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2652 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2653 // Check for duplicate discriminant values
2654 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2655 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2656 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2657 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2658 let i_span = match variant_i.disr_expr {
2659 Some(ref expr) => tcx.hir().span(expr.hir_id),
2660 None => tcx.hir().span(variant_i_hir_id),
2662 let span = match v.disr_expr {
2663 Some(ref expr) => tcx.hir().span(expr.hir_id),
2670 "discriminant value `{}` already exists",
2673 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2674 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2677 disr_vals.push(discr);
2680 check_representable(tcx, sp, def_id);
2681 check_transparent(tcx, sp, def_id);
2684 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2689 "expected unit struct, unit variant or constant, found {}{}",
2691 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2696 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2697 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2701 fn item_def_id(&self) -> Option<DefId> {
2705 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2706 // FIXME: refactor this into a method
2707 let node = self.tcx.hir().get(self.body_id);
2708 if let Some(fn_like) = FnLikeNode::from_node(node) {
2711 hir::Constness::NotConst
2715 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2717 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2718 let item_id = tcx.hir().ty_param_owner(hir_id);
2719 let item_def_id = tcx.hir().local_def_id(item_id);
2720 let generics = tcx.generics_of(item_def_id);
2721 let index = generics.param_def_id_to_index[&def_id];
2722 ty::GenericPredicates {
2724 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2725 |&predicate| match predicate {
2726 ty::Predicate::Trait(ref data, _)
2727 if data.skip_binder().self_ty().is_param(index) =>
2729 // HACK(eddyb) should get the original `Span`.
2730 let span = tcx.def_span(def_id);
2731 Some((predicate, span))
2739 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2741 Some(def) => infer::EarlyBoundRegion(span, def.name),
2742 None => infer::MiscVariable(span),
2744 Some(self.next_region_var(v))
2747 fn allow_ty_infer(&self) -> bool {
2751 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2752 if let Some(param) = param {
2753 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2758 self.next_ty_var(TypeVariableOrigin {
2759 kind: TypeVariableOriginKind::TypeInference,
2768 param: Option<&ty::GenericParamDef>,
2770 ) -> &'tcx Const<'tcx> {
2771 if let Some(param) = param {
2772 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2777 self.next_const_var(
2779 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2784 fn projected_ty_from_poly_trait_ref(
2788 item_segment: &hir::PathSegment<'_>,
2789 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2791 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2793 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2797 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2806 self.tcx().mk_projection(item_def_id, item_substs)
2809 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2810 if ty.has_escaping_bound_vars() {
2811 ty // FIXME: normalization and escaping regions
2813 self.normalize_associated_types_in(span, &ty)
2817 fn set_tainted_by_errors(&self) {
2818 self.infcx.set_tainted_by_errors()
2821 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2822 self.write_ty(hir_id, ty)
2826 /// Controls whether the arguments are tupled. This is used for the call
2829 /// Tupling means that all call-side arguments are packed into a tuple and
2830 /// passed as a single parameter. For example, if tupling is enabled, this
2833 /// fn f(x: (isize, isize))
2835 /// Can be called as:
2842 #[derive(Clone, Eq, PartialEq)]
2843 enum TupleArgumentsFlag {
2848 /// Controls how we perform fallback for unconstrained
2851 /// Do not fallback type variables to opaque types.
2853 /// Perform all possible kinds of fallback, including
2854 /// turning type variables to opaque types.
2858 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2860 inh: &'a Inherited<'a, 'tcx>,
2861 param_env: ty::ParamEnv<'tcx>,
2862 body_id: hir::HirId,
2863 ) -> FnCtxt<'a, 'tcx> {
2867 err_count_on_creation: inh.tcx.sess.err_count(),
2869 ret_coercion_span: RefCell::new(None),
2870 resume_yield_tys: None,
2871 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2872 diverges: Cell::new(Diverges::Maybe),
2873 has_errors: Cell::new(false),
2874 enclosing_breakables: RefCell::new(EnclosingBreakables {
2876 by_id: Default::default(),
2882 pub fn sess(&self) -> &Session {
2886 pub fn errors_reported_since_creation(&self) -> bool {
2887 self.tcx.sess.err_count() > self.err_count_on_creation
2890 /// Produces warning on the given node, if the current point in the
2891 /// function is unreachable, and there hasn't been another warning.
2892 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2893 // FIXME: Combine these two 'if' expressions into one once
2894 // let chains are implemented
2895 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2896 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2897 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2898 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2899 if !span.is_desugaring(DesugaringKind::CondTemporary)
2900 && !span.is_desugaring(DesugaringKind::Async)
2901 && !orig_span.is_desugaring(DesugaringKind::Await)
2903 self.diverges.set(Diverges::WarnedAlways);
2905 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2907 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
2908 let msg = format!("unreachable {}", kind);
2910 .span_label(span, &msg)
2914 .unwrap_or("any code following this expression is unreachable"),
2922 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2923 ObligationCause::new(span, self.body_id, code)
2926 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2927 self.cause(span, ObligationCauseCode::MiscObligation)
2930 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2931 /// version (resolve_vars_if_possible), this version will
2932 /// also select obligations if it seems useful, in an effort
2933 /// to get more type information.
2934 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2935 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2937 // No Infer()? Nothing needs doing.
2938 if !ty.has_infer_types_or_consts() {
2939 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2943 // If `ty` is a type variable, see whether we already know what it is.
2944 ty = self.resolve_vars_if_possible(&ty);
2945 if !ty.has_infer_types_or_consts() {
2946 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2950 // If not, try resolving pending obligations as much as
2951 // possible. This can help substantially when there are
2952 // indirect dependencies that don't seem worth tracking
2954 self.select_obligations_where_possible(false, |_| {});
2955 ty = self.resolve_vars_if_possible(&ty);
2957 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2961 fn record_deferred_call_resolution(
2963 closure_def_id: DefId,
2964 r: DeferredCallResolution<'tcx>,
2966 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2967 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2970 fn remove_deferred_call_resolutions(
2972 closure_def_id: DefId,
2973 ) -> Vec<DeferredCallResolution<'tcx>> {
2974 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2975 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2978 pub fn tag(&self) -> String {
2979 format!("{:p}", self)
2982 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2983 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
2984 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
2989 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2991 "write_ty({:?}, {:?}) in fcx {}",
2993 self.resolve_vars_if_possible(&ty),
2996 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2998 if ty.references_error() {
2999 self.has_errors.set(true);
3000 self.set_tainted_by_errors();
3004 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3005 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
3008 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3009 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3012 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3013 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3014 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3015 self.write_substs(hir_id, method.substs);
3017 // When the method is confirmed, the `method.substs` includes
3018 // parameters from not just the method, but also the impl of
3019 // the method -- in particular, the `Self` type will be fully
3020 // resolved. However, those are not something that the "user
3021 // specified" -- i.e., those types come from the inferred type
3022 // of the receiver, not something the user wrote. So when we
3023 // create the user-substs, we want to replace those earlier
3024 // types with just the types that the user actually wrote --
3025 // that is, those that appear on the *method itself*.
3027 // As an example, if the user wrote something like
3028 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3029 // type of `foo` (possibly adjusted), but we don't want to
3030 // include that. We want just the `[_, u32]` part.
3031 if !method.substs.is_noop() {
3032 let method_generics = self.tcx.generics_of(method.def_id);
3033 if !method_generics.params.is_empty() {
3034 let user_type_annotation = self.infcx.probe(|_| {
3035 let user_substs = UserSubsts {
3036 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3037 let i = param.index as usize;
3038 if i < method_generics.parent_count {
3039 self.infcx.var_for_def(DUMMY_SP, param)
3044 user_self_ty: None, // not relevant here
3047 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3053 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3054 self.write_user_type_annotation(hir_id, user_type_annotation);
3059 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3060 if !substs.is_noop() {
3061 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3063 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3067 /// Given the substs that we just converted from the HIR, try to
3068 /// canonicalize them and store them as user-given substitutions
3069 /// (i.e., substitutions that must be respected by the NLL check).
3071 /// This should be invoked **before any unifications have
3072 /// occurred**, so that annotations like `Vec<_>` are preserved
3074 pub fn write_user_type_annotation_from_substs(
3078 substs: SubstsRef<'tcx>,
3079 user_self_ty: Option<UserSelfTy<'tcx>>,
3082 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3083 user_self_ty={:?} in fcx {}",
3091 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3092 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3094 UserSubsts { substs, user_self_ty },
3096 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3097 self.write_user_type_annotation(hir_id, canonicalized);
3101 pub fn write_user_type_annotation(
3104 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3107 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3109 canonical_user_type_annotation,
3113 if !canonical_user_type_annotation.is_identity() {
3116 .user_provided_types_mut()
3117 .insert(hir_id, canonical_user_type_annotation);
3119 debug!("write_user_type_annotation: skipping identity substs");
3123 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3124 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3130 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3131 Entry::Vacant(entry) => {
3134 Entry::Occupied(mut entry) => {
3135 debug!(" - composing on top of {:?}", entry.get());
3136 match (&entry.get()[..], &adj[..]) {
3137 // Applying any adjustment on top of a NeverToAny
3138 // is a valid NeverToAny adjustment, because it can't
3140 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3142 Adjustment { kind: Adjust::Deref(_), .. },
3143 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3145 Adjustment { kind: Adjust::Deref(_), .. },
3146 .. // Any following adjustments are allowed.
3148 // A reborrow has no effect before a dereference.
3150 // FIXME: currently we never try to compose autoderefs
3151 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3153 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3154 expr, entry.get(), adj)
3156 *entry.get_mut() = adj;
3161 /// Basically whenever we are converting from a type scheme into
3162 /// the fn body space, we always want to normalize associated
3163 /// types as well. This function combines the two.
3164 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3166 T: TypeFoldable<'tcx>,
3168 let value = value.subst(self.tcx, substs);
3169 let result = self.normalize_associated_types_in(span, &value);
3170 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3174 /// As `instantiate_type_scheme`, but for the bounds found in a
3175 /// generic type scheme.
3176 fn instantiate_bounds(
3180 substs: SubstsRef<'tcx>,
3181 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3182 let bounds = self.tcx.predicates_of(def_id);
3183 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3184 let result = bounds.instantiate(self.tcx, substs);
3185 let result = self.normalize_associated_types_in(span, &result);
3187 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3188 bounds, substs, result, spans,
3193 /// Replaces the opaque types from the given value with type variables,
3194 /// and records the `OpaqueTypeMap` for later use during writeback. See
3195 /// `InferCtxt::instantiate_opaque_types` for more details.
3196 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3198 parent_id: hir::HirId,
3202 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3204 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3205 parent_def_id, value
3208 let (value, opaque_type_map) =
3209 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3217 let mut opaque_types = self.opaque_types.borrow_mut();
3218 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3219 for (ty, decl) in opaque_type_map {
3220 let _ = opaque_types.insert(ty, decl);
3221 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3227 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3229 T: TypeFoldable<'tcx>,
3231 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3234 fn normalize_associated_types_in_as_infer_ok<T>(
3238 ) -> InferOk<'tcx, T>
3240 T: TypeFoldable<'tcx>,
3242 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3245 pub fn require_type_meets(
3249 code: traits::ObligationCauseCode<'tcx>,
3252 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3255 pub fn require_type_is_sized(
3259 code: traits::ObligationCauseCode<'tcx>,
3261 if !ty.references_error() {
3262 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
3263 self.require_type_meets(ty, span, code, lang_item);
3267 pub fn require_type_is_sized_deferred(
3271 code: traits::ObligationCauseCode<'tcx>,
3273 if !ty.references_error() {
3274 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3278 pub fn register_bound(
3282 cause: traits::ObligationCause<'tcx>,
3284 if !ty.references_error() {
3285 self.fulfillment_cx.borrow_mut().register_bound(
3295 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3296 let t = AstConv::ast_ty_to_ty(self, ast_t);
3297 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3301 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3302 let ty = self.to_ty(ast_ty);
3303 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3305 if Self::can_contain_user_lifetime_bounds(ty) {
3306 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3307 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3308 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3314 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3315 let c = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local();
3316 ty::Const::from_anon_const(self.tcx, c)
3319 // If the type given by the user has free regions, save it for later, since
3320 // NLL would like to enforce those. Also pass in types that involve
3321 // projections, since those can resolve to `'static` bounds (modulo #54940,
3322 // which hopefully will be fixed by the time you see this comment, dear
3323 // reader, although I have my doubts). Also pass in types with inference
3324 // types, because they may be repeated. Other sorts of things are already
3325 // sufficiently enforced with erased regions. =)
3326 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3328 T: TypeFoldable<'tcx>,
3330 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3333 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3334 match self.tables.borrow().node_types().get(id) {
3336 None if self.is_tainted_by_errors() => self.tcx.types.err,
3339 "no type for node {}: {} in fcx {}",
3341 self.tcx.hir().node_to_string(id),
3348 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3349 /// outlive the region `r`.
3350 pub fn register_wf_obligation(
3354 code: traits::ObligationCauseCode<'tcx>,
3356 // WF obligations never themselves fail, so no real need to give a detailed cause:
3357 let cause = traits::ObligationCause::new(span, self.body_id, code);
3358 self.register_predicate(traits::Obligation::new(
3361 ty::Predicate::WellFormed(ty),
3365 /// Registers obligations that all types appearing in `substs` are well-formed.
3366 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3367 for ty in substs.types() {
3368 if !ty.references_error() {
3369 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3374 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3375 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3376 /// trait/region obligations.
3378 /// For example, if there is a function:
3381 /// fn foo<'a,T:'a>(...)
3384 /// and a reference:
3390 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3391 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3392 pub fn add_obligations_for_parameters(
3394 cause: traits::ObligationCause<'tcx>,
3395 predicates: &ty::InstantiatedPredicates<'tcx>,
3397 assert!(!predicates.has_escaping_bound_vars());
3399 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3401 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3402 self.register_predicate(obligation);
3406 // FIXME(arielb1): use this instead of field.ty everywhere
3407 // Only for fields! Returns <none> for methods>
3408 // Indifferent to privacy flags
3412 field: &'tcx ty::FieldDef,
3413 substs: SubstsRef<'tcx>,
3415 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3418 fn check_casts(&self) {
3419 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3420 for cast in deferred_cast_checks.drain(..) {
3425 fn resolve_generator_interiors(&self, def_id: DefId) {
3426 let mut generators = self.deferred_generator_interiors.borrow_mut();
3427 for (body_id, interior, kind) in generators.drain(..) {
3428 self.select_obligations_where_possible(false, |_| {});
3429 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3433 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3435 // - Unconstrained ints are replaced with `i32`.
3437 // - Unconstrained floats are replaced with with `f64`.
3439 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3440 // is enabled. Otherwise, they are replaced with `()`.
3442 // Fallback becomes very dubious if we have encountered type-checking errors.
3443 // In that case, fallback to Error.
3444 // The return value indicates whether fallback has occurred.
3445 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3446 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3447 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3449 assert!(ty.is_ty_infer());
3450 let fallback = match self.type_is_unconstrained_numeric(ty) {
3451 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3452 UnconstrainedInt => self.tcx.types.i32,
3453 UnconstrainedFloat => self.tcx.types.f64,
3454 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3456 // This type variable was created from the instantiation of an opaque
3457 // type. The fact that we're attempting to perform fallback for it
3458 // means that the function neither constrained it to a concrete
3459 // type, nor to the opaque type itself.
3461 // For example, in this code:
3464 // type MyType = impl Copy;
3465 // fn defining_use() -> MyType { true }
3466 // fn other_use() -> MyType { defining_use() }
3469 // `defining_use` will constrain the instantiated inference
3470 // variable to `bool`, while `other_use` will constrain
3471 // the instantiated inference variable to `MyType`.
3473 // When we process opaque types during writeback, we
3474 // will handle cases like `other_use`, and not count
3475 // them as defining usages
3477 // However, we also need to handle cases like this:
3480 // pub type Foo = impl Copy;
3481 // fn produce() -> Option<Foo> {
3486 // In the above snippet, the inference variable created by
3487 // instantiating `Option<Foo>` will be completely unconstrained.
3488 // We treat this as a non-defining use by making the inference
3489 // variable fall back to the opaque type itself.
3490 if let FallbackMode::All = mode {
3491 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3493 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3505 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3506 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3510 fn select_all_obligations_or_error(&self) {
3511 debug!("select_all_obligations_or_error");
3512 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3513 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3517 /// Select as many obligations as we can at present.
3518 fn select_obligations_where_possible(
3520 fallback_has_occurred: bool,
3521 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3523 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3524 if let Err(mut errors) = result {
3525 mutate_fullfillment_errors(&mut errors);
3526 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3530 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3531 /// returns a type of `&T`, but the actual type we assign to the
3532 /// *expression* is `T`. So this function just peels off the return
3533 /// type by one layer to yield `T`.
3534 fn make_overloaded_place_return_type(
3536 method: MethodCallee<'tcx>,
3537 ) -> ty::TypeAndMut<'tcx> {
3538 // extract method return type, which will be &T;
3539 let ret_ty = method.sig.output();
3541 // method returns &T, but the type as visible to user is T, so deref
3542 ret_ty.builtin_deref(true).unwrap()
3547 expr: &hir::Expr<'_>,
3548 base_expr: &'tcx hir::Expr<'tcx>,
3552 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3553 // FIXME(#18741) -- this is almost but not quite the same as the
3554 // autoderef that normal method probing does. They could likely be
3557 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3558 let mut result = None;
3559 while result.is_none() && autoderef.next().is_some() {
3560 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3562 autoderef.finalize(self);
3566 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3567 /// (and otherwise adjust) `base_expr`, looking for a type which either
3568 /// supports builtin indexing or overloaded indexing.
3569 /// This loop implements one step in that search; the autoderef loop
3570 /// is implemented by `lookup_indexing`.
3573 expr: &hir::Expr<'_>,
3574 base_expr: &hir::Expr<'_>,
3575 autoderef: &Autoderef<'a, 'tcx>,
3578 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3579 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3581 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3583 expr, base_expr, adjusted_ty, index_ty
3586 for &unsize in &[false, true] {
3587 let mut self_ty = adjusted_ty;
3589 // We only unsize arrays here.
3590 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3591 self_ty = self.tcx.mk_slice(element_ty);
3597 // If some lookup succeeds, write callee into table and extract index/element
3598 // type from the method signature.
3599 // If some lookup succeeded, install method in table
3600 let input_ty = self.next_ty_var(TypeVariableOrigin {
3601 kind: TypeVariableOriginKind::AutoDeref,
3602 span: base_expr.span,
3604 let method = self.try_overloaded_place_op(
3612 let result = method.map(|ok| {
3613 debug!("try_index_step: success, using overloaded indexing");
3614 let method = self.register_infer_ok_obligations(ok);
3616 let mut adjustments = autoderef.adjust_steps(self, needs);
3617 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3618 let mutbl = match r_mutbl {
3619 hir::Mutability::Not => AutoBorrowMutability::Not,
3620 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3621 // Indexing can be desugared to a method call,
3622 // so maybe we could use two-phase here.
3623 // See the documentation of AllowTwoPhase for why that's
3624 // not the case today.
3625 allow_two_phase_borrow: AllowTwoPhase::No,
3628 adjustments.push(Adjustment {
3629 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3632 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3636 adjustments.push(Adjustment {
3637 kind: Adjust::Pointer(PointerCast::Unsize),
3638 target: method.sig.inputs()[0],
3641 self.apply_adjustments(base_expr, adjustments);
3643 self.write_method_call(expr.hir_id, method);
3644 (input_ty, self.make_overloaded_place_return_type(method).ty)
3646 if result.is_some() {
3654 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3655 let (tr, name) = match (op, is_mut) {
3656 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3657 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3658 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3659 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3661 (tr, ast::Ident::with_dummy_span(name))
3664 fn try_overloaded_place_op(
3668 arg_tys: &[Ty<'tcx>],
3671 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3672 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3674 // Try Mut first, if needed.
3675 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3676 let method = match (needs, mut_tr) {
3677 (Needs::MutPlace, Some(trait_did)) => {
3678 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3683 // Otherwise, fall back to the immutable version.
3684 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3685 match (method, imm_tr) {
3686 (None, Some(trait_did)) => {
3687 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3689 (method, _) => method,
3693 fn check_method_argument_types(
3696 expr: &'tcx hir::Expr<'tcx>,
3697 method: Result<MethodCallee<'tcx>, ()>,
3698 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3699 tuple_arguments: TupleArgumentsFlag,
3700 expected: Expectation<'tcx>,
3702 let has_error = match method {
3703 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3707 let err_inputs = self.err_args(args_no_rcvr.len());
3709 let err_inputs = match tuple_arguments {
3710 DontTupleArguments => err_inputs,
3711 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3714 self.check_argument_types(
3724 return self.tcx.types.err;
3727 let method = method.unwrap();
3728 // HACK(eddyb) ignore self in the definition (see above).
3729 let expected_arg_tys = self.expected_inputs_for_expected_output(
3732 method.sig.output(),
3733 &method.sig.inputs()[1..],
3735 self.check_argument_types(
3738 &method.sig.inputs()[1..],
3739 &expected_arg_tys[..],
3741 method.sig.c_variadic,
3743 self.tcx.hir().span_if_local(method.def_id),
3748 fn self_type_matches_expected_vid(
3750 trait_ref: ty::PolyTraitRef<'tcx>,
3751 expected_vid: ty::TyVid,
3753 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3755 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3756 trait_ref, self_ty, expected_vid
3758 match self_ty.kind {
3759 ty::Infer(ty::TyVar(found_vid)) => {
3760 // FIXME: consider using `sub_root_var` here so we
3761 // can see through subtyping.
3762 let found_vid = self.root_var(found_vid);
3763 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3764 expected_vid == found_vid
3770 fn obligations_for_self_ty<'b>(
3773 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3776 // FIXME: consider using `sub_root_var` here so we
3777 // can see through subtyping.
3778 let ty_var_root = self.root_var(self_ty);
3780 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3783 self.fulfillment_cx.borrow().pending_obligations()
3788 .pending_obligations()
3790 .filter_map(move |obligation| match obligation.predicate {
3791 ty::Predicate::Projection(ref data) => {
3792 Some((data.to_poly_trait_ref(self.tcx), obligation))
3794 ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
3795 ty::Predicate::Subtype(..) => None,
3796 ty::Predicate::RegionOutlives(..) => None,
3797 ty::Predicate::TypeOutlives(..) => None,
3798 ty::Predicate::WellFormed(..) => None,
3799 ty::Predicate::ObjectSafe(..) => None,
3800 ty::Predicate::ConstEvaluatable(..) => None,
3801 // N.B., this predicate is created by breaking down a
3802 // `ClosureType: FnFoo()` predicate, where
3803 // `ClosureType` represents some `Closure`. It can't
3804 // possibly be referring to the current closure,
3805 // because we haven't produced the `Closure` for
3806 // this closure yet; this is exactly why the other
3807 // code is looking for a self type of a unresolved
3808 // inference variable.
3809 ty::Predicate::ClosureKind(..) => None,
3811 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3814 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3815 self.obligations_for_self_ty(self_ty)
3816 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3819 /// Generic function that factors out common logic from function calls,
3820 /// method calls and overloaded operators.
3821 fn check_argument_types(
3824 expr: &'tcx hir::Expr<'tcx>,
3825 fn_inputs: &[Ty<'tcx>],
3826 expected_arg_tys: &[Ty<'tcx>],
3827 args: &'tcx [hir::Expr<'tcx>],
3829 tuple_arguments: TupleArgumentsFlag,
3830 def_span: Option<Span>,
3833 // Grab the argument types, supplying fresh type variables
3834 // if the wrong number of arguments were supplied
3835 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3837 // All the input types from the fn signature must outlive the call
3838 // so as to validate implied bounds.
3839 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3840 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3843 let expected_arg_count = fn_inputs.len();
3845 let param_count_error = |expected_count: usize,
3850 let (span, start_span, args) = match &expr.kind {
3851 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3852 hir::ExprKind::MethodCall(path_segment, span, args) => (
3854 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3857 .and_then(|args| args.args.iter().last())
3858 // Account for `foo.bar::<T>()`.
3860 // Skip the closing `>`.
3863 .next_point(tcx.sess.source_map().next_point(arg.span()))
3866 &args[1..], // Skip the receiver.
3868 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3870 let arg_spans = if args.is_empty() {
3872 // ^^^-- supplied 0 arguments
3874 // expected 2 arguments
3875 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3878 // ^^^ - - - supplied 3 arguments
3880 // expected 2 arguments
3881 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3884 let mut err = tcx.sess.struct_span_err_with_code(
3887 "this function takes {}{} but {} {} supplied",
3888 if c_variadic { "at least " } else { "" },
3889 potentially_plural_count(expected_count, "argument"),
3890 potentially_plural_count(arg_count, "argument"),
3891 if arg_count == 1 { "was" } else { "were" }
3893 DiagnosticId::Error(error_code.to_owned()),
3895 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
3896 for (i, span) in arg_spans.into_iter().enumerate() {
3899 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
3903 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
3904 err.span_label(def_s, "defined here");
3907 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3908 // remove closing `)` from the span
3909 let sugg_span = sugg_span.shrink_to_lo();
3910 err.span_suggestion(
3912 "expected the unit value `()`; create it with empty parentheses",
3914 Applicability::MachineApplicable,
3921 if c_variadic { "at least " } else { "" },
3922 potentially_plural_count(expected_count, "argument")
3929 let mut expected_arg_tys = expected_arg_tys.to_vec();
3931 let formal_tys = if tuple_arguments == TupleArguments {
3932 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3933 match tuple_type.kind {
3934 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3935 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3936 expected_arg_tys = vec![];
3937 self.err_args(args.len())
3939 ty::Tuple(arg_types) => {
3940 expected_arg_tys = match expected_arg_tys.get(0) {
3941 Some(&ty) => match ty.kind {
3942 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3947 arg_types.iter().map(|k| k.expect_ty()).collect()
3954 "cannot use call notation; the first type parameter \
3955 for the function trait is neither a tuple nor unit"
3958 expected_arg_tys = vec![];
3959 self.err_args(args.len())
3962 } else if expected_arg_count == supplied_arg_count {
3964 } else if c_variadic {
3965 if supplied_arg_count >= expected_arg_count {
3968 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3969 expected_arg_tys = vec![];
3970 self.err_args(supplied_arg_count)
3973 // is the missing argument of type `()`?
3974 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3975 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3976 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3977 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3981 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3983 expected_arg_tys = vec![];
3984 self.err_args(supplied_arg_count)
3988 "check_argument_types: formal_tys={:?}",
3989 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
3992 // If there is no expectation, expect formal_tys.
3993 let expected_arg_tys =
3994 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
3996 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
3998 // Check the arguments.
3999 // We do this in a pretty awful way: first we type-check any arguments
4000 // that are not closures, then we type-check the closures. This is so
4001 // that we have more information about the types of arguments when we
4002 // type-check the functions. This isn't really the right way to do this.
4003 for &check_closures in &[false, true] {
4004 debug!("check_closures={}", check_closures);
4006 // More awful hacks: before we check argument types, try to do
4007 // an "opportunistic" vtable resolution of any trait bounds on
4008 // the call. This helps coercions.
4010 self.select_obligations_where_possible(false, |errors| {
4011 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4012 self.point_at_arg_instead_of_call_if_possible(
4014 &final_arg_types[..],
4021 // For C-variadic functions, we don't have a declared type for all of
4022 // the arguments hence we only do our usual type checking with
4023 // the arguments who's types we do know.
4024 let t = if c_variadic {
4026 } else if tuple_arguments == TupleArguments {
4031 for (i, arg) in args.iter().take(t).enumerate() {
4032 // Warn only for the first loop (the "no closures" one).
4033 // Closure arguments themselves can't be diverging, but
4034 // a previous argument can, e.g., `foo(panic!(), || {})`.
4035 if !check_closures {
4036 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4039 let is_closure = match arg.kind {
4040 ExprKind::Closure(..) => true,
4044 if is_closure != check_closures {
4048 debug!("checking the argument");
4049 let formal_ty = formal_tys[i];
4051 // The special-cased logic below has three functions:
4052 // 1. Provide as good of an expected type as possible.
4053 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4055 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4057 // 2. Coerce to the most detailed type that could be coerced
4058 // to, which is `expected_ty` if `rvalue_hint` returns an
4059 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4060 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4061 // We're processing function arguments so we definitely want to use
4062 // two-phase borrows.
4063 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4064 final_arg_types.push((i, checked_ty, coerce_ty));
4066 // 3. Relate the expected type and the formal one,
4067 // if the expected type was used for the coercion.
4068 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4072 // We also need to make sure we at least write the ty of the other
4073 // arguments which we skipped above.
4075 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4076 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4077 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4080 for arg in args.iter().skip(expected_arg_count) {
4081 let arg_ty = self.check_expr(&arg);
4083 // There are a few types which get autopromoted when passed via varargs
4084 // in C but we just error out instead and require explicit casts.
4085 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4087 ty::Float(ast::FloatTy::F32) => {
4088 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4090 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
4091 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4093 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
4094 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4097 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4098 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4099 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4107 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4108 vec![self.tcx.types.err; len]
4111 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4112 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4113 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4114 /// can be not easily comparable with predicate type (because of coercion). If the types match
4115 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4116 /// the corresponding argument's expression span instead of the `fn` call path span.
4117 fn point_at_arg_instead_of_call_if_possible(
4119 errors: &mut Vec<traits::FulfillmentError<'_>>,
4120 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4122 args: &'tcx [hir::Expr<'tcx>],
4124 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4125 // the `?` operator.
4126 if call_sp.desugaring_kind().is_some() {
4130 for error in errors {
4131 // Only if the cause is somewhere inside the expression we want try to point at arg.
4132 // Otherwise, it means that the cause is somewhere else and we should not change
4133 // anything because we can break the correct span.
4134 if !call_sp.contains(error.obligation.cause.span) {
4138 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4139 // Collect the argument position for all arguments that could have caused this
4140 // `FulfillmentError`.
4141 let mut referenced_in = final_arg_types
4143 .map(|&(i, checked_ty, _)| (i, checked_ty))
4144 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4145 .flat_map(|(i, ty)| {
4146 let ty = self.resolve_vars_if_possible(&ty);
4147 // We walk the argument type because the argument's type could have
4148 // been `Option<T>`, but the `FulfillmentError` references `T`.
4149 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4155 .collect::<Vec<_>>();
4157 // Both checked and coerced types could have matched, thus we need to remove
4159 referenced_in.sort();
4160 referenced_in.dedup();
4162 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4163 // We make sure that only *one* argument matches the obligation failure
4164 // and we assign the obligation's span to its expression's.
4165 error.obligation.cause.span = args[ref_in].span;
4166 error.points_at_arg_span = true;
4172 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4173 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4174 /// were caused by them. If they were, we point at the corresponding type argument's span
4175 /// instead of the `fn` call path span.
4176 fn point_at_type_arg_instead_of_call_if_possible(
4178 errors: &mut Vec<traits::FulfillmentError<'_>>,
4179 call_expr: &'tcx hir::Expr<'tcx>,
4181 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4182 if let hir::ExprKind::Path(qpath) = &path.kind {
4183 if let hir::QPath::Resolved(_, path) = &qpath {
4184 for error in errors {
4185 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4186 // If any of the type arguments in this path segment caused the
4187 // `FullfillmentError`, point at its span (#61860).
4191 .filter_map(|seg| seg.args.as_ref())
4192 .flat_map(|a| a.args.iter())
4194 if let hir::GenericArg::Type(hir_ty) = &arg {
4195 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4198 // Avoid ICE with associated types. As this is best
4199 // effort only, it's ok to ignore the case. It
4200 // would trigger in `is_send::<T::AssocType>();`
4201 // from `typeck-default-trait-impl-assoc-type.rs`.
4203 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4204 let ty = self.resolve_vars_if_possible(&ty);
4205 if ty == predicate.skip_binder().self_ty() {
4206 error.obligation.cause.span = hir_ty.span;
4218 // AST fragment checking
4219 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4223 ast::LitKind::Str(..) => tcx.mk_static_str(),
4224 ast::LitKind::ByteStr(ref v) => {
4225 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4227 ast::LitKind::Byte(_) => tcx.types.u8,
4228 ast::LitKind::Char(_) => tcx.types.char,
4229 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4230 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4231 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4232 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4233 ty::Int(_) | ty::Uint(_) => Some(ty),
4234 ty::Char => Some(tcx.types.u8),
4235 ty::RawPtr(..) => Some(tcx.types.usize),
4236 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4239 opt_ty.unwrap_or_else(|| self.next_int_var())
4241 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4242 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4243 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4244 ty::Float(_) => Some(ty),
4247 opt_ty.unwrap_or_else(|| self.next_float_var())
4249 ast::LitKind::Bool(_) => tcx.types.bool,
4250 ast::LitKind::Err(_) => tcx.types.err,
4254 // Determine the `Self` type, using fresh variables for all variables
4255 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
4256 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
4258 pub fn impl_self_ty(
4260 span: Span, // (potential) receiver for this impl
4262 ) -> TypeAndSubsts<'tcx> {
4263 let ity = self.tcx.type_of(did);
4264 debug!("impl_self_ty: ity={:?}", ity);
4266 let substs = self.fresh_substs_for_item(span, did);
4267 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
4269 TypeAndSubsts { substs, ty: substd_ty }
4272 /// Unifies the output type with the expected type early, for more coercions
4273 /// and forward type information on the input expressions.
4274 fn expected_inputs_for_expected_output(
4277 expected_ret: Expectation<'tcx>,
4278 formal_ret: Ty<'tcx>,
4279 formal_args: &[Ty<'tcx>],
4280 ) -> Vec<Ty<'tcx>> {
4281 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4282 let ret_ty = match expected_ret.only_has_type(self) {
4284 None => return Vec::new(),
4286 let expect_args = self
4287 .fudge_inference_if_ok(|| {
4288 // Attempt to apply a subtyping relationship between the formal
4289 // return type (likely containing type variables if the function
4290 // is polymorphic) and the expected return type.
4291 // No argument expectations are produced if unification fails.
4292 let origin = self.misc(call_span);
4293 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4295 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4296 // to identity so the resulting type is not constrained.
4299 // Process any obligations locally as much as
4300 // we can. We don't care if some things turn
4301 // out unconstrained or ambiguous, as we're
4302 // just trying to get hints here.
4303 self.save_and_restore_in_snapshot_flag(|_| {
4304 let mut fulfill = TraitEngine::new(self.tcx);
4305 for obligation in ok.obligations {
4306 fulfill.register_predicate_obligation(self, obligation);
4308 fulfill.select_where_possible(self)
4312 Err(_) => return Err(()),
4315 // Record all the argument types, with the substitutions
4316 // produced from the above subtyping unification.
4317 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4319 .unwrap_or_default();
4321 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4322 formal_args, formal_ret, expect_args, expected_ret
4327 pub fn check_struct_path(
4331 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4332 let path_span = match *qpath {
4333 QPath::Resolved(_, ref path) => path.span,
4334 QPath::TypeRelative(ref qself, _) => qself.span,
4336 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4337 let variant = match def {
4339 self.set_tainted_by_errors();
4342 Res::Def(DefKind::Variant, _) => match ty.kind {
4343 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4344 _ => bug!("unexpected type: {:?}", ty),
4346 Res::Def(DefKind::Struct, _)
4347 | Res::Def(DefKind::Union, _)
4348 | Res::Def(DefKind::TyAlias, _)
4349 | Res::Def(DefKind::AssocTy, _)
4350 | Res::SelfTy(..) => match ty.kind {
4351 ty::Adt(adt, substs) if !adt.is_enum() => {
4352 Some((adt.non_enum_variant(), adt.did, substs))
4356 _ => bug!("unexpected definition: {:?}", def),
4359 if let Some((variant, did, substs)) = variant {
4360 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4361 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4363 // Check bounds on type arguments used in the path.
4364 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4366 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4367 self.add_obligations_for_parameters(cause, &bounds);
4375 "expected struct, variant or union type, found {}",
4376 ty.sort_string(self.tcx)
4378 .span_label(path_span, "not a struct")
4384 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4385 // The newly resolved definition is written into `type_dependent_defs`.
4386 fn finish_resolving_struct_path(
4391 ) -> (Res, Ty<'tcx>) {
4393 QPath::Resolved(ref maybe_qself, ref path) => {
4394 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4395 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4398 QPath::TypeRelative(ref qself, ref segment) => {
4399 let ty = self.to_ty(qself);
4401 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4407 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4408 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4409 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4411 // Write back the new resolution.
4412 self.write_resolution(hir_id, result);
4414 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4419 /// Resolves an associated value path into a base type and associated constant, or method
4420 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4421 pub fn resolve_ty_and_res_ufcs<'b>(
4423 qpath: &'b QPath<'b>,
4426 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4427 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4428 let (ty, qself, item_segment) = match *qpath {
4429 QPath::Resolved(ref opt_qself, ref path) => {
4432 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4436 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4438 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4439 // Return directly on cache hit. This is useful to avoid doubly reporting
4440 // errors with default match binding modes. See #44614.
4442 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4443 return (def, Some(ty), slice::from_ref(&**item_segment));
4445 let item_name = item_segment.ident;
4446 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4447 let result = match error {
4448 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4449 _ => Err(ErrorReported),
4451 if item_name.name != kw::Invalid {
4452 self.report_method_error(
4456 SelfSource::QPath(qself),
4460 .map(|mut e| e.emit());
4465 // Write back the new resolution.
4466 self.write_resolution(hir_id, result);
4468 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4470 slice::from_ref(&**item_segment),
4474 pub fn check_decl_initializer(
4476 local: &'tcx hir::Local<'tcx>,
4477 init: &'tcx hir::Expr<'tcx>,
4479 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4480 // for #42640 (default match binding modes).
4483 let ref_bindings = local.pat.contains_explicit_ref_binding();
4485 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4486 if let Some(m) = ref_bindings {
4487 // Somewhat subtle: if we have a `ref` binding in the pattern,
4488 // we want to avoid introducing coercions for the RHS. This is
4489 // both because it helps preserve sanity and, in the case of
4490 // ref mut, for soundness (issue #23116). In particular, in
4491 // the latter case, we need to be clear that the type of the
4492 // referent for the reference that results is *equal to* the
4493 // type of the place it is referencing, and not some
4494 // supertype thereof.
4495 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4496 self.demand_eqtype(init.span, local_ty, init_ty);
4499 self.check_expr_coercable_to_type(init, local_ty)
4503 /// Type check a `let` statement.
4504 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4505 // Determine and write the type which we'll check the pattern against.
4506 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4507 self.write_ty(local.hir_id, ty);
4509 // Type check the initializer.
4510 if let Some(ref init) = local.init {
4511 let init_ty = self.check_decl_initializer(local, &init);
4512 self.overwrite_local_ty_if_err(local, ty, init_ty);
4515 // Does the expected pattern type originate from an expression and what is the span?
4516 let (origin_expr, ty_span) = match (local.ty, local.init) {
4517 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4518 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4519 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4522 // Type check the pattern. Override if necessary to avoid knock-on errors.
4523 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4524 let pat_ty = self.node_ty(local.pat.hir_id);
4525 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4528 fn overwrite_local_ty_if_err(
4530 local: &'tcx hir::Local<'tcx>,
4534 if ty.references_error() {
4535 // Override the types everywhere with `types.err` to avoid knock on errors.
4536 self.write_ty(local.hir_id, ty);
4537 self.write_ty(local.pat.hir_id, ty);
4538 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4539 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4540 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4544 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4545 err.span_suggestion_short(
4546 span.shrink_to_hi(),
4547 "consider using a semicolon here",
4549 Applicability::MachineApplicable,
4553 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4554 // Don't do all the complex logic below for `DeclItem`.
4556 hir::StmtKind::Item(..) => return,
4557 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4560 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4562 // Hide the outer diverging and `has_errors` flags.
4563 let old_diverges = self.diverges.replace(Diverges::Maybe);
4564 let old_has_errors = self.has_errors.replace(false);
4567 hir::StmtKind::Local(ref l) => {
4568 self.check_decl_local(&l);
4571 hir::StmtKind::Item(_) => {}
4572 hir::StmtKind::Expr(ref expr) => {
4573 // Check with expected type of `()`.
4574 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4575 self.suggest_semicolon_at_end(expr.span, err);
4578 hir::StmtKind::Semi(ref expr) => {
4579 self.check_expr(&expr);
4583 // Combine the diverging and `has_error` flags.
4584 self.diverges.set(self.diverges.get() | old_diverges);
4585 self.has_errors.set(self.has_errors.get() | old_has_errors);
4588 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4589 let unit = self.tcx.mk_unit();
4590 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4592 // if the block produces a `!` value, that can always be
4593 // (effectively) coerced to unit.
4595 self.demand_suptype(blk.span, unit, ty);
4599 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4600 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4601 /// when given code like the following:
4603 /// if false { return 0i32; } else { 1u32 }
4604 /// // ^^^^ point at this instead of the whole `if` expression
4606 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4607 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4608 let arm_spans: Vec<Span> = arms
4611 self.in_progress_tables
4612 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4613 .and_then(|arm_ty| {
4614 if arm_ty.is_never() {
4617 Some(match &arm.body.kind {
4618 // Point at the tail expression when possible.
4619 hir::ExprKind::Block(block, _) => {
4620 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4628 if arm_spans.len() == 1 {
4629 return arm_spans[0];
4635 fn check_block_with_expected(
4637 blk: &'tcx hir::Block<'tcx>,
4638 expected: Expectation<'tcx>,
4641 let mut fcx_ps = self.ps.borrow_mut();
4642 let unsafety_state = fcx_ps.recurse(blk);
4643 replace(&mut *fcx_ps, unsafety_state)
4646 // In some cases, blocks have just one exit, but other blocks
4647 // can be targeted by multiple breaks. This can happen both
4648 // with labeled blocks as well as when we desugar
4649 // a `try { ... }` expression.
4653 // 'a: { if true { break 'a Err(()); } Ok(()) }
4655 // Here we would wind up with two coercions, one from
4656 // `Err(())` and the other from the tail expression
4657 // `Ok(())`. If the tail expression is omitted, that's a
4658 // "forced unit" -- unless the block diverges, in which
4659 // case we can ignore the tail expression (e.g., `'a: {
4660 // break 'a 22; }` would not force the type of the block
4662 let tail_expr = blk.expr.as_ref();
4663 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4664 let coerce = if blk.targeted_by_break {
4665 CoerceMany::new(coerce_to_ty)
4667 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4668 Some(e) => slice::from_ref(e),
4671 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4674 let prev_diverges = self.diverges.get();
4675 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4677 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4678 for s in blk.stmts {
4682 // check the tail expression **without** holding the
4683 // `enclosing_breakables` lock below.
4684 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4686 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4687 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4688 let coerce = ctxt.coerce.as_mut().unwrap();
4689 if let Some(tail_expr_ty) = tail_expr_ty {
4690 let tail_expr = tail_expr.unwrap();
4691 let span = self.get_expr_coercion_span(tail_expr);
4692 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4693 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4695 // Subtle: if there is no explicit tail expression,
4696 // that is typically equivalent to a tail expression
4697 // of `()` -- except if the block diverges. In that
4698 // case, there is no value supplied from the tail
4699 // expression (assuming there are no other breaks,
4700 // this implies that the type of the block will be
4703 // #41425 -- label the implicit `()` as being the
4704 // "found type" here, rather than the "expected type".
4705 if !self.diverges.get().is_always() {
4706 // #50009 -- Do not point at the entire fn block span, point at the return type
4707 // span, as it is the cause of the requirement, and
4708 // `consider_hint_about_removing_semicolon` will point at the last expression
4709 // if it were a relevant part of the error. This improves usability in editors
4710 // that highlight errors inline.
4711 let mut sp = blk.span;
4712 let mut fn_span = None;
4713 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4714 let ret_sp = decl.output.span();
4715 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4716 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4717 // output would otherwise be incorrect and even misleading. Make sure
4718 // the span we're aiming at correspond to a `fn` body.
4719 if block_sp == blk.span {
4721 fn_span = Some(ident.span);
4725 coerce.coerce_forced_unit(
4729 if let Some(expected_ty) = expected.only_has_type(self) {
4730 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4732 if let Some(fn_span) = fn_span {
4735 "implicitly returns `()` as its body has no tail or `return` \
4747 // If we can break from the block, then the block's exit is always reachable
4748 // (... as long as the entry is reachable) - regardless of the tail of the block.
4749 self.diverges.set(prev_diverges);
4752 let mut ty = ctxt.coerce.unwrap().complete(self);
4754 if self.has_errors.get() || ty.references_error() {
4755 ty = self.tcx.types.err
4758 self.write_ty(blk.hir_id, ty);
4760 *self.ps.borrow_mut() = prev;
4764 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4765 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4767 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4768 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4769 let body = self.tcx.hir().body(body_id);
4770 if let ExprKind::Block(block, _) = &body.value.kind {
4771 return Some(block.span);
4779 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4780 fn get_parent_fn_decl(
4783 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
4784 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4785 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4788 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4789 fn get_node_fn_decl(
4792 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
4794 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4795 // This is less than ideal, it will not suggest a return type span on any
4796 // method called `main`, regardless of whether it is actually the entry point,
4797 // but it will still present it as the reason for the expected type.
4798 Some((&sig.decl, ident, ident.name != sym::main))
4800 Node::TraitItem(&hir::TraitItem {
4802 kind: hir::TraitItemKind::Fn(ref sig, ..),
4804 }) => Some((&sig.decl, ident, true)),
4805 Node::ImplItem(&hir::ImplItem {
4807 kind: hir::ImplItemKind::Fn(ref sig, ..),
4809 }) => Some((&sig.decl, ident, false)),
4814 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4815 /// suggestion can be made, `None` otherwise.
4816 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4817 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4818 // `while` before reaching it, as block tail returns are not available in them.
4819 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4820 let parent = self.tcx.hir().get(blk_id);
4821 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4825 /// On implicit return expressions with mismatched types, provides the following suggestions:
4827 /// - Points out the method's return type as the reason for the expected type.
4828 /// - Possible missing semicolon.
4829 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4830 pub fn suggest_mismatched_types_on_tail(
4832 err: &mut DiagnosticBuilder<'_>,
4833 expr: &'tcx hir::Expr<'tcx>,
4839 let expr = expr.peel_drop_temps();
4840 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4841 let mut pointing_at_return_type = false;
4842 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4843 pointing_at_return_type =
4844 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4846 pointing_at_return_type
4849 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4850 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4852 /// fn foo(x: usize) -> usize { x }
4853 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4857 err: &mut DiagnosticBuilder<'_>,
4858 expr: &hir::Expr<'_>,
4862 let hir = self.tcx.hir();
4863 let (def_id, sig) = match found.kind {
4864 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4865 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4869 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4870 let sig = self.normalize_associated_types_in(expr.span, &sig);
4871 if self.can_coerce(sig.output(), expected) {
4872 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4873 (String::new(), Applicability::MachineApplicable)
4875 ("...".to_string(), Applicability::HasPlaceholders)
4877 let mut msg = "call this function";
4878 match hir.get_if_local(def_id) {
4879 Some(Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. }))
4880 | Some(Node::ImplItem(hir::ImplItem {
4881 kind: hir::ImplItemKind::Fn(_, body_id),
4884 | Some(Node::TraitItem(hir::TraitItem {
4885 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4888 let body = hir.body(*body_id);
4892 .map(|param| match ¶m.pat.kind {
4893 hir::PatKind::Binding(_, _, ident, None)
4894 if ident.name != kw::SelfLower =>
4898 _ => "_".to_string(),
4900 .collect::<Vec<_>>()
4903 Some(Node::Expr(hir::Expr {
4904 kind: ExprKind::Closure(_, _, body_id, _, _),
4905 span: full_closure_span,
4908 if *full_closure_span == expr.span {
4911 msg = "call this closure";
4912 let body = hir.body(*body_id);
4916 .map(|param| match ¶m.pat.kind {
4917 hir::PatKind::Binding(_, _, ident, None)
4918 if ident.name != kw::SelfLower =>
4922 _ => "_".to_string(),
4924 .collect::<Vec<_>>()
4927 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4928 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4929 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4930 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4931 msg = "instantiate this tuple variant";
4933 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4934 msg = "instantiate this tuple struct";
4939 Some(Node::ForeignItem(hir::ForeignItem {
4940 kind: hir::ForeignItemKind::Fn(_, idents, _),
4946 if ident.name != kw::SelfLower {
4952 .collect::<Vec<_>>()
4955 Some(Node::TraitItem(hir::TraitItem {
4956 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
4962 if ident.name != kw::SelfLower {
4968 .collect::<Vec<_>>()
4973 err.span_suggestion_verbose(
4974 expr.span.shrink_to_hi(),
4975 &format!("use parentheses to {}", msg),
4976 format!("({})", sugg_call),
4984 pub fn suggest_ref_or_into(
4986 err: &mut DiagnosticBuilder<'_>,
4987 expr: &hir::Expr<'_>,
4991 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4992 err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable);
4993 } else if let (ty::FnDef(def_id, ..), true) =
4994 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
4996 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4997 let sp = self.sess().source_map().guess_head_span(sp);
4998 err.span_label(sp, &format!("{} defined here", found));
5000 } else if !self.check_for_cast(err, expr, found, expected) {
5001 let is_struct_pat_shorthand_field =
5002 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5003 let methods = self.get_conversion_methods(expr.span, expected, found);
5004 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5005 let mut suggestions = iter::repeat(&expr_text)
5006 .zip(methods.iter())
5007 .filter_map(|(receiver, method)| {
5008 let method_call = format!(".{}()", method.ident);
5009 if receiver.ends_with(&method_call) {
5010 None // do not suggest code that is already there (#53348)
5012 let method_call_list = [".to_vec()", ".to_string()"];
5013 let sugg = if receiver.ends_with(".clone()")
5014 && method_call_list.contains(&method_call.as_str())
5016 let max_len = receiver.rfind('.').unwrap();
5017 format!("{}{}", &receiver[..max_len], method_call)
5019 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5020 format!("({}){}", receiver, method_call)
5022 format!("{}{}", receiver, method_call)
5025 Some(if is_struct_pat_shorthand_field {
5026 format!("{}: {}", receiver, sugg)
5033 if suggestions.peek().is_some() {
5034 err.span_suggestions(
5036 "try using a conversion method",
5038 Applicability::MaybeIncorrect,
5045 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5046 /// in the heap by calling `Box::new()`.
5047 fn suggest_boxing_when_appropriate(
5049 err: &mut DiagnosticBuilder<'_>,
5050 expr: &hir::Expr<'_>,
5054 if self.tcx.hir().is_const_context(expr.hir_id) {
5055 // Do not suggest `Box::new` in const context.
5058 if !expected.is_box() || found.is_box() {
5061 let boxed_found = self.tcx.mk_box(found);
5062 if let (true, Ok(snippet)) = (
5063 self.can_coerce(boxed_found, expected),
5064 self.sess().source_map().span_to_snippet(expr.span),
5066 err.span_suggestion(
5068 "store this in the heap by calling `Box::new`",
5069 format!("Box::new({})", snippet),
5070 Applicability::MachineApplicable,
5073 "for more on the distinction between the stack and the heap, read \
5074 https://doc.rust-lang.org/book/ch15-01-box.html, \
5075 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5076 https://doc.rust-lang.org/std/boxed/index.html",
5081 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5082 fn suggest_calling_boxed_future_when_appropriate(
5084 err: &mut DiagnosticBuilder<'_>,
5085 expr: &hir::Expr<'_>,
5091 if self.tcx.hir().is_const_context(expr.hir_id) {
5092 // Do not suggest `Box::new` in const context.
5095 let pin_did = self.tcx.lang_items().pin_type();
5096 match expected.kind {
5097 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5098 // This guards the `unwrap` and `mk_box` below.
5099 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5102 let boxed_found = self.tcx.mk_box(found);
5103 let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap();
5104 if let (true, Ok(snippet)) = (
5105 self.can_coerce(new_found, expected),
5106 self.sess().source_map().span_to_snippet(expr.span),
5109 ty::Adt(def, _) if def.is_box() => {
5110 err.help("use `Box::pin`");
5113 err.span_suggestion(
5115 "you need to pin and box this expression",
5116 format!("Box::pin({})", snippet),
5117 Applicability::MachineApplicable,
5127 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5131 /// bar_that_returns_u32()
5135 /// This routine checks if the return expression in a block would make sense on its own as a
5136 /// statement and the return type has been left as default or has been specified as `()`. If so,
5137 /// it suggests adding a semicolon.
5138 fn suggest_missing_semicolon(
5140 err: &mut DiagnosticBuilder<'_>,
5141 expression: &'tcx hir::Expr<'tcx>,
5145 if expected.is_unit() {
5146 // `BlockTailExpression` only relevant if the tail expr would be
5147 // useful on its own.
5148 match expression.kind {
5150 | ExprKind::MethodCall(..)
5151 | ExprKind::Loop(..)
5152 | ExprKind::Match(..)
5153 | ExprKind::Block(..) => {
5154 err.span_suggestion(
5155 cause_span.shrink_to_hi(),
5156 "try adding a semicolon",
5158 Applicability::MachineApplicable,
5166 /// A possible error is to forget to add a return type that is needed:
5170 /// bar_that_returns_u32()
5174 /// This routine checks if the return type is left as default, the method is not part of an
5175 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5177 fn suggest_missing_return_type(
5179 err: &mut DiagnosticBuilder<'_>,
5180 fn_decl: &hir::FnDecl<'_>,
5185 // Only suggest changing the return type for methods that
5186 // haven't set a return type at all (and aren't `fn main()` or an impl).
5187 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5188 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5189 err.span_suggestion(
5191 "try adding a return type",
5192 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5193 Applicability::MachineApplicable,
5197 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5198 err.span_label(span, "possibly return type missing here?");
5201 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5202 // `fn main()` must return `()`, do not suggest changing return type
5203 err.span_label(span, "expected `()` because of default return type");
5206 // expectation was caused by something else, not the default return
5207 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5208 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5209 // Only point to return type if the expected type is the return type, as if they
5210 // are not, the expectation must have been caused by something else.
5211 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5213 let ty = AstConv::ast_ty_to_ty(self, ty);
5214 debug!("suggest_missing_return_type: return type {:?}", ty);
5215 debug!("suggest_missing_return_type: expected type {:?}", ty);
5216 if ty.kind == expected.kind {
5217 err.span_label(sp, format!("expected `{}` because of return type", expected));
5225 /// A possible error is to forget to add `.await` when using futures:
5228 /// async fn make_u32() -> u32 {
5232 /// fn take_u32(x: u32) {}
5234 /// async fn foo() {
5235 /// let x = make_u32();
5240 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5241 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5242 /// `.await` to the tail of the expression.
5243 fn suggest_missing_await(
5245 err: &mut DiagnosticBuilder<'_>,
5246 expr: &hir::Expr<'_>,
5250 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5251 // body isn't `async`.
5252 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5253 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5254 let body = self.tcx().hir().body(body_id);
5255 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5257 // Check for `Future` implementations by constructing a predicate to
5258 // prove: `<T as Future>::Output == U`
5259 let future_trait = self.tcx.lang_items().future_trait().unwrap();
5260 let item_def_id = self
5262 .associated_items(future_trait)
5263 .in_definition_order()
5268 ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5269 // `<T as Future>::Output`
5270 projection_ty: ty::ProjectionTy {
5272 substs: self.tcx.mk_substs_trait(
5274 self.fresh_substs_for_item(sp, item_def_id),
5281 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5282 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5283 if self.infcx.predicate_may_hold(&obligation) {
5284 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5285 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5286 err.span_suggestion(
5288 "consider using `.await` here",
5289 format!("{}.await", code),
5290 Applicability::MaybeIncorrect,
5293 debug!("suggest_missing_await: no snippet for {:?}", sp);
5296 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5302 /// A common error is to add an extra semicolon:
5305 /// fn foo() -> usize {
5310 /// This routine checks if the final statement in a block is an
5311 /// expression with an explicit semicolon whose type is compatible
5312 /// with `expected_ty`. If so, it suggests removing the semicolon.
5313 fn consider_hint_about_removing_semicolon(
5315 blk: &'tcx hir::Block<'tcx>,
5316 expected_ty: Ty<'tcx>,
5317 err: &mut DiagnosticBuilder<'_>,
5319 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5320 err.span_suggestion(
5322 "consider removing this semicolon",
5324 Applicability::MachineApplicable,
5329 fn could_remove_semicolon(
5331 blk: &'tcx hir::Block<'tcx>,
5332 expected_ty: Ty<'tcx>,
5334 // Be helpful when the user wrote `{... expr;}` and
5335 // taking the `;` off is enough to fix the error.
5336 let last_stmt = blk.stmts.last()?;
5337 let last_expr = match last_stmt.kind {
5338 hir::StmtKind::Semi(ref e) => e,
5341 let last_expr_ty = self.node_ty(last_expr.hir_id);
5342 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5345 let original_span = original_sp(last_stmt.span, blk.span);
5346 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5349 // Instantiates the given path, which must refer to an item with the given
5350 // number of type parameters and type.
5351 pub fn instantiate_value_path(
5353 segments: &[hir::PathSegment<'_>],
5354 self_ty: Option<Ty<'tcx>>,
5358 ) -> (Ty<'tcx>, Res) {
5360 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5361 segments, self_ty, res, hir_id,
5366 let path_segs = match res {
5367 Res::Local(_) | Res::SelfCtor(_) => vec![],
5368 Res::Def(kind, def_id) => {
5369 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5371 _ => bug!("instantiate_value_path on {:?}", res),
5374 let mut user_self_ty = None;
5375 let mut is_alias_variant_ctor = false;
5377 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5378 if let Some(self_ty) = self_ty {
5379 let adt_def = self_ty.ty_adt_def().unwrap();
5380 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5381 is_alias_variant_ctor = true;
5384 Res::Def(DefKind::AssocFn, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
5385 let container = tcx.associated_item(def_id).container;
5386 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5388 ty::TraitContainer(trait_did) => {
5389 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5391 ty::ImplContainer(impl_def_id) => {
5392 if segments.len() == 1 {
5393 // `<T>::assoc` will end up here, and so
5394 // can `T::assoc`. It this came from an
5395 // inherent impl, we need to record the
5396 // `T` for posterity (see `UserSelfTy` for
5398 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5399 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5407 // Now that we have categorized what space the parameters for each
5408 // segment belong to, let's sort out the parameters that the user
5409 // provided (if any) into their appropriate spaces. We'll also report
5410 // errors if type parameters are provided in an inappropriate place.
5412 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5413 let generics_has_err = AstConv::prohibit_generics(
5415 segments.iter().enumerate().filter_map(|(index, seg)| {
5416 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5424 if let Res::Local(hid) = res {
5425 let ty = self.local_ty(span, hid).decl_ty;
5426 let ty = self.normalize_associated_types_in(span, &ty);
5427 self.write_ty(hir_id, ty);
5431 if generics_has_err {
5432 // Don't try to infer type parameters when prohibited generic arguments were given.
5433 user_self_ty = None;
5436 // Now we have to compare the types that the user *actually*
5437 // provided against the types that were *expected*. If the user
5438 // did not provide any types, then we want to substitute inference
5439 // variables. If the user provided some types, we may still need
5440 // to add defaults. If the user provided *too many* types, that's
5443 let mut infer_args_for_err = FxHashSet::default();
5444 for &PathSeg(def_id, index) in &path_segs {
5445 let seg = &segments[index];
5446 let generics = tcx.generics_of(def_id);
5447 // Argument-position `impl Trait` is treated as a normal generic
5448 // parameter internally, but we don't allow users to specify the
5449 // parameter's value explicitly, so we have to do some error-
5451 if let Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }) =
5452 AstConv::check_generic_arg_count_for_call(
5453 tcx, span, &generics, &seg, false, // `is_method_call`
5456 infer_args_for_err.insert(index);
5457 self.set_tainted_by_errors(); // See issue #53251.
5461 let has_self = path_segs
5463 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5466 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5467 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5469 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5470 let variant = adt_def.non_enum_variant();
5471 let ctor_def_id = variant.ctor_def_id.unwrap();
5473 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5478 let mut err = tcx.sess.struct_span_err(
5480 "the `Self` constructor can only be used with tuple or unit structs",
5482 if let Some(adt_def) = ty.ty_adt_def() {
5483 match adt_def.adt_kind() {
5485 err.help("did you mean to use one of the enum's variants?");
5487 AdtKind::Struct | AdtKind::Union => {
5488 err.span_suggestion(
5490 "use curly brackets",
5491 String::from("Self { /* fields */ }"),
5492 Applicability::HasPlaceholders,
5499 return (tcx.types.err, res);
5505 let def_id = res.def_id();
5507 // The things we are substituting into the type should not contain
5508 // escaping late-bound regions, and nor should the base type scheme.
5509 let ty = tcx.type_of(def_id);
5511 let substs = self_ctor_substs.unwrap_or_else(|| {
5512 AstConv::create_substs_for_generic_args(
5518 infer_args_for_err.is_empty(),
5519 // Provide the generic args, and whether types should be inferred.
5521 if let Some(&PathSeg(_, index)) =
5522 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5524 // If we've encountered an `impl Trait`-related error, we're just
5525 // going to infer the arguments for better error messages.
5526 if !infer_args_for_err.contains(&index) {
5527 // Check whether the user has provided generic arguments.
5528 if let Some(ref data) = segments[index].args {
5529 return (Some(data), segments[index].infer_args);
5532 return (None, segments[index].infer_args);
5537 // Provide substitutions for parameters for which (valid) arguments have been provided.
5538 |param, arg| match (¶m.kind, arg) {
5539 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5540 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5542 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5543 self.to_ty(ty).into()
5545 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5546 self.to_const(&ct.value).into()
5548 _ => unreachable!(),
5550 // Provide substitutions for parameters for which arguments are inferred.
5551 |substs, param, infer_args| {
5553 GenericParamDefKind::Lifetime => {
5554 self.re_infer(Some(param), span).unwrap().into()
5556 GenericParamDefKind::Type { has_default, .. } => {
5557 if !infer_args && has_default {
5558 // If we have a default, then we it doesn't matter that we're not
5559 // inferring the type arguments: we provide the default where any
5561 let default = tcx.type_of(param.def_id);
5564 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5568 // If no type arguments were provided, we have to infer them.
5569 // This case also occurs as a result of some malformed input, e.g.
5570 // a lifetime argument being given instead of a type parameter.
5571 // Using inference instead of `Error` gives better error messages.
5572 self.var_for_def(span, param)
5575 GenericParamDefKind::Const => {
5576 // FIXME(const_generics:defaults)
5577 // No const parameters were provided, we have to infer them.
5578 self.var_for_def(span, param)
5584 assert!(!substs.has_escaping_bound_vars());
5585 assert!(!ty.has_escaping_bound_vars());
5587 // First, store the "user substs" for later.
5588 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5590 self.add_required_obligations(span, def_id, &substs);
5592 // Substitute the values for the type parameters into the type of
5593 // the referenced item.
5594 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5596 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5597 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5598 // is inherent, there is no `Self` parameter; instead, the impl needs
5599 // type parameters, which we can infer by unifying the provided `Self`
5600 // with the substituted impl type.
5601 // This also occurs for an enum variant on a type alias.
5602 let ty = tcx.type_of(impl_def_id);
5604 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5605 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5606 Ok(ok) => self.register_infer_ok_obligations(ok),
5608 self.tcx.sess.delay_span_bug(
5611 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5620 self.check_rustc_args_require_const(def_id, hir_id, span);
5622 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5623 self.write_substs(hir_id, substs);
5625 (ty_substituted, res)
5628 /// Add all the obligations that are required, substituting and normalized appropriately.
5629 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5630 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5632 for (i, mut obligation) in traits::predicates_for_generics(
5633 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5640 // This makes the error point at the bound, but we want to point at the argument
5641 if let Some(span) = spans.get(i) {
5642 obligation.cause.code = traits::BindingObligation(def_id, *span);
5644 self.register_predicate(obligation);
5648 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5649 // We're only interested in functions tagged with
5650 // #[rustc_args_required_const], so ignore anything that's not.
5651 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5655 // If our calling expression is indeed the function itself, we're good!
5656 // If not, generate an error that this can only be called directly.
5657 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5658 if let ExprKind::Call(ref callee, ..) = expr.kind {
5659 if callee.hir_id == hir_id {
5665 self.tcx.sess.span_err(
5667 "this function can only be invoked directly, not through a function pointer",
5671 /// Resolves `typ` by a single level if `typ` is a type variable.
5672 /// If no resolution is possible, then an error is reported.
5673 /// Numeric inference variables may be left unresolved.
5674 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5675 let ty = self.resolve_vars_with_obligations(ty);
5676 if !ty.is_ty_var() {
5679 if !self.is_tainted_by_errors() {
5680 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5681 .note("type must be known at this point")
5684 self.demand_suptype(sp, self.tcx.types.err, ty);
5689 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5692 ctxt: BreakableCtxt<'tcx>,
5694 ) -> (BreakableCtxt<'tcx>, R) {
5697 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5698 index = enclosing_breakables.stack.len();
5699 enclosing_breakables.by_id.insert(id, index);
5700 enclosing_breakables.stack.push(ctxt);
5704 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5705 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5706 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5707 enclosing_breakables.stack.pop().expect("missing breakable context")
5712 /// Instantiate a QueryResponse in a probe context, without a
5713 /// good ObligationCause.
5714 fn probe_instantiate_query_response(
5717 original_values: &OriginalQueryValues<'tcx>,
5718 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5719 ) -> InferResult<'tcx, Ty<'tcx>> {
5720 self.instantiate_query_response_and_region_obligations(
5721 &traits::ObligationCause::misc(span, self.body_id),
5728 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5729 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5730 let mut contained_in_place = false;
5732 while let hir::Node::Expr(parent_expr) =
5733 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5735 match &parent_expr.kind {
5736 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5737 if lhs.hir_id == expr_id {
5738 contained_in_place = true;
5744 expr_id = parent_expr.hir_id;
5751 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5752 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5754 assert_eq!(generics.parent, None);
5756 if generics.own_counts().types == 0 {
5760 let mut params_used = BitSet::new_empty(generics.params.len());
5762 if ty.references_error() {
5763 // If there is already another error, do not emit
5764 // an error for not using a type parameter.
5765 assert!(tcx.sess.has_errors());
5769 for leaf in ty.walk() {
5770 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5771 if let ty::Param(param) = leaf_ty.kind {
5772 debug!("found use of ty param {:?}", param);
5773 params_used.insert(param.index);
5778 for param in &generics.params {
5779 if !params_used.contains(param.index) {
5780 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5781 let span = tcx.def_span(param.def_id);
5786 "type parameter `{}` is unused",
5789 .span_label(span, "unused type parameter")
5796 fn fatally_break_rust(sess: &Session) {
5797 let handler = sess.diagnostic();
5798 handler.span_bug_no_panic(
5800 "It looks like you're trying to break rust; would you like some ICE?",
5802 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5803 handler.note_without_error(
5804 "we would appreciate a joke overview: \
5805 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5807 handler.note_without_error(&format!(
5808 "rustc {} running on {}",
5809 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5810 config::host_triple(),
5814 fn potentially_plural_count(count: usize, word: &str) -> String {
5815 format!("{} {}{}", count, word, pluralize!(count))