1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - writeback: writes the final types within a function body, replacing
35 type variables with their final inferred types. These final types
36 are written into the `tcx.node_types` table, which should *never* contain
37 any reference to a type variable.
41 While type checking a function, the intermediate types for the
42 expressions, blocks, and so forth contained within the function are
43 stored in `fcx.node_types` and `fcx.node_substs`. These types
44 may contain unresolved type variables. After type checking is
45 complete, the functions in the writeback module are used to take the
46 types from this table, resolve them, and then write them into their
47 permanent home in the type context `tcx`.
49 This means that during inferencing you should use `fcx.write_ty()`
50 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
51 nodes within the function.
53 The types of top-level items, which never contain unbound type
54 variables, are stored directly into the `tcx` typeck_results.
56 N.B., a type variable is not the same thing as a type parameter. A
57 type variable is rather an "instance" of a type parameter: that is,
58 given a generic function `fn foo<T>(t: T)`: while checking the
59 function `foo`, the type `ty_param(0)` refers to the type `T`, which
60 is treated in abstract. When `foo()` is called, however, `T` will be
61 substituted for a fresh type variable `N`. This variable will
62 eventually be resolved to some concrete type (which might itself be
77 mod generator_interior;
89 AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, 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, LocalDefId, LOCAL_CRATE};
101 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
102 use rustc_hir::itemlikevisit::ItemLikeVisitor;
103 use rustc_hir::lang_items::LangItem;
104 use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath};
105 use rustc_index::bit_set::BitSet;
106 use rustc_index::vec::Idx;
107 use rustc_infer::infer;
108 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
109 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
110 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
111 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
112 use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
113 use rustc_middle::hir::map::blocks::FnLikeNode;
114 use rustc_middle::mir::interpret::ConstValue;
115 use rustc_middle::ty::adjustment::{
116 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
118 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
119 use rustc_middle::ty::query::Providers;
120 use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
121 use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts};
122 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
123 use rustc_middle::ty::WithConstness;
124 use rustc_middle::ty::{self, AdtKind, CanonicalUserType, Const, DefIdTree, GenericParamDefKind};
125 use rustc_middle::ty::{RegionKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, UserType};
126 use rustc_session::config::{self, EntryFnType};
127 use rustc_session::lint;
128 use rustc_session::parse::feature_err;
129 use rustc_session::Session;
130 use rustc_span::hygiene::DesugaringKind;
131 use rustc_span::source_map::{original_sp, DUMMY_SP};
132 use rustc_span::symbol::{kw, sym, Ident};
133 use rustc_span::{self, BytePos, MultiSpan, Span};
134 use rustc_target::abi::VariantIdx;
135 use rustc_target::spec::abi::Abi;
136 use rustc_trait_selection::infer::InferCtxtExt as _;
137 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
138 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
139 use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
140 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
141 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
142 use rustc_trait_selection::traits::{
143 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
146 use std::cell::{Cell, Ref, RefCell, RefMut};
148 use std::collections::hash_map::Entry;
150 use std::mem::replace;
151 use std::ops::{self, Deref};
154 use crate::require_c_abi_if_c_variadic;
155 use crate::util::common::indenter;
157 use self::callee::DeferredCallResolution;
158 use self::coercion::{CoerceMany, DynamicCoerceMany};
159 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
160 use self::method::{MethodCallee, SelfSource};
161 pub use self::Expectation::*;
162 use self::TupleArgumentsFlag::*;
165 macro_rules! type_error_struct {
166 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
167 if $typ.references_error() {
168 $session.diagnostic().struct_dummy()
170 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
175 /// The type of a local binding, including the revealed type for anon types.
176 #[derive(Copy, Clone, Debug)]
177 pub struct LocalTy<'tcx> {
179 revealed_ty: Ty<'tcx>,
182 /// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
183 #[derive(Copy, Clone)]
184 struct MaybeInProgressTables<'a, 'tcx> {
185 maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
188 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
189 fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
190 match self.maybe_typeck_results {
191 Some(typeck_results) => typeck_results.borrow(),
193 "MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
198 fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
199 match self.maybe_typeck_results {
200 Some(typeck_results) => typeck_results.borrow_mut(),
202 "MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
208 /// Closures defined within the function. For example:
211 /// bar(move|| { ... })
214 /// Here, the function `foo()` and the closure passed to
215 /// `bar()` will each have their own `FnCtxt`, but they will
216 /// share the inherited fields.
217 pub struct Inherited<'a, 'tcx> {
218 infcx: InferCtxt<'a, 'tcx>,
220 typeck_results: MaybeInProgressTables<'a, 'tcx>,
222 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
224 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
226 // Some additional `Sized` obligations badly affect type inference.
227 // These obligations are added in a later stage of typeck.
228 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
230 // When we process a call like `c()` where `c` is a closure type,
231 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
232 // `FnOnce` closure. In that case, we defer full resolution of the
233 // call until upvar inference can kick in and make the
234 // decision. We keep these deferred resolutions grouped by the
235 // def-id of the closure, so that once we decide, we can easily go
236 // back and process them.
237 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
239 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
241 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
243 // Opaque types found in explicit return types and their
244 // associated fresh inference variable. Writeback resolves these
245 // variables to get the concrete type, which can be used to
246 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
247 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
249 /// A map from inference variables created from opaque
250 /// type instantiations (`ty::Infer`) to the actual opaque
251 /// type (`ty::Opaque`). Used during fallback to map unconstrained
252 /// opaque type inference variables to their corresponding
254 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
256 body_id: Option<hir::BodyId>,
259 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
260 type Target = InferCtxt<'a, 'tcx>;
261 fn deref(&self) -> &Self::Target {
266 /// When type-checking an expression, we propagate downward
267 /// whatever type hint we are able in the form of an `Expectation`.
268 #[derive(Copy, Clone, Debug)]
269 pub enum Expectation<'tcx> {
270 /// We know nothing about what type this expression should have.
273 /// This expression should have the type given (or some subtype).
274 ExpectHasType(Ty<'tcx>),
276 /// This expression will be cast to the `Ty`.
277 ExpectCastableToType(Ty<'tcx>),
279 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
280 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
281 ExpectRvalueLikeUnsized(Ty<'tcx>),
284 impl<'a, 'tcx> Expectation<'tcx> {
285 // Disregard "castable to" expectations because they
286 // can lead us astray. Consider for example `if cond
287 // {22} else {c} as u8` -- if we propagate the
288 // "castable to u8" constraint to 22, it will pick the
289 // type 22u8, which is overly constrained (c might not
290 // be a u8). In effect, the problem is that the
291 // "castable to" expectation is not the tightest thing
292 // we can say, so we want to drop it in this case.
293 // The tightest thing we can say is "must unify with
294 // else branch". Note that in the case of a "has type"
295 // constraint, this limitation does not hold.
297 // If the expected type is just a type variable, then don't use
298 // an expected type. Otherwise, we might write parts of the type
299 // when checking the 'then' block which are incompatible with the
301 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
303 ExpectHasType(ety) => {
304 let ety = fcx.shallow_resolve(ety);
305 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
307 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
312 /// Provides an expectation for an rvalue expression given an *optional*
313 /// hint, which is not required for type safety (the resulting type might
314 /// be checked higher up, as is the case with `&expr` and `box expr`), but
315 /// is useful in determining the concrete type.
317 /// The primary use case is where the expected type is a fat pointer,
318 /// like `&[isize]`. For example, consider the following statement:
320 /// let x: &[isize] = &[1, 2, 3];
322 /// In this case, the expected type for the `&[1, 2, 3]` expression is
323 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
324 /// expectation `ExpectHasType([isize])`, that would be too strong --
325 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
326 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
327 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
328 /// which still is useful, because it informs integer literals and the like.
329 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
330 /// for examples of where this comes up,.
331 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
332 match fcx.tcx.struct_tail_without_normalization(ty).kind() {
333 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
334 _ => ExpectHasType(ty),
338 // Resolves `expected` by a single level if it is a variable. If
339 // there is no expected type or resolution is not possible (e.g.,
340 // no constraints yet present), just returns `None`.
341 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
343 NoExpectation => NoExpectation,
344 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
345 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
346 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
350 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
351 match self.resolve(fcx) {
352 NoExpectation => None,
353 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
357 /// It sometimes happens that we want to turn an expectation into
358 /// a **hard constraint** (i.e., something that must be satisfied
359 /// for the program to type-check). `only_has_type` will return
360 /// such a constraint, if it exists.
361 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
362 match self.resolve(fcx) {
363 ExpectHasType(ty) => Some(ty),
364 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
368 /// Like `only_has_type`, but instead of returning `None` if no
369 /// hard constraint exists, creates a fresh type variable.
370 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
371 self.only_has_type(fcx).unwrap_or_else(|| {
372 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
377 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
384 fn maybe_mut_place(m: hir::Mutability) -> Self {
386 hir::Mutability::Mut => Needs::MutPlace,
387 hir::Mutability::Not => Needs::None,
392 #[derive(Copy, Clone)]
393 pub struct UnsafetyState {
395 pub unsafety: hir::Unsafety,
396 pub unsafe_push_count: u32,
401 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
402 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
405 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
406 use hir::BlockCheckMode;
407 match self.unsafety {
408 // If this unsafe, then if the outer function was already marked as
409 // unsafe we shouldn't attribute the unsafe'ness to the block. This
410 // way the block can be warned about instead of ignoring this
411 // extraneous block (functions are never warned about).
412 hir::Unsafety::Unsafe if self.from_fn => *self,
415 let (unsafety, def, count) = match blk.rules {
416 BlockCheckMode::PushUnsafeBlock(..) => {
417 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
419 BlockCheckMode::PopUnsafeBlock(..) => {
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
422 BlockCheckMode::UnsafeBlock(..) => {
423 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
425 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
427 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
433 #[derive(Debug, Copy, Clone)]
439 /// Tracks whether executing a node may exit normally (versus
440 /// return/break/panic, which "diverge", leaving dead code in their
441 /// wake). Tracked semi-automatically (through type variables marked
442 /// as diverging), with some manual adjustments for control-flow
443 /// primitives (approximating a CFG).
444 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
446 /// Potentially unknown, some cases converge,
447 /// others require a CFG to determine them.
450 /// Definitely known to diverge and therefore
451 /// not reach the next sibling or its parent.
453 /// The `Span` points to the expression
454 /// that caused us to diverge
455 /// (e.g. `return`, `break`, etc).
457 /// In some cases (e.g. a `match` expression
458 /// where all arms diverge), we may be
459 /// able to provide a more informative
460 /// message to the user.
461 /// If this is `None`, a default message
462 /// will be generated, which is suitable
464 custom_note: Option<&'static str>,
467 /// Same as `Always` but with a reachability
468 /// warning already emitted.
472 // Convenience impls for combining `Diverges`.
474 impl ops::BitAnd for Diverges {
476 fn bitand(self, other: Self) -> Self {
477 cmp::min(self, other)
481 impl ops::BitOr for Diverges {
483 fn bitor(self, other: Self) -> Self {
484 cmp::max(self, other)
488 impl ops::BitAndAssign for Diverges {
489 fn bitand_assign(&mut self, other: Self) {
490 *self = *self & other;
494 impl ops::BitOrAssign for Diverges {
495 fn bitor_assign(&mut self, other: Self) {
496 *self = *self | other;
501 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
502 fn always(span: Span) -> Diverges {
503 Diverges::Always { span, custom_note: None }
506 fn is_always(self) -> bool {
507 // Enum comparison ignores the
508 // contents of fields, so we just
509 // fill them in with garbage here.
510 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
514 pub struct BreakableCtxt<'tcx> {
517 // this is `null` for loops where break with a value is illegal,
518 // such as `while`, `for`, and `while let`
519 coerce: Option<DynamicCoerceMany<'tcx>>,
522 pub struct EnclosingBreakables<'tcx> {
523 stack: Vec<BreakableCtxt<'tcx>>,
524 by_id: HirIdMap<usize>,
527 impl<'tcx> EnclosingBreakables<'tcx> {
528 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
529 self.opt_find_breakable(target_id).unwrap_or_else(|| {
530 bug!("could not find enclosing breakable with id {}", target_id);
534 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
535 match self.by_id.get(&target_id) {
536 Some(ix) => Some(&mut self.stack[*ix]),
542 pub struct FnCtxt<'a, 'tcx> {
545 /// The parameter environment used for proving trait obligations
546 /// in this function. This can change when we descend into
547 /// closures (as they bring new things into scope), hence it is
548 /// not part of `Inherited` (as of the time of this writing,
549 /// closures do not yet change the environment, but they will
551 param_env: ty::ParamEnv<'tcx>,
553 /// Number of errors that had been reported when we started
554 /// checking this function. On exit, if we find that *more* errors
555 /// have been reported, we will skip regionck and other work that
556 /// expects the types within the function to be consistent.
557 // FIXME(matthewjasper) This should not exist, and it's not correct
558 // if type checking is run in parallel.
559 err_count_on_creation: usize,
561 /// If `Some`, this stores coercion information for returned
562 /// expressions. If `None`, this is in a context where return is
563 /// inappropriate, such as a const expression.
565 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
566 /// can track all the return expressions and then use them to
567 /// compute a useful coercion from the set, similar to a match
568 /// expression or other branching context. You can use methods
569 /// like `expected_ty` to access the declared return type (if
571 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
573 /// First span of a return site that we find. Used in error messages.
574 ret_coercion_span: RefCell<Option<Span>>,
576 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
578 ps: RefCell<UnsafetyState>,
580 /// Whether the last checked node generates a divergence (e.g.,
581 /// `return` will set this to `Always`). In general, when entering
582 /// an expression or other node in the tree, the initial value
583 /// indicates whether prior parts of the containing expression may
584 /// have diverged. It is then typically set to `Maybe` (and the
585 /// old value remembered) for processing the subparts of the
586 /// current expression. As each subpart is processed, they may set
587 /// the flag to `Always`, etc. Finally, at the end, we take the
588 /// result and "union" it with the original value, so that when we
589 /// return the flag indicates if any subpart of the parent
590 /// expression (up to and including this part) has diverged. So,
591 /// if you read it after evaluating a subexpression `X`, the value
592 /// you get indicates whether any subexpression that was
593 /// evaluating up to and including `X` diverged.
595 /// We currently use this flag only for diagnostic purposes:
597 /// - To warn about unreachable code: if, after processing a
598 /// sub-expression but before we have applied the effects of the
599 /// current node, we see that the flag is set to `Always`, we
600 /// can issue a warning. This corresponds to something like
601 /// `foo(return)`; we warn on the `foo()` expression. (We then
602 /// update the flag to `WarnedAlways` to suppress duplicate
603 /// reports.) Similarly, if we traverse to a fresh statement (or
604 /// tail expression) from a `Always` setting, we will issue a
605 /// warning. This corresponds to something like `{return;
606 /// foo();}` or `{return; 22}`, where we would warn on the
609 /// An expression represents dead code if, after checking it,
610 /// the diverges flag is set to something other than `Maybe`.
611 diverges: Cell<Diverges>,
613 /// Whether any child nodes have any type errors.
614 has_errors: Cell<bool>,
616 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
618 inh: &'a Inherited<'a, 'tcx>,
621 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
622 type Target = Inherited<'a, 'tcx>;
623 fn deref(&self) -> &Self::Target {
628 /// Helper type of a temporary returned by `Inherited::build(...)`.
629 /// Necessary because we can't write the following bound:
630 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
631 pub struct InheritedBuilder<'tcx> {
632 infcx: infer::InferCtxtBuilder<'tcx>,
636 impl Inherited<'_, 'tcx> {
637 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
638 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
641 infcx: tcx.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner),
647 impl<'tcx> InheritedBuilder<'tcx> {
648 pub fn enter<F, R>(&mut self, f: F) -> R
650 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
652 let def_id = self.def_id;
653 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
657 impl Inherited<'a, 'tcx> {
658 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
660 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
661 let body_id = tcx.hir().maybe_body_owned_by(item_id);
664 typeck_results: MaybeInProgressTables {
665 maybe_typeck_results: infcx.in_progress_typeck_results,
668 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
669 locals: RefCell::new(Default::default()),
670 deferred_sized_obligations: RefCell::new(Vec::new()),
671 deferred_call_resolutions: RefCell::new(Default::default()),
672 deferred_cast_checks: RefCell::new(Vec::new()),
673 deferred_generator_interiors: RefCell::new(Vec::new()),
674 opaque_types: RefCell::new(Default::default()),
675 opaque_types_vars: RefCell::new(Default::default()),
680 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
681 debug!("register_predicate({:?})", obligation);
682 if obligation.has_escaping_bound_vars() {
683 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
685 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
688 fn register_predicates<I>(&self, obligations: I)
690 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
692 for obligation in obligations {
693 self.register_predicate(obligation);
697 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
698 self.register_predicates(infer_ok.obligations);
702 fn normalize_associated_types_in<T>(
706 param_env: ty::ParamEnv<'tcx>,
710 T: TypeFoldable<'tcx>,
712 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
713 self.register_infer_ok_obligations(ok)
717 struct CheckItemTypesVisitor<'tcx> {
721 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
722 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
723 check_item_type(self.tcx, i);
725 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
726 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
729 pub fn check_wf_new(tcx: TyCtxt<'_>) {
730 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
731 tcx.hir().krate().par_visit_all_item_likes(&visit);
734 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
735 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
738 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
739 debug_assert!(crate_num == LOCAL_CRATE);
740 tcx.par_body_owners(|body_owner_def_id| {
741 tcx.ensure().typeck(body_owner_def_id);
745 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
746 wfcheck::check_item_well_formed(tcx, def_id);
749 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
750 wfcheck::check_trait_item(tcx, def_id);
753 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
754 wfcheck::check_impl_item(tcx, def_id);
757 pub fn provide(providers: &mut Providers) {
758 method::provide(providers);
759 *providers = Providers {
763 diagnostic_only_typeck,
767 check_item_well_formed,
768 check_trait_item_well_formed,
769 check_impl_item_well_formed,
770 check_mod_item_types,
775 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
776 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
779 /// If this `DefId` is a "primary tables entry", returns
780 /// `Some((body_id, header, decl))` with information about
781 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
784 /// If this function returns `Some`, then `typeck_results(def_id)` will
785 /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
786 /// may not succeed. In some cases where this function returns `None`
787 /// (notably closures), `typeck_results(def_id)` would wind up
788 /// redirecting to the owning function.
792 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
793 match tcx.hir().get(id) {
794 Node::Item(item) => match item.kind {
795 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
796 Some((body, Some(ty), None, None))
798 hir::ItemKind::Fn(ref sig, .., body) => {
799 Some((body, None, Some(&sig.header), Some(&sig.decl)))
803 Node::TraitItem(item) => match item.kind {
804 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
805 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
806 Some((body, None, Some(&sig.header), Some(&sig.decl)))
810 Node::ImplItem(item) => match item.kind {
811 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
812 hir::ImplItemKind::Fn(ref sig, body) => {
813 Some((body, None, Some(&sig.header), Some(&sig.decl)))
817 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
822 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
823 // Closures' typeck results come from their outermost function,
824 // as they are part of the same "inference environment".
825 let outer_def_id = tcx.closure_base_def_id(def_id);
826 if outer_def_id != def_id {
827 return tcx.has_typeck_results(outer_def_id);
830 if let Some(def_id) = def_id.as_local() {
831 let id = tcx.hir().local_def_id_to_hir_id(def_id);
832 primary_body_of(tcx, id).is_some()
838 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
839 &*tcx.typeck(def_id).used_trait_imports
842 /// Inspects the substs of opaque types, replacing any inference variables
843 /// with proper generic parameter from the identity substs.
845 /// This is run after we normalize the function signature, to fix any inference
846 /// variables introduced by the projection of associated types. This ensures that
847 /// any opaque types used in the signature continue to refer to generic parameters,
848 /// allowing them to be considered for defining uses in the function body
850 /// For example, consider this code.
855 /// fn use_it(self) -> Self::MyItem
857 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
858 /// type MyItem = impl Iterator<Item = I>;
859 /// fn use_it(self) -> Self::MyItem {
865 /// When we normalize the signature of `use_it` from the impl block,
866 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
867 /// However, this projection result may contain inference variables, due
868 /// to the way that projection works. We didn't have any inference variables
869 /// in the signature to begin with - leaving them in will cause us to incorrectly
870 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
871 /// variables back to the actual generic parameters, we will correctly see that
872 /// we have a defining use of `MyItem`
873 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
875 T: TypeFoldable<'tcx>,
877 struct FixupFolder<'tcx> {
881 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
882 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
886 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
888 ty::Opaque(def_id, substs) => {
889 debug!("fixup_opaque_types: found type {:?}", ty);
890 // Here, we replace any inference variables that occur within
891 // the substs of an opaque type. By definition, any type occurring
892 // in the substs has a corresponding generic parameter, which is what
893 // we replace it with.
894 // This replacement is only run on the function signature, so any
895 // inference variables that we come across must be the rust of projection
896 // (there's no other way for a user to get inference variables into
897 // a function signature).
898 if ty.needs_infer() {
899 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
900 let old_param = substs[param.index as usize];
901 match old_param.unpack() {
902 GenericArgKind::Type(old_ty) => {
903 if let ty::Infer(_) = old_ty.kind() {
904 // Replace inference type with a generic parameter
905 self.tcx.mk_param_from_def(param)
907 old_param.fold_with(self)
910 GenericArgKind::Const(old_const) => {
911 if let ty::ConstKind::Infer(_) = old_const.val {
912 // This should never happen - we currently do not support
913 // 'const projections', e.g.:
914 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
915 // which should be the only way for us to end up with a const inference
916 // variable after projection. If Rust ever gains support for this kind
917 // of projection, this should *probably* be changed to
918 // `self.tcx.mk_param_from_def(param)`
920 "Found infer const: `{:?}` in opaque type: {:?}",
925 old_param.fold_with(self)
928 GenericArgKind::Lifetime(old_region) => {
929 if let RegionKind::ReVar(_) = old_region {
930 self.tcx.mk_param_from_def(param)
932 old_param.fold_with(self)
937 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
938 debug!("fixup_opaque_types: new type: {:?}", new_ty);
944 _ => ty.super_fold_with(self),
949 debug!("fixup_opaque_types({:?})", val);
950 val.fold_with(&mut FixupFolder { tcx })
953 fn typeck_const_arg<'tcx>(
955 (did, param_did): (LocalDefId, DefId),
956 ) -> &ty::TypeckResults<'tcx> {
957 let fallback = move || tcx.type_of(param_did);
958 typeck_with_fallback(tcx, did, fallback)
961 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
962 if let Some(param_did) = tcx.opt_const_param_of(def_id) {
963 tcx.typeck_const_arg((def_id, param_did))
965 let fallback = move || tcx.type_of(def_id.to_def_id());
966 typeck_with_fallback(tcx, def_id, fallback)
970 /// Used only to get `TypeckResults` for type inference during error recovery.
971 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
972 fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
973 let fallback = move || {
974 let span = tcx.hir().span(tcx.hir().local_def_id_to_hir_id(def_id));
975 tcx.ty_error_with_message(span, "diagnostic only typeck table used")
977 typeck_with_fallback(tcx, def_id, fallback)
980 fn typeck_with_fallback<'tcx>(
983 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
984 ) -> &'tcx ty::TypeckResults<'tcx> {
985 // Closures' typeck results come from their outermost function,
986 // as they are part of the same "inference environment".
987 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
988 if outer_def_id != def_id {
989 return tcx.typeck(outer_def_id);
992 let id = tcx.hir().local_def_id_to_hir_id(def_id);
993 let span = tcx.hir().span(id);
995 // Figure out what primary body this item has.
996 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
997 span_bug!(span, "can't type-check body of {:?}", def_id);
999 let body = tcx.hir().body(body_id);
1001 let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
1002 let param_env = tcx.param_env(def_id);
1003 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1004 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1005 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1011 &hir::Generics::empty(),
1018 check_abi(tcx, span, fn_sig.abi());
1020 // Compute the fty from point of view of inside the fn.
1021 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1022 let fn_sig = inh.normalize_associated_types_in(
1029 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1031 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1034 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1035 let expected_type = body_ty
1036 .and_then(|ty| match ty.kind {
1037 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1040 .unwrap_or_else(fallback);
1041 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1042 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1044 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1045 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1050 // Gather locals in statics (because of block expressions).
1051 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1053 fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
1055 fcx.write_ty(id, revealed_ty);
1060 // All type checking constraints were added, try to fallback unsolved variables.
1061 fcx.select_obligations_where_possible(false, |_| {});
1062 let mut fallback_has_occurred = false;
1064 // We do fallback in two passes, to try to generate
1065 // better error messages.
1066 // The first time, we do *not* replace opaque types.
1067 for ty in &fcx.unsolved_variables() {
1068 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1070 // We now see if we can make progress. This might
1071 // cause us to unify inference variables for opaque types,
1072 // since we may have unified some other type variables
1073 // during the first phase of fallback.
1074 // This means that we only replace inference variables with their underlying
1075 // opaque types as a last resort.
1077 // In code like this:
1080 // type MyType = impl Copy;
1081 // fn produce() -> MyType { true }
1082 // fn bad_produce() -> MyType { panic!() }
1085 // we want to unify the opaque inference variable in `bad_produce`
1086 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1087 // This will produce a nice error message about conflicting concrete
1088 // types for `MyType`.
1090 // If we had tried to fallback the opaque inference variable to `MyType`,
1091 // we will generate a confusing type-check error that does not explicitly
1092 // refer to opaque types.
1093 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1095 // We now run fallback again, but this time we allow it to replace
1096 // unconstrained opaque type variables, in addition to performing
1097 // other kinds of fallback.
1098 for ty in &fcx.unsolved_variables() {
1099 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1102 // See if we can make any more progress.
1103 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1105 // Even though coercion casts provide type hints, we check casts after fallback for
1106 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1109 // Closure and generator analysis may run after fallback
1110 // because they don't constrain other type variables.
1111 fcx.closure_analyze(body);
1112 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1113 fcx.resolve_generator_interiors(def_id.to_def_id());
1115 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1116 let ty = fcx.normalize_ty(span, ty);
1117 fcx.require_type_is_sized(ty, span, code);
1120 fcx.select_all_obligations_or_error();
1122 if fn_decl.is_some() {
1123 fcx.regionck_fn(id, body);
1125 fcx.regionck_expr(body);
1128 fcx.resolve_type_vars_in_body(body)
1131 // Consistency check our TypeckResults instance can hold all ItemLocalIds
1132 // it will need to hold.
1133 assert_eq!(typeck_results.hir_owner, id.owner);
1138 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1139 if !tcx.sess.target.target.is_abi_supported(abi) {
1144 "The ABI `{}` is not supported for the current target",
1151 struct GatherLocalsVisitor<'a, 'tcx> {
1152 fcx: &'a FnCtxt<'a, 'tcx>,
1153 parent_id: hir::HirId,
1156 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1157 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1160 // Infer the variable's type.
1161 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1162 kind: TypeVariableOriginKind::TypeInference,
1168 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1172 // Take type that the user specified.
1173 self.fcx.locals.borrow_mut().insert(nid, typ);
1180 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1181 type Map = intravisit::ErasedMap<'tcx>;
1183 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1184 NestedVisitorMap::None
1187 // Add explicitly-declared locals.
1188 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1189 let local_ty = match local.ty {
1191 let o_ty = self.fcx.to_ty(&ty);
1193 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1194 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1203 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1205 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1206 ty.hir_id, o_ty, revealed_ty, c_ty
1211 .user_provided_types_mut()
1212 .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 let revealed_ret_ty =
1306 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1307 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1308 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1309 fn_sig = tcx.mk_fn_sig(
1310 fn_sig.inputs().iter().cloned(),
1317 let span = body.value.span;
1319 fn_maybe_err(tcx, span, fn_sig.abi);
1321 if body.generator_kind.is_some() && can_be_generator.is_some() {
1323 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1324 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1326 // Resume type defaults to `()` if the generator has no argument.
1327 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1329 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1332 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
1333 let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
1334 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1336 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1337 // (as it's created inside the body itself, not passed in from outside).
1338 let maybe_va_list = if fn_sig.c_variadic {
1339 let span = body.params.last().unwrap().span;
1340 let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
1341 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1343 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1348 // Add formal parameters.
1349 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1350 let inputs_fn = fn_sig.inputs().iter().copied();
1351 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1352 // Check the pattern.
1353 let ty_span = try { inputs_hir?.get(idx)?.span };
1354 fcx.check_pat_top(¶m.pat, param_ty, ty_span, false);
1356 // Check that argument is Sized.
1357 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1358 // for simple cases like `fn foo(x: Trait)`,
1359 // where we would error once on the parameter as a whole, and once on the binding `x`.
1360 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1361 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
1364 fcx.write_ty(param.hir_id, param_ty);
1367 inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1369 if let ty::Dynamic(..) = declared_ret_ty.kind() {
1370 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1371 // been evaluated so that we have types available for all the nodes being returned, but that
1372 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1373 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1374 // while keeping the current ordering we will ignore the tail expression's type because we
1375 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1376 // because we will trigger "unreachable expression" lints unconditionally.
1377 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1378 // case that a newcomer might make, returning a bare trait, and in that case we populate
1379 // the tail expression's type so that the suggestion will be correct, but ignore all other
1381 fcx.check_expr(&body.value);
1382 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1383 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1385 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1386 fcx.check_return_expr(&body.value);
1389 // We insert the deferred_generator_interiors entry after visiting the body.
1390 // This ensures that all nested generators appear before the entry of this generator.
1391 // resolve_generator_interiors relies on this property.
1392 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1394 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1395 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1397 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1398 Some(GeneratorTypes {
1402 movability: can_be_generator.unwrap(),
1408 // Finalize the return check by taking the LUB of the return types
1409 // we saw and assigning it to the expected return type. This isn't
1410 // really expected to fail, since the coercions would have failed
1411 // earlier when trying to find a LUB.
1413 // However, the behavior around `!` is sort of complex. In the
1414 // event that the `actual_return_ty` comes back as `!`, that
1415 // indicates that the fn either does not return or "returns" only
1416 // values of type `!`. In this case, if there is an expected
1417 // return type that is *not* `!`, that should be ok. But if the
1418 // return type is being inferred, we want to "fallback" to `!`:
1420 // let x = move || panic!();
1422 // To allow for that, I am creating a type variable with diverging
1423 // fallback. This was deemed ever so slightly better than unifying
1424 // the return value with `!` because it allows for the caller to
1425 // make more assumptions about the return type (e.g., they could do
1427 // let y: Option<u32> = Some(x());
1429 // which would then cause this return type to become `u32`, not
1431 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1432 let mut actual_return_ty = coercion.complete(&fcx);
1433 if actual_return_ty.is_never() {
1434 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1435 kind: TypeVariableOriginKind::DivergingFn,
1439 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1441 // Check that the main return type implements the termination trait.
1442 if let Some(term_id) = tcx.lang_items().termination() {
1443 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1444 let main_id = hir.local_def_id_to_hir_id(def_id);
1445 if main_id == fn_id {
1446 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1447 let trait_ref = ty::TraitRef::new(term_id, substs);
1448 let return_ty_span = decl.output.span();
1449 let cause = traits::ObligationCause::new(
1452 ObligationCauseCode::MainFunctionType,
1455 inherited.register_predicate(traits::Obligation::new(
1458 trait_ref.without_const().to_predicate(tcx),
1464 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1465 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1466 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1467 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1468 if *declared_ret_ty.kind() != ty::Never {
1469 sess.span_err(decl.output.span(), "return type should be `!`");
1472 let inputs = fn_sig.inputs();
1473 let span = hir.span(fn_id);
1474 if inputs.len() == 1 {
1475 let arg_is_panic_info = match *inputs[0].kind() {
1476 ty::Ref(region, ty, mutbl) => match *ty.kind() {
1477 ty::Adt(ref adt, _) => {
1478 adt.did == panic_info_did
1479 && mutbl == hir::Mutability::Not
1480 && *region != RegionKind::ReStatic
1487 if !arg_is_panic_info {
1488 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1491 if let Node::Item(item) = hir.get(fn_id) {
1492 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1493 if !generics.params.is_empty() {
1494 sess.span_err(span, "should have no type parameters");
1499 let span = sess.source_map().guess_head_span(span);
1500 sess.span_err(span, "function should have one argument");
1503 sess.err("language item required, but not found: `panic_info`");
1508 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1509 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1510 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1511 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1512 if *declared_ret_ty.kind() != ty::Never {
1513 sess.span_err(decl.output.span(), "return type should be `!`");
1516 let inputs = fn_sig.inputs();
1517 let span = hir.span(fn_id);
1518 if inputs.len() == 1 {
1519 let arg_is_alloc_layout = match inputs[0].kind() {
1520 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1524 if !arg_is_alloc_layout {
1525 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1528 if let Node::Item(item) = hir.get(fn_id) {
1529 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1530 if !generics.params.is_empty() {
1533 "`#[alloc_error_handler]` function should have no type \
1540 let span = sess.source_map().guess_head_span(span);
1541 sess.span_err(span, "function should have one argument");
1544 sess.err("language item required, but not found: `alloc_layout`");
1552 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1553 let def_id = tcx.hir().local_def_id(id);
1554 let def = tcx.adt_def(def_id);
1555 def.destructor(tcx); // force the destructor to be evaluated
1556 check_representable(tcx, span, def_id);
1558 if def.repr.simd() {
1559 check_simd(tcx, span, def_id);
1562 check_transparent(tcx, span, def);
1563 check_packed(tcx, span, def);
1566 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1567 let def_id = tcx.hir().local_def_id(id);
1568 let def = tcx.adt_def(def_id);
1569 def.destructor(tcx); // force the destructor to be evaluated
1570 check_representable(tcx, span, def_id);
1571 check_transparent(tcx, span, def);
1572 check_union_fields(tcx, span, def_id);
1573 check_packed(tcx, span, def);
1576 /// When the `#![feature(untagged_unions)]` gate is active,
1577 /// check that the fields of the `union` does not contain fields that need dropping.
1578 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1579 let item_type = tcx.type_of(item_def_id);
1580 if let ty::Adt(def, substs) = item_type.kind() {
1581 assert!(def.is_union());
1582 let fields = &def.non_enum_variant().fields;
1583 let param_env = tcx.param_env(item_def_id);
1584 for field in fields {
1585 let field_ty = field.ty(tcx, substs);
1586 // We are currently checking the type this field came from, so it must be local.
1587 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1588 if field_ty.needs_drop(tcx, param_env) {
1593 "unions may not contain fields that need dropping"
1595 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1601 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind());
1606 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1607 /// projections that would result in "inheriting lifetimes".
1608 fn check_opaque<'tcx>(
1611 substs: SubstsRef<'tcx>,
1613 origin: &hir::OpaqueTyOrigin,
1615 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1616 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1619 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1620 /// in "inheriting lifetimes".
1621 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1622 let item = tcx.hir().expect_item(tcx.hir().local_def_id_to_hir_id(def_id));
1624 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1629 struct ProhibitOpaqueVisitor<'tcx> {
1630 opaque_identity_ty: Ty<'tcx>,
1631 generics: &'tcx ty::Generics,
1632 ty: Option<Ty<'tcx>>,
1635 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1636 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1637 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1638 if t != self.opaque_identity_ty && t.super_visit_with(self) {
1645 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1646 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1647 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1648 return *index < self.generics.parent_count as u32;
1651 r.super_visit_with(self)
1654 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1655 if let ty::ConstKind::Unevaluated(..) = c.val {
1656 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1657 // which would violate this check. Even though the particular substitution is not used
1658 // within the const, this should still be fixed.
1661 c.super_visit_with(self)
1665 if let ItemKind::OpaqueTy(hir::OpaqueTy {
1666 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1670 let mut visitor = ProhibitOpaqueVisitor {
1671 opaque_identity_ty: tcx.mk_opaque(
1673 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1675 generics: tcx.generics_of(def_id),
1678 let prohibit_opaque = tcx
1679 .predicates_of(def_id)
1682 .any(|(predicate, _)| predicate.visit_with(&mut visitor));
1684 "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
1685 prohibit_opaque, visitor
1688 if prohibit_opaque {
1689 let is_async = match item.kind {
1690 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1691 hir::OpaqueTyOrigin::AsyncFn => true,
1694 _ => unreachable!(),
1697 let mut err = struct_span_err!(
1701 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1703 if is_async { "async fn" } else { "impl Trait" },
1706 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
1707 if snippet == "Self" {
1708 if let Some(ty) = visitor.ty {
1709 err.span_suggestion(
1711 "consider spelling out the type instead",
1712 format!("{:?}", ty),
1713 Applicability::MaybeIncorrect,
1723 /// Given a `DefId` for an opaque type in return position, find its parent item's return
1725 fn get_owner_return_paths(
1728 ) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
1729 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1730 let id = tcx.hir().get_parent_item(hir_id);
1734 .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
1735 .map(|(hir_id, body_id)| {
1736 let body = tcx.hir().body(body_id);
1737 let mut visitor = ReturnsVisitor::default();
1738 visitor.visit_body(body);
1743 /// Emit an error for recursive opaque types.
1745 /// If this is a return `impl Trait`, find the item's return expressions and point at them. For
1746 /// direct recursion this is enough, but for indirect recursion also point at the last intermediary
1749 /// If all the return expressions evaluate to `!`, then we explain that the error will go away
1750 /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
1751 fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1752 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1754 let mut label = false;
1755 if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
1756 let typeck_results = tcx.typeck(tcx.hir().local_def_id(hir_id));
1760 .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1761 .all(|ty| matches!(ty.kind(), ty::Never))
1766 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1767 .map(|expr| expr.span)
1768 .collect::<Vec<Span>>();
1769 let span_len = spans.len();
1771 err.span_label(spans[0], "this returned value is of `!` type");
1773 let mut multispan: MultiSpan = spans.clone().into();
1776 .push_span_label(span, "this returned value is of `!` type".to_string());
1778 err.span_note(multispan, "these returned values have a concrete \"never\" type");
1780 err.help("this error will resolve once the item's body returns a concrete type");
1782 let mut seen = FxHashSet::default();
1784 err.span_label(span, "recursive opaque type");
1786 for (sp, ty) in visitor
1789 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1790 .filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
1792 struct VisitTypes(Vec<DefId>);
1793 impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes {
1794 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1796 ty::Opaque(def, _) => {
1800 _ => t.super_visit_with(self),
1804 let mut visitor = VisitTypes(vec![]);
1805 ty.visit_with(&mut visitor);
1806 for def_id in visitor.0 {
1807 let ty_span = tcx.def_span(def_id);
1808 if !seen.contains(&ty_span) {
1809 err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
1810 seen.insert(ty_span);
1812 err.span_label(sp, &format!("returning here with type `{}`", ty));
1818 err.span_label(span, "cannot resolve opaque type");
1823 /// Emit an error for recursive opaque types in a `let` binding.
1824 fn binding_opaque_type_cycle_error(
1828 partially_expanded_type: Ty<'tcx>,
1830 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1831 err.span_label(span, "cannot resolve opaque type");
1832 // Find the the owner that declared this `impl Trait` type.
1833 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1834 let mut prev_hir_id = hir_id;
1835 let mut hir_id = tcx.hir().get_parent_node(hir_id);
1836 while let Some(node) = tcx.hir().find(hir_id) {
1838 hir::Node::Local(hir::Local {
1842 source: hir::LocalSource::Normal,
1845 err.span_label(pat.span, "this binding might not have a concrete type");
1846 err.span_suggestion_verbose(
1847 ty.span.shrink_to_hi(),
1848 "set the binding to a value for a concrete type to be resolved",
1849 " = /* value */".to_string(),
1850 Applicability::HasPlaceholders,
1853 hir::Node::Local(hir::Local {
1855 source: hir::LocalSource::Normal,
1858 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1859 let typeck_results =
1860 tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
1861 if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
1865 "this is of type `{}`, which doesn't constrain \
1866 `{}` enough to arrive to a concrete type",
1867 ty, partially_expanded_type
1874 if prev_hir_id == hir_id {
1877 prev_hir_id = hir_id;
1878 hir_id = tcx.hir().get_parent_node(hir_id);
1883 fn async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span) {
1884 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
1885 .span_label(span, "recursive `async fn`")
1886 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1890 /// Checks that an opaque type does not contain cycles.
1891 fn check_opaque_for_cycles<'tcx>(
1894 substs: SubstsRef<'tcx>,
1896 origin: &hir::OpaqueTyOrigin,
1898 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1901 hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
1902 hir::OpaqueTyOrigin::Binding => {
1903 binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
1905 _ => opaque_type_cycle_error(tcx, def_id, span),
1910 // Forbid defining intrinsics in Rust code,
1911 // as they must always be defined by the compiler.
1912 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1913 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1914 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1918 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1920 "check_item_type(it.hir_id={}, it.name={})",
1922 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1924 let _indenter = indenter();
1926 // Consts can play a role in type-checking, so they are included here.
1927 hir::ItemKind::Static(..) => {
1928 let def_id = tcx.hir().local_def_id(it.hir_id);
1929 tcx.ensure().typeck(def_id);
1930 maybe_check_static_with_link_section(tcx, def_id, it.span);
1932 hir::ItemKind::Const(..) => {
1933 tcx.ensure().typeck(tcx.hir().local_def_id(it.hir_id));
1935 hir::ItemKind::Enum(ref enum_definition, _) => {
1936 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1938 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1939 hir::ItemKind::Impl { ref items, .. } => {
1940 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1941 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1942 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1943 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1944 let trait_def_id = impl_trait_ref.def_id;
1945 check_on_unimplemented(tcx, trait_def_id, it);
1948 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1949 let def_id = tcx.hir().local_def_id(it.hir_id);
1950 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1952 for item in items.iter() {
1953 let item = tcx.hir().trait_item(item.id);
1954 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1955 let abi = sig.header.abi;
1956 fn_maybe_err(tcx, item.ident.span, abi);
1960 hir::ItemKind::Struct(..) => {
1961 check_struct(tcx, it.hir_id, it.span);
1963 hir::ItemKind::Union(..) => {
1964 check_union(tcx, it.hir_id, it.span);
1966 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1967 // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
1968 // `async-std` (and `pub async fn` in general).
1969 // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
1970 // See https://github.com/rust-lang/rust/issues/75100
1971 if !tcx.sess.opts.actually_rustdoc {
1972 let def_id = tcx.hir().local_def_id(it.hir_id);
1974 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1975 check_opaque(tcx, def_id, substs, it.span, &origin);
1978 hir::ItemKind::TyAlias(..) => {
1979 let def_id = tcx.hir().local_def_id(it.hir_id);
1980 let pty_ty = tcx.type_of(def_id);
1981 let generics = tcx.generics_of(def_id);
1982 check_type_params_are_used(tcx, &generics, pty_ty);
1984 hir::ItemKind::ForeignMod(ref m) => {
1985 check_abi(tcx, it.span, m.abi);
1987 if m.abi == Abi::RustIntrinsic {
1988 for item in m.items {
1989 intrinsic::check_intrinsic_type(tcx, item);
1991 } else if m.abi == Abi::PlatformIntrinsic {
1992 for item in m.items {
1993 intrinsic::check_platform_intrinsic_type(tcx, item);
1996 for item in m.items {
1997 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1998 let own_counts = generics.own_counts();
1999 if generics.params.len() - own_counts.lifetimes != 0 {
2000 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
2001 (_, 0) => ("type", "types", Some("u32")),
2002 // We don't specify an example value, because we can't generate
2003 // a valid value for any type.
2004 (0, _) => ("const", "consts", None),
2005 _ => ("type or const", "types or consts", None),
2011 "foreign items may not have {} parameters",
2014 .span_label(item.span, &format!("can't have {} parameters", kinds))
2016 // FIXME: once we start storing spans for type arguments, turn this
2017 // into a suggestion.
2019 "replace the {} parameters with concrete {}{}",
2022 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
2028 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
2029 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
2034 _ => { /* nothing to do */ }
2038 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
2039 // Only restricted on wasm32 target for now
2040 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
2044 // If `#[link_section]` is missing, then nothing to verify
2045 let attrs = tcx.codegen_fn_attrs(id);
2046 if attrs.link_section.is_none() {
2050 // For the wasm32 target statics with `#[link_section]` are placed into custom
2051 // sections of the final output file, but this isn't link custom sections of
2052 // other executable formats. Namely we can only embed a list of bytes,
2053 // nothing with pointers to anything else or relocations. If any relocation
2054 // show up, reject them here.
2055 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
2056 // the consumer's responsibility to ensure all bytes that have been read
2057 // have defined values.
2058 match tcx.const_eval_poly(id.to_def_id()) {
2059 Ok(ConstValue::ByRef { alloc, .. }) => {
2060 if alloc.relocations().len() != 0 {
2061 let msg = "statics with a custom `#[link_section]` must be a \
2062 simple list of bytes on the wasm target with no \
2063 extra levels of indirection such as references";
2064 tcx.sess.span_err(span, msg);
2067 Ok(_) => bug!("Matching on non-ByRef static"),
2072 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
2073 let item_def_id = tcx.hir().local_def_id(item.hir_id);
2074 // an error would be reported if this fails.
2075 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
2078 fn report_forbidden_specialization(
2080 impl_item: &hir::ImplItem<'_>,
2083 let mut err = struct_span_err!(
2087 "`{}` specializes an item from a parent `impl`, but \
2088 that item is not marked `default`",
2091 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
2093 match tcx.span_of_impl(parent_impl) {
2095 err.span_label(span, "parent `impl` is here");
2097 "to specialize, `{}` in the parent `impl` must be marked `default`",
2102 err.note(&format!("parent implementation is in crate `{}`", cname));
2109 fn check_specialization_validity<'tcx>(
2111 trait_def: &ty::TraitDef,
2112 trait_item: &ty::AssocItem,
2114 impl_item: &hir::ImplItem<'_>,
2116 let kind = match impl_item.kind {
2117 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
2118 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
2119 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
2122 let ancestors = match trait_def.ancestors(tcx, impl_id) {
2123 Ok(ancestors) => ancestors,
2126 let mut ancestor_impls = ancestors
2128 .filter_map(|parent| {
2129 if parent.is_from_trait() {
2132 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
2137 if ancestor_impls.peek().is_none() {
2138 // No parent, nothing to specialize.
2142 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
2144 // Parent impl exists, and contains the parent item we're trying to specialize, but
2145 // doesn't mark it `default`.
2146 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
2147 Some(Err(parent_impl.def_id()))
2150 // Parent impl contains item and makes it specializable.
2151 Some(_) => Some(Ok(())),
2153 // Parent impl doesn't mention the item. This means it's inherited from the
2154 // grandparent. In that case, if parent is a `default impl`, inherited items use the
2155 // "defaultness" from the grandparent, else they are final.
2157 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
2160 Some(Err(parent_impl.def_id()))
2166 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
2167 // item. This is allowed, the item isn't actually getting specialized here.
2168 let result = opt_result.unwrap_or(Ok(()));
2170 if let Err(parent_impl) = result {
2171 report_forbidden_specialization(tcx, impl_item, parent_impl);
2175 fn check_impl_items_against_trait<'tcx>(
2177 full_impl_span: Span,
2178 impl_id: LocalDefId,
2179 impl_trait_ref: ty::TraitRef<'tcx>,
2180 impl_item_refs: &[hir::ImplItemRef<'_>],
2182 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2184 // If the trait reference itself is erroneous (so the compilation is going
2185 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2186 // isn't populated for such impls.
2187 if impl_trait_ref.references_error() {
2191 // Negative impls are not expected to have any items
2192 match tcx.impl_polarity(impl_id) {
2193 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2194 ty::ImplPolarity::Negative => {
2195 if let [first_item_ref, ..] = impl_item_refs {
2196 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2201 "negative impls cannot have any items"
2209 // Locate trait definition and items
2210 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2212 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2214 // Check existing impl methods to see if they are both present in trait
2215 // and compatible with trait signature
2216 for impl_item in impl_items() {
2217 let namespace = impl_item.kind.namespace();
2218 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2219 let ty_trait_item = tcx
2220 .associated_items(impl_trait_ref.def_id)
2221 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2223 // Not compatible, but needed for the error message
2224 tcx.associated_items(impl_trait_ref.def_id)
2225 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2229 // Check that impl definition matches trait definition
2230 if let Some(ty_trait_item) = ty_trait_item {
2231 match impl_item.kind {
2232 hir::ImplItemKind::Const(..) => {
2233 // Find associated const definition.
2234 if ty_trait_item.kind == ty::AssocKind::Const {
2243 let mut err = struct_span_err!(
2247 "item `{}` is an associated const, \
2248 which doesn't match its trait `{}`",
2250 impl_trait_ref.print_only_trait_path()
2252 err.span_label(impl_item.span, "does not match trait");
2253 // We can only get the spans from local trait definition
2254 // Same for E0324 and E0325
2255 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2256 err.span_label(trait_span, "item in trait");
2261 hir::ImplItemKind::Fn(..) => {
2262 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2263 if ty_trait_item.kind == ty::AssocKind::Fn {
2264 compare_impl_method(
2273 let mut err = struct_span_err!(
2277 "item `{}` is an associated method, \
2278 which doesn't match its trait `{}`",
2280 impl_trait_ref.print_only_trait_path()
2282 err.span_label(impl_item.span, "does not match trait");
2283 if let Some(trait_span) = opt_trait_span {
2284 err.span_label(trait_span, "item in trait");
2289 hir::ImplItemKind::TyAlias(_) => {
2290 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2291 if ty_trait_item.kind == ty::AssocKind::Type {
2301 let mut err = struct_span_err!(
2305 "item `{}` is an associated type, \
2306 which doesn't match its trait `{}`",
2308 impl_trait_ref.print_only_trait_path()
2310 err.span_label(impl_item.span, "does not match trait");
2311 if let Some(trait_span) = opt_trait_span {
2312 err.span_label(trait_span, "item in trait");
2319 check_specialization_validity(
2323 impl_id.to_def_id(),
2329 // Check for missing items from trait
2330 let mut missing_items = Vec::new();
2331 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2332 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2333 let is_implemented = ancestors
2334 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2335 .map(|node_item| !node_item.defining_node.is_from_trait())
2338 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2339 if !trait_item.defaultness.has_value() {
2340 missing_items.push(*trait_item);
2346 if !missing_items.is_empty() {
2347 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2351 fn missing_items_err(
2354 missing_items: &[ty::AssocItem],
2355 full_impl_span: Span,
2357 let missing_items_msg = missing_items
2359 .map(|trait_item| trait_item.ident.to_string())
2360 .collect::<Vec<_>>()
2363 let mut err = struct_span_err!(
2367 "not all trait items implemented, missing: `{}`",
2370 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2372 // `Span` before impl block closing brace.
2373 let hi = full_impl_span.hi() - BytePos(1);
2374 // Point at the place right before the closing brace of the relevant `impl` to suggest
2375 // adding the associated item at the end of its body.
2376 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2377 // Obtain the level of indentation ending in `sugg_sp`.
2378 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2379 // Make the whitespace that will make the suggestion have the right indentation.
2380 let padding: String = (0..indentation).map(|_| " ").collect();
2382 for trait_item in missing_items {
2383 let snippet = suggestion_signature(&trait_item, tcx);
2384 let code = format!("{}{}\n{}", padding, snippet, padding);
2385 let msg = format!("implement the missing item: `{}`", snippet);
2386 let appl = Applicability::HasPlaceholders;
2387 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2388 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2389 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2391 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2397 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2398 fn bounds_from_generic_predicates<'tcx>(
2400 predicates: ty::GenericPredicates<'tcx>,
2401 ) -> (String, String) {
2402 let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
2403 let mut projections = vec![];
2404 for (predicate, _) in predicates.predicates {
2405 debug!("predicate {:?}", predicate);
2406 match predicate.skip_binders() {
2407 ty::PredicateAtom::Trait(trait_predicate, _) => {
2408 let entry = types.entry(trait_predicate.self_ty()).or_default();
2409 let def_id = trait_predicate.def_id();
2410 if Some(def_id) != tcx.lang_items().sized_trait() {
2411 // Type params are `Sized` by default, do not add that restriction to the list
2412 // if it is a positive requirement.
2413 entry.push(trait_predicate.def_id());
2416 ty::PredicateAtom::Projection(projection_pred) => {
2417 projections.push(ty::Binder::bind(projection_pred));
2422 let generics = if types.is_empty() {
2429 .filter_map(|t| match t.kind() {
2430 ty::Param(_) => Some(t.to_string()),
2431 // Avoid suggesting the following:
2432 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2435 .collect::<Vec<_>>()
2439 let mut where_clauses = vec![];
2440 for (ty, bounds) in types {
2441 for bound in &bounds {
2442 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2445 for projection in &projections {
2446 let p = projection.skip_binder();
2447 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2448 // insert the associated types where they correspond, but for now let's be "lazy" and
2449 // propose this instead of the following valid resugaring:
2450 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2451 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2453 let where_clauses = if where_clauses.is_empty() {
2456 format!(" where {}", where_clauses.join(", "))
2458 (generics, where_clauses)
2461 /// Return placeholder code for the given function.
2462 fn fn_sig_suggestion<'tcx>(
2464 sig: ty::FnSig<'tcx>,
2466 predicates: ty::GenericPredicates<'tcx>,
2467 assoc: &ty::AssocItem,
2474 Some(match ty.kind() {
2475 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2476 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2477 let reg = match &format!("{}", reg)[..] {
2478 "'_" | "" => String::new(),
2479 reg => format!("{} ", reg),
2481 if assoc.fn_has_self_parameter {
2482 match ref_ty.kind() {
2483 ty::Param(param) if param.name == kw::SelfUpper => {
2484 format!("&{}{}self", reg, mutability.prefix_str())
2487 _ => format!("self: {}", ty),
2490 format!("_: {}", ty)
2494 if assoc.fn_has_self_parameter && i == 0 {
2495 format!("self: {}", ty)
2497 format!("_: {}", ty)
2502 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2503 .filter_map(|arg| arg)
2504 .collect::<Vec<String>>()
2506 let output = sig.output();
2507 let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
2509 let unsafety = sig.unsafety.prefix_str();
2510 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2512 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2513 // not be present in the `fn` definition, not will we account for renamed
2514 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2515 // fill in a significant portion of the missing code, and other subsequent
2516 // suggestions can help the user fix the code.
2518 "{}fn {}{}({}){}{} {{ todo!() }}",
2519 unsafety, ident, generics, args, output, where_clauses
2523 /// Return placeholder code for the given associated item.
2524 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2525 /// structured suggestion.
2526 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2528 ty::AssocKind::Fn => {
2529 // We skip the binder here because the binder would deanonymize all
2530 // late-bound regions, and we don't want method signatures to show up
2531 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2532 // regions just fine, showing `fn(&MyType)`.
2535 tcx.fn_sig(assoc.def_id).skip_binder(),
2537 tcx.predicates_of(assoc.def_id),
2541 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2542 ty::AssocKind::Const => {
2543 let ty = tcx.type_of(assoc.def_id);
2544 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2545 format!("const {}: {} = {};", assoc.ident, ty, val)
2550 /// Checks whether a type can be represented in memory. In particular, it
2551 /// identifies types that contain themselves without indirection through a
2552 /// pointer, which would mean their size is unbounded.
2553 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2554 let rty = tcx.type_of(item_def_id);
2556 // Check that it is possible to represent this type. This call identifies
2557 // (1) types that contain themselves and (2) types that contain a different
2558 // recursive type. It is only necessary to throw an error on those that
2559 // contain themselves. For case 2, there must be an inner type that will be
2560 // caught by case 1.
2561 match rty.is_representable(tcx, sp) {
2562 Representability::SelfRecursive(spans) => {
2563 recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
2566 Representability::Representable | Representability::ContainsRecursive => (),
2571 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2572 let t = tcx.type_of(def_id);
2573 if let ty::Adt(def, substs) = t.kind() {
2574 if def.is_struct() {
2575 let fields = &def.non_enum_variant().fields;
2576 if fields.is_empty() {
2577 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2580 let e = fields[0].ty(tcx, substs);
2581 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2582 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2583 .span_label(sp, "SIMD elements must have the same type")
2588 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2589 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2595 "SIMD vector element type should be machine type"
2605 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2606 let repr = def.repr;
2608 for attr in tcx.get_attrs(def.did).iter() {
2609 for r in attr::find_repr_attrs(&tcx.sess, attr) {
2610 if let attr::ReprPacked(pack) = r {
2611 if let Some(repr_pack) = repr.pack {
2612 if pack as u64 != repr_pack.bytes() {
2617 "type has conflicting packed representation hints"
2625 if repr.align.is_some() {
2630 "type has conflicting packed and align representation hints"
2634 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2635 let mut err = struct_span_err!(
2639 "packed type cannot transitively contain a `#[repr(align)]` type"
2643 tcx.def_span(def_spans[0].0),
2645 "`{}` has a `#[repr(align)]` attribute",
2646 tcx.item_name(def_spans[0].0)
2650 if def_spans.len() > 2 {
2651 let mut first = true;
2652 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2653 let ident = tcx.item_name(*adt_def);
2658 "`{}` contains a field of type `{}`",
2659 tcx.type_of(def.did),
2663 format!("...which contains a field of type `{}`", ident)
2676 fn check_packed_inner(
2679 stack: &mut Vec<DefId>,
2680 ) -> Option<Vec<(DefId, Span)>> {
2681 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
2682 if def.is_struct() || def.is_union() {
2683 if def.repr.align.is_some() {
2684 return Some(vec![(def.did, DUMMY_SP)]);
2688 for field in &def.non_enum_variant().fields {
2689 if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
2690 if !stack.contains(&def.did) {
2691 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2692 defs.push((def.did, field.ident.span));
2705 /// Emit an error when encountering more or less than one variant in a transparent enum.
2706 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2707 let variant_spans: Vec<_> = adt
2710 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2712 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2713 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2714 err.span_label(sp, &msg);
2715 if let [start @ .., end] = &*variant_spans {
2716 for variant_span in start {
2717 err.span_label(*variant_span, "");
2719 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2724 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2726 fn bad_non_zero_sized_fields<'tcx>(
2728 adt: &'tcx ty::AdtDef,
2730 field_spans: impl Iterator<Item = Span>,
2733 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2734 let mut err = struct_span_err!(
2738 "{}transparent {} {}",
2739 if adt.is_enum() { "the variant of a " } else { "" },
2743 err.span_label(sp, &msg);
2744 for sp in field_spans {
2745 err.span_label(sp, "this field is non-zero-sized");
2750 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2751 if !adt.repr.transparent() {
2754 let sp = tcx.sess.source_map().guess_head_span(sp);
2756 if adt.is_union() && !tcx.features().transparent_unions {
2758 &tcx.sess.parse_sess,
2759 sym::transparent_unions,
2761 "transparent unions are unstable",
2766 if adt.variants.len() != 1 {
2767 bad_variant_count(tcx, adt, sp, adt.did);
2768 if adt.variants.is_empty() {
2769 // Don't bother checking the fields. No variants (and thus no fields) exist.
2774 // For each field, figure out if it's known to be a ZST and align(1)
2775 let field_infos = adt.all_fields().map(|field| {
2776 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2777 let param_env = tcx.param_env(field.did);
2778 let layout = tcx.layout_of(param_env.and(ty));
2779 // We are currently checking the type this field came from, so it must be local
2780 let span = tcx.hir().span_if_local(field.did).unwrap();
2781 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2782 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2786 let non_zst_fields =
2787 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2788 let non_zst_count = non_zst_fields.clone().count();
2789 if non_zst_count != 1 {
2790 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2792 for (span, zst, align1) in field_infos {
2798 "zero-sized field in transparent {} has alignment larger than 1",
2801 .span_label(span, "has alignment larger than 1")
2807 #[allow(trivial_numeric_casts)]
2808 pub fn check_enum<'tcx>(
2811 vs: &'tcx [hir::Variant<'tcx>],
2814 let def_id = tcx.hir().local_def_id(id);
2815 let def = tcx.adt_def(def_id);
2816 def.destructor(tcx); // force the destructor to be evaluated
2819 let attributes = tcx.get_attrs(def_id.to_def_id());
2820 if let Some(attr) = tcx.sess.find_by_name(&attributes, sym::repr) {
2825 "unsupported representation for zero-variant enum"
2827 .span_label(sp, "zero-variant enum")
2832 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2833 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2834 if !tcx.features().repr128 {
2836 &tcx.sess.parse_sess,
2839 "repr with 128-bit type is unstable",
2846 if let Some(ref e) = v.disr_expr {
2847 tcx.ensure().typeck(tcx.hir().local_def_id(e.hir_id));
2851 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2852 let is_unit = |var: &hir::Variant<'_>| match var.data {
2853 hir::VariantData::Unit(..) => true,
2857 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2858 let has_non_units = vs.iter().any(|var| !is_unit(var));
2859 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2860 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2862 if disr_non_unit || (disr_units && has_non_units) {
2864 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2869 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2870 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2871 // Check for duplicate discriminant values
2872 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2873 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2874 let variant_i_hir_id = tcx.hir().local_def_id_to_hir_id(variant_did.expect_local());
2875 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2876 let i_span = match variant_i.disr_expr {
2877 Some(ref expr) => tcx.hir().span(expr.hir_id),
2878 None => tcx.hir().span(variant_i_hir_id),
2880 let span = match v.disr_expr {
2881 Some(ref expr) => tcx.hir().span(expr.hir_id),
2888 "discriminant value `{}` already exists",
2891 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2892 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2895 disr_vals.push(discr);
2898 check_representable(tcx, sp, def_id);
2899 check_transparent(tcx, sp, def);
2902 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2907 "expected unit struct, unit variant or constant, found {}{}",
2909 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2914 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2915 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2919 fn item_def_id(&self) -> Option<DefId> {
2923 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2924 // FIXME: refactor this into a method
2925 let node = self.tcx.hir().get(self.body_id);
2926 if let Some(fn_like) = FnLikeNode::from_node(node) {
2929 hir::Constness::NotConst
2933 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2935 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
2936 let item_id = tcx.hir().ty_param_owner(hir_id);
2937 let item_def_id = tcx.hir().local_def_id(item_id);
2938 let generics = tcx.generics_of(item_def_id);
2939 let index = generics.param_def_id_to_index[&def_id];
2940 ty::GenericPredicates {
2942 predicates: tcx.arena.alloc_from_iter(
2943 self.param_env.caller_bounds().iter().filter_map(|predicate| {
2944 match predicate.skip_binders() {
2945 ty::PredicateAtom::Trait(data, _) if data.self_ty().is_param(index) => {
2946 // HACK(eddyb) should get the original `Span`.
2947 let span = tcx.def_span(def_id);
2948 Some((predicate, span))
2957 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2959 Some(def) => infer::EarlyBoundRegion(span, def.name),
2960 None => infer::MiscVariable(span),
2962 Some(self.next_region_var(v))
2965 fn allow_ty_infer(&self) -> bool {
2969 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2970 if let Some(param) = param {
2971 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2976 self.next_ty_var(TypeVariableOrigin {
2977 kind: TypeVariableOriginKind::TypeInference,
2986 param: Option<&ty::GenericParamDef>,
2988 ) -> &'tcx Const<'tcx> {
2989 if let Some(param) = param {
2990 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2995 self.next_const_var(
2997 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
3002 fn projected_ty_from_poly_trait_ref(
3006 item_segment: &hir::PathSegment<'_>,
3007 poly_trait_ref: ty::PolyTraitRef<'tcx>,
3009 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
3011 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
3015 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
3024 self.tcx().mk_projection(item_def_id, item_substs)
3027 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
3028 if ty.has_escaping_bound_vars() {
3029 ty // FIXME: normalization and escaping regions
3031 self.normalize_associated_types_in(span, &ty)
3035 fn set_tainted_by_errors(&self) {
3036 self.infcx.set_tainted_by_errors()
3039 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
3040 self.write_ty(hir_id, ty)
3044 /// Controls whether the arguments are tupled. This is used for the call
3047 /// Tupling means that all call-side arguments are packed into a tuple and
3048 /// passed as a single parameter. For example, if tupling is enabled, this
3051 /// fn f(x: (isize, isize))
3053 /// Can be called as:
3060 #[derive(Clone, Eq, PartialEq)]
3061 enum TupleArgumentsFlag {
3066 /// Controls how we perform fallback for unconstrained
3069 /// Do not fallback type variables to opaque types.
3071 /// Perform all possible kinds of fallback, including
3072 /// turning type variables to opaque types.
3076 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3078 inh: &'a Inherited<'a, 'tcx>,
3079 param_env: ty::ParamEnv<'tcx>,
3080 body_id: hir::HirId,
3081 ) -> FnCtxt<'a, 'tcx> {
3085 err_count_on_creation: inh.tcx.sess.err_count(),
3087 ret_coercion_span: RefCell::new(None),
3088 resume_yield_tys: None,
3089 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
3090 diverges: Cell::new(Diverges::Maybe),
3091 has_errors: Cell::new(false),
3092 enclosing_breakables: RefCell::new(EnclosingBreakables {
3094 by_id: Default::default(),
3100 pub fn sess(&self) -> &Session {
3104 pub fn errors_reported_since_creation(&self) -> bool {
3105 self.tcx.sess.err_count() > self.err_count_on_creation
3108 /// Produces warning on the given node, if the current point in the
3109 /// function is unreachable, and there hasn't been another warning.
3110 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
3111 // FIXME: Combine these two 'if' expressions into one once
3112 // let chains are implemented
3113 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
3114 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
3115 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
3116 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
3117 if !span.is_desugaring(DesugaringKind::CondTemporary)
3118 && !span.is_desugaring(DesugaringKind::Async)
3119 && !orig_span.is_desugaring(DesugaringKind::Await)
3121 self.diverges.set(Diverges::WarnedAlways);
3123 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
3125 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
3126 let msg = format!("unreachable {}", kind);
3128 .span_label(span, &msg)
3132 .unwrap_or("any code following this expression is unreachable"),
3140 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
3141 ObligationCause::new(span, self.body_id, code)
3144 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
3145 self.cause(span, ObligationCauseCode::MiscObligation)
3148 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
3149 /// version (resolve_vars_if_possible), this version will
3150 /// also select obligations if it seems useful, in an effort
3151 /// to get more type information.
3152 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3153 debug!("resolve_vars_with_obligations(ty={:?})", ty);
3155 // No Infer()? Nothing needs doing.
3156 if !ty.has_infer_types_or_consts() {
3157 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3161 // If `ty` is a type variable, see whether we already know what it is.
3162 ty = self.resolve_vars_if_possible(&ty);
3163 if !ty.has_infer_types_or_consts() {
3164 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3168 // If not, try resolving pending obligations as much as
3169 // possible. This can help substantially when there are
3170 // indirect dependencies that don't seem worth tracking
3172 self.select_obligations_where_possible(false, |_| {});
3173 ty = self.resolve_vars_if_possible(&ty);
3175 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3179 fn record_deferred_call_resolution(
3181 closure_def_id: DefId,
3182 r: DeferredCallResolution<'tcx>,
3184 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3185 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3188 fn remove_deferred_call_resolutions(
3190 closure_def_id: DefId,
3191 ) -> Vec<DeferredCallResolution<'tcx>> {
3192 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3193 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3196 pub fn tag(&self) -> String {
3197 format!("{:p}", self)
3200 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3201 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3202 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3207 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3209 "write_ty({:?}, {:?}) in fcx {}",
3211 self.resolve_vars_if_possible(&ty),
3214 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
3216 if ty.references_error() {
3217 self.has_errors.set(true);
3218 self.set_tainted_by_errors();
3222 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3223 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
3226 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3227 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3230 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3231 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3232 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3233 self.write_substs(hir_id, method.substs);
3235 // When the method is confirmed, the `method.substs` includes
3236 // parameters from not just the method, but also the impl of
3237 // the method -- in particular, the `Self` type will be fully
3238 // resolved. However, those are not something that the "user
3239 // specified" -- i.e., those types come from the inferred type
3240 // of the receiver, not something the user wrote. So when we
3241 // create the user-substs, we want to replace those earlier
3242 // types with just the types that the user actually wrote --
3243 // that is, those that appear on the *method itself*.
3245 // As an example, if the user wrote something like
3246 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3247 // type of `foo` (possibly adjusted), but we don't want to
3248 // include that. We want just the `[_, u32]` part.
3249 if !method.substs.is_noop() {
3250 let method_generics = self.tcx.generics_of(method.def_id);
3251 if !method_generics.params.is_empty() {
3252 let user_type_annotation = self.infcx.probe(|_| {
3253 let user_substs = UserSubsts {
3254 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3255 let i = param.index as usize;
3256 if i < method_generics.parent_count {
3257 self.infcx.var_for_def(DUMMY_SP, param)
3262 user_self_ty: None, // not relevant here
3265 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3271 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3272 self.write_user_type_annotation(hir_id, user_type_annotation);
3277 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3278 if !substs.is_noop() {
3279 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3281 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
3285 /// Given the substs that we just converted from the HIR, try to
3286 /// canonicalize them and store them as user-given substitutions
3287 /// (i.e., substitutions that must be respected by the NLL check).
3289 /// This should be invoked **before any unifications have
3290 /// occurred**, so that annotations like `Vec<_>` are preserved
3292 pub fn write_user_type_annotation_from_substs(
3296 substs: SubstsRef<'tcx>,
3297 user_self_ty: Option<UserSelfTy<'tcx>>,
3300 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3301 user_self_ty={:?} in fcx {}",
3309 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3310 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3312 UserSubsts { substs, user_self_ty },
3314 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3315 self.write_user_type_annotation(hir_id, canonicalized);
3319 pub fn write_user_type_annotation(
3322 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3325 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3327 canonical_user_type_annotation,
3331 if !canonical_user_type_annotation.is_identity() {
3334 .user_provided_types_mut()
3335 .insert(hir_id, canonical_user_type_annotation);
3337 debug!("write_user_type_annotation: skipping identity substs");
3341 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3342 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3348 let autoborrow_mut = adj.iter().any(|adj| {
3349 matches!(adj, &Adjustment {
3350 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
3355 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3356 Entry::Vacant(entry) => {
3359 Entry::Occupied(mut entry) => {
3360 debug!(" - composing on top of {:?}", entry.get());
3361 match (&entry.get()[..], &adj[..]) {
3362 // Applying any adjustment on top of a NeverToAny
3363 // is a valid NeverToAny adjustment, because it can't
3365 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3367 Adjustment { kind: Adjust::Deref(_), .. },
3368 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3370 Adjustment { kind: Adjust::Deref(_), .. },
3371 .. // Any following adjustments are allowed.
3373 // A reborrow has no effect before a dereference.
3375 // FIXME: currently we never try to compose autoderefs
3376 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3378 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3379 expr, entry.get(), adj)
3381 *entry.get_mut() = adj;
3385 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
3386 // In this case implicit use of `Deref` and `Index` within `<expr>` should
3387 // instead be `DerefMut` and `IndexMut`, so fix those up.
3389 self.convert_place_derefs_to_mutable(expr);
3393 /// Basically whenever we are converting from a type scheme into
3394 /// the fn body space, we always want to normalize associated
3395 /// types as well. This function combines the two.
3396 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3398 T: TypeFoldable<'tcx>,
3400 let value = value.subst(self.tcx, substs);
3401 let result = self.normalize_associated_types_in(span, &value);
3402 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3406 /// As `instantiate_type_scheme`, but for the bounds found in a
3407 /// generic type scheme.
3408 fn instantiate_bounds(
3412 substs: SubstsRef<'tcx>,
3413 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3414 let bounds = self.tcx.predicates_of(def_id);
3415 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3416 let result = bounds.instantiate(self.tcx, substs);
3417 let result = self.normalize_associated_types_in(span, &result);
3419 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3420 bounds, substs, result, spans,
3425 /// Replaces the opaque types from the given value with type variables,
3426 /// and records the `OpaqueTypeMap` for later use during writeback. See
3427 /// `InferCtxt::instantiate_opaque_types` for more details.
3428 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3430 parent_id: hir::HirId,
3434 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3436 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3437 parent_def_id, value
3440 let (value, opaque_type_map) =
3441 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3449 let mut opaque_types = self.opaque_types.borrow_mut();
3450 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3451 for (ty, decl) in opaque_type_map {
3452 let _ = opaque_types.insert(ty, decl);
3453 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3459 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3461 T: TypeFoldable<'tcx>,
3463 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3466 fn normalize_associated_types_in_as_infer_ok<T>(
3470 ) -> InferOk<'tcx, T>
3472 T: TypeFoldable<'tcx>,
3474 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3477 pub fn require_type_meets(
3481 code: traits::ObligationCauseCode<'tcx>,
3484 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3487 pub fn require_type_is_sized(
3491 code: traits::ObligationCauseCode<'tcx>,
3493 if !ty.references_error() {
3494 let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
3495 self.require_type_meets(ty, span, code, lang_item);
3499 pub fn require_type_is_sized_deferred(
3503 code: traits::ObligationCauseCode<'tcx>,
3505 if !ty.references_error() {
3506 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3510 pub fn register_bound(
3514 cause: traits::ObligationCause<'tcx>,
3516 if !ty.references_error() {
3517 self.fulfillment_cx.borrow_mut().register_bound(
3527 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3528 let t = AstConv::ast_ty_to_ty(self, ast_t);
3529 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3533 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3534 let ty = self.to_ty(ast_ty);
3535 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3537 if Self::can_contain_user_lifetime_bounds(ty) {
3538 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3539 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3540 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3546 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3547 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3548 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3549 self.register_wf_obligation(
3551 self.tcx.hir().span(ast_c.hir_id),
3552 ObligationCauseCode::MiscObligation,
3557 pub fn const_arg_to_const(
3559 ast_c: &hir::AnonConst,
3560 param_def_id: DefId,
3561 ) -> &'tcx ty::Const<'tcx> {
3562 let const_def = ty::WithOptConstParam {
3563 did: self.tcx.hir().local_def_id(ast_c.hir_id),
3564 const_param_did: Some(param_def_id),
3566 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
3567 self.register_wf_obligation(
3569 self.tcx.hir().span(ast_c.hir_id),
3570 ObligationCauseCode::MiscObligation,
3575 // If the type given by the user has free regions, save it for later, since
3576 // NLL would like to enforce those. Also pass in types that involve
3577 // projections, since those can resolve to `'static` bounds (modulo #54940,
3578 // which hopefully will be fixed by the time you see this comment, dear
3579 // reader, although I have my doubts). Also pass in types with inference
3580 // types, because they may be repeated. Other sorts of things are already
3581 // sufficiently enforced with erased regions. =)
3582 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3584 T: TypeFoldable<'tcx>,
3586 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3589 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3590 match self.typeck_results.borrow().node_types().get(id) {
3592 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
3595 "no type for node {}: {} in fcx {}",
3597 self.tcx.hir().node_to_string(id),
3604 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3605 pub fn register_wf_obligation(
3607 arg: subst::GenericArg<'tcx>,
3609 code: traits::ObligationCauseCode<'tcx>,
3611 // WF obligations never themselves fail, so no real need to give a detailed cause:
3612 let cause = traits::ObligationCause::new(span, self.body_id, code);
3613 self.register_predicate(traits::Obligation::new(
3616 ty::PredicateAtom::WellFormed(arg).to_predicate(self.tcx),
3620 /// Registers obligations that all `substs` are well-formed.
3621 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3622 for arg in substs.iter().filter(|arg| {
3623 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3625 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3629 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3630 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3631 /// trait/region obligations.
3633 /// For example, if there is a function:
3636 /// fn foo<'a,T:'a>(...)
3639 /// and a reference:
3645 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3646 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3647 pub fn add_obligations_for_parameters(
3649 cause: traits::ObligationCause<'tcx>,
3650 predicates: ty::InstantiatedPredicates<'tcx>,
3652 assert!(!predicates.has_escaping_bound_vars());
3654 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3656 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3657 self.register_predicate(obligation);
3661 // FIXME(arielb1): use this instead of field.ty everywhere
3662 // Only for fields! Returns <none> for methods>
3663 // Indifferent to privacy flags
3667 field: &'tcx ty::FieldDef,
3668 substs: SubstsRef<'tcx>,
3670 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3673 fn check_casts(&self) {
3674 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3675 for cast in deferred_cast_checks.drain(..) {
3680 fn resolve_generator_interiors(&self, def_id: DefId) {
3681 let mut generators = self.deferred_generator_interiors.borrow_mut();
3682 for (body_id, interior, kind) in generators.drain(..) {
3683 self.select_obligations_where_possible(false, |_| {});
3684 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3688 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3690 // - Unconstrained ints are replaced with `i32`.
3692 // - Unconstrained floats are replaced with with `f64`.
3694 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3695 // is enabled. Otherwise, they are replaced with `()`.
3697 // Fallback becomes very dubious if we have encountered type-checking errors.
3698 // In that case, fallback to Error.
3699 // The return value indicates whether fallback has occurred.
3700 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3701 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3702 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3704 assert!(ty.is_ty_infer());
3705 let fallback = match self.type_is_unconstrained_numeric(ty) {
3706 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
3707 UnconstrainedInt => self.tcx.types.i32,
3708 UnconstrainedFloat => self.tcx.types.f64,
3709 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3711 // This type variable was created from the instantiation of an opaque
3712 // type. The fact that we're attempting to perform fallback for it
3713 // means that the function neither constrained it to a concrete
3714 // type, nor to the opaque type itself.
3716 // For example, in this code:
3719 // type MyType = impl Copy;
3720 // fn defining_use() -> MyType { true }
3721 // fn other_use() -> MyType { defining_use() }
3724 // `defining_use` will constrain the instantiated inference
3725 // variable to `bool`, while `other_use` will constrain
3726 // the instantiated inference variable to `MyType`.
3728 // When we process opaque types during writeback, we
3729 // will handle cases like `other_use`, and not count
3730 // them as defining usages
3732 // However, we also need to handle cases like this:
3735 // pub type Foo = impl Copy;
3736 // fn produce() -> Option<Foo> {
3741 // In the above snippet, the inference variable created by
3742 // instantiating `Option<Foo>` will be completely unconstrained.
3743 // We treat this as a non-defining use by making the inference
3744 // variable fall back to the opaque type itself.
3745 if let FallbackMode::All = mode {
3746 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3748 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3760 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3761 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3765 fn select_all_obligations_or_error(&self) {
3766 debug!("select_all_obligations_or_error");
3767 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3768 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3772 /// Select as many obligations as we can at present.
3773 fn select_obligations_where_possible(
3775 fallback_has_occurred: bool,
3776 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3778 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3779 if let Err(mut errors) = result {
3780 mutate_fullfillment_errors(&mut errors);
3781 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3785 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3786 /// returns a type of `&T`, but the actual type we assign to the
3787 /// *expression* is `T`. So this function just peels off the return
3788 /// type by one layer to yield `T`.
3789 fn make_overloaded_place_return_type(
3791 method: MethodCallee<'tcx>,
3792 ) -> ty::TypeAndMut<'tcx> {
3793 // extract method return type, which will be &T;
3794 let ret_ty = method.sig.output();
3796 // method returns &T, but the type as visible to user is T, so deref
3797 ret_ty.builtin_deref(true).unwrap()
3800 fn check_method_argument_types(
3803 expr: &'tcx hir::Expr<'tcx>,
3804 method: Result<MethodCallee<'tcx>, ()>,
3805 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3806 tuple_arguments: TupleArgumentsFlag,
3807 expected: Expectation<'tcx>,
3809 let has_error = match method {
3810 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3814 let err_inputs = self.err_args(args_no_rcvr.len());
3816 let err_inputs = match tuple_arguments {
3817 DontTupleArguments => err_inputs,
3818 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3821 self.check_argument_types(
3831 return self.tcx.ty_error();
3834 let method = method.unwrap();
3835 // HACK(eddyb) ignore self in the definition (see above).
3836 let expected_arg_tys = self.expected_inputs_for_expected_output(
3839 method.sig.output(),
3840 &method.sig.inputs()[1..],
3842 self.check_argument_types(
3845 &method.sig.inputs()[1..],
3846 &expected_arg_tys[..],
3848 method.sig.c_variadic,
3850 self.tcx.hir().span_if_local(method.def_id),
3855 fn self_type_matches_expected_vid(
3857 trait_ref: ty::PolyTraitRef<'tcx>,
3858 expected_vid: ty::TyVid,
3860 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3862 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3863 trait_ref, self_ty, expected_vid
3865 match *self_ty.kind() {
3866 ty::Infer(ty::TyVar(found_vid)) => {
3867 // FIXME: consider using `sub_root_var` here so we
3868 // can see through subtyping.
3869 let found_vid = self.root_var(found_vid);
3870 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3871 expected_vid == found_vid
3877 fn obligations_for_self_ty<'b>(
3880 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3883 // FIXME: consider using `sub_root_var` here so we
3884 // can see through subtyping.
3885 let ty_var_root = self.root_var(self_ty);
3887 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3890 self.fulfillment_cx.borrow().pending_obligations()
3895 .pending_obligations()
3897 .filter_map(move |obligation| {
3898 match obligation.predicate.skip_binders() {
3899 ty::PredicateAtom::Projection(data) => {
3900 Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation))
3902 ty::PredicateAtom::Trait(data, _) => {
3903 Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation))
3905 ty::PredicateAtom::Subtype(..) => None,
3906 ty::PredicateAtom::RegionOutlives(..) => None,
3907 ty::PredicateAtom::TypeOutlives(..) => None,
3908 ty::PredicateAtom::WellFormed(..) => None,
3909 ty::PredicateAtom::ObjectSafe(..) => None,
3910 ty::PredicateAtom::ConstEvaluatable(..) => None,
3911 ty::PredicateAtom::ConstEquate(..) => None,
3912 // N.B., this predicate is created by breaking down a
3913 // `ClosureType: FnFoo()` predicate, where
3914 // `ClosureType` represents some `Closure`. It can't
3915 // possibly be referring to the current closure,
3916 // because we haven't produced the `Closure` for
3917 // this closure yet; this is exactly why the other
3918 // code is looking for a self type of a unresolved
3919 // inference variable.
3920 ty::PredicateAtom::ClosureKind(..) => None,
3921 ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
3924 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3927 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3928 self.obligations_for_self_ty(self_ty)
3929 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3932 /// Generic function that factors out common logic from function calls,
3933 /// method calls and overloaded operators.
3934 fn check_argument_types(
3937 expr: &'tcx hir::Expr<'tcx>,
3938 fn_inputs: &[Ty<'tcx>],
3939 expected_arg_tys: &[Ty<'tcx>],
3940 args: &'tcx [hir::Expr<'tcx>],
3942 tuple_arguments: TupleArgumentsFlag,
3943 def_span: Option<Span>,
3946 // Grab the argument types, supplying fresh type variables
3947 // if the wrong number of arguments were supplied
3948 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3950 // All the input types from the fn signature must outlive the call
3951 // so as to validate implied bounds.
3952 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3953 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3956 let expected_arg_count = fn_inputs.len();
3958 let param_count_error = |expected_count: usize,
3963 let (span, start_span, args) = match &expr.kind {
3964 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3965 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
3967 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3970 .and_then(|args| args.args.iter().last())
3971 // Account for `foo.bar::<T>()`.
3973 // Skip the closing `>`.
3976 .next_point(tcx.sess.source_map().next_point(arg.span()))
3979 &args[1..], // Skip the receiver.
3981 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3983 let arg_spans = if args.is_empty() {
3985 // ^^^-- supplied 0 arguments
3987 // expected 2 arguments
3988 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3991 // ^^^ - - - supplied 3 arguments
3993 // expected 2 arguments
3994 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3997 let mut err = tcx.sess.struct_span_err_with_code(
4000 "this function takes {}{} but {} {} supplied",
4001 if c_variadic { "at least " } else { "" },
4002 potentially_plural_count(expected_count, "argument"),
4003 potentially_plural_count(arg_count, "argument"),
4004 if arg_count == 1 { "was" } else { "were" }
4006 DiagnosticId::Error(error_code.to_owned()),
4008 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
4009 for (i, span) in arg_spans.into_iter().enumerate() {
4012 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
4016 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
4017 err.span_label(def_s, "defined here");
4020 let sugg_span = tcx.sess.source_map().end_point(expr.span);
4021 // remove closing `)` from the span
4022 let sugg_span = sugg_span.shrink_to_lo();
4023 err.span_suggestion(
4025 "expected the unit value `()`; create it with empty parentheses",
4027 Applicability::MachineApplicable,
4034 if c_variadic { "at least " } else { "" },
4035 potentially_plural_count(expected_count, "argument")
4042 let mut expected_arg_tys = expected_arg_tys.to_vec();
4044 let formal_tys = if tuple_arguments == TupleArguments {
4045 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4046 match tuple_type.kind() {
4047 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4048 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4049 expected_arg_tys = vec![];
4050 self.err_args(args.len())
4052 ty::Tuple(arg_types) => {
4053 expected_arg_tys = match expected_arg_tys.get(0) {
4054 Some(&ty) => match ty.kind() {
4055 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4060 arg_types.iter().map(|k| k.expect_ty()).collect()
4067 "cannot use call notation; the first type parameter \
4068 for the function trait is neither a tuple nor unit"
4071 expected_arg_tys = vec![];
4072 self.err_args(args.len())
4075 } else if expected_arg_count == supplied_arg_count {
4077 } else if c_variadic {
4078 if supplied_arg_count >= expected_arg_count {
4081 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4082 expected_arg_tys = vec![];
4083 self.err_args(supplied_arg_count)
4086 // is the missing argument of type `()`?
4087 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4088 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4089 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4090 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4094 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4096 expected_arg_tys = vec![];
4097 self.err_args(supplied_arg_count)
4101 "check_argument_types: formal_tys={:?}",
4102 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4105 // If there is no expectation, expect formal_tys.
4106 let expected_arg_tys =
4107 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4109 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4111 // Check the arguments.
4112 // We do this in a pretty awful way: first we type-check any arguments
4113 // that are not closures, then we type-check the closures. This is so
4114 // that we have more information about the types of arguments when we
4115 // type-check the functions. This isn't really the right way to do this.
4116 for &check_closures in &[false, true] {
4117 debug!("check_closures={}", check_closures);
4119 // More awful hacks: before we check argument types, try to do
4120 // an "opportunistic" trait resolution of any trait bounds on
4121 // the call. This helps coercions.
4123 self.select_obligations_where_possible(false, |errors| {
4124 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4125 self.point_at_arg_instead_of_call_if_possible(
4127 &final_arg_types[..],
4134 // For C-variadic functions, we don't have a declared type for all of
4135 // the arguments hence we only do our usual type checking with
4136 // the arguments who's types we do know.
4137 let t = if c_variadic {
4139 } else if tuple_arguments == TupleArguments {
4144 for (i, arg) in args.iter().take(t).enumerate() {
4145 // Warn only for the first loop (the "no closures" one).
4146 // Closure arguments themselves can't be diverging, but
4147 // a previous argument can, e.g., `foo(panic!(), || {})`.
4148 if !check_closures {
4149 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4152 let is_closure = match arg.kind {
4153 ExprKind::Closure(..) => true,
4157 if is_closure != check_closures {
4161 debug!("checking the argument");
4162 let formal_ty = formal_tys[i];
4164 // The special-cased logic below has three functions:
4165 // 1. Provide as good of an expected type as possible.
4166 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4168 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4170 // 2. Coerce to the most detailed type that could be coerced
4171 // to, which is `expected_ty` if `rvalue_hint` returns an
4172 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4173 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4174 // We're processing function arguments so we definitely want to use
4175 // two-phase borrows.
4176 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
4177 final_arg_types.push((i, checked_ty, coerce_ty));
4179 // 3. Relate the expected type and the formal one,
4180 // if the expected type was used for the coercion.
4181 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4185 // We also need to make sure we at least write the ty of the other
4186 // arguments which we skipped above.
4188 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4189 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4190 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4193 for arg in args.iter().skip(expected_arg_count) {
4194 let arg_ty = self.check_expr(&arg);
4196 // There are a few types which get autopromoted when passed via varargs
4197 // in C but we just error out instead and require explicit casts.
4198 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4199 match arg_ty.kind() {
4200 ty::Float(ast::FloatTy::F32) => {
4201 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4203 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4204 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4206 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4207 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4210 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4211 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4212 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4220 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4221 vec![self.tcx.ty_error(); len]
4224 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4225 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4226 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4227 /// can be not easily comparable with predicate type (because of coercion). If the types match
4228 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4229 /// the corresponding argument's expression span instead of the `fn` call path span.
4230 fn point_at_arg_instead_of_call_if_possible(
4232 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4233 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4235 args: &'tcx [hir::Expr<'tcx>],
4237 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4238 // the `?` operator.
4239 if call_sp.desugaring_kind().is_some() {
4243 for error in errors {
4244 // Only if the cause is somewhere inside the expression we want try to point at arg.
4245 // Otherwise, it means that the cause is somewhere else and we should not change
4246 // anything because we can break the correct span.
4247 if !call_sp.contains(error.obligation.cause.span) {
4251 if let ty::PredicateAtom::Trait(predicate, _) =
4252 error.obligation.predicate.skip_binders()
4254 // Collect the argument position for all arguments that could have caused this
4255 // `FulfillmentError`.
4256 let mut referenced_in = final_arg_types
4258 .map(|&(i, checked_ty, _)| (i, checked_ty))
4259 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4260 .flat_map(|(i, ty)| {
4261 let ty = self.resolve_vars_if_possible(&ty);
4262 // We walk the argument type because the argument's type could have
4263 // been `Option<T>`, but the `FulfillmentError` references `T`.
4264 if ty.walk().any(|arg| arg == predicate.self_ty().into()) {
4270 .collect::<Vec<_>>();
4272 // Both checked and coerced types could have matched, thus we need to remove
4274 referenced_in.sort();
4275 referenced_in.dedup();
4277 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4278 // We make sure that only *one* argument matches the obligation failure
4279 // and we assign the obligation's span to its expression's.
4280 error.obligation.cause.make_mut().span = args[ref_in].span;
4281 error.points_at_arg_span = true;
4287 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4288 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4289 /// were caused by them. If they were, we point at the corresponding type argument's span
4290 /// instead of the `fn` call path span.
4291 fn point_at_type_arg_instead_of_call_if_possible(
4293 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4294 call_expr: &'tcx hir::Expr<'tcx>,
4296 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4297 if let hir::ExprKind::Path(qpath) = &path.kind {
4298 if let hir::QPath::Resolved(_, path) = &qpath {
4299 for error in errors {
4300 if let ty::PredicateAtom::Trait(predicate, _) =
4301 error.obligation.predicate.skip_binders()
4303 // If any of the type arguments in this path segment caused the
4304 // `FullfillmentError`, point at its span (#61860).
4308 .filter_map(|seg| seg.args.as_ref())
4309 .flat_map(|a| a.args.iter())
4311 if let hir::GenericArg::Type(hir_ty) = &arg {
4312 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4315 // Avoid ICE with associated types. As this is best
4316 // effort only, it's ok to ignore the case. It
4317 // would trigger in `is_send::<T::AssocType>();`
4318 // from `typeck-default-trait-impl-assoc-type.rs`.
4320 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4321 let ty = self.resolve_vars_if_possible(&ty);
4322 if ty == predicate.self_ty() {
4323 error.obligation.cause.make_mut().span = hir_ty.span;
4335 // AST fragment checking
4336 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4340 ast::LitKind::Str(..) => tcx.mk_static_str(),
4341 ast::LitKind::ByteStr(ref v) => {
4342 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4344 ast::LitKind::Byte(_) => tcx.types.u8,
4345 ast::LitKind::Char(_) => tcx.types.char,
4346 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4347 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4348 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4349 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
4350 ty::Int(_) | ty::Uint(_) => Some(ty),
4351 ty::Char => Some(tcx.types.u8),
4352 ty::RawPtr(..) => Some(tcx.types.usize),
4353 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4356 opt_ty.unwrap_or_else(|| self.next_int_var())
4358 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4359 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4360 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
4361 ty::Float(_) => Some(ty),
4364 opt_ty.unwrap_or_else(|| self.next_float_var())
4366 ast::LitKind::Bool(_) => tcx.types.bool,
4367 ast::LitKind::Err(_) => tcx.ty_error(),
4371 /// Unifies the output type with the expected type early, for more coercions
4372 /// and forward type information on the input expressions.
4373 fn expected_inputs_for_expected_output(
4376 expected_ret: Expectation<'tcx>,
4377 formal_ret: Ty<'tcx>,
4378 formal_args: &[Ty<'tcx>],
4379 ) -> Vec<Ty<'tcx>> {
4380 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4381 let ret_ty = match expected_ret.only_has_type(self) {
4383 None => return Vec::new(),
4385 let expect_args = self
4386 .fudge_inference_if_ok(|| {
4387 // Attempt to apply a subtyping relationship between the formal
4388 // return type (likely containing type variables if the function
4389 // is polymorphic) and the expected return type.
4390 // No argument expectations are produced if unification fails.
4391 let origin = self.misc(call_span);
4392 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4394 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4395 // to identity so the resulting type is not constrained.
4398 // Process any obligations locally as much as
4399 // we can. We don't care if some things turn
4400 // out unconstrained or ambiguous, as we're
4401 // just trying to get hints here.
4402 self.save_and_restore_in_snapshot_flag(|_| {
4403 let mut fulfill = TraitEngine::new(self.tcx);
4404 for obligation in ok.obligations {
4405 fulfill.register_predicate_obligation(self, obligation);
4407 fulfill.select_where_possible(self)
4411 Err(_) => return Err(()),
4414 // Record all the argument types, with the substitutions
4415 // produced from the above subtyping unification.
4416 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4418 .unwrap_or_default();
4420 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4421 formal_args, formal_ret, expect_args, expected_ret
4426 pub fn check_struct_path(
4430 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4431 let path_span = qpath.qself_span();
4432 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4433 let variant = match def {
4435 self.set_tainted_by_errors();
4438 Res::Def(DefKind::Variant, _) => match ty.kind() {
4439 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4440 _ => bug!("unexpected type: {:?}", ty),
4442 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4443 | Res::SelfTy(..) => match ty.kind() {
4444 ty::Adt(adt, substs) if !adt.is_enum() => {
4445 Some((adt.non_enum_variant(), adt.did, substs))
4449 _ => bug!("unexpected definition: {:?}", def),
4452 if let Some((variant, did, substs)) = variant {
4453 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4454 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4456 // Check bounds on type arguments used in the path.
4457 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4459 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4460 self.add_obligations_for_parameters(cause, bounds);
4468 "expected struct, variant or union type, found {}",
4469 ty.sort_string(self.tcx)
4471 .span_label(path_span, "not a struct")
4477 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4478 // The newly resolved definition is written into `type_dependent_defs`.
4479 fn finish_resolving_struct_path(
4484 ) -> (Res, Ty<'tcx>) {
4486 QPath::Resolved(ref maybe_qself, ref path) => {
4487 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4488 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4491 QPath::TypeRelative(ref qself, ref segment) => {
4492 let ty = self.to_ty(qself);
4494 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4500 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4501 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
4502 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4504 // Write back the new resolution.
4505 self.write_resolution(hir_id, result);
4507 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4509 QPath::LangItem(lang_item, span) => {
4510 self.resolve_lang_item_path(lang_item, span, hir_id)
4515 fn resolve_lang_item_path(
4517 lang_item: hir::LangItem,
4520 ) -> (Res, Ty<'tcx>) {
4521 let def_id = self.tcx.require_lang_item(lang_item, Some(span));
4522 let def_kind = self.tcx.def_kind(def_id);
4524 let item_ty = if let DefKind::Variant = def_kind {
4525 self.tcx.type_of(self.tcx.parent(def_id).expect("variant w/out parent"))
4527 self.tcx.type_of(def_id)
4529 let substs = self.infcx.fresh_substs_for_item(span, def_id);
4530 let ty = item_ty.subst(self.tcx, substs);
4532 self.write_resolution(hir_id, Ok((def_kind, def_id)));
4533 self.add_required_obligations(span, def_id, &substs);
4534 (Res::Def(def_kind, def_id), ty)
4537 /// Resolves an associated value path into a base type and associated constant, or method
4538 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4539 pub fn resolve_ty_and_res_ufcs<'b>(
4541 qpath: &'b QPath<'b>,
4544 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4545 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4546 let (ty, qself, item_segment) = match *qpath {
4547 QPath::Resolved(ref opt_qself, ref path) => {
4550 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4554 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4555 QPath::LangItem(..) => bug!("`resolve_ty_and_res_ufcs` called on `LangItem`"),
4557 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
4559 // Return directly on cache hit. This is useful to avoid doubly reporting
4560 // errors with default match binding modes. See #44614.
4562 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4563 return (def, Some(ty), slice::from_ref(&**item_segment));
4565 let item_name = item_segment.ident;
4566 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4567 let result = match error {
4568 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4569 _ => Err(ErrorReported),
4571 if item_name.name != kw::Invalid {
4572 if let Some(mut e) = self.report_method_error(
4576 SelfSource::QPath(qself),
4586 // Write back the new resolution.
4587 self.write_resolution(hir_id, result);
4589 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4591 slice::from_ref(&**item_segment),
4595 pub fn check_decl_initializer(
4597 local: &'tcx hir::Local<'tcx>,
4598 init: &'tcx hir::Expr<'tcx>,
4600 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4601 // for #42640 (default match binding modes).
4604 let ref_bindings = local.pat.contains_explicit_ref_binding();
4606 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4607 if let Some(m) = ref_bindings {
4608 // Somewhat subtle: if we have a `ref` binding in the pattern,
4609 // we want to avoid introducing coercions for the RHS. This is
4610 // both because it helps preserve sanity and, in the case of
4611 // ref mut, for soundness (issue #23116). In particular, in
4612 // the latter case, we need to be clear that the type of the
4613 // referent for the reference that results is *equal to* the
4614 // type of the place it is referencing, and not some
4615 // supertype thereof.
4616 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4617 self.demand_eqtype(init.span, local_ty, init_ty);
4620 self.check_expr_coercable_to_type(init, local_ty, None)
4624 /// Type check a `let` statement.
4625 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4626 // Determine and write the type which we'll check the pattern against.
4627 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4628 self.write_ty(local.hir_id, ty);
4630 // Type check the initializer.
4631 if let Some(ref init) = local.init {
4632 let init_ty = self.check_decl_initializer(local, &init);
4633 self.overwrite_local_ty_if_err(local, ty, init_ty);
4636 // Does the expected pattern type originate from an expression and what is the span?
4637 let (origin_expr, ty_span) = match (local.ty, local.init) {
4638 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4639 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4640 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4643 // Type check the pattern. Override if necessary to avoid knock-on errors.
4644 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4645 let pat_ty = self.node_ty(local.pat.hir_id);
4646 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4649 fn overwrite_local_ty_if_err(
4651 local: &'tcx hir::Local<'tcx>,
4655 if ty.references_error() {
4656 // Override the types everywhere with `err()` to avoid knock on errors.
4657 self.write_ty(local.hir_id, ty);
4658 self.write_ty(local.pat.hir_id, ty);
4659 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4660 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4661 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4665 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4666 err.span_suggestion_short(
4667 span.shrink_to_hi(),
4668 "consider using a semicolon here",
4670 Applicability::MachineApplicable,
4674 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4675 // Don't do all the complex logic below for `DeclItem`.
4677 hir::StmtKind::Item(..) => return,
4678 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4681 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4683 // Hide the outer diverging and `has_errors` flags.
4684 let old_diverges = self.diverges.replace(Diverges::Maybe);
4685 let old_has_errors = self.has_errors.replace(false);
4688 hir::StmtKind::Local(ref l) => {
4689 self.check_decl_local(&l);
4692 hir::StmtKind::Item(_) => {}
4693 hir::StmtKind::Expr(ref expr) => {
4694 // Check with expected type of `()`.
4695 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4696 self.suggest_semicolon_at_end(expr.span, err);
4699 hir::StmtKind::Semi(ref expr) => {
4700 self.check_expr(&expr);
4704 // Combine the diverging and `has_error` flags.
4705 self.diverges.set(self.diverges.get() | old_diverges);
4706 self.has_errors.set(self.has_errors.get() | old_has_errors);
4709 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4710 let unit = self.tcx.mk_unit();
4711 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4713 // if the block produces a `!` value, that can always be
4714 // (effectively) coerced to unit.
4716 self.demand_suptype(blk.span, unit, ty);
4720 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4721 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4722 /// when given code like the following:
4724 /// if false { return 0i32; } else { 1u32 }
4725 /// // ^^^^ point at this instead of the whole `if` expression
4727 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4728 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4729 let arm_spans: Vec<Span> = arms
4732 self.in_progress_typeck_results
4733 .and_then(|typeck_results| {
4734 typeck_results.borrow().node_type_opt(arm.body.hir_id)
4736 .and_then(|arm_ty| {
4737 if arm_ty.is_never() {
4740 Some(match &arm.body.kind {
4741 // Point at the tail expression when possible.
4742 hir::ExprKind::Block(block, _) => {
4743 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4751 if arm_spans.len() == 1 {
4752 return arm_spans[0];
4758 fn check_block_with_expected(
4760 blk: &'tcx hir::Block<'tcx>,
4761 expected: Expectation<'tcx>,
4764 let mut fcx_ps = self.ps.borrow_mut();
4765 let unsafety_state = fcx_ps.recurse(blk);
4766 replace(&mut *fcx_ps, unsafety_state)
4769 // In some cases, blocks have just one exit, but other blocks
4770 // can be targeted by multiple breaks. This can happen both
4771 // with labeled blocks as well as when we desugar
4772 // a `try { ... }` expression.
4776 // 'a: { if true { break 'a Err(()); } Ok(()) }
4778 // Here we would wind up with two coercions, one from
4779 // `Err(())` and the other from the tail expression
4780 // `Ok(())`. If the tail expression is omitted, that's a
4781 // "forced unit" -- unless the block diverges, in which
4782 // case we can ignore the tail expression (e.g., `'a: {
4783 // break 'a 22; }` would not force the type of the block
4785 let tail_expr = blk.expr.as_ref();
4786 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4787 let coerce = if blk.targeted_by_break {
4788 CoerceMany::new(coerce_to_ty)
4790 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4791 Some(e) => slice::from_ref(e),
4794 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4797 let prev_diverges = self.diverges.get();
4798 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4800 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4801 for s in blk.stmts {
4805 // check the tail expression **without** holding the
4806 // `enclosing_breakables` lock below.
4807 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4809 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4810 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4811 let coerce = ctxt.coerce.as_mut().unwrap();
4812 if let Some(tail_expr_ty) = tail_expr_ty {
4813 let tail_expr = tail_expr.unwrap();
4814 let span = self.get_expr_coercion_span(tail_expr);
4815 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4816 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4818 // Subtle: if there is no explicit tail expression,
4819 // that is typically equivalent to a tail expression
4820 // of `()` -- except if the block diverges. In that
4821 // case, there is no value supplied from the tail
4822 // expression (assuming there are no other breaks,
4823 // this implies that the type of the block will be
4826 // #41425 -- label the implicit `()` as being the
4827 // "found type" here, rather than the "expected type".
4828 if !self.diverges.get().is_always() {
4829 // #50009 -- Do not point at the entire fn block span, point at the return type
4830 // span, as it is the cause of the requirement, and
4831 // `consider_hint_about_removing_semicolon` will point at the last expression
4832 // if it were a relevant part of the error. This improves usability in editors
4833 // that highlight errors inline.
4834 let mut sp = blk.span;
4835 let mut fn_span = None;
4836 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4837 let ret_sp = decl.output.span();
4838 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4839 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4840 // output would otherwise be incorrect and even misleading. Make sure
4841 // the span we're aiming at correspond to a `fn` body.
4842 if block_sp == blk.span {
4844 fn_span = Some(ident.span);
4848 coerce.coerce_forced_unit(
4852 if let Some(expected_ty) = expected.only_has_type(self) {
4853 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4855 if let Some(fn_span) = fn_span {
4858 "implicitly returns `()` as its body has no tail or `return` \
4870 // If we can break from the block, then the block's exit is always reachable
4871 // (... as long as the entry is reachable) - regardless of the tail of the block.
4872 self.diverges.set(prev_diverges);
4875 let mut ty = ctxt.coerce.unwrap().complete(self);
4877 if self.has_errors.get() || ty.references_error() {
4878 ty = self.tcx.ty_error()
4881 self.write_ty(blk.hir_id, ty);
4883 *self.ps.borrow_mut() = prev;
4887 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4888 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4890 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4891 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4892 let body = self.tcx.hir().body(body_id);
4893 if let ExprKind::Block(block, _) = &body.value.kind {
4894 return Some(block.span);
4902 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4903 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4904 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4905 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4908 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4909 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4911 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4912 // This is less than ideal, it will not suggest a return type span on any
4913 // method called `main`, regardless of whether it is actually the entry point,
4914 // but it will still present it as the reason for the expected type.
4915 Some((&sig.decl, ident, ident.name != sym::main))
4917 Node::TraitItem(&hir::TraitItem {
4919 kind: hir::TraitItemKind::Fn(ref sig, ..),
4921 }) => Some((&sig.decl, ident, true)),
4922 Node::ImplItem(&hir::ImplItem {
4924 kind: hir::ImplItemKind::Fn(ref sig, ..),
4926 }) => Some((&sig.decl, ident, false)),
4931 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4932 /// suggestion can be made, `None` otherwise.
4933 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4934 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4935 // `while` before reaching it, as block tail returns are not available in them.
4936 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4937 let parent = self.tcx.hir().get(blk_id);
4938 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4942 /// On implicit return expressions with mismatched types, provides the following suggestions:
4944 /// - Points out the method's return type as the reason for the expected type.
4945 /// - Possible missing semicolon.
4946 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4947 pub fn suggest_mismatched_types_on_tail(
4949 err: &mut DiagnosticBuilder<'_>,
4950 expr: &'tcx hir::Expr<'tcx>,
4956 let expr = expr.peel_drop_temps();
4957 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4958 let mut pointing_at_return_type = false;
4959 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4960 pointing_at_return_type =
4961 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4963 pointing_at_return_type
4966 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4967 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4969 /// fn foo(x: usize) -> usize { x }
4970 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4974 err: &mut DiagnosticBuilder<'_>,
4975 expr: &hir::Expr<'_>,
4979 let hir = self.tcx.hir();
4980 let (def_id, sig) = match *found.kind() {
4981 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4982 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4986 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4987 let sig = self.normalize_associated_types_in(expr.span, &sig);
4988 if self.can_coerce(sig.output(), expected) {
4989 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4990 (String::new(), Applicability::MachineApplicable)
4992 ("...".to_string(), Applicability::HasPlaceholders)
4994 let mut msg = "call this function";
4995 match hir.get_if_local(def_id) {
4997 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4998 | Node::ImplItem(hir::ImplItem {
4999 kind: hir::ImplItemKind::Fn(_, body_id), ..
5001 | Node::TraitItem(hir::TraitItem {
5002 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
5006 let body = hir.body(*body_id);
5010 .map(|param| match ¶m.pat.kind {
5011 hir::PatKind::Binding(_, _, ident, None)
5012 if ident.name != kw::SelfLower =>
5016 _ => "_".to_string(),
5018 .collect::<Vec<_>>()
5021 Some(Node::Expr(hir::Expr {
5022 kind: ExprKind::Closure(_, _, body_id, _, _),
5023 span: full_closure_span,
5026 if *full_closure_span == expr.span {
5029 msg = "call this closure";
5030 let body = hir.body(*body_id);
5034 .map(|param| match ¶m.pat.kind {
5035 hir::PatKind::Binding(_, _, ident, None)
5036 if ident.name != kw::SelfLower =>
5040 _ => "_".to_string(),
5042 .collect::<Vec<_>>()
5045 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
5046 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
5047 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
5048 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
5049 msg = "instantiate this tuple variant";
5051 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
5052 msg = "instantiate this tuple struct";
5057 Some(Node::ForeignItem(hir::ForeignItem {
5058 kind: hir::ForeignItemKind::Fn(_, idents, _),
5064 if ident.name != kw::SelfLower {
5070 .collect::<Vec<_>>()
5073 Some(Node::TraitItem(hir::TraitItem {
5074 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5080 if ident.name != kw::SelfLower {
5086 .collect::<Vec<_>>()
5091 err.span_suggestion_verbose(
5092 expr.span.shrink_to_hi(),
5093 &format!("use parentheses to {}", msg),
5094 format!("({})", sugg_call),
5102 pub fn suggest_deref_ref_or_into(
5104 err: &mut DiagnosticBuilder<'_>,
5105 expr: &hir::Expr<'_>,
5108 expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
5110 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5111 err.span_suggestion(sp, msg, suggestion, applicability);
5112 } else if let (ty::FnDef(def_id, ..), true) =
5113 (&found.kind(), self.suggest_fn_call(err, expr, expected, found))
5115 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5116 let sp = self.sess().source_map().guess_head_span(sp);
5117 err.span_label(sp, &format!("{} defined here", found));
5119 } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
5120 let is_struct_pat_shorthand_field =
5121 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5122 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5123 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5124 let mut suggestions = iter::repeat(&expr_text)
5125 .zip(methods.iter())
5126 .filter_map(|(receiver, method)| {
5127 let method_call = format!(".{}()", method.ident);
5128 if receiver.ends_with(&method_call) {
5129 None // do not suggest code that is already there (#53348)
5131 let method_call_list = [".to_vec()", ".to_string()"];
5132 let sugg = if receiver.ends_with(".clone()")
5133 && method_call_list.contains(&method_call.as_str())
5135 let max_len = receiver.rfind('.').unwrap();
5136 format!("{}{}", &receiver[..max_len], method_call)
5138 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5139 format!("({}){}", receiver, method_call)
5141 format!("{}{}", receiver, method_call)
5144 Some(if is_struct_pat_shorthand_field {
5145 format!("{}: {}", receiver, sugg)
5152 if suggestions.peek().is_some() {
5153 err.span_suggestions(
5155 "try using a conversion method",
5157 Applicability::MaybeIncorrect,
5164 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5165 /// in the heap by calling `Box::new()`.
5166 fn suggest_boxing_when_appropriate(
5168 err: &mut DiagnosticBuilder<'_>,
5169 expr: &hir::Expr<'_>,
5173 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5174 // Do not suggest `Box::new` in const context.
5177 if !expected.is_box() || found.is_box() {
5180 let boxed_found = self.tcx.mk_box(found);
5181 if let (true, Ok(snippet)) = (
5182 self.can_coerce(boxed_found, expected),
5183 self.sess().source_map().span_to_snippet(expr.span),
5185 err.span_suggestion(
5187 "store this in the heap by calling `Box::new`",
5188 format!("Box::new({})", snippet),
5189 Applicability::MachineApplicable,
5192 "for more on the distinction between the stack and the heap, read \
5193 https://doc.rust-lang.org/book/ch15-01-box.html, \
5194 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5195 https://doc.rust-lang.org/std/boxed/index.html",
5200 fn note_internal_mutation_in_method(
5202 err: &mut DiagnosticBuilder<'_>,
5203 expr: &hir::Expr<'_>,
5207 if found != self.tcx.types.unit {
5210 if let ExprKind::MethodCall(path_segment, _, [rcvr, ..], _) = expr.kind {
5214 .expr_ty_adjusted_opt(rcvr)
5215 .map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
5219 let mut sp = MultiSpan::from_span(path_segment.ident.span);
5221 path_segment.ident.span,
5223 "this call modifies {} in-place",
5225 ExprKind::Path(QPath::Resolved(
5227 hir::Path { segments: [segment], .. },
5228 )) => format!("`{}`", segment.ident),
5229 _ => "its receiver".to_string(),
5235 "you probably want to use this value after calling the method...".to_string(),
5239 &format!("method `{}` modifies its receiver in-place", path_segment.ident),
5241 err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
5245 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5246 fn suggest_calling_boxed_future_when_appropriate(
5248 err: &mut DiagnosticBuilder<'_>,
5249 expr: &hir::Expr<'_>,
5255 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5256 // Do not suggest `Box::new` in const context.
5259 let pin_did = self.tcx.lang_items().pin_type();
5260 match expected.kind() {
5261 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5262 // This guards the `unwrap` and `mk_box` below.
5263 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5266 let boxed_found = self.tcx.mk_box(found);
5267 let new_found = self.tcx.mk_lang_item(boxed_found, LangItem::Pin).unwrap();
5268 if let (true, Ok(snippet)) = (
5269 self.can_coerce(new_found, expected),
5270 self.sess().source_map().span_to_snippet(expr.span),
5272 match found.kind() {
5273 ty::Adt(def, _) if def.is_box() => {
5274 err.help("use `Box::pin`");
5277 err.span_suggestion(
5279 "you need to pin and box this expression",
5280 format!("Box::pin({})", snippet),
5281 Applicability::MachineApplicable,
5291 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5295 /// bar_that_returns_u32()
5299 /// This routine checks if the return expression in a block would make sense on its own as a
5300 /// statement and the return type has been left as default or has been specified as `()`. If so,
5301 /// it suggests adding a semicolon.
5302 fn suggest_missing_semicolon(
5304 err: &mut DiagnosticBuilder<'_>,
5305 expression: &'tcx hir::Expr<'tcx>,
5309 if expected.is_unit() {
5310 // `BlockTailExpression` only relevant if the tail expr would be
5311 // useful on its own.
5312 match expression.kind {
5314 | ExprKind::MethodCall(..)
5315 | ExprKind::Loop(..)
5316 | ExprKind::Match(..)
5317 | ExprKind::Block(..) => {
5318 err.span_suggestion(
5319 cause_span.shrink_to_hi(),
5320 "try adding a semicolon",
5322 Applicability::MachineApplicable,
5330 /// A possible error is to forget to add a return type that is needed:
5334 /// bar_that_returns_u32()
5338 /// This routine checks if the return type is left as default, the method is not part of an
5339 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5341 fn suggest_missing_return_type(
5343 err: &mut DiagnosticBuilder<'_>,
5344 fn_decl: &hir::FnDecl<'_>,
5349 // Only suggest changing the return type for methods that
5350 // haven't set a return type at all (and aren't `fn main()` or an impl).
5351 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5352 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5353 err.span_suggestion(
5355 "try adding a return type",
5356 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5357 Applicability::MachineApplicable,
5361 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5362 err.span_label(span, "possibly return type missing here?");
5365 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5366 // `fn main()` must return `()`, do not suggest changing return type
5367 err.span_label(span, "expected `()` because of default return type");
5370 // expectation was caused by something else, not the default return
5371 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5372 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5373 // Only point to return type if the expected type is the return type, as if they
5374 // are not, the expectation must have been caused by something else.
5375 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5377 let ty = AstConv::ast_ty_to_ty(self, ty);
5378 debug!("suggest_missing_return_type: return type {:?}", ty);
5379 debug!("suggest_missing_return_type: expected type {:?}", ty);
5380 if ty.kind() == expected.kind() {
5381 err.span_label(sp, format!("expected `{}` because of return type", expected));
5389 /// A possible error is to forget to add `.await` when using futures:
5392 /// async fn make_u32() -> u32 {
5396 /// fn take_u32(x: u32) {}
5398 /// async fn foo() {
5399 /// let x = make_u32();
5404 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5405 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5406 /// `.await` to the tail of the expression.
5407 fn suggest_missing_await(
5409 err: &mut DiagnosticBuilder<'_>,
5410 expr: &hir::Expr<'_>,
5414 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5415 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5416 // body isn't `async`.
5417 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5418 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5419 let body = self.tcx().hir().body(body_id);
5420 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5422 // Check for `Future` implementations by constructing a predicate to
5423 // prove: `<T as Future>::Output == U`
5424 let future_trait = self.tcx.require_lang_item(LangItem::Future, Some(sp));
5425 let item_def_id = self
5427 .associated_items(future_trait)
5428 .in_definition_order()
5432 // `<T as Future>::Output`
5433 let projection_ty = ty::ProjectionTy {
5437 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5442 let predicate = ty::PredicateAtom::Projection(ty::ProjectionPredicate {
5446 .potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
5447 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5449 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5451 if self.infcx.predicate_may_hold(&obligation) {
5452 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5453 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5454 err.span_suggestion(
5456 "consider using `.await` here",
5457 format!("{}.await", code),
5458 Applicability::MaybeIncorrect,
5461 debug!("suggest_missing_await: no snippet for {:?}", sp);
5464 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5470 fn suggest_missing_parentheses(&self, err: &mut DiagnosticBuilder<'_>, expr: &hir::Expr<'_>) {
5471 let sp = self.tcx.sess.source_map().start_point(expr.span);
5472 if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
5473 // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
5474 self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None);
5478 fn note_need_for_fn_pointer(
5480 err: &mut DiagnosticBuilder<'_>,
5484 let (sig, did, substs) = match (&expected.kind(), &found.kind()) {
5485 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
5486 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
5487 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
5492 "different `fn` items always have unique types, even if their signatures are \
5495 (sig1, *did1, substs1)
5497 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
5498 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
5502 (sig1, *did, substs)
5506 err.help(&format!("change the expected type to be function pointer `{}`", sig));
5508 "if the expected type is due to type inference, cast the expected `fn` to a function \
5509 pointer: `{} as {}`",
5510 self.tcx.def_path_str_with_substs(did, substs),
5515 /// A common error is to add an extra semicolon:
5518 /// fn foo() -> usize {
5523 /// This routine checks if the final statement in a block is an
5524 /// expression with an explicit semicolon whose type is compatible
5525 /// with `expected_ty`. If so, it suggests removing the semicolon.
5526 fn consider_hint_about_removing_semicolon(
5528 blk: &'tcx hir::Block<'tcx>,
5529 expected_ty: Ty<'tcx>,
5530 err: &mut DiagnosticBuilder<'_>,
5532 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5533 err.span_suggestion(
5535 "consider removing this semicolon",
5537 Applicability::MachineApplicable,
5542 fn could_remove_semicolon(
5544 blk: &'tcx hir::Block<'tcx>,
5545 expected_ty: Ty<'tcx>,
5547 // Be helpful when the user wrote `{... expr;}` and
5548 // taking the `;` off is enough to fix the error.
5549 let last_stmt = blk.stmts.last()?;
5550 let last_expr = match last_stmt.kind {
5551 hir::StmtKind::Semi(ref e) => e,
5554 let last_expr_ty = self.node_ty(last_expr.hir_id);
5555 if matches!(last_expr_ty.kind(), ty::Error(_))
5556 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5560 let original_span = original_sp(last_stmt.span, blk.span);
5561 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5564 // Instantiates the given path, which must refer to an item with the given
5565 // number of type parameters and type.
5566 pub fn instantiate_value_path(
5568 segments: &[hir::PathSegment<'_>],
5569 self_ty: Option<Ty<'tcx>>,
5573 ) -> (Ty<'tcx>, Res) {
5575 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5576 segments, self_ty, res, hir_id,
5581 let path_segs = match res {
5582 Res::Local(_) | Res::SelfCtor(_) => vec![],
5583 Res::Def(kind, def_id) => {
5584 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5586 _ => bug!("instantiate_value_path on {:?}", res),
5589 let mut user_self_ty = None;
5590 let mut is_alias_variant_ctor = false;
5592 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5593 if let Some(self_ty) = self_ty {
5594 let adt_def = self_ty.ty_adt_def().unwrap();
5595 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5596 is_alias_variant_ctor = true;
5599 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5600 let container = tcx.associated_item(def_id).container;
5601 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5603 ty::TraitContainer(trait_did) => {
5604 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5606 ty::ImplContainer(impl_def_id) => {
5607 if segments.len() == 1 {
5608 // `<T>::assoc` will end up here, and so
5609 // can `T::assoc`. It this came from an
5610 // inherent impl, we need to record the
5611 // `T` for posterity (see `UserSelfTy` for
5613 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5614 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5622 // Now that we have categorized what space the parameters for each
5623 // segment belong to, let's sort out the parameters that the user
5624 // provided (if any) into their appropriate spaces. We'll also report
5625 // errors if type parameters are provided in an inappropriate place.
5627 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5628 let generics_has_err = AstConv::prohibit_generics(
5630 segments.iter().enumerate().filter_map(|(index, seg)| {
5631 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5639 if let Res::Local(hid) = res {
5640 let ty = self.local_ty(span, hid).decl_ty;
5641 let ty = self.normalize_associated_types_in(span, &ty);
5642 self.write_ty(hir_id, ty);
5646 if generics_has_err {
5647 // Don't try to infer type parameters when prohibited generic arguments were given.
5648 user_self_ty = None;
5651 // Now we have to compare the types that the user *actually*
5652 // provided against the types that were *expected*. If the user
5653 // did not provide any types, then we want to substitute inference
5654 // variables. If the user provided some types, we may still need
5655 // to add defaults. If the user provided *too many* types, that's
5658 let mut infer_args_for_err = FxHashSet::default();
5659 for &PathSeg(def_id, index) in &path_segs {
5660 let seg = &segments[index];
5661 let generics = tcx.generics_of(def_id);
5662 // Argument-position `impl Trait` is treated as a normal generic
5663 // parameter internally, but we don't allow users to specify the
5664 // parameter's value explicitly, so we have to do some error-
5666 if let GenericArgCountResult {
5667 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5669 } = AstConv::check_generic_arg_count_for_call(
5670 tcx, span, &generics, &seg, false, // `is_method_call`
5672 infer_args_for_err.insert(index);
5673 self.set_tainted_by_errors(); // See issue #53251.
5677 let has_self = path_segs
5679 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5682 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5683 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5685 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5686 let variant = adt_def.non_enum_variant();
5687 let ctor_def_id = variant.ctor_def_id.unwrap();
5689 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5694 let mut err = tcx.sess.struct_span_err(
5696 "the `Self` constructor can only be used with tuple or unit structs",
5698 if let Some(adt_def) = ty.ty_adt_def() {
5699 match adt_def.adt_kind() {
5701 err.help("did you mean to use one of the enum's variants?");
5703 AdtKind::Struct | AdtKind::Union => {
5704 err.span_suggestion(
5706 "use curly brackets",
5707 String::from("Self { /* fields */ }"),
5708 Applicability::HasPlaceholders,
5715 return (tcx.ty_error(), res);
5721 let def_id = res.def_id();
5723 // The things we are substituting into the type should not contain
5724 // escaping late-bound regions, and nor should the base type scheme.
5725 let ty = tcx.type_of(def_id);
5727 let arg_count = GenericArgCountResult {
5728 explicit_late_bound: ExplicitLateBound::No,
5729 correct: if infer_args_for_err.is_empty() {
5732 Err(GenericArgCountMismatch::default())
5736 let substs = self_ctor_substs.unwrap_or_else(|| {
5737 AstConv::create_substs_for_generic_args(
5744 // Provide the generic args, and whether types should be inferred.
5746 if let Some(&PathSeg(_, index)) =
5747 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5749 // If we've encountered an `impl Trait`-related error, we're just
5750 // going to infer the arguments for better error messages.
5751 if !infer_args_for_err.contains(&index) {
5752 // Check whether the user has provided generic arguments.
5753 if let Some(ref data) = segments[index].args {
5754 return (Some(data), segments[index].infer_args);
5757 return (None, segments[index].infer_args);
5762 // Provide substitutions for parameters for which (valid) arguments have been provided.
5763 |param, arg| match (¶m.kind, arg) {
5764 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5765 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5767 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5768 self.to_ty(ty).into()
5770 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5771 self.const_arg_to_const(&ct.value, param.def_id).into()
5773 _ => unreachable!(),
5775 // Provide substitutions for parameters for which arguments are inferred.
5776 |substs, param, infer_args| {
5778 GenericParamDefKind::Lifetime => {
5779 self.re_infer(Some(param), span).unwrap().into()
5781 GenericParamDefKind::Type { has_default, .. } => {
5782 if !infer_args && has_default {
5783 // If we have a default, then we it doesn't matter that we're not
5784 // inferring the type arguments: we provide the default where any
5786 let default = tcx.type_of(param.def_id);
5789 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5793 // If no type arguments were provided, we have to infer them.
5794 // This case also occurs as a result of some malformed input, e.g.
5795 // a lifetime argument being given instead of a type parameter.
5796 // Using inference instead of `Error` gives better error messages.
5797 self.var_for_def(span, param)
5800 GenericParamDefKind::Const => {
5801 // FIXME(const_generics:defaults)
5802 // No const parameters were provided, we have to infer them.
5803 self.var_for_def(span, param)
5809 assert!(!substs.has_escaping_bound_vars());
5810 assert!(!ty.has_escaping_bound_vars());
5812 // First, store the "user substs" for later.
5813 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5815 self.add_required_obligations(span, def_id, &substs);
5817 // Substitute the values for the type parameters into the type of
5818 // the referenced item.
5819 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5821 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5822 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5823 // is inherent, there is no `Self` parameter; instead, the impl needs
5824 // type parameters, which we can infer by unifying the provided `Self`
5825 // with the substituted impl type.
5826 // This also occurs for an enum variant on a type alias.
5827 let ty = tcx.type_of(impl_def_id);
5829 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5830 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5831 Ok(ok) => self.register_infer_ok_obligations(ok),
5833 self.tcx.sess.delay_span_bug(
5836 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5845 self.check_rustc_args_require_const(def_id, hir_id, span);
5847 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5848 self.write_substs(hir_id, substs);
5850 (ty_substituted, res)
5853 /// Add all the obligations that are required, substituting and normalized appropriately.
5854 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5855 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5857 for (i, mut obligation) in traits::predicates_for_generics(
5858 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5864 // This makes the error point at the bound, but we want to point at the argument
5865 if let Some(span) = spans.get(i) {
5866 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
5868 self.register_predicate(obligation);
5872 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5873 // We're only interested in functions tagged with
5874 // #[rustc_args_required_const], so ignore anything that's not.
5875 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5879 // If our calling expression is indeed the function itself, we're good!
5880 // If not, generate an error that this can only be called directly.
5881 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5882 if let ExprKind::Call(ref callee, ..) = expr.kind {
5883 if callee.hir_id == hir_id {
5889 self.tcx.sess.span_err(
5891 "this function can only be invoked directly, not through a function pointer",
5895 /// Resolves `typ` by a single level if `typ` is a type variable.
5896 /// If no resolution is possible, then an error is reported.
5897 /// Numeric inference variables may be left unresolved.
5898 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5899 let ty = self.resolve_vars_with_obligations(ty);
5900 if !ty.is_ty_var() {
5903 if !self.is_tainted_by_errors() {
5904 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5905 .note("type must be known at this point")
5908 let err = self.tcx.ty_error();
5909 self.demand_suptype(sp, err, ty);
5914 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5917 ctxt: BreakableCtxt<'tcx>,
5919 ) -> (BreakableCtxt<'tcx>, R) {
5922 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5923 index = enclosing_breakables.stack.len();
5924 enclosing_breakables.by_id.insert(id, index);
5925 enclosing_breakables.stack.push(ctxt);
5929 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5930 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5931 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5932 enclosing_breakables.stack.pop().expect("missing breakable context")
5937 /// Instantiate a QueryResponse in a probe context, without a
5938 /// good ObligationCause.
5939 fn probe_instantiate_query_response(
5942 original_values: &OriginalQueryValues<'tcx>,
5943 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5944 ) -> InferResult<'tcx, Ty<'tcx>> {
5945 self.instantiate_query_response_and_region_obligations(
5946 &traits::ObligationCause::misc(span, self.body_id),
5953 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5954 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5955 let mut contained_in_place = false;
5957 while let hir::Node::Expr(parent_expr) =
5958 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5960 match &parent_expr.kind {
5961 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5962 if lhs.hir_id == expr_id {
5963 contained_in_place = true;
5969 expr_id = parent_expr.hir_id;
5976 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5977 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5979 assert_eq!(generics.parent, None);
5981 if generics.own_counts().types == 0 {
5985 let mut params_used = BitSet::new_empty(generics.params.len());
5987 if ty.references_error() {
5988 // If there is already another error, do not emit
5989 // an error for not using a type parameter.
5990 assert!(tcx.sess.has_errors());
5994 for leaf in ty.walk() {
5995 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5996 if let ty::Param(param) = leaf_ty.kind() {
5997 debug!("found use of ty param {:?}", param);
5998 params_used.insert(param.index);
6003 for param in &generics.params {
6004 if !params_used.contains(param.index) {
6005 if let ty::GenericParamDefKind::Type { .. } = param.kind {
6006 let span = tcx.def_span(param.def_id);
6011 "type parameter `{}` is unused",
6014 .span_label(span, "unused type parameter")
6021 fn fatally_break_rust(sess: &Session) {
6022 let handler = sess.diagnostic();
6023 handler.span_bug_no_panic(
6025 "It looks like you're trying to break rust; would you like some ICE?",
6027 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
6028 handler.note_without_error(
6029 "we would appreciate a joke overview: \
6030 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
6032 handler.note_without_error(&format!(
6033 "rustc {} running on {}",
6034 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
6035 config::host_triple(),
6039 fn potentially_plural_count(count: usize, word: &str) -> String {
6040 format!("{} {}{}", count, word, pluralize!(count))