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::{
104 FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem,
106 use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath};
107 use rustc_index::bit_set::BitSet;
108 use rustc_index::vec::Idx;
109 use rustc_infer::infer;
110 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
111 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
112 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
113 use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
114 use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
115 use rustc_middle::hir::map::blocks::FnLikeNode;
116 use rustc_middle::mir::interpret::ConstValue;
117 use rustc_middle::ty::adjustment::{
118 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
120 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
121 use rustc_middle::ty::query::Providers;
122 use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
123 use rustc_middle::ty::subst::{GenericArgKind, UserSelfTy, UserSubsts};
124 use rustc_middle::ty::util::{Discr, IntTypeExt, Representability};
125 use rustc_middle::ty::{
126 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
127 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
129 use rustc_session::config::{self, EntryFnType};
130 use rustc_session::lint;
131 use rustc_session::parse::feature_err;
132 use rustc_session::Session;
133 use rustc_span::hygiene::DesugaringKind;
134 use rustc_span::source_map::{original_sp, DUMMY_SP};
135 use rustc_span::symbol::{kw, sym, Ident};
136 use rustc_span::{self, BytePos, MultiSpan, Span};
137 use rustc_target::abi::VariantIdx;
138 use rustc_target::spec::abi::Abi;
139 use rustc_trait_selection::infer::InferCtxtExt as _;
140 use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
141 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
142 use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
143 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
144 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
145 use rustc_trait_selection::traits::{
146 self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
149 use std::cell::{Cell, Ref, RefCell, RefMut};
151 use std::collections::hash_map::Entry;
153 use std::mem::replace;
154 use std::ops::{self, Deref};
157 use crate::require_c_abi_if_c_variadic;
158 use crate::util::common::indenter;
160 use self::callee::DeferredCallResolution;
161 use self::coercion::{CoerceMany, DynamicCoerceMany};
162 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
163 use self::method::{MethodCallee, SelfSource};
164 pub use self::Expectation::*;
165 use self::TupleArgumentsFlag::*;
168 macro_rules! type_error_struct {
169 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
170 if $typ.references_error() {
171 $session.diagnostic().struct_dummy()
173 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
178 /// The type of a local binding, including the revealed type for anon types.
179 #[derive(Copy, Clone, Debug)]
180 pub struct LocalTy<'tcx> {
182 revealed_ty: Ty<'tcx>,
185 /// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
186 #[derive(Copy, Clone)]
187 struct MaybeInProgressTables<'a, 'tcx> {
188 maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
191 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
192 fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
193 match self.maybe_typeck_results {
194 Some(typeck_results) => typeck_results.borrow(),
196 "MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
201 fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
202 match self.maybe_typeck_results {
203 Some(typeck_results) => typeck_results.borrow_mut(),
205 "MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
211 /// Closures defined within the function. For example:
214 /// bar(move|| { ... })
217 /// Here, the function `foo()` and the closure passed to
218 /// `bar()` will each have their own `FnCtxt`, but they will
219 /// share the inherited fields.
220 pub struct Inherited<'a, 'tcx> {
221 infcx: InferCtxt<'a, 'tcx>,
223 typeck_results: MaybeInProgressTables<'a, 'tcx>,
225 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
227 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
229 // Some additional `Sized` obligations badly affect type inference.
230 // These obligations are added in a later stage of typeck.
231 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
233 // When we process a call like `c()` where `c` is a closure type,
234 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
235 // `FnOnce` closure. In that case, we defer full resolution of the
236 // call until upvar inference can kick in and make the
237 // decision. We keep these deferred resolutions grouped by the
238 // def-id of the closure, so that once we decide, we can easily go
239 // back and process them.
240 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
242 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
244 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
246 // Opaque types found in explicit return types and their
247 // associated fresh inference variable. Writeback resolves these
248 // variables to get the concrete type, which can be used to
249 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
250 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
252 /// A map from inference variables created from opaque
253 /// type instantiations (`ty::Infer`) to the actual opaque
254 /// type (`ty::Opaque`). Used during fallback to map unconstrained
255 /// opaque type inference variables to their corresponding
257 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
259 /// Each type parameter has an implicit region bound that
260 /// indicates it must outlive at least the function body (the user
261 /// may specify stronger requirements). This field indicates the
262 /// region of the callee. If it is `None`, then the parameter
263 /// environment is for an item or something where the "callee" is
265 implicit_region_bound: Option<ty::Region<'tcx>>,
267 body_id: Option<hir::BodyId>,
270 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
271 type Target = InferCtxt<'a, 'tcx>;
272 fn deref(&self) -> &Self::Target {
277 /// When type-checking an expression, we propagate downward
278 /// whatever type hint we are able in the form of an `Expectation`.
279 #[derive(Copy, Clone, Debug)]
280 pub enum Expectation<'tcx> {
281 /// We know nothing about what type this expression should have.
284 /// This expression should have the type given (or some subtype).
285 ExpectHasType(Ty<'tcx>),
287 /// This expression will be cast to the `Ty`.
288 ExpectCastableToType(Ty<'tcx>),
290 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
291 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
292 ExpectRvalueLikeUnsized(Ty<'tcx>),
295 impl<'a, 'tcx> Expectation<'tcx> {
296 // Disregard "castable to" expectations because they
297 // can lead us astray. Consider for example `if cond
298 // {22} else {c} as u8` -- if we propagate the
299 // "castable to u8" constraint to 22, it will pick the
300 // type 22u8, which is overly constrained (c might not
301 // be a u8). In effect, the problem is that the
302 // "castable to" expectation is not the tightest thing
303 // we can say, so we want to drop it in this case.
304 // The tightest thing we can say is "must unify with
305 // else branch". Note that in the case of a "has type"
306 // constraint, this limitation does not hold.
308 // If the expected type is just a type variable, then don't use
309 // an expected type. Otherwise, we might write parts of the type
310 // when checking the 'then' block which are incompatible with the
312 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
314 ExpectHasType(ety) => {
315 let ety = fcx.shallow_resolve(ety);
316 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
318 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
323 /// Provides an expectation for an rvalue expression given an *optional*
324 /// hint, which is not required for type safety (the resulting type might
325 /// be checked higher up, as is the case with `&expr` and `box expr`), but
326 /// is useful in determining the concrete type.
328 /// The primary use case is where the expected type is a fat pointer,
329 /// like `&[isize]`. For example, consider the following statement:
331 /// let x: &[isize] = &[1, 2, 3];
333 /// In this case, the expected type for the `&[1, 2, 3]` expression is
334 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
335 /// expectation `ExpectHasType([isize])`, that would be too strong --
336 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
337 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
338 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
339 /// which still is useful, because it informs integer literals and the like.
340 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
341 /// for examples of where this comes up,.
342 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
343 match fcx.tcx.struct_tail_without_normalization(ty).kind {
344 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
345 _ => ExpectHasType(ty),
349 // Resolves `expected` by a single level if it is a variable. If
350 // there is no expected type or resolution is not possible (e.g.,
351 // no constraints yet present), just returns `None`.
352 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
354 NoExpectation => NoExpectation,
355 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
356 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
357 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
361 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
362 match self.resolve(fcx) {
363 NoExpectation => None,
364 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
368 /// It sometimes happens that we want to turn an expectation into
369 /// a **hard constraint** (i.e., something that must be satisfied
370 /// for the program to type-check). `only_has_type` will return
371 /// such a constraint, if it exists.
372 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
373 match self.resolve(fcx) {
374 ExpectHasType(ty) => Some(ty),
375 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
379 /// Like `only_has_type`, but instead of returning `None` if no
380 /// hard constraint exists, creates a fresh type variable.
381 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
382 self.only_has_type(fcx).unwrap_or_else(|| {
383 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
388 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
395 fn maybe_mut_place(m: hir::Mutability) -> Self {
397 hir::Mutability::Mut => Needs::MutPlace,
398 hir::Mutability::Not => Needs::None,
403 #[derive(Copy, Clone)]
404 pub struct UnsafetyState {
406 pub unsafety: hir::Unsafety,
407 pub unsafe_push_count: u32,
412 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
413 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
416 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
417 use hir::BlockCheckMode;
418 match self.unsafety {
419 // If this unsafe, then if the outer function was already marked as
420 // unsafe we shouldn't attribute the unsafe'ness to the block. This
421 // way the block can be warned about instead of ignoring this
422 // extraneous block (functions are never warned about).
423 hir::Unsafety::Unsafe if self.from_fn => *self,
426 let (unsafety, def, count) = match blk.rules {
427 BlockCheckMode::PushUnsafeBlock(..) => {
428 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
430 BlockCheckMode::PopUnsafeBlock(..) => {
431 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
433 BlockCheckMode::UnsafeBlock(..) => {
434 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
436 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
438 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
444 #[derive(Debug, Copy, Clone)]
450 /// Tracks whether executing a node may exit normally (versus
451 /// return/break/panic, which "diverge", leaving dead code in their
452 /// wake). Tracked semi-automatically (through type variables marked
453 /// as diverging), with some manual adjustments for control-flow
454 /// primitives (approximating a CFG).
455 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
457 /// Potentially unknown, some cases converge,
458 /// others require a CFG to determine them.
461 /// Definitely known to diverge and therefore
462 /// not reach the next sibling or its parent.
464 /// The `Span` points to the expression
465 /// that caused us to diverge
466 /// (e.g. `return`, `break`, etc).
468 /// In some cases (e.g. a `match` expression
469 /// where all arms diverge), we may be
470 /// able to provide a more informative
471 /// message to the user.
472 /// If this is `None`, a default message
473 /// will be generated, which is suitable
475 custom_note: Option<&'static str>,
478 /// Same as `Always` but with a reachability
479 /// warning already emitted.
483 // Convenience impls for combining `Diverges`.
485 impl ops::BitAnd for Diverges {
487 fn bitand(self, other: Self) -> Self {
488 cmp::min(self, other)
492 impl ops::BitOr for Diverges {
494 fn bitor(self, other: Self) -> Self {
495 cmp::max(self, other)
499 impl ops::BitAndAssign for Diverges {
500 fn bitand_assign(&mut self, other: Self) {
501 *self = *self & other;
505 impl ops::BitOrAssign for Diverges {
506 fn bitor_assign(&mut self, other: Self) {
507 *self = *self | other;
512 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
513 fn always(span: Span) -> Diverges {
514 Diverges::Always { span, custom_note: None }
517 fn is_always(self) -> bool {
518 // Enum comparison ignores the
519 // contents of fields, so we just
520 // fill them in with garbage here.
521 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
525 pub struct BreakableCtxt<'tcx> {
528 // this is `null` for loops where break with a value is illegal,
529 // such as `while`, `for`, and `while let`
530 coerce: Option<DynamicCoerceMany<'tcx>>,
533 pub struct EnclosingBreakables<'tcx> {
534 stack: Vec<BreakableCtxt<'tcx>>,
535 by_id: HirIdMap<usize>,
538 impl<'tcx> EnclosingBreakables<'tcx> {
539 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
540 self.opt_find_breakable(target_id).unwrap_or_else(|| {
541 bug!("could not find enclosing breakable with id {}", target_id);
545 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
546 match self.by_id.get(&target_id) {
547 Some(ix) => Some(&mut self.stack[*ix]),
553 pub struct FnCtxt<'a, 'tcx> {
556 /// The parameter environment used for proving trait obligations
557 /// in this function. This can change when we descend into
558 /// closures (as they bring new things into scope), hence it is
559 /// not part of `Inherited` (as of the time of this writing,
560 /// closures do not yet change the environment, but they will
562 param_env: ty::ParamEnv<'tcx>,
564 /// Number of errors that had been reported when we started
565 /// checking this function. On exit, if we find that *more* errors
566 /// have been reported, we will skip regionck and other work that
567 /// expects the types within the function to be consistent.
568 // FIXME(matthewjasper) This should not exist, and it's not correct
569 // if type checking is run in parallel.
570 err_count_on_creation: usize,
572 /// If `Some`, this stores coercion information for returned
573 /// expressions. If `None`, this is in a context where return is
574 /// inappropriate, such as a const expression.
576 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
577 /// can track all the return expressions and then use them to
578 /// compute a useful coercion from the set, similar to a match
579 /// expression or other branching context. You can use methods
580 /// like `expected_ty` to access the declared return type (if
582 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
584 /// First span of a return site that we find. Used in error messages.
585 ret_coercion_span: RefCell<Option<Span>>,
587 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
589 ps: RefCell<UnsafetyState>,
591 /// Whether the last checked node generates a divergence (e.g.,
592 /// `return` will set this to `Always`). In general, when entering
593 /// an expression or other node in the tree, the initial value
594 /// indicates whether prior parts of the containing expression may
595 /// have diverged. It is then typically set to `Maybe` (and the
596 /// old value remembered) for processing the subparts of the
597 /// current expression. As each subpart is processed, they may set
598 /// the flag to `Always`, etc. Finally, at the end, we take the
599 /// result and "union" it with the original value, so that when we
600 /// return the flag indicates if any subpart of the parent
601 /// expression (up to and including this part) has diverged. So,
602 /// if you read it after evaluating a subexpression `X`, the value
603 /// you get indicates whether any subexpression that was
604 /// evaluating up to and including `X` diverged.
606 /// We currently use this flag only for diagnostic purposes:
608 /// - To warn about unreachable code: if, after processing a
609 /// sub-expression but before we have applied the effects of the
610 /// current node, we see that the flag is set to `Always`, we
611 /// can issue a warning. This corresponds to something like
612 /// `foo(return)`; we warn on the `foo()` expression. (We then
613 /// update the flag to `WarnedAlways` to suppress duplicate
614 /// reports.) Similarly, if we traverse to a fresh statement (or
615 /// tail expression) from a `Always` setting, we will issue a
616 /// warning. This corresponds to something like `{return;
617 /// foo();}` or `{return; 22}`, where we would warn on the
620 /// An expression represents dead code if, after checking it,
621 /// the diverges flag is set to something other than `Maybe`.
622 diverges: Cell<Diverges>,
624 /// Whether any child nodes have any type errors.
625 has_errors: Cell<bool>,
627 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
629 inh: &'a Inherited<'a, 'tcx>,
632 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
633 type Target = Inherited<'a, 'tcx>;
634 fn deref(&self) -> &Self::Target {
639 /// Helper type of a temporary returned by `Inherited::build(...)`.
640 /// Necessary because we can't write the following bound:
641 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
642 pub struct InheritedBuilder<'tcx> {
643 infcx: infer::InferCtxtBuilder<'tcx>,
647 impl Inherited<'_, 'tcx> {
648 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
649 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
652 infcx: tcx.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner),
658 impl<'tcx> InheritedBuilder<'tcx> {
659 fn enter<F, R>(&mut self, f: F) -> R
661 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
663 let def_id = self.def_id;
664 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
668 impl Inherited<'a, 'tcx> {
669 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
671 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
672 let body_id = tcx.hir().maybe_body_owned_by(item_id);
675 typeck_results: MaybeInProgressTables {
676 maybe_typeck_results: infcx.in_progress_typeck_results,
679 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
680 locals: RefCell::new(Default::default()),
681 deferred_sized_obligations: RefCell::new(Vec::new()),
682 deferred_call_resolutions: RefCell::new(Default::default()),
683 deferred_cast_checks: RefCell::new(Vec::new()),
684 deferred_generator_interiors: RefCell::new(Vec::new()),
685 opaque_types: RefCell::new(Default::default()),
686 opaque_types_vars: RefCell::new(Default::default()),
687 implicit_region_bound: None,
692 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
693 debug!("register_predicate({:?})", obligation);
694 if obligation.has_escaping_bound_vars() {
695 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
697 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
700 fn register_predicates<I>(&self, obligations: I)
702 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
704 for obligation in obligations {
705 self.register_predicate(obligation);
709 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
710 self.register_predicates(infer_ok.obligations);
714 fn normalize_associated_types_in<T>(
718 param_env: ty::ParamEnv<'tcx>,
722 T: TypeFoldable<'tcx>,
724 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
725 self.register_infer_ok_obligations(ok)
729 struct CheckItemTypesVisitor<'tcx> {
733 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
734 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
735 check_item_type(self.tcx, i);
737 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
738 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
741 pub fn check_wf_new(tcx: TyCtxt<'_>) {
742 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
743 tcx.hir().krate().par_visit_all_item_likes(&visit);
746 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
747 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
750 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
751 debug_assert!(crate_num == LOCAL_CRATE);
752 tcx.par_body_owners(|body_owner_def_id| {
753 tcx.ensure().typeck(body_owner_def_id);
757 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
758 wfcheck::check_item_well_formed(tcx, def_id);
761 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
762 wfcheck::check_trait_item(tcx, def_id);
765 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
766 wfcheck::check_impl_item(tcx, def_id);
769 pub fn provide(providers: &mut Providers) {
770 method::provide(providers);
771 *providers = Providers {
775 diagnostic_only_typeck,
779 check_item_well_formed,
780 check_trait_item_well_formed,
781 check_impl_item_well_formed,
782 check_mod_item_types,
787 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
788 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
791 /// If this `DefId` is a "primary tables entry", returns
792 /// `Some((body_id, header, decl))` with information about
793 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
796 /// If this function returns `Some`, then `typeck_results(def_id)` will
797 /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
798 /// may not succeed. In some cases where this function returns `None`
799 /// (notably closures), `typeck_results(def_id)` would wind up
800 /// redirecting to the owning function.
804 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
805 match tcx.hir().get(id) {
806 Node::Item(item) => match item.kind {
807 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
808 Some((body, Some(ty), None, None))
810 hir::ItemKind::Fn(ref sig, .., body) => {
811 Some((body, None, Some(&sig.header), Some(&sig.decl)))
815 Node::TraitItem(item) => match item.kind {
816 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
817 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
818 Some((body, None, Some(&sig.header), Some(&sig.decl)))
822 Node::ImplItem(item) => match item.kind {
823 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
824 hir::ImplItemKind::Fn(ref sig, body) => {
825 Some((body, None, Some(&sig.header), Some(&sig.decl)))
829 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
834 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
835 // Closures' typeck results come from their outermost function,
836 // as they are part of the same "inference environment".
837 let outer_def_id = tcx.closure_base_def_id(def_id);
838 if outer_def_id != def_id {
839 return tcx.has_typeck_results(outer_def_id);
842 if let Some(def_id) = def_id.as_local() {
843 let id = tcx.hir().local_def_id_to_hir_id(def_id);
844 primary_body_of(tcx, id).is_some()
850 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
851 &*tcx.typeck(def_id).used_trait_imports
854 /// Inspects the substs of opaque types, replacing any inference variables
855 /// with proper generic parameter from the identity substs.
857 /// This is run after we normalize the function signature, to fix any inference
858 /// variables introduced by the projection of associated types. This ensures that
859 /// any opaque types used in the signature continue to refer to generic parameters,
860 /// allowing them to be considered for defining uses in the function body
862 /// For example, consider this code.
867 /// fn use_it(self) -> Self::MyItem
869 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
870 /// type MyItem = impl Iterator<Item = I>;
871 /// fn use_it(self) -> Self::MyItem {
877 /// When we normalize the signature of `use_it` from the impl block,
878 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
879 /// However, this projection result may contain inference variables, due
880 /// to the way that projection works. We didn't have any inference variables
881 /// in the signature to begin with - leaving them in will cause us to incorrectly
882 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
883 /// variables back to the actual generic parameters, we will correctly see that
884 /// we have a defining use of `MyItem`
885 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
887 T: TypeFoldable<'tcx>,
889 struct FixupFolder<'tcx> {
893 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
894 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
898 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
900 ty::Opaque(def_id, substs) => {
901 debug!("fixup_opaque_types: found type {:?}", ty);
902 // Here, we replace any inference variables that occur within
903 // the substs of an opaque type. By definition, any type occurring
904 // in the substs has a corresponding generic parameter, which is what
905 // we replace it with.
906 // This replacement is only run on the function signature, so any
907 // inference variables that we come across must be the rust of projection
908 // (there's no other way for a user to get inference variables into
909 // a function signature).
910 if ty.needs_infer() {
911 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
912 let old_param = substs[param.index as usize];
913 match old_param.unpack() {
914 GenericArgKind::Type(old_ty) => {
915 if let ty::Infer(_) = old_ty.kind {
916 // Replace inference type with a generic parameter
917 self.tcx.mk_param_from_def(param)
919 old_param.fold_with(self)
922 GenericArgKind::Const(old_const) => {
923 if let ty::ConstKind::Infer(_) = old_const.val {
924 // This should never happen - we currently do not support
925 // 'const projections', e.g.:
926 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
927 // which should be the only way for us to end up with a const inference
928 // variable after projection. If Rust ever gains support for this kind
929 // of projection, this should *probably* be changed to
930 // `self.tcx.mk_param_from_def(param)`
932 "Found infer const: `{:?}` in opaque type: {:?}",
937 old_param.fold_with(self)
940 GenericArgKind::Lifetime(old_region) => {
941 if let RegionKind::ReVar(_) = old_region {
942 self.tcx.mk_param_from_def(param)
944 old_param.fold_with(self)
949 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
950 debug!("fixup_opaque_types: new type: {:?}", new_ty);
956 _ => ty.super_fold_with(self),
961 debug!("fixup_opaque_types({:?})", val);
962 val.fold_with(&mut FixupFolder { tcx })
965 fn typeck_const_arg<'tcx>(
967 (did, param_did): (LocalDefId, DefId),
968 ) -> &ty::TypeckResults<'tcx> {
969 let fallback = move || tcx.type_of(param_did);
970 typeck_with_fallback(tcx, did, fallback)
973 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
974 if let Some(param_did) = tcx.opt_const_param_of(def_id) {
975 tcx.typeck_const_arg((def_id, param_did))
977 let fallback = move || tcx.type_of(def_id.to_def_id());
978 typeck_with_fallback(tcx, def_id, fallback)
982 /// Used only to get `TypeckResults` for type inference during error recovery.
983 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
984 fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
985 let fallback = move || {
986 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
987 tcx.ty_error_with_message(span, "diagnostic only typeck table used")
989 typeck_with_fallback(tcx, def_id, fallback)
992 fn typeck_with_fallback<'tcx>(
995 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
996 ) -> &'tcx ty::TypeckResults<'tcx> {
997 // Closures' typeck results come from their outermost function,
998 // as they are part of the same "inference environment".
999 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
1000 if outer_def_id != def_id {
1001 return tcx.typeck(outer_def_id);
1004 let id = tcx.hir().as_local_hir_id(def_id);
1005 let span = tcx.hir().span(id);
1007 // Figure out what primary body this item has.
1008 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
1009 span_bug!(span, "can't type-check body of {:?}", def_id);
1011 let body = tcx.hir().body(body_id);
1013 let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
1014 let param_env = tcx.param_env(def_id);
1015 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1016 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1017 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1023 &hir::Generics::empty(),
1030 check_abi(tcx, span, fn_sig.abi());
1032 // Compute the fty from point of view of inside the fn.
1033 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1034 let fn_sig = inh.normalize_associated_types_in(
1041 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1043 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1046 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1047 let expected_type = body_ty
1048 .and_then(|ty| match ty.kind {
1049 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1052 .unwrap_or_else(fallback);
1053 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1054 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1056 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1057 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1062 // Gather locals in statics (because of block expressions).
1063 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1065 fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
1067 fcx.write_ty(id, revealed_ty);
1072 // All type checking constraints were added, try to fallback unsolved variables.
1073 fcx.select_obligations_where_possible(false, |_| {});
1074 let mut fallback_has_occurred = false;
1076 // We do fallback in two passes, to try to generate
1077 // better error messages.
1078 // The first time, we do *not* replace opaque types.
1079 for ty in &fcx.unsolved_variables() {
1080 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1082 // We now see if we can make progress. This might
1083 // cause us to unify inference variables for opaque types,
1084 // since we may have unified some other type variables
1085 // during the first phase of fallback.
1086 // This means that we only replace inference variables with their underlying
1087 // opaque types as a last resort.
1089 // In code like this:
1092 // type MyType = impl Copy;
1093 // fn produce() -> MyType { true }
1094 // fn bad_produce() -> MyType { panic!() }
1097 // we want to unify the opaque inference variable in `bad_produce`
1098 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1099 // This will produce a nice error message about conflicting concrete
1100 // types for `MyType`.
1102 // If we had tried to fallback the opaque inference variable to `MyType`,
1103 // we will generate a confusing type-check error that does not explicitly
1104 // refer to opaque types.
1105 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1107 // We now run fallback again, but this time we allow it to replace
1108 // unconstrained opaque type variables, in addition to performing
1109 // other kinds of fallback.
1110 for ty in &fcx.unsolved_variables() {
1111 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1114 // See if we can make any more progress.
1115 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1117 // Even though coercion casts provide type hints, we check casts after fallback for
1118 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1121 // Closure and generator analysis may run after fallback
1122 // because they don't constrain other type variables.
1123 fcx.closure_analyze(body);
1124 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1125 fcx.resolve_generator_interiors(def_id.to_def_id());
1127 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1128 let ty = fcx.normalize_ty(span, ty);
1129 fcx.require_type_is_sized(ty, span, code);
1132 fcx.select_all_obligations_or_error();
1134 if fn_decl.is_some() {
1135 fcx.regionck_fn(id, body);
1137 fcx.regionck_expr(body);
1140 fcx.resolve_type_vars_in_body(body)
1143 // Consistency check our TypeckResults instance can hold all ItemLocalIds
1144 // it will need to hold.
1145 assert_eq!(typeck_results.hir_owner, id.owner);
1150 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1151 if !tcx.sess.target.target.is_abi_supported(abi) {
1156 "The ABI `{}` is not supported for the current target",
1163 struct GatherLocalsVisitor<'a, 'tcx> {
1164 fcx: &'a FnCtxt<'a, 'tcx>,
1165 parent_id: hir::HirId,
1168 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1169 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1172 // Infer the variable's type.
1173 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1174 kind: TypeVariableOriginKind::TypeInference,
1180 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1184 // Take type that the user specified.
1185 self.fcx.locals.borrow_mut().insert(nid, typ);
1192 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1193 type Map = intravisit::ErasedMap<'tcx>;
1195 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1196 NestedVisitorMap::None
1199 // Add explicitly-declared locals.
1200 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1201 let local_ty = match local.ty {
1203 let o_ty = self.fcx.to_ty(&ty);
1205 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1206 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1215 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1217 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1218 ty.hir_id, o_ty, revealed_ty, c_ty
1223 .user_provided_types_mut()
1224 .insert(ty.hir_id, c_ty);
1226 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1230 self.assign(local.span, local.hir_id, local_ty);
1233 "local variable {:?} is assigned type {}",
1235 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1237 intravisit::walk_local(self, local);
1240 // Add pattern bindings.
1241 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1242 if let PatKind::Binding(_, _, ident, _) = p.kind {
1243 let var_ty = self.assign(p.span, p.hir_id, None);
1245 if !self.fcx.tcx.features().unsized_locals {
1246 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1250 "pattern binding {} is assigned to {} with type {:?}",
1252 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1256 intravisit::walk_pat(self, p);
1259 // Don't descend into the bodies of nested closures.
1262 _: intravisit::FnKind<'tcx>,
1263 _: &'tcx hir::FnDecl<'tcx>,
1271 /// When `check_fn` is invoked on a generator (i.e., a body that
1272 /// includes yield), it returns back some information about the yield
1274 struct GeneratorTypes<'tcx> {
1275 /// Type of generator argument / values returned by `yield`.
1276 resume_ty: Ty<'tcx>,
1278 /// Type of value that is yielded.
1281 /// Types that are captured (see `GeneratorInterior` for more).
1284 /// Indicates if the generator is movable or static (immovable).
1285 movability: hir::Movability,
1288 /// Helper used for fns and closures. Does the grungy work of checking a function
1289 /// body and returns the function context used for that purpose, since in the case of a fn item
1290 /// there is still a bit more to do.
1293 /// * inherited: other fields inherited from the enclosing fn (if any)
1294 fn check_fn<'a, 'tcx>(
1295 inherited: &'a Inherited<'a, 'tcx>,
1296 param_env: ty::ParamEnv<'tcx>,
1297 fn_sig: ty::FnSig<'tcx>,
1298 decl: &'tcx hir::FnDecl<'tcx>,
1300 body: &'tcx hir::Body<'tcx>,
1301 can_be_generator: Option<hir::Movability>,
1302 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1303 let mut fn_sig = fn_sig;
1305 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1307 // Create the function context. This is either derived from scratch or,
1308 // in the case of closures, based on the outer context.
1309 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1310 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1313 let sess = tcx.sess;
1314 let hir = tcx.hir();
1316 let declared_ret_ty = fn_sig.output();
1317 let revealed_ret_ty =
1318 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1319 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1320 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1321 fn_sig = tcx.mk_fn_sig(
1322 fn_sig.inputs().iter().cloned(),
1329 let span = body.value.span;
1331 fn_maybe_err(tcx, span, fn_sig.abi);
1333 if body.generator_kind.is_some() && can_be_generator.is_some() {
1335 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1336 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1338 // Resume type defaults to `()` if the generator has no argument.
1339 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1341 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1344 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
1345 let outer_hir_id = hir.as_local_hir_id(outer_def_id);
1346 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1348 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1349 // (as it's created inside the body itself, not passed in from outside).
1350 let maybe_va_list = if fn_sig.c_variadic {
1351 let span = body.params.last().unwrap().span;
1352 let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
1353 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1355 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1360 // Add formal parameters.
1361 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1362 let inputs_fn = fn_sig.inputs().iter().copied();
1363 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1364 // Check the pattern.
1365 let ty_span = try { inputs_hir?.get(idx)?.span };
1366 fcx.check_pat_top(¶m.pat, param_ty, ty_span, false);
1368 // Check that argument is Sized.
1369 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1370 // for simple cases like `fn foo(x: Trait)`,
1371 // where we would error once on the parameter as a whole, and once on the binding `x`.
1372 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1373 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
1376 fcx.write_ty(param.hir_id, param_ty);
1379 inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1381 if let ty::Dynamic(..) = declared_ret_ty.kind {
1382 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1383 // been evaluated so that we have types available for all the nodes being returned, but that
1384 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1385 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1386 // while keeping the current ordering we will ignore the tail expression's type because we
1387 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1388 // because we will trigger "unreachable expression" lints unconditionally.
1389 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1390 // case that a newcomer might make, returning a bare trait, and in that case we populate
1391 // the tail expression's type so that the suggestion will be correct, but ignore all other
1393 fcx.check_expr(&body.value);
1394 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1395 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1397 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1398 fcx.check_return_expr(&body.value);
1401 // We insert the deferred_generator_interiors entry after visiting the body.
1402 // This ensures that all nested generators appear before the entry of this generator.
1403 // resolve_generator_interiors relies on this property.
1404 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1406 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1407 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1409 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1410 Some(GeneratorTypes {
1414 movability: can_be_generator.unwrap(),
1420 // Finalize the return check by taking the LUB of the return types
1421 // we saw and assigning it to the expected return type. This isn't
1422 // really expected to fail, since the coercions would have failed
1423 // earlier when trying to find a LUB.
1425 // However, the behavior around `!` is sort of complex. In the
1426 // event that the `actual_return_ty` comes back as `!`, that
1427 // indicates that the fn either does not return or "returns" only
1428 // values of type `!`. In this case, if there is an expected
1429 // return type that is *not* `!`, that should be ok. But if the
1430 // return type is being inferred, we want to "fallback" to `!`:
1432 // let x = move || panic!();
1434 // To allow for that, I am creating a type variable with diverging
1435 // fallback. This was deemed ever so slightly better than unifying
1436 // the return value with `!` because it allows for the caller to
1437 // make more assumptions about the return type (e.g., they could do
1439 // let y: Option<u32> = Some(x());
1441 // which would then cause this return type to become `u32`, not
1443 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1444 let mut actual_return_ty = coercion.complete(&fcx);
1445 if actual_return_ty.is_never() {
1446 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1447 kind: TypeVariableOriginKind::DivergingFn,
1451 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1453 // Check that the main return type implements the termination trait.
1454 if let Some(term_id) = tcx.lang_items().termination() {
1455 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1456 let main_id = hir.as_local_hir_id(def_id);
1457 if main_id == fn_id {
1458 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1459 let trait_ref = ty::TraitRef::new(term_id, substs);
1460 let return_ty_span = decl.output.span();
1461 let cause = traits::ObligationCause::new(
1464 ObligationCauseCode::MainFunctionType,
1467 inherited.register_predicate(traits::Obligation::new(
1470 trait_ref.without_const().to_predicate(tcx),
1476 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1477 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1478 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1479 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1480 if declared_ret_ty.kind != ty::Never {
1481 sess.span_err(decl.output.span(), "return type should be `!`");
1484 let inputs = fn_sig.inputs();
1485 let span = hir.span(fn_id);
1486 if inputs.len() == 1 {
1487 let arg_is_panic_info = match inputs[0].kind {
1488 ty::Ref(region, ty, mutbl) => match ty.kind {
1489 ty::Adt(ref adt, _) => {
1490 adt.did == panic_info_did
1491 && mutbl == hir::Mutability::Not
1492 && *region != RegionKind::ReStatic
1499 if !arg_is_panic_info {
1500 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1503 if let Node::Item(item) = hir.get(fn_id) {
1504 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1505 if !generics.params.is_empty() {
1506 sess.span_err(span, "should have no type parameters");
1511 let span = sess.source_map().guess_head_span(span);
1512 sess.span_err(span, "function should have one argument");
1515 sess.err("language item required, but not found: `panic_info`");
1520 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1521 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1522 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1523 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1524 if declared_ret_ty.kind != ty::Never {
1525 sess.span_err(decl.output.span(), "return type should be `!`");
1528 let inputs = fn_sig.inputs();
1529 let span = hir.span(fn_id);
1530 if inputs.len() == 1 {
1531 let arg_is_alloc_layout = match inputs[0].kind {
1532 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1536 if !arg_is_alloc_layout {
1537 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1540 if let Node::Item(item) = hir.get(fn_id) {
1541 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1542 if !generics.params.is_empty() {
1545 "`#[alloc_error_handler]` function should have no type \
1552 let span = sess.source_map().guess_head_span(span);
1553 sess.span_err(span, "function should have one argument");
1556 sess.err("language item required, but not found: `alloc_layout`");
1564 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1565 let def_id = tcx.hir().local_def_id(id);
1566 let def = tcx.adt_def(def_id);
1567 def.destructor(tcx); // force the destructor to be evaluated
1568 check_representable(tcx, span, def_id);
1570 if def.repr.simd() {
1571 check_simd(tcx, span, def_id);
1574 check_transparent(tcx, span, def);
1575 check_packed(tcx, span, def);
1578 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1579 let def_id = tcx.hir().local_def_id(id);
1580 let def = tcx.adt_def(def_id);
1581 def.destructor(tcx); // force the destructor to be evaluated
1582 check_representable(tcx, span, def_id);
1583 check_transparent(tcx, span, def);
1584 check_union_fields(tcx, span, def_id);
1585 check_packed(tcx, span, def);
1588 /// When the `#![feature(untagged_unions)]` gate is active,
1589 /// check that the fields of the `union` does not contain fields that need dropping.
1590 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1591 let item_type = tcx.type_of(item_def_id);
1592 if let ty::Adt(def, substs) = item_type.kind {
1593 assert!(def.is_union());
1594 let fields = &def.non_enum_variant().fields;
1595 let param_env = tcx.param_env(item_def_id);
1596 for field in fields {
1597 let field_ty = field.ty(tcx, substs);
1598 // We are currently checking the type this field came from, so it must be local.
1599 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1600 if field_ty.needs_drop(tcx, param_env) {
1605 "unions may not contain fields that need dropping"
1607 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1613 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1618 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1619 /// projections that would result in "inheriting lifetimes".
1620 fn check_opaque<'tcx>(
1623 substs: SubstsRef<'tcx>,
1625 origin: &hir::OpaqueTyOrigin,
1627 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1628 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1631 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1632 /// in "inheriting lifetimes".
1633 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1634 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1636 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1641 struct ProhibitOpaqueVisitor<'tcx> {
1642 opaque_identity_ty: Ty<'tcx>,
1643 generics: &'tcx ty::Generics,
1644 ty: Option<Ty<'tcx>>,
1647 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1648 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1649 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1650 if t != self.opaque_identity_ty && t.super_visit_with(self) {
1657 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1658 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1659 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1660 return *index < self.generics.parent_count as u32;
1663 r.super_visit_with(self)
1666 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1667 if let ty::ConstKind::Unevaluated(..) = c.val {
1668 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1669 // which would violate this check. Even though the particular substitution is not used
1670 // within the const, this should still be fixed.
1673 c.super_visit_with(self)
1677 if let ItemKind::OpaqueTy(hir::OpaqueTy {
1678 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1682 let mut visitor = ProhibitOpaqueVisitor {
1683 opaque_identity_ty: tcx.mk_opaque(
1685 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1687 generics: tcx.generics_of(def_id),
1690 let prohibit_opaque = tcx
1691 .predicates_of(def_id)
1694 .any(|(predicate, _)| predicate.visit_with(&mut visitor));
1696 "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
1697 prohibit_opaque, visitor
1700 if prohibit_opaque {
1701 let is_async = match item.kind {
1702 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1703 hir::OpaqueTyOrigin::AsyncFn => true,
1706 _ => unreachable!(),
1709 let mut err = struct_span_err!(
1713 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1715 if is_async { "async fn" } else { "impl Trait" },
1718 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
1719 if snippet == "Self" {
1720 if let Some(ty) = visitor.ty {
1721 err.span_suggestion(
1723 "consider spelling out the type instead",
1724 format!("{:?}", ty),
1725 Applicability::MaybeIncorrect,
1735 /// Given a `DefId` for an opaque type in return position, find its parent item's return
1737 fn get_owner_return_paths(
1740 ) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
1741 let hir_id = tcx.hir().as_local_hir_id(def_id);
1742 let id = tcx.hir().get_parent_item(hir_id);
1746 .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
1747 .map(|(hir_id, body_id)| {
1748 let body = tcx.hir().body(body_id);
1749 let mut visitor = ReturnsVisitor::default();
1750 visitor.visit_body(body);
1755 /// Emit an error for recursive opaque types.
1757 /// If this is a return `impl Trait`, find the item's return expressions and point at them. For
1758 /// direct recursion this is enough, but for indirect recursion also point at the last intermediary
1761 /// If all the return expressions evaluate to `!`, then we explain that the error will go away
1762 /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
1763 fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1764 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1766 let mut label = false;
1767 if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
1768 let typeck_results = tcx.typeck(tcx.hir().local_def_id(hir_id));
1772 .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1773 .all(|ty| matches!(ty.kind, ty::Never))
1778 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1779 .map(|expr| expr.span)
1780 .collect::<Vec<Span>>();
1781 let span_len = spans.len();
1783 err.span_label(spans[0], "this returned value is of `!` type");
1785 let mut multispan: MultiSpan = spans.clone().into();
1788 .push_span_label(span, "this returned value is of `!` type".to_string());
1790 err.span_note(multispan, "these returned values have a concrete \"never\" type");
1792 err.help("this error will resolve once the item's body returns a concrete type");
1794 let mut seen = FxHashSet::default();
1796 err.span_label(span, "recursive opaque type");
1798 for (sp, ty) in visitor
1801 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1802 .filter(|(_, ty)| !matches!(ty.kind, ty::Never))
1804 struct VisitTypes(Vec<DefId>);
1805 impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes {
1806 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1808 ty::Opaque(def, _) => {
1812 _ => t.super_visit_with(self),
1816 let mut visitor = VisitTypes(vec![]);
1817 ty.visit_with(&mut visitor);
1818 for def_id in visitor.0 {
1819 let ty_span = tcx.def_span(def_id);
1820 if !seen.contains(&ty_span) {
1821 err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
1822 seen.insert(ty_span);
1824 err.span_label(sp, &format!("returning here with type `{}`", ty));
1830 err.span_label(span, "cannot resolve opaque type");
1835 /// Emit an error for recursive opaque types in a `let` binding.
1836 fn binding_opaque_type_cycle_error(
1840 partially_expanded_type: Ty<'tcx>,
1842 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1843 err.span_label(span, "cannot resolve opaque type");
1844 // Find the the owner that declared this `impl Trait` type.
1845 let hir_id = tcx.hir().as_local_hir_id(def_id);
1846 let mut prev_hir_id = hir_id;
1847 let mut hir_id = tcx.hir().get_parent_node(hir_id);
1848 while let Some(node) = tcx.hir().find(hir_id) {
1850 hir::Node::Local(hir::Local {
1854 source: hir::LocalSource::Normal,
1857 err.span_label(pat.span, "this binding might not have a concrete type");
1858 err.span_suggestion_verbose(
1859 ty.span.shrink_to_hi(),
1860 "set the binding to a value for a concrete type to be resolved",
1861 " = /* value */".to_string(),
1862 Applicability::HasPlaceholders,
1865 hir::Node::Local(hir::Local {
1867 source: hir::LocalSource::Normal,
1870 let hir_id = tcx.hir().as_local_hir_id(def_id);
1871 let typeck_results =
1872 tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
1873 if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
1877 "this is of type `{}`, which doesn't constrain \
1878 `{}` enough to arrive to a concrete type",
1879 ty, partially_expanded_type
1886 if prev_hir_id == hir_id {
1889 prev_hir_id = hir_id;
1890 hir_id = tcx.hir().get_parent_node(hir_id);
1895 fn async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span) {
1896 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
1897 .span_label(span, "recursive `async fn`")
1898 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1902 /// Checks that an opaque type does not contain cycles.
1903 fn check_opaque_for_cycles<'tcx>(
1906 substs: SubstsRef<'tcx>,
1908 origin: &hir::OpaqueTyOrigin,
1910 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1913 hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
1914 hir::OpaqueTyOrigin::Binding => {
1915 binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
1917 _ => opaque_type_cycle_error(tcx, def_id, span),
1922 // Forbid defining intrinsics in Rust code,
1923 // as they must always be defined by the compiler.
1924 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1925 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1926 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1930 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1932 "check_item_type(it.hir_id={}, it.name={})",
1934 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1936 let _indenter = indenter();
1938 // Consts can play a role in type-checking, so they are included here.
1939 hir::ItemKind::Static(..) => {
1940 let def_id = tcx.hir().local_def_id(it.hir_id);
1941 tcx.ensure().typeck(def_id);
1942 maybe_check_static_with_link_section(tcx, def_id, it.span);
1944 hir::ItemKind::Const(..) => {
1945 tcx.ensure().typeck(tcx.hir().local_def_id(it.hir_id));
1947 hir::ItemKind::Enum(ref enum_definition, _) => {
1948 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1950 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1951 hir::ItemKind::Impl { ref items, .. } => {
1952 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1953 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1954 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1955 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1956 let trait_def_id = impl_trait_ref.def_id;
1957 check_on_unimplemented(tcx, trait_def_id, it);
1960 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1961 let def_id = tcx.hir().local_def_id(it.hir_id);
1962 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1964 for item in items.iter() {
1965 let item = tcx.hir().trait_item(item.id);
1966 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1967 let abi = sig.header.abi;
1968 fn_maybe_err(tcx, item.ident.span, abi);
1972 hir::ItemKind::Struct(..) => {
1973 check_struct(tcx, it.hir_id, it.span);
1975 hir::ItemKind::Union(..) => {
1976 check_union(tcx, it.hir_id, it.span);
1978 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1979 let def_id = tcx.hir().local_def_id(it.hir_id);
1981 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1982 check_opaque(tcx, def_id, substs, it.span, &origin);
1984 hir::ItemKind::TyAlias(..) => {
1985 let def_id = tcx.hir().local_def_id(it.hir_id);
1986 let pty_ty = tcx.type_of(def_id);
1987 let generics = tcx.generics_of(def_id);
1988 check_type_params_are_used(tcx, &generics, pty_ty);
1990 hir::ItemKind::ForeignMod(ref m) => {
1991 check_abi(tcx, it.span, m.abi);
1993 if m.abi == Abi::RustIntrinsic {
1994 for item in m.items {
1995 intrinsic::check_intrinsic_type(tcx, item);
1997 } else if m.abi == Abi::PlatformIntrinsic {
1998 for item in m.items {
1999 intrinsic::check_platform_intrinsic_type(tcx, item);
2002 for item in m.items {
2003 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
2004 let own_counts = generics.own_counts();
2005 if generics.params.len() - own_counts.lifetimes != 0 {
2006 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
2007 (_, 0) => ("type", "types", Some("u32")),
2008 // We don't specify an example value, because we can't generate
2009 // a valid value for any type.
2010 (0, _) => ("const", "consts", None),
2011 _ => ("type or const", "types or consts", None),
2017 "foreign items may not have {} parameters",
2020 .span_label(item.span, &format!("can't have {} parameters", kinds))
2022 // FIXME: once we start storing spans for type arguments, turn this
2023 // into a suggestion.
2025 "replace the {} parameters with concrete {}{}",
2028 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
2034 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
2035 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
2040 _ => { /* nothing to do */ }
2044 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
2045 // Only restricted on wasm32 target for now
2046 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
2050 // If `#[link_section]` is missing, then nothing to verify
2051 let attrs = tcx.codegen_fn_attrs(id);
2052 if attrs.link_section.is_none() {
2056 // For the wasm32 target statics with `#[link_section]` are placed into custom
2057 // sections of the final output file, but this isn't link custom sections of
2058 // other executable formats. Namely we can only embed a list of bytes,
2059 // nothing with pointers to anything else or relocations. If any relocation
2060 // show up, reject them here.
2061 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
2062 // the consumer's responsibility to ensure all bytes that have been read
2063 // have defined values.
2064 match tcx.const_eval_poly(id.to_def_id()) {
2065 Ok(ConstValue::ByRef { alloc, .. }) => {
2066 if alloc.relocations().len() != 0 {
2067 let msg = "statics with a custom `#[link_section]` must be a \
2068 simple list of bytes on the wasm target with no \
2069 extra levels of indirection such as references";
2070 tcx.sess.span_err(span, msg);
2073 Ok(_) => bug!("Matching on non-ByRef static"),
2078 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
2079 let item_def_id = tcx.hir().local_def_id(item.hir_id);
2080 // an error would be reported if this fails.
2081 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
2084 fn report_forbidden_specialization(
2086 impl_item: &hir::ImplItem<'_>,
2089 let mut err = struct_span_err!(
2093 "`{}` specializes an item from a parent `impl`, but \
2094 that item is not marked `default`",
2097 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
2099 match tcx.span_of_impl(parent_impl) {
2101 err.span_label(span, "parent `impl` is here");
2103 "to specialize, `{}` in the parent `impl` must be marked `default`",
2108 err.note(&format!("parent implementation is in crate `{}`", cname));
2115 fn check_specialization_validity<'tcx>(
2117 trait_def: &ty::TraitDef,
2118 trait_item: &ty::AssocItem,
2120 impl_item: &hir::ImplItem<'_>,
2122 let kind = match impl_item.kind {
2123 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
2124 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
2125 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
2128 let ancestors = match trait_def.ancestors(tcx, impl_id) {
2129 Ok(ancestors) => ancestors,
2132 let mut ancestor_impls = ancestors
2134 .filter_map(|parent| {
2135 if parent.is_from_trait() {
2138 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
2143 if ancestor_impls.peek().is_none() {
2144 // No parent, nothing to specialize.
2148 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
2150 // Parent impl exists, and contains the parent item we're trying to specialize, but
2151 // doesn't mark it `default`.
2152 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
2153 Some(Err(parent_impl.def_id()))
2156 // Parent impl contains item and makes it specializable.
2157 Some(_) => Some(Ok(())),
2159 // Parent impl doesn't mention the item. This means it's inherited from the
2160 // grandparent. In that case, if parent is a `default impl`, inherited items use the
2161 // "defaultness" from the grandparent, else they are final.
2163 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
2166 Some(Err(parent_impl.def_id()))
2172 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
2173 // item. This is allowed, the item isn't actually getting specialized here.
2174 let result = opt_result.unwrap_or(Ok(()));
2176 if let Err(parent_impl) = result {
2177 report_forbidden_specialization(tcx, impl_item, parent_impl);
2181 fn check_impl_items_against_trait<'tcx>(
2183 full_impl_span: Span,
2184 impl_id: LocalDefId,
2185 impl_trait_ref: ty::TraitRef<'tcx>,
2186 impl_item_refs: &[hir::ImplItemRef<'_>],
2188 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2190 // If the trait reference itself is erroneous (so the compilation is going
2191 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2192 // isn't populated for such impls.
2193 if impl_trait_ref.references_error() {
2197 // Negative impls are not expected to have any items
2198 match tcx.impl_polarity(impl_id) {
2199 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2200 ty::ImplPolarity::Negative => {
2201 if let [first_item_ref, ..] = impl_item_refs {
2202 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2207 "negative impls cannot have any items"
2215 // Locate trait definition and items
2216 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2218 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2220 // Check existing impl methods to see if they are both present in trait
2221 // and compatible with trait signature
2222 for impl_item in impl_items() {
2223 let namespace = impl_item.kind.namespace();
2224 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2225 let ty_trait_item = tcx
2226 .associated_items(impl_trait_ref.def_id)
2227 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2229 // Not compatible, but needed for the error message
2230 tcx.associated_items(impl_trait_ref.def_id)
2231 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2235 // Check that impl definition matches trait definition
2236 if let Some(ty_trait_item) = ty_trait_item {
2237 match impl_item.kind {
2238 hir::ImplItemKind::Const(..) => {
2239 // Find associated const definition.
2240 if ty_trait_item.kind == ty::AssocKind::Const {
2249 let mut err = struct_span_err!(
2253 "item `{}` is an associated const, \
2254 which doesn't match its trait `{}`",
2256 impl_trait_ref.print_only_trait_path()
2258 err.span_label(impl_item.span, "does not match trait");
2259 // We can only get the spans from local trait definition
2260 // Same for E0324 and E0325
2261 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2262 err.span_label(trait_span, "item in trait");
2267 hir::ImplItemKind::Fn(..) => {
2268 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2269 if ty_trait_item.kind == ty::AssocKind::Fn {
2270 compare_impl_method(
2279 let mut err = struct_span_err!(
2283 "item `{}` is an associated method, \
2284 which doesn't match its trait `{}`",
2286 impl_trait_ref.print_only_trait_path()
2288 err.span_label(impl_item.span, "does not match trait");
2289 if let Some(trait_span) = opt_trait_span {
2290 err.span_label(trait_span, "item in trait");
2295 hir::ImplItemKind::TyAlias(_) => {
2296 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2297 if ty_trait_item.kind == ty::AssocKind::Type {
2307 let mut err = struct_span_err!(
2311 "item `{}` is an associated type, \
2312 which doesn't match its trait `{}`",
2314 impl_trait_ref.print_only_trait_path()
2316 err.span_label(impl_item.span, "does not match trait");
2317 if let Some(trait_span) = opt_trait_span {
2318 err.span_label(trait_span, "item in trait");
2325 check_specialization_validity(
2329 impl_id.to_def_id(),
2335 // Check for missing items from trait
2336 let mut missing_items = Vec::new();
2337 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2338 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2339 let is_implemented = ancestors
2340 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2341 .map(|node_item| !node_item.defining_node.is_from_trait())
2344 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2345 if !trait_item.defaultness.has_value() {
2346 missing_items.push(*trait_item);
2352 if !missing_items.is_empty() {
2353 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2357 fn missing_items_err(
2360 missing_items: &[ty::AssocItem],
2361 full_impl_span: Span,
2363 let missing_items_msg = missing_items
2365 .map(|trait_item| trait_item.ident.to_string())
2366 .collect::<Vec<_>>()
2369 let mut err = struct_span_err!(
2373 "not all trait items implemented, missing: `{}`",
2376 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2378 // `Span` before impl block closing brace.
2379 let hi = full_impl_span.hi() - BytePos(1);
2380 // Point at the place right before the closing brace of the relevant `impl` to suggest
2381 // adding the associated item at the end of its body.
2382 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2383 // Obtain the level of indentation ending in `sugg_sp`.
2384 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2385 // Make the whitespace that will make the suggestion have the right indentation.
2386 let padding: String = (0..indentation).map(|_| " ").collect();
2388 for trait_item in missing_items {
2389 let snippet = suggestion_signature(&trait_item, tcx);
2390 let code = format!("{}{}\n{}", padding, snippet, padding);
2391 let msg = format!("implement the missing item: `{}`", snippet);
2392 let appl = Applicability::HasPlaceholders;
2393 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2394 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2395 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2397 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2403 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2404 fn bounds_from_generic_predicates(
2406 predicates: ty::GenericPredicates<'_>,
2407 ) -> (String, String) {
2408 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2409 let mut projections = vec![];
2410 for (predicate, _) in predicates.predicates {
2411 debug!("predicate {:?}", predicate);
2412 match predicate.kind() {
2413 ty::PredicateKind::Trait(trait_predicate, _) => {
2414 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2415 let def_id = trait_predicate.skip_binder().def_id();
2416 if Some(def_id) != tcx.lang_items().sized_trait() {
2417 // Type params are `Sized` by default, do not add that restriction to the list
2418 // if it is a positive requirement.
2419 entry.push(trait_predicate.skip_binder().def_id());
2422 ty::PredicateKind::Projection(projection_pred) => {
2423 projections.push(projection_pred);
2428 let generics = if types.is_empty() {
2435 .filter_map(|t| match t.kind {
2436 ty::Param(_) => Some(t.to_string()),
2437 // Avoid suggesting the following:
2438 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2441 .collect::<Vec<_>>()
2445 let mut where_clauses = vec![];
2446 for (ty, bounds) in types {
2447 for bound in &bounds {
2448 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2451 for projection in &projections {
2452 let p = projection.skip_binder();
2453 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2454 // insert the associated types where they correspond, but for now let's be "lazy" and
2455 // propose this instead of the following valid resugaring:
2456 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2457 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2459 let where_clauses = if where_clauses.is_empty() {
2462 format!(" where {}", where_clauses.join(", "))
2464 (generics, where_clauses)
2467 /// Return placeholder code for the given function.
2468 fn fn_sig_suggestion(
2472 predicates: ty::GenericPredicates<'_>,
2473 assoc: &ty::AssocItem,
2480 Some(match ty.kind {
2481 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2482 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2483 let reg = match &format!("{}", reg)[..] {
2484 "'_" | "" => String::new(),
2485 reg => format!("{} ", reg),
2487 if assoc.fn_has_self_parameter {
2489 ty::Param(param) if param.name == kw::SelfUpper => {
2490 format!("&{}{}self", reg, mutability.prefix_str())
2493 _ => format!("self: {}", ty),
2496 format!("_: {:?}", ty)
2500 if assoc.fn_has_self_parameter && i == 0 {
2501 format!("self: {:?}", ty)
2503 format!("_: {:?}", ty)
2508 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2509 .filter_map(|arg| arg)
2510 .collect::<Vec<String>>()
2512 let output = sig.output();
2513 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2515 let unsafety = sig.unsafety.prefix_str();
2516 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2518 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2519 // not be present in the `fn` definition, not will we account for renamed
2520 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2521 // fill in a significant portion of the missing code, and other subsequent
2522 // suggestions can help the user fix the code.
2524 "{}fn {}{}({}){}{} {{ todo!() }}",
2525 unsafety, ident, generics, args, output, where_clauses
2529 /// Return placeholder code for the given associated item.
2530 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2531 /// structured suggestion.
2532 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2534 ty::AssocKind::Fn => {
2535 // We skip the binder here because the binder would deanonymize all
2536 // late-bound regions, and we don't want method signatures to show up
2537 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2538 // regions just fine, showing `fn(&MyType)`.
2541 tcx.fn_sig(assoc.def_id).skip_binder(),
2543 tcx.predicates_of(assoc.def_id),
2547 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2548 ty::AssocKind::Const => {
2549 let ty = tcx.type_of(assoc.def_id);
2550 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2551 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2556 /// Checks whether a type can be represented in memory. In particular, it
2557 /// identifies types that contain themselves without indirection through a
2558 /// pointer, which would mean their size is unbounded.
2559 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2560 let rty = tcx.type_of(item_def_id);
2562 // Check that it is possible to represent this type. This call identifies
2563 // (1) types that contain themselves and (2) types that contain a different
2564 // recursive type. It is only necessary to throw an error on those that
2565 // contain themselves. For case 2, there must be an inner type that will be
2566 // caught by case 1.
2567 match rty.is_representable(tcx, sp) {
2568 Representability::SelfRecursive(spans) => {
2569 recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
2572 Representability::Representable | Representability::ContainsRecursive => (),
2577 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2578 let t = tcx.type_of(def_id);
2579 if let ty::Adt(def, substs) = t.kind {
2580 if def.is_struct() {
2581 let fields = &def.non_enum_variant().fields;
2582 if fields.is_empty() {
2583 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2586 let e = fields[0].ty(tcx, substs);
2587 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2588 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2589 .span_label(sp, "SIMD elements must have the same type")
2594 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2595 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2601 "SIMD vector element type should be machine type"
2611 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2612 let repr = def.repr;
2614 for attr in tcx.get_attrs(def.did).iter() {
2615 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2616 if let attr::ReprPacked(pack) = r {
2617 if let Some(repr_pack) = repr.pack {
2618 if pack as u64 != repr_pack.bytes() {
2623 "type has conflicting packed representation hints"
2631 if repr.align.is_some() {
2636 "type has conflicting packed and align representation hints"
2640 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2641 let mut err = struct_span_err!(
2645 "packed type cannot transitively contain a `#[repr(align)]` type"
2649 tcx.def_span(def_spans[0].0),
2651 "`{}` has a `#[repr(align)]` attribute",
2652 tcx.item_name(def_spans[0].0)
2656 if def_spans.len() > 2 {
2657 let mut first = true;
2658 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2659 let ident = tcx.item_name(*adt_def);
2664 "`{}` contains a field of type `{}`",
2665 tcx.type_of(def.did),
2669 format!("...which contains a field of type `{}`", ident)
2682 fn check_packed_inner(
2685 stack: &mut Vec<DefId>,
2686 ) -> Option<Vec<(DefId, Span)>> {
2687 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2688 if def.is_struct() || def.is_union() {
2689 if def.repr.align.is_some() {
2690 return Some(vec![(def.did, DUMMY_SP)]);
2694 for field in &def.non_enum_variant().fields {
2695 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2696 if !stack.contains(&def.did) {
2697 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2698 defs.push((def.did, field.ident.span));
2711 /// Emit an error when encountering more or less than one variant in a transparent enum.
2712 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2713 let variant_spans: Vec<_> = adt
2716 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2718 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2719 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2720 err.span_label(sp, &msg);
2721 if let [start @ .., end] = &*variant_spans {
2722 for variant_span in start {
2723 err.span_label(*variant_span, "");
2725 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2730 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2732 fn bad_non_zero_sized_fields<'tcx>(
2734 adt: &'tcx ty::AdtDef,
2736 field_spans: impl Iterator<Item = Span>,
2739 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2740 let mut err = struct_span_err!(
2744 "{}transparent {} {}",
2745 if adt.is_enum() { "the variant of a " } else { "" },
2749 err.span_label(sp, &msg);
2750 for sp in field_spans {
2751 err.span_label(sp, "this field is non-zero-sized");
2756 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2757 if !adt.repr.transparent() {
2760 let sp = tcx.sess.source_map().guess_head_span(sp);
2762 if adt.is_union() && !tcx.features().transparent_unions {
2764 &tcx.sess.parse_sess,
2765 sym::transparent_unions,
2767 "transparent unions are unstable",
2772 if adt.variants.len() != 1 {
2773 bad_variant_count(tcx, adt, sp, adt.did);
2774 if adt.variants.is_empty() {
2775 // Don't bother checking the fields. No variants (and thus no fields) exist.
2780 // For each field, figure out if it's known to be a ZST and align(1)
2781 let field_infos = adt.all_fields().map(|field| {
2782 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2783 let param_env = tcx.param_env(field.did);
2784 let layout = tcx.layout_of(param_env.and(ty));
2785 // We are currently checking the type this field came from, so it must be local
2786 let span = tcx.hir().span_if_local(field.did).unwrap();
2787 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2788 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2792 let non_zst_fields =
2793 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2794 let non_zst_count = non_zst_fields.clone().count();
2795 if non_zst_count != 1 {
2796 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2798 for (span, zst, align1) in field_infos {
2804 "zero-sized field in transparent {} has alignment larger than 1",
2807 .span_label(span, "has alignment larger than 1")
2813 #[allow(trivial_numeric_casts)]
2814 pub fn check_enum<'tcx>(
2817 vs: &'tcx [hir::Variant<'tcx>],
2820 let def_id = tcx.hir().local_def_id(id);
2821 let def = tcx.adt_def(def_id);
2822 def.destructor(tcx); // force the destructor to be evaluated
2825 let attributes = tcx.get_attrs(def_id.to_def_id());
2826 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2831 "unsupported representation for zero-variant enum"
2833 .span_label(sp, "zero-variant enum")
2838 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2839 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2840 if !tcx.features().repr128 {
2842 &tcx.sess.parse_sess,
2845 "repr with 128-bit type is unstable",
2852 if let Some(ref e) = v.disr_expr {
2853 tcx.ensure().typeck(tcx.hir().local_def_id(e.hir_id));
2857 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2858 let is_unit = |var: &hir::Variant<'_>| match var.data {
2859 hir::VariantData::Unit(..) => true,
2863 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2864 let has_non_units = vs.iter().any(|var| !is_unit(var));
2865 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2866 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2868 if disr_non_unit || (disr_units && has_non_units) {
2870 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2875 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2876 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2877 // Check for duplicate discriminant values
2878 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2879 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2880 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2881 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2882 let i_span = match variant_i.disr_expr {
2883 Some(ref expr) => tcx.hir().span(expr.hir_id),
2884 None => tcx.hir().span(variant_i_hir_id),
2886 let span = match v.disr_expr {
2887 Some(ref expr) => tcx.hir().span(expr.hir_id),
2894 "discriminant value `{}` already exists",
2897 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2898 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2901 disr_vals.push(discr);
2904 check_representable(tcx, sp, def_id);
2905 check_transparent(tcx, sp, def);
2908 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2913 "expected unit struct, unit variant or constant, found {}{}",
2915 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2920 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2921 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2925 fn item_def_id(&self) -> Option<DefId> {
2929 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2930 // FIXME: refactor this into a method
2931 let node = self.tcx.hir().get(self.body_id);
2932 if let Some(fn_like) = FnLikeNode::from_node(node) {
2935 hir::Constness::NotConst
2939 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2941 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2942 let item_id = tcx.hir().ty_param_owner(hir_id);
2943 let item_def_id = tcx.hir().local_def_id(item_id);
2944 let generics = tcx.generics_of(item_def_id);
2945 let index = generics.param_def_id_to_index[&def_id];
2946 ty::GenericPredicates {
2948 predicates: tcx.arena.alloc_from_iter(
2949 self.param_env.caller_bounds().iter().filter_map(|predicate| {
2950 match predicate.kind() {
2951 ty::PredicateKind::Trait(ref data, _)
2952 if data.skip_binder().self_ty().is_param(index) =>
2954 // HACK(eddyb) should get the original `Span`.
2955 let span = tcx.def_span(def_id);
2956 Some((predicate, span))
2965 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2967 Some(def) => infer::EarlyBoundRegion(span, def.name),
2968 None => infer::MiscVariable(span),
2970 Some(self.next_region_var(v))
2973 fn allow_ty_infer(&self) -> bool {
2977 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2978 if let Some(param) = param {
2979 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2984 self.next_ty_var(TypeVariableOrigin {
2985 kind: TypeVariableOriginKind::TypeInference,
2994 param: Option<&ty::GenericParamDef>,
2996 ) -> &'tcx Const<'tcx> {
2997 if let Some(param) = param {
2998 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
3003 self.next_const_var(
3005 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
3010 fn projected_ty_from_poly_trait_ref(
3014 item_segment: &hir::PathSegment<'_>,
3015 poly_trait_ref: ty::PolyTraitRef<'tcx>,
3017 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
3019 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
3023 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
3032 self.tcx().mk_projection(item_def_id, item_substs)
3035 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
3036 if ty.has_escaping_bound_vars() {
3037 ty // FIXME: normalization and escaping regions
3039 self.normalize_associated_types_in(span, &ty)
3043 fn set_tainted_by_errors(&self) {
3044 self.infcx.set_tainted_by_errors()
3047 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
3048 self.write_ty(hir_id, ty)
3052 /// Controls whether the arguments are tupled. This is used for the call
3055 /// Tupling means that all call-side arguments are packed into a tuple and
3056 /// passed as a single parameter. For example, if tupling is enabled, this
3059 /// fn f(x: (isize, isize))
3061 /// Can be called as:
3068 #[derive(Clone, Eq, PartialEq)]
3069 enum TupleArgumentsFlag {
3074 /// Controls how we perform fallback for unconstrained
3077 /// Do not fallback type variables to opaque types.
3079 /// Perform all possible kinds of fallback, including
3080 /// turning type variables to opaque types.
3084 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3086 inh: &'a Inherited<'a, 'tcx>,
3087 param_env: ty::ParamEnv<'tcx>,
3088 body_id: hir::HirId,
3089 ) -> FnCtxt<'a, 'tcx> {
3093 err_count_on_creation: inh.tcx.sess.err_count(),
3095 ret_coercion_span: RefCell::new(None),
3096 resume_yield_tys: None,
3097 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
3098 diverges: Cell::new(Diverges::Maybe),
3099 has_errors: Cell::new(false),
3100 enclosing_breakables: RefCell::new(EnclosingBreakables {
3102 by_id: Default::default(),
3108 pub fn sess(&self) -> &Session {
3112 pub fn errors_reported_since_creation(&self) -> bool {
3113 self.tcx.sess.err_count() > self.err_count_on_creation
3116 /// Produces warning on the given node, if the current point in the
3117 /// function is unreachable, and there hasn't been another warning.
3118 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
3119 // FIXME: Combine these two 'if' expressions into one once
3120 // let chains are implemented
3121 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
3122 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
3123 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
3124 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
3125 if !span.is_desugaring(DesugaringKind::CondTemporary)
3126 && !span.is_desugaring(DesugaringKind::Async)
3127 && !orig_span.is_desugaring(DesugaringKind::Await)
3129 self.diverges.set(Diverges::WarnedAlways);
3131 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
3133 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
3134 let msg = format!("unreachable {}", kind);
3136 .span_label(span, &msg)
3140 .unwrap_or("any code following this expression is unreachable"),
3148 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
3149 ObligationCause::new(span, self.body_id, code)
3152 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
3153 self.cause(span, ObligationCauseCode::MiscObligation)
3156 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
3157 /// version (resolve_vars_if_possible), this version will
3158 /// also select obligations if it seems useful, in an effort
3159 /// to get more type information.
3160 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3161 debug!("resolve_vars_with_obligations(ty={:?})", ty);
3163 // No Infer()? Nothing needs doing.
3164 if !ty.has_infer_types_or_consts() {
3165 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3169 // If `ty` is a type variable, see whether we already know what it is.
3170 ty = self.resolve_vars_if_possible(&ty);
3171 if !ty.has_infer_types_or_consts() {
3172 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3176 // If not, try resolving pending obligations as much as
3177 // possible. This can help substantially when there are
3178 // indirect dependencies that don't seem worth tracking
3180 self.select_obligations_where_possible(false, |_| {});
3181 ty = self.resolve_vars_if_possible(&ty);
3183 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3187 fn record_deferred_call_resolution(
3189 closure_def_id: DefId,
3190 r: DeferredCallResolution<'tcx>,
3192 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3193 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3196 fn remove_deferred_call_resolutions(
3198 closure_def_id: DefId,
3199 ) -> Vec<DeferredCallResolution<'tcx>> {
3200 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3201 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3204 pub fn tag(&self) -> String {
3205 format!("{:p}", self)
3208 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3209 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3210 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3215 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3217 "write_ty({:?}, {:?}) in fcx {}",
3219 self.resolve_vars_if_possible(&ty),
3222 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
3224 if ty.references_error() {
3225 self.has_errors.set(true);
3226 self.set_tainted_by_errors();
3230 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3231 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
3234 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3235 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3238 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3239 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3240 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3241 self.write_substs(hir_id, method.substs);
3243 // When the method is confirmed, the `method.substs` includes
3244 // parameters from not just the method, but also the impl of
3245 // the method -- in particular, the `Self` type will be fully
3246 // resolved. However, those are not something that the "user
3247 // specified" -- i.e., those types come from the inferred type
3248 // of the receiver, not something the user wrote. So when we
3249 // create the user-substs, we want to replace those earlier
3250 // types with just the types that the user actually wrote --
3251 // that is, those that appear on the *method itself*.
3253 // As an example, if the user wrote something like
3254 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3255 // type of `foo` (possibly adjusted), but we don't want to
3256 // include that. We want just the `[_, u32]` part.
3257 if !method.substs.is_noop() {
3258 let method_generics = self.tcx.generics_of(method.def_id);
3259 if !method_generics.params.is_empty() {
3260 let user_type_annotation = self.infcx.probe(|_| {
3261 let user_substs = UserSubsts {
3262 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3263 let i = param.index as usize;
3264 if i < method_generics.parent_count {
3265 self.infcx.var_for_def(DUMMY_SP, param)
3270 user_self_ty: None, // not relevant here
3273 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3279 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3280 self.write_user_type_annotation(hir_id, user_type_annotation);
3285 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3286 if !substs.is_noop() {
3287 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3289 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
3293 /// Given the substs that we just converted from the HIR, try to
3294 /// canonicalize them and store them as user-given substitutions
3295 /// (i.e., substitutions that must be respected by the NLL check).
3297 /// This should be invoked **before any unifications have
3298 /// occurred**, so that annotations like `Vec<_>` are preserved
3300 pub fn write_user_type_annotation_from_substs(
3304 substs: SubstsRef<'tcx>,
3305 user_self_ty: Option<UserSelfTy<'tcx>>,
3308 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3309 user_self_ty={:?} in fcx {}",
3317 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3318 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3320 UserSubsts { substs, user_self_ty },
3322 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3323 self.write_user_type_annotation(hir_id, canonicalized);
3327 pub fn write_user_type_annotation(
3330 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3333 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3335 canonical_user_type_annotation,
3339 if !canonical_user_type_annotation.is_identity() {
3342 .user_provided_types_mut()
3343 .insert(hir_id, canonical_user_type_annotation);
3345 debug!("write_user_type_annotation: skipping identity substs");
3349 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3350 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3356 let autoborrow_mut = adj.iter().any(|adj| {
3357 matches!(adj, &Adjustment {
3358 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
3363 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3364 Entry::Vacant(entry) => {
3367 Entry::Occupied(mut entry) => {
3368 debug!(" - composing on top of {:?}", entry.get());
3369 match (&entry.get()[..], &adj[..]) {
3370 // Applying any adjustment on top of a NeverToAny
3371 // is a valid NeverToAny adjustment, because it can't
3373 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3375 Adjustment { kind: Adjust::Deref(_), .. },
3376 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3378 Adjustment { kind: Adjust::Deref(_), .. },
3379 .. // Any following adjustments are allowed.
3381 // A reborrow has no effect before a dereference.
3383 // FIXME: currently we never try to compose autoderefs
3384 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3386 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3387 expr, entry.get(), adj)
3389 *entry.get_mut() = adj;
3393 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
3394 // In this case implicit use of `Deref` and `Index` within `<expr>` should
3395 // instead be `DerefMut` and `IndexMut`, so fix those up.
3397 self.convert_place_derefs_to_mutable(expr);
3401 /// Basically whenever we are converting from a type scheme into
3402 /// the fn body space, we always want to normalize associated
3403 /// types as well. This function combines the two.
3404 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3406 T: TypeFoldable<'tcx>,
3408 let value = value.subst(self.tcx, substs);
3409 let result = self.normalize_associated_types_in(span, &value);
3410 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3414 /// As `instantiate_type_scheme`, but for the bounds found in a
3415 /// generic type scheme.
3416 fn instantiate_bounds(
3420 substs: SubstsRef<'tcx>,
3421 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3422 let bounds = self.tcx.predicates_of(def_id);
3423 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3424 let result = bounds.instantiate(self.tcx, substs);
3425 let result = self.normalize_associated_types_in(span, &result);
3427 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3428 bounds, substs, result, spans,
3433 /// Replaces the opaque types from the given value with type variables,
3434 /// and records the `OpaqueTypeMap` for later use during writeback. See
3435 /// `InferCtxt::instantiate_opaque_types` for more details.
3436 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3438 parent_id: hir::HirId,
3442 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3444 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3445 parent_def_id, value
3448 let (value, opaque_type_map) =
3449 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3457 let mut opaque_types = self.opaque_types.borrow_mut();
3458 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3459 for (ty, decl) in opaque_type_map {
3460 let _ = opaque_types.insert(ty, decl);
3461 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3467 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3469 T: TypeFoldable<'tcx>,
3471 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3474 fn normalize_associated_types_in_as_infer_ok<T>(
3478 ) -> InferOk<'tcx, T>
3480 T: TypeFoldable<'tcx>,
3482 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3485 pub fn require_type_meets(
3489 code: traits::ObligationCauseCode<'tcx>,
3492 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3495 pub fn require_type_is_sized(
3499 code: traits::ObligationCauseCode<'tcx>,
3501 if !ty.references_error() {
3502 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3503 self.require_type_meets(ty, span, code, lang_item);
3507 pub fn require_type_is_sized_deferred(
3511 code: traits::ObligationCauseCode<'tcx>,
3513 if !ty.references_error() {
3514 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3518 pub fn register_bound(
3522 cause: traits::ObligationCause<'tcx>,
3524 if !ty.references_error() {
3525 self.fulfillment_cx.borrow_mut().register_bound(
3535 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3536 let t = AstConv::ast_ty_to_ty(self, ast_t);
3537 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3541 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3542 let ty = self.to_ty(ast_ty);
3543 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3545 if Self::can_contain_user_lifetime_bounds(ty) {
3546 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3547 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3548 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3554 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3555 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3556 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3557 self.register_wf_obligation(
3559 self.tcx.hir().span(ast_c.hir_id),
3560 ObligationCauseCode::MiscObligation,
3565 pub fn const_arg_to_const(
3567 ast_c: &hir::AnonConst,
3568 param_def_id: DefId,
3569 ) -> &'tcx ty::Const<'tcx> {
3570 let const_def = ty::WithOptConstParam {
3571 did: self.tcx.hir().local_def_id(ast_c.hir_id),
3572 const_param_did: Some(param_def_id),
3574 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
3575 self.register_wf_obligation(
3577 self.tcx.hir().span(ast_c.hir_id),
3578 ObligationCauseCode::MiscObligation,
3583 // If the type given by the user has free regions, save it for later, since
3584 // NLL would like to enforce those. Also pass in types that involve
3585 // projections, since those can resolve to `'static` bounds (modulo #54940,
3586 // which hopefully will be fixed by the time you see this comment, dear
3587 // reader, although I have my doubts). Also pass in types with inference
3588 // types, because they may be repeated. Other sorts of things are already
3589 // sufficiently enforced with erased regions. =)
3590 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3592 T: TypeFoldable<'tcx>,
3594 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3597 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3598 match self.typeck_results.borrow().node_types().get(id) {
3600 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
3603 "no type for node {}: {} in fcx {}",
3605 self.tcx.hir().node_to_string(id),
3612 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3613 pub fn register_wf_obligation(
3615 arg: subst::GenericArg<'tcx>,
3617 code: traits::ObligationCauseCode<'tcx>,
3619 // WF obligations never themselves fail, so no real need to give a detailed cause:
3620 let cause = traits::ObligationCause::new(span, self.body_id, code);
3621 self.register_predicate(traits::Obligation::new(
3624 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3628 /// Registers obligations that all `substs` are well-formed.
3629 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3630 for arg in substs.iter().filter(|arg| {
3631 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3633 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3637 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3638 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3639 /// trait/region obligations.
3641 /// For example, if there is a function:
3644 /// fn foo<'a,T:'a>(...)
3647 /// and a reference:
3653 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3654 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3655 pub fn add_obligations_for_parameters(
3657 cause: traits::ObligationCause<'tcx>,
3658 predicates: ty::InstantiatedPredicates<'tcx>,
3660 assert!(!predicates.has_escaping_bound_vars());
3662 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3664 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3665 self.register_predicate(obligation);
3669 // FIXME(arielb1): use this instead of field.ty everywhere
3670 // Only for fields! Returns <none> for methods>
3671 // Indifferent to privacy flags
3675 field: &'tcx ty::FieldDef,
3676 substs: SubstsRef<'tcx>,
3678 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3681 fn check_casts(&self) {
3682 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3683 for cast in deferred_cast_checks.drain(..) {
3688 fn resolve_generator_interiors(&self, def_id: DefId) {
3689 let mut generators = self.deferred_generator_interiors.borrow_mut();
3690 for (body_id, interior, kind) in generators.drain(..) {
3691 self.select_obligations_where_possible(false, |_| {});
3692 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3696 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3698 // - Unconstrained ints are replaced with `i32`.
3700 // - Unconstrained floats are replaced with with `f64`.
3702 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3703 // is enabled. Otherwise, they are replaced with `()`.
3705 // Fallback becomes very dubious if we have encountered type-checking errors.
3706 // In that case, fallback to Error.
3707 // The return value indicates whether fallback has occurred.
3708 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3709 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3710 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3712 assert!(ty.is_ty_infer());
3713 let fallback = match self.type_is_unconstrained_numeric(ty) {
3714 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
3715 UnconstrainedInt => self.tcx.types.i32,
3716 UnconstrainedFloat => self.tcx.types.f64,
3717 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3719 // This type variable was created from the instantiation of an opaque
3720 // type. The fact that we're attempting to perform fallback for it
3721 // means that the function neither constrained it to a concrete
3722 // type, nor to the opaque type itself.
3724 // For example, in this code:
3727 // type MyType = impl Copy;
3728 // fn defining_use() -> MyType { true }
3729 // fn other_use() -> MyType { defining_use() }
3732 // `defining_use` will constrain the instantiated inference
3733 // variable to `bool`, while `other_use` will constrain
3734 // the instantiated inference variable to `MyType`.
3736 // When we process opaque types during writeback, we
3737 // will handle cases like `other_use`, and not count
3738 // them as defining usages
3740 // However, we also need to handle cases like this:
3743 // pub type Foo = impl Copy;
3744 // fn produce() -> Option<Foo> {
3749 // In the above snippet, the inference variable created by
3750 // instantiating `Option<Foo>` will be completely unconstrained.
3751 // We treat this as a non-defining use by making the inference
3752 // variable fall back to the opaque type itself.
3753 if let FallbackMode::All = mode {
3754 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3756 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3768 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3769 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3773 fn select_all_obligations_or_error(&self) {
3774 debug!("select_all_obligations_or_error");
3775 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3776 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3780 /// Select as many obligations as we can at present.
3781 fn select_obligations_where_possible(
3783 fallback_has_occurred: bool,
3784 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3786 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3787 if let Err(mut errors) = result {
3788 mutate_fullfillment_errors(&mut errors);
3789 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3793 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3794 /// returns a type of `&T`, but the actual type we assign to the
3795 /// *expression* is `T`. So this function just peels off the return
3796 /// type by one layer to yield `T`.
3797 fn make_overloaded_place_return_type(
3799 method: MethodCallee<'tcx>,
3800 ) -> ty::TypeAndMut<'tcx> {
3801 // extract method return type, which will be &T;
3802 let ret_ty = method.sig.output();
3804 // method returns &T, but the type as visible to user is T, so deref
3805 ret_ty.builtin_deref(true).unwrap()
3808 fn check_method_argument_types(
3811 expr: &'tcx hir::Expr<'tcx>,
3812 method: Result<MethodCallee<'tcx>, ()>,
3813 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3814 tuple_arguments: TupleArgumentsFlag,
3815 expected: Expectation<'tcx>,
3817 let has_error = match method {
3818 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3822 let err_inputs = self.err_args(args_no_rcvr.len());
3824 let err_inputs = match tuple_arguments {
3825 DontTupleArguments => err_inputs,
3826 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3829 self.check_argument_types(
3839 return self.tcx.ty_error();
3842 let method = method.unwrap();
3843 // HACK(eddyb) ignore self in the definition (see above).
3844 let expected_arg_tys = self.expected_inputs_for_expected_output(
3847 method.sig.output(),
3848 &method.sig.inputs()[1..],
3850 self.check_argument_types(
3853 &method.sig.inputs()[1..],
3854 &expected_arg_tys[..],
3856 method.sig.c_variadic,
3858 self.tcx.hir().span_if_local(method.def_id),
3863 fn self_type_matches_expected_vid(
3865 trait_ref: ty::PolyTraitRef<'tcx>,
3866 expected_vid: ty::TyVid,
3868 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3870 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3871 trait_ref, self_ty, expected_vid
3873 match self_ty.kind {
3874 ty::Infer(ty::TyVar(found_vid)) => {
3875 // FIXME: consider using `sub_root_var` here so we
3876 // can see through subtyping.
3877 let found_vid = self.root_var(found_vid);
3878 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3879 expected_vid == found_vid
3885 fn obligations_for_self_ty<'b>(
3888 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3891 // FIXME: consider using `sub_root_var` here so we
3892 // can see through subtyping.
3893 let ty_var_root = self.root_var(self_ty);
3895 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3898 self.fulfillment_cx.borrow().pending_obligations()
3903 .pending_obligations()
3905 .filter_map(move |obligation| match obligation.predicate.kind() {
3906 ty::PredicateKind::Projection(ref data) => {
3907 Some((data.to_poly_trait_ref(self.tcx), obligation))
3909 ty::PredicateKind::Trait(ref data, _) => {
3910 Some((data.to_poly_trait_ref(), obligation))
3912 ty::PredicateKind::Subtype(..) => None,
3913 ty::PredicateKind::RegionOutlives(..) => None,
3914 ty::PredicateKind::TypeOutlives(..) => None,
3915 ty::PredicateKind::WellFormed(..) => None,
3916 ty::PredicateKind::ObjectSafe(..) => None,
3917 ty::PredicateKind::ConstEvaluatable(..) => None,
3918 ty::PredicateKind::ConstEquate(..) => None,
3919 // N.B., this predicate is created by breaking down a
3920 // `ClosureType: FnFoo()` predicate, where
3921 // `ClosureType` represents some `Closure`. It can't
3922 // possibly be referring to the current closure,
3923 // because we haven't produced the `Closure` for
3924 // this closure yet; this is exactly why the other
3925 // code is looking for a self type of a unresolved
3926 // inference variable.
3927 ty::PredicateKind::ClosureKind(..) => None,
3929 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3932 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3933 self.obligations_for_self_ty(self_ty)
3934 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3937 /// Generic function that factors out common logic from function calls,
3938 /// method calls and overloaded operators.
3939 fn check_argument_types(
3942 expr: &'tcx hir::Expr<'tcx>,
3943 fn_inputs: &[Ty<'tcx>],
3944 expected_arg_tys: &[Ty<'tcx>],
3945 args: &'tcx [hir::Expr<'tcx>],
3947 tuple_arguments: TupleArgumentsFlag,
3948 def_span: Option<Span>,
3951 // Grab the argument types, supplying fresh type variables
3952 // if the wrong number of arguments were supplied
3953 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3955 // All the input types from the fn signature must outlive the call
3956 // so as to validate implied bounds.
3957 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3958 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3961 let expected_arg_count = fn_inputs.len();
3963 let param_count_error = |expected_count: usize,
3968 let (span, start_span, args) = match &expr.kind {
3969 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3970 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
3972 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3975 .and_then(|args| args.args.iter().last())
3976 // Account for `foo.bar::<T>()`.
3978 // Skip the closing `>`.
3981 .next_point(tcx.sess.source_map().next_point(arg.span()))
3984 &args[1..], // Skip the receiver.
3986 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3988 let arg_spans = if args.is_empty() {
3990 // ^^^-- supplied 0 arguments
3992 // expected 2 arguments
3993 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3996 // ^^^ - - - supplied 3 arguments
3998 // expected 2 arguments
3999 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
4002 let mut err = tcx.sess.struct_span_err_with_code(
4005 "this function takes {}{} but {} {} supplied",
4006 if c_variadic { "at least " } else { "" },
4007 potentially_plural_count(expected_count, "argument"),
4008 potentially_plural_count(arg_count, "argument"),
4009 if arg_count == 1 { "was" } else { "were" }
4011 DiagnosticId::Error(error_code.to_owned()),
4013 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
4014 for (i, span) in arg_spans.into_iter().enumerate() {
4017 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
4021 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
4022 err.span_label(def_s, "defined here");
4025 let sugg_span = tcx.sess.source_map().end_point(expr.span);
4026 // remove closing `)` from the span
4027 let sugg_span = sugg_span.shrink_to_lo();
4028 err.span_suggestion(
4030 "expected the unit value `()`; create it with empty parentheses",
4032 Applicability::MachineApplicable,
4039 if c_variadic { "at least " } else { "" },
4040 potentially_plural_count(expected_count, "argument")
4047 let mut expected_arg_tys = expected_arg_tys.to_vec();
4049 let formal_tys = if tuple_arguments == TupleArguments {
4050 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4051 match tuple_type.kind {
4052 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4053 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4054 expected_arg_tys = vec![];
4055 self.err_args(args.len())
4057 ty::Tuple(arg_types) => {
4058 expected_arg_tys = match expected_arg_tys.get(0) {
4059 Some(&ty) => match ty.kind {
4060 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4065 arg_types.iter().map(|k| k.expect_ty()).collect()
4072 "cannot use call notation; the first type parameter \
4073 for the function trait is neither a tuple nor unit"
4076 expected_arg_tys = vec![];
4077 self.err_args(args.len())
4080 } else if expected_arg_count == supplied_arg_count {
4082 } else if c_variadic {
4083 if supplied_arg_count >= expected_arg_count {
4086 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4087 expected_arg_tys = vec![];
4088 self.err_args(supplied_arg_count)
4091 // is the missing argument of type `()`?
4092 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4093 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4094 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4095 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4099 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4101 expected_arg_tys = vec![];
4102 self.err_args(supplied_arg_count)
4106 "check_argument_types: formal_tys={:?}",
4107 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4110 // If there is no expectation, expect formal_tys.
4111 let expected_arg_tys =
4112 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4114 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4116 // Check the arguments.
4117 // We do this in a pretty awful way: first we type-check any arguments
4118 // that are not closures, then we type-check the closures. This is so
4119 // that we have more information about the types of arguments when we
4120 // type-check the functions. This isn't really the right way to do this.
4121 for &check_closures in &[false, true] {
4122 debug!("check_closures={}", check_closures);
4124 // More awful hacks: before we check argument types, try to do
4125 // an "opportunistic" trait resolution of any trait bounds on
4126 // the call. This helps coercions.
4128 self.select_obligations_where_possible(false, |errors| {
4129 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4130 self.point_at_arg_instead_of_call_if_possible(
4132 &final_arg_types[..],
4139 // For C-variadic functions, we don't have a declared type for all of
4140 // the arguments hence we only do our usual type checking with
4141 // the arguments who's types we do know.
4142 let t = if c_variadic {
4144 } else if tuple_arguments == TupleArguments {
4149 for (i, arg) in args.iter().take(t).enumerate() {
4150 // Warn only for the first loop (the "no closures" one).
4151 // Closure arguments themselves can't be diverging, but
4152 // a previous argument can, e.g., `foo(panic!(), || {})`.
4153 if !check_closures {
4154 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4157 let is_closure = match arg.kind {
4158 ExprKind::Closure(..) => true,
4162 if is_closure != check_closures {
4166 debug!("checking the argument");
4167 let formal_ty = formal_tys[i];
4169 // The special-cased logic below has three functions:
4170 // 1. Provide as good of an expected type as possible.
4171 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4173 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4175 // 2. Coerce to the most detailed type that could be coerced
4176 // to, which is `expected_ty` if `rvalue_hint` returns an
4177 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4178 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4179 // We're processing function arguments so we definitely want to use
4180 // two-phase borrows.
4181 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
4182 final_arg_types.push((i, checked_ty, coerce_ty));
4184 // 3. Relate the expected type and the formal one,
4185 // if the expected type was used for the coercion.
4186 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4190 // We also need to make sure we at least write the ty of the other
4191 // arguments which we skipped above.
4193 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4194 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4195 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4198 for arg in args.iter().skip(expected_arg_count) {
4199 let arg_ty = self.check_expr(&arg);
4201 // There are a few types which get autopromoted when passed via varargs
4202 // in C but we just error out instead and require explicit casts.
4203 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4205 ty::Float(ast::FloatTy::F32) => {
4206 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4208 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4209 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4211 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4212 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4215 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4216 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4217 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4225 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4226 vec![self.tcx.ty_error(); len]
4229 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4230 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4231 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4232 /// can be not easily comparable with predicate type (because of coercion). If the types match
4233 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4234 /// the corresponding argument's expression span instead of the `fn` call path span.
4235 fn point_at_arg_instead_of_call_if_possible(
4237 errors: &mut Vec<traits::FulfillmentError<'_>>,
4238 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4240 args: &'tcx [hir::Expr<'tcx>],
4242 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4243 // the `?` operator.
4244 if call_sp.desugaring_kind().is_some() {
4248 for error in errors {
4249 // Only if the cause is somewhere inside the expression we want try to point at arg.
4250 // Otherwise, it means that the cause is somewhere else and we should not change
4251 // anything because we can break the correct span.
4252 if !call_sp.contains(error.obligation.cause.span) {
4256 if let ty::PredicateKind::Trait(predicate, _) = error.obligation.predicate.kind() {
4257 // Collect the argument position for all arguments that could have caused this
4258 // `FulfillmentError`.
4259 let mut referenced_in = final_arg_types
4261 .map(|&(i, checked_ty, _)| (i, checked_ty))
4262 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4263 .flat_map(|(i, ty)| {
4264 let ty = self.resolve_vars_if_possible(&ty);
4265 // We walk the argument type because the argument's type could have
4266 // been `Option<T>`, but the `FulfillmentError` references `T`.
4267 if ty.walk().any(|arg| arg == predicate.skip_binder().self_ty().into()) {
4273 .collect::<Vec<_>>();
4275 // Both checked and coerced types could have matched, thus we need to remove
4277 referenced_in.sort();
4278 referenced_in.dedup();
4280 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4281 // We make sure that only *one* argument matches the obligation failure
4282 // and we assign the obligation's span to its expression's.
4283 error.obligation.cause.make_mut().span = args[ref_in].span;
4284 error.points_at_arg_span = true;
4290 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4291 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4292 /// were caused by them. If they were, we point at the corresponding type argument's span
4293 /// instead of the `fn` call path span.
4294 fn point_at_type_arg_instead_of_call_if_possible(
4296 errors: &mut Vec<traits::FulfillmentError<'_>>,
4297 call_expr: &'tcx hir::Expr<'tcx>,
4299 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4300 if let hir::ExprKind::Path(qpath) = &path.kind {
4301 if let hir::QPath::Resolved(_, path) = &qpath {
4302 for error in errors {
4303 if let ty::PredicateKind::Trait(predicate, _) =
4304 error.obligation.predicate.kind()
4306 // If any of the type arguments in this path segment caused the
4307 // `FullfillmentError`, point at its span (#61860).
4311 .filter_map(|seg| seg.args.as_ref())
4312 .flat_map(|a| a.args.iter())
4314 if let hir::GenericArg::Type(hir_ty) = &arg {
4315 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4318 // Avoid ICE with associated types. As this is best
4319 // effort only, it's ok to ignore the case. It
4320 // would trigger in `is_send::<T::AssocType>();`
4321 // from `typeck-default-trait-impl-assoc-type.rs`.
4323 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4324 let ty = self.resolve_vars_if_possible(&ty);
4325 if ty == predicate.skip_binder().self_ty() {
4326 error.obligation.cause.make_mut().span = hir_ty.span;
4338 // AST fragment checking
4339 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4343 ast::LitKind::Str(..) => tcx.mk_static_str(),
4344 ast::LitKind::ByteStr(ref v) => {
4345 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4347 ast::LitKind::Byte(_) => tcx.types.u8,
4348 ast::LitKind::Char(_) => tcx.types.char,
4349 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4350 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4351 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4352 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4353 ty::Int(_) | ty::Uint(_) => Some(ty),
4354 ty::Char => Some(tcx.types.u8),
4355 ty::RawPtr(..) => Some(tcx.types.usize),
4356 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4359 opt_ty.unwrap_or_else(|| self.next_int_var())
4361 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4362 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4363 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4364 ty::Float(_) => Some(ty),
4367 opt_ty.unwrap_or_else(|| self.next_float_var())
4369 ast::LitKind::Bool(_) => tcx.types.bool,
4370 ast::LitKind::Err(_) => tcx.ty_error(),
4374 /// Unifies the output type with the expected type early, for more coercions
4375 /// and forward type information on the input expressions.
4376 fn expected_inputs_for_expected_output(
4379 expected_ret: Expectation<'tcx>,
4380 formal_ret: Ty<'tcx>,
4381 formal_args: &[Ty<'tcx>],
4382 ) -> Vec<Ty<'tcx>> {
4383 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4384 let ret_ty = match expected_ret.only_has_type(self) {
4386 None => return Vec::new(),
4388 let expect_args = self
4389 .fudge_inference_if_ok(|| {
4390 // Attempt to apply a subtyping relationship between the formal
4391 // return type (likely containing type variables if the function
4392 // is polymorphic) and the expected return type.
4393 // No argument expectations are produced if unification fails.
4394 let origin = self.misc(call_span);
4395 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4397 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4398 // to identity so the resulting type is not constrained.
4401 // Process any obligations locally as much as
4402 // we can. We don't care if some things turn
4403 // out unconstrained or ambiguous, as we're
4404 // just trying to get hints here.
4405 self.save_and_restore_in_snapshot_flag(|_| {
4406 let mut fulfill = TraitEngine::new(self.tcx);
4407 for obligation in ok.obligations {
4408 fulfill.register_predicate_obligation(self, obligation);
4410 fulfill.select_where_possible(self)
4414 Err(_) => return Err(()),
4417 // Record all the argument types, with the substitutions
4418 // produced from the above subtyping unification.
4419 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4421 .unwrap_or_default();
4423 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4424 formal_args, formal_ret, expect_args, expected_ret
4429 pub fn check_struct_path(
4433 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4434 let path_span = match *qpath {
4435 QPath::Resolved(_, ref path) => path.span,
4436 QPath::TypeRelative(ref qself, _) => qself.span,
4438 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4439 let variant = match def {
4441 self.set_tainted_by_errors();
4444 Res::Def(DefKind::Variant, _) => match ty.kind {
4445 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4446 _ => bug!("unexpected type: {:?}", ty),
4448 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4449 | Res::SelfTy(..) => match ty.kind {
4450 ty::Adt(adt, substs) if !adt.is_enum() => {
4451 Some((adt.non_enum_variant(), adt.did, substs))
4455 _ => bug!("unexpected definition: {:?}", def),
4458 if let Some((variant, did, substs)) = variant {
4459 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4460 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4462 // Check bounds on type arguments used in the path.
4463 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4465 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4466 self.add_obligations_for_parameters(cause, bounds);
4474 "expected struct, variant or union type, found {}",
4475 ty.sort_string(self.tcx)
4477 .span_label(path_span, "not a struct")
4483 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4484 // The newly resolved definition is written into `type_dependent_defs`.
4485 fn finish_resolving_struct_path(
4490 ) -> (Res, Ty<'tcx>) {
4492 QPath::Resolved(ref maybe_qself, ref path) => {
4493 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4494 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4497 QPath::TypeRelative(ref qself, ref segment) => {
4498 let ty = self.to_ty(qself);
4500 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4506 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4507 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
4508 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4510 // Write back the new resolution.
4511 self.write_resolution(hir_id, result);
4513 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4518 /// Resolves an associated value path into a base type and associated constant, or method
4519 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4520 pub fn resolve_ty_and_res_ufcs<'b>(
4522 qpath: &'b QPath<'b>,
4525 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4526 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4527 let (ty, qself, item_segment) = match *qpath {
4528 QPath::Resolved(ref opt_qself, ref path) => {
4531 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4535 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4537 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
4539 // Return directly on cache hit. This is useful to avoid doubly reporting
4540 // errors with default match binding modes. See #44614.
4542 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4543 return (def, Some(ty), slice::from_ref(&**item_segment));
4545 let item_name = item_segment.ident;
4546 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4547 let result = match error {
4548 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4549 _ => Err(ErrorReported),
4551 if item_name.name != kw::Invalid {
4552 if let Some(mut e) = self.report_method_error(
4556 SelfSource::QPath(qself),
4566 // Write back the new resolution.
4567 self.write_resolution(hir_id, result);
4569 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4571 slice::from_ref(&**item_segment),
4575 pub fn check_decl_initializer(
4577 local: &'tcx hir::Local<'tcx>,
4578 init: &'tcx hir::Expr<'tcx>,
4580 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4581 // for #42640 (default match binding modes).
4584 let ref_bindings = local.pat.contains_explicit_ref_binding();
4586 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4587 if let Some(m) = ref_bindings {
4588 // Somewhat subtle: if we have a `ref` binding in the pattern,
4589 // we want to avoid introducing coercions for the RHS. This is
4590 // both because it helps preserve sanity and, in the case of
4591 // ref mut, for soundness (issue #23116). In particular, in
4592 // the latter case, we need to be clear that the type of the
4593 // referent for the reference that results is *equal to* the
4594 // type of the place it is referencing, and not some
4595 // supertype thereof.
4596 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4597 self.demand_eqtype(init.span, local_ty, init_ty);
4600 self.check_expr_coercable_to_type(init, local_ty, None)
4604 /// Type check a `let` statement.
4605 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4606 // Determine and write the type which we'll check the pattern against.
4607 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4608 self.write_ty(local.hir_id, ty);
4610 // Type check the initializer.
4611 if let Some(ref init) = local.init {
4612 let init_ty = self.check_decl_initializer(local, &init);
4613 self.overwrite_local_ty_if_err(local, ty, init_ty);
4616 // Does the expected pattern type originate from an expression and what is the span?
4617 let (origin_expr, ty_span) = match (local.ty, local.init) {
4618 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4619 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4620 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4623 // Type check the pattern. Override if necessary to avoid knock-on errors.
4624 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4625 let pat_ty = self.node_ty(local.pat.hir_id);
4626 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4629 fn overwrite_local_ty_if_err(
4631 local: &'tcx hir::Local<'tcx>,
4635 if ty.references_error() {
4636 // Override the types everywhere with `err()` to avoid knock on errors.
4637 self.write_ty(local.hir_id, ty);
4638 self.write_ty(local.pat.hir_id, ty);
4639 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4640 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4641 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4645 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4646 err.span_suggestion_short(
4647 span.shrink_to_hi(),
4648 "consider using a semicolon here",
4650 Applicability::MachineApplicable,
4654 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4655 // Don't do all the complex logic below for `DeclItem`.
4657 hir::StmtKind::Item(..) => return,
4658 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4661 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4663 // Hide the outer diverging and `has_errors` flags.
4664 let old_diverges = self.diverges.replace(Diverges::Maybe);
4665 let old_has_errors = self.has_errors.replace(false);
4668 hir::StmtKind::Local(ref l) => {
4669 self.check_decl_local(&l);
4672 hir::StmtKind::Item(_) => {}
4673 hir::StmtKind::Expr(ref expr) => {
4674 // Check with expected type of `()`.
4675 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4676 self.suggest_semicolon_at_end(expr.span, err);
4679 hir::StmtKind::Semi(ref expr) => {
4680 self.check_expr(&expr);
4684 // Combine the diverging and `has_error` flags.
4685 self.diverges.set(self.diverges.get() | old_diverges);
4686 self.has_errors.set(self.has_errors.get() | old_has_errors);
4689 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4690 let unit = self.tcx.mk_unit();
4691 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4693 // if the block produces a `!` value, that can always be
4694 // (effectively) coerced to unit.
4696 self.demand_suptype(blk.span, unit, ty);
4700 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4701 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4702 /// when given code like the following:
4704 /// if false { return 0i32; } else { 1u32 }
4705 /// // ^^^^ point at this instead of the whole `if` expression
4707 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4708 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4709 let arm_spans: Vec<Span> = arms
4712 self.in_progress_typeck_results
4713 .and_then(|typeck_results| {
4714 typeck_results.borrow().node_type_opt(arm.body.hir_id)
4716 .and_then(|arm_ty| {
4717 if arm_ty.is_never() {
4720 Some(match &arm.body.kind {
4721 // Point at the tail expression when possible.
4722 hir::ExprKind::Block(block, _) => {
4723 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4731 if arm_spans.len() == 1 {
4732 return arm_spans[0];
4738 fn check_block_with_expected(
4740 blk: &'tcx hir::Block<'tcx>,
4741 expected: Expectation<'tcx>,
4744 let mut fcx_ps = self.ps.borrow_mut();
4745 let unsafety_state = fcx_ps.recurse(blk);
4746 replace(&mut *fcx_ps, unsafety_state)
4749 // In some cases, blocks have just one exit, but other blocks
4750 // can be targeted by multiple breaks. This can happen both
4751 // with labeled blocks as well as when we desugar
4752 // a `try { ... }` expression.
4756 // 'a: { if true { break 'a Err(()); } Ok(()) }
4758 // Here we would wind up with two coercions, one from
4759 // `Err(())` and the other from the tail expression
4760 // `Ok(())`. If the tail expression is omitted, that's a
4761 // "forced unit" -- unless the block diverges, in which
4762 // case we can ignore the tail expression (e.g., `'a: {
4763 // break 'a 22; }` would not force the type of the block
4765 let tail_expr = blk.expr.as_ref();
4766 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4767 let coerce = if blk.targeted_by_break {
4768 CoerceMany::new(coerce_to_ty)
4770 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4771 Some(e) => slice::from_ref(e),
4774 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4777 let prev_diverges = self.diverges.get();
4778 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4780 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4781 for s in blk.stmts {
4785 // check the tail expression **without** holding the
4786 // `enclosing_breakables` lock below.
4787 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4789 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4790 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4791 let coerce = ctxt.coerce.as_mut().unwrap();
4792 if let Some(tail_expr_ty) = tail_expr_ty {
4793 let tail_expr = tail_expr.unwrap();
4794 let span = self.get_expr_coercion_span(tail_expr);
4795 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4796 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4798 // Subtle: if there is no explicit tail expression,
4799 // that is typically equivalent to a tail expression
4800 // of `()` -- except if the block diverges. In that
4801 // case, there is no value supplied from the tail
4802 // expression (assuming there are no other breaks,
4803 // this implies that the type of the block will be
4806 // #41425 -- label the implicit `()` as being the
4807 // "found type" here, rather than the "expected type".
4808 if !self.diverges.get().is_always() {
4809 // #50009 -- Do not point at the entire fn block span, point at the return type
4810 // span, as it is the cause of the requirement, and
4811 // `consider_hint_about_removing_semicolon` will point at the last expression
4812 // if it were a relevant part of the error. This improves usability in editors
4813 // that highlight errors inline.
4814 let mut sp = blk.span;
4815 let mut fn_span = None;
4816 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4817 let ret_sp = decl.output.span();
4818 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4819 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4820 // output would otherwise be incorrect and even misleading. Make sure
4821 // the span we're aiming at correspond to a `fn` body.
4822 if block_sp == blk.span {
4824 fn_span = Some(ident.span);
4828 coerce.coerce_forced_unit(
4832 if let Some(expected_ty) = expected.only_has_type(self) {
4833 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4835 if let Some(fn_span) = fn_span {
4838 "implicitly returns `()` as its body has no tail or `return` \
4850 // If we can break from the block, then the block's exit is always reachable
4851 // (... as long as the entry is reachable) - regardless of the tail of the block.
4852 self.diverges.set(prev_diverges);
4855 let mut ty = ctxt.coerce.unwrap().complete(self);
4857 if self.has_errors.get() || ty.references_error() {
4858 ty = self.tcx.ty_error()
4861 self.write_ty(blk.hir_id, ty);
4863 *self.ps.borrow_mut() = prev;
4867 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4868 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4870 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4871 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4872 let body = self.tcx.hir().body(body_id);
4873 if let ExprKind::Block(block, _) = &body.value.kind {
4874 return Some(block.span);
4882 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4883 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4884 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4885 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4888 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4889 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4891 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4892 // This is less than ideal, it will not suggest a return type span on any
4893 // method called `main`, regardless of whether it is actually the entry point,
4894 // but it will still present it as the reason for the expected type.
4895 Some((&sig.decl, ident, ident.name != sym::main))
4897 Node::TraitItem(&hir::TraitItem {
4899 kind: hir::TraitItemKind::Fn(ref sig, ..),
4901 }) => Some((&sig.decl, ident, true)),
4902 Node::ImplItem(&hir::ImplItem {
4904 kind: hir::ImplItemKind::Fn(ref sig, ..),
4906 }) => Some((&sig.decl, ident, false)),
4911 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4912 /// suggestion can be made, `None` otherwise.
4913 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4914 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4915 // `while` before reaching it, as block tail returns are not available in them.
4916 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4917 let parent = self.tcx.hir().get(blk_id);
4918 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4922 /// On implicit return expressions with mismatched types, provides the following suggestions:
4924 /// - Points out the method's return type as the reason for the expected type.
4925 /// - Possible missing semicolon.
4926 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4927 pub fn suggest_mismatched_types_on_tail(
4929 err: &mut DiagnosticBuilder<'_>,
4930 expr: &'tcx hir::Expr<'tcx>,
4936 let expr = expr.peel_drop_temps();
4937 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4938 let mut pointing_at_return_type = false;
4939 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4940 pointing_at_return_type =
4941 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4943 pointing_at_return_type
4946 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4947 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4949 /// fn foo(x: usize) -> usize { x }
4950 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4954 err: &mut DiagnosticBuilder<'_>,
4955 expr: &hir::Expr<'_>,
4959 let hir = self.tcx.hir();
4960 let (def_id, sig) = match found.kind {
4961 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4962 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4966 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4967 let sig = self.normalize_associated_types_in(expr.span, &sig);
4968 if self.can_coerce(sig.output(), expected) {
4969 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4970 (String::new(), Applicability::MachineApplicable)
4972 ("...".to_string(), Applicability::HasPlaceholders)
4974 let mut msg = "call this function";
4975 match hir.get_if_local(def_id) {
4977 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4978 | Node::ImplItem(hir::ImplItem {
4979 kind: hir::ImplItemKind::Fn(_, body_id), ..
4981 | Node::TraitItem(hir::TraitItem {
4982 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4986 let body = hir.body(*body_id);
4990 .map(|param| match ¶m.pat.kind {
4991 hir::PatKind::Binding(_, _, ident, None)
4992 if ident.name != kw::SelfLower =>
4996 _ => "_".to_string(),
4998 .collect::<Vec<_>>()
5001 Some(Node::Expr(hir::Expr {
5002 kind: ExprKind::Closure(_, _, body_id, _, _),
5003 span: full_closure_span,
5006 if *full_closure_span == expr.span {
5009 msg = "call this closure";
5010 let body = hir.body(*body_id);
5014 .map(|param| match ¶m.pat.kind {
5015 hir::PatKind::Binding(_, _, ident, None)
5016 if ident.name != kw::SelfLower =>
5020 _ => "_".to_string(),
5022 .collect::<Vec<_>>()
5025 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
5026 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
5027 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
5028 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
5029 msg = "instantiate this tuple variant";
5031 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
5032 msg = "instantiate this tuple struct";
5037 Some(Node::ForeignItem(hir::ForeignItem {
5038 kind: hir::ForeignItemKind::Fn(_, idents, _),
5044 if ident.name != kw::SelfLower {
5050 .collect::<Vec<_>>()
5053 Some(Node::TraitItem(hir::TraitItem {
5054 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5060 if ident.name != kw::SelfLower {
5066 .collect::<Vec<_>>()
5071 err.span_suggestion_verbose(
5072 expr.span.shrink_to_hi(),
5073 &format!("use parentheses to {}", msg),
5074 format!("({})", sugg_call),
5082 pub fn suggest_deref_ref_or_into(
5084 err: &mut DiagnosticBuilder<'_>,
5085 expr: &hir::Expr<'_>,
5088 expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
5090 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5091 err.span_suggestion(sp, msg, suggestion, applicability);
5092 } else if let (ty::FnDef(def_id, ..), true) =
5093 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5095 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5096 let sp = self.sess().source_map().guess_head_span(sp);
5097 err.span_label(sp, &format!("{} defined here", found));
5099 } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
5100 let is_struct_pat_shorthand_field =
5101 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5102 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5103 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5104 let mut suggestions = iter::repeat(&expr_text)
5105 .zip(methods.iter())
5106 .filter_map(|(receiver, method)| {
5107 let method_call = format!(".{}()", method.ident);
5108 if receiver.ends_with(&method_call) {
5109 None // do not suggest code that is already there (#53348)
5111 let method_call_list = [".to_vec()", ".to_string()"];
5112 let sugg = if receiver.ends_with(".clone()")
5113 && method_call_list.contains(&method_call.as_str())
5115 let max_len = receiver.rfind('.').unwrap();
5116 format!("{}{}", &receiver[..max_len], method_call)
5118 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5119 format!("({}){}", receiver, method_call)
5121 format!("{}{}", receiver, method_call)
5124 Some(if is_struct_pat_shorthand_field {
5125 format!("{}: {}", receiver, sugg)
5132 if suggestions.peek().is_some() {
5133 err.span_suggestions(
5135 "try using a conversion method",
5137 Applicability::MaybeIncorrect,
5144 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5145 /// in the heap by calling `Box::new()`.
5146 fn suggest_boxing_when_appropriate(
5148 err: &mut DiagnosticBuilder<'_>,
5149 expr: &hir::Expr<'_>,
5153 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5154 // Do not suggest `Box::new` in const context.
5157 if !expected.is_box() || found.is_box() {
5160 let boxed_found = self.tcx.mk_box(found);
5161 if let (true, Ok(snippet)) = (
5162 self.can_coerce(boxed_found, expected),
5163 self.sess().source_map().span_to_snippet(expr.span),
5165 err.span_suggestion(
5167 "store this in the heap by calling `Box::new`",
5168 format!("Box::new({})", snippet),
5169 Applicability::MachineApplicable,
5172 "for more on the distinction between the stack and the heap, read \
5173 https://doc.rust-lang.org/book/ch15-01-box.html, \
5174 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5175 https://doc.rust-lang.org/std/boxed/index.html",
5180 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5181 fn suggest_calling_boxed_future_when_appropriate(
5183 err: &mut DiagnosticBuilder<'_>,
5184 expr: &hir::Expr<'_>,
5190 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5191 // Do not suggest `Box::new` in const context.
5194 let pin_did = self.tcx.lang_items().pin_type();
5195 match expected.kind {
5196 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5197 // This guards the `unwrap` and `mk_box` below.
5198 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5201 let boxed_found = self.tcx.mk_box(found);
5202 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5203 if let (true, Ok(snippet)) = (
5204 self.can_coerce(new_found, expected),
5205 self.sess().source_map().span_to_snippet(expr.span),
5208 ty::Adt(def, _) if def.is_box() => {
5209 err.help("use `Box::pin`");
5212 err.span_suggestion(
5214 "you need to pin and box this expression",
5215 format!("Box::pin({})", snippet),
5216 Applicability::MachineApplicable,
5226 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5230 /// bar_that_returns_u32()
5234 /// This routine checks if the return expression in a block would make sense on its own as a
5235 /// statement and the return type has been left as default or has been specified as `()`. If so,
5236 /// it suggests adding a semicolon.
5237 fn suggest_missing_semicolon(
5239 err: &mut DiagnosticBuilder<'_>,
5240 expression: &'tcx hir::Expr<'tcx>,
5244 if expected.is_unit() {
5245 // `BlockTailExpression` only relevant if the tail expr would be
5246 // useful on its own.
5247 match expression.kind {
5249 | ExprKind::MethodCall(..)
5250 | ExprKind::Loop(..)
5251 | ExprKind::Match(..)
5252 | ExprKind::Block(..) => {
5253 err.span_suggestion(
5254 cause_span.shrink_to_hi(),
5255 "try adding a semicolon",
5257 Applicability::MachineApplicable,
5265 /// A possible error is to forget to add a return type that is needed:
5269 /// bar_that_returns_u32()
5273 /// This routine checks if the return type is left as default, the method is not part of an
5274 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5276 fn suggest_missing_return_type(
5278 err: &mut DiagnosticBuilder<'_>,
5279 fn_decl: &hir::FnDecl<'_>,
5284 // Only suggest changing the return type for methods that
5285 // haven't set a return type at all (and aren't `fn main()` or an impl).
5286 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5287 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5288 err.span_suggestion(
5290 "try adding a return type",
5291 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5292 Applicability::MachineApplicable,
5296 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5297 err.span_label(span, "possibly return type missing here?");
5300 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5301 // `fn main()` must return `()`, do not suggest changing return type
5302 err.span_label(span, "expected `()` because of default return type");
5305 // expectation was caused by something else, not the default return
5306 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5307 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5308 // Only point to return type if the expected type is the return type, as if they
5309 // are not, the expectation must have been caused by something else.
5310 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5312 let ty = AstConv::ast_ty_to_ty(self, ty);
5313 debug!("suggest_missing_return_type: return type {:?}", ty);
5314 debug!("suggest_missing_return_type: expected type {:?}", ty);
5315 if ty.kind == expected.kind {
5316 err.span_label(sp, format!("expected `{}` because of return type", expected));
5324 /// A possible error is to forget to add `.await` when using futures:
5327 /// async fn make_u32() -> u32 {
5331 /// fn take_u32(x: u32) {}
5333 /// async fn foo() {
5334 /// let x = make_u32();
5339 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5340 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5341 /// `.await` to the tail of the expression.
5342 fn suggest_missing_await(
5344 err: &mut DiagnosticBuilder<'_>,
5345 expr: &hir::Expr<'_>,
5349 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5350 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5351 // body isn't `async`.
5352 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5353 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5354 let body = self.tcx().hir().body(body_id);
5355 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5357 // Check for `Future` implementations by constructing a predicate to
5358 // prove: `<T as Future>::Output == U`
5359 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5360 let item_def_id = self
5362 .associated_items(future_trait)
5363 .in_definition_order()
5367 // `<T as Future>::Output`
5368 let projection_ty = ty::ProjectionTy {
5372 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5378 ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5382 .to_predicate(self.tcx);
5383 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5385 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5387 if self.infcx.predicate_may_hold(&obligation) {
5388 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5389 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5390 err.span_suggestion(
5392 "consider using `.await` here",
5393 format!("{}.await", code),
5394 Applicability::MaybeIncorrect,
5397 debug!("suggest_missing_await: no snippet for {:?}", sp);
5400 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5406 fn note_need_for_fn_pointer(
5408 err: &mut DiagnosticBuilder<'_>,
5412 let (sig, did, substs) = match (&expected.kind, &found.kind) {
5413 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
5414 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
5415 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
5420 "different `fn` items always have unique types, even if their signatures are \
5423 (sig1, *did1, substs1)
5425 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
5426 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
5430 (sig1, *did, substs)
5434 err.help(&format!("change the expected type to be function pointer `{}`", sig));
5436 "if the expected type is due to type inference, cast the expected `fn` to a function \
5437 pointer: `{} as {}`",
5438 self.tcx.def_path_str_with_substs(did, substs),
5443 /// A common error is to add an extra semicolon:
5446 /// fn foo() -> usize {
5451 /// This routine checks if the final statement in a block is an
5452 /// expression with an explicit semicolon whose type is compatible
5453 /// with `expected_ty`. If so, it suggests removing the semicolon.
5454 fn consider_hint_about_removing_semicolon(
5456 blk: &'tcx hir::Block<'tcx>,
5457 expected_ty: Ty<'tcx>,
5458 err: &mut DiagnosticBuilder<'_>,
5460 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5461 err.span_suggestion(
5463 "consider removing this semicolon",
5465 Applicability::MachineApplicable,
5470 fn could_remove_semicolon(
5472 blk: &'tcx hir::Block<'tcx>,
5473 expected_ty: Ty<'tcx>,
5475 // Be helpful when the user wrote `{... expr;}` and
5476 // taking the `;` off is enough to fix the error.
5477 let last_stmt = blk.stmts.last()?;
5478 let last_expr = match last_stmt.kind {
5479 hir::StmtKind::Semi(ref e) => e,
5482 let last_expr_ty = self.node_ty(last_expr.hir_id);
5483 if matches!(last_expr_ty.kind, ty::Error(_))
5484 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5488 let original_span = original_sp(last_stmt.span, blk.span);
5489 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5492 // Instantiates the given path, which must refer to an item with the given
5493 // number of type parameters and type.
5494 pub fn instantiate_value_path(
5496 segments: &[hir::PathSegment<'_>],
5497 self_ty: Option<Ty<'tcx>>,
5501 ) -> (Ty<'tcx>, Res) {
5503 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5504 segments, self_ty, res, hir_id,
5509 let path_segs = match res {
5510 Res::Local(_) | Res::SelfCtor(_) => vec![],
5511 Res::Def(kind, def_id) => {
5512 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5514 _ => bug!("instantiate_value_path on {:?}", res),
5517 let mut user_self_ty = None;
5518 let mut is_alias_variant_ctor = false;
5520 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5521 if let Some(self_ty) = self_ty {
5522 let adt_def = self_ty.ty_adt_def().unwrap();
5523 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5524 is_alias_variant_ctor = true;
5527 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5528 let container = tcx.associated_item(def_id).container;
5529 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5531 ty::TraitContainer(trait_did) => {
5532 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5534 ty::ImplContainer(impl_def_id) => {
5535 if segments.len() == 1 {
5536 // `<T>::assoc` will end up here, and so
5537 // can `T::assoc`. It this came from an
5538 // inherent impl, we need to record the
5539 // `T` for posterity (see `UserSelfTy` for
5541 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5542 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5550 // Now that we have categorized what space the parameters for each
5551 // segment belong to, let's sort out the parameters that the user
5552 // provided (if any) into their appropriate spaces. We'll also report
5553 // errors if type parameters are provided in an inappropriate place.
5555 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5556 let generics_has_err = AstConv::prohibit_generics(
5558 segments.iter().enumerate().filter_map(|(index, seg)| {
5559 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5567 if let Res::Local(hid) = res {
5568 let ty = self.local_ty(span, hid).decl_ty;
5569 let ty = self.normalize_associated_types_in(span, &ty);
5570 self.write_ty(hir_id, ty);
5574 if generics_has_err {
5575 // Don't try to infer type parameters when prohibited generic arguments were given.
5576 user_self_ty = None;
5579 // Now we have to compare the types that the user *actually*
5580 // provided against the types that were *expected*. If the user
5581 // did not provide any types, then we want to substitute inference
5582 // variables. If the user provided some types, we may still need
5583 // to add defaults. If the user provided *too many* types, that's
5586 let mut infer_args_for_err = FxHashSet::default();
5587 for &PathSeg(def_id, index) in &path_segs {
5588 let seg = &segments[index];
5589 let generics = tcx.generics_of(def_id);
5590 // Argument-position `impl Trait` is treated as a normal generic
5591 // parameter internally, but we don't allow users to specify the
5592 // parameter's value explicitly, so we have to do some error-
5594 if let GenericArgCountResult {
5595 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5597 } = AstConv::check_generic_arg_count_for_call(
5598 tcx, span, &generics, &seg, false, // `is_method_call`
5600 infer_args_for_err.insert(index);
5601 self.set_tainted_by_errors(); // See issue #53251.
5605 let has_self = path_segs
5607 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5610 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5611 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5613 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5614 let variant = adt_def.non_enum_variant();
5615 let ctor_def_id = variant.ctor_def_id.unwrap();
5617 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5622 let mut err = tcx.sess.struct_span_err(
5624 "the `Self` constructor can only be used with tuple or unit structs",
5626 if let Some(adt_def) = ty.ty_adt_def() {
5627 match adt_def.adt_kind() {
5629 err.help("did you mean to use one of the enum's variants?");
5631 AdtKind::Struct | AdtKind::Union => {
5632 err.span_suggestion(
5634 "use curly brackets",
5635 String::from("Self { /* fields */ }"),
5636 Applicability::HasPlaceholders,
5643 return (tcx.ty_error(), res);
5649 let def_id = res.def_id();
5651 // The things we are substituting into the type should not contain
5652 // escaping late-bound regions, and nor should the base type scheme.
5653 let ty = tcx.type_of(def_id);
5655 let arg_count = GenericArgCountResult {
5656 explicit_late_bound: ExplicitLateBound::No,
5657 correct: if infer_args_for_err.is_empty() {
5660 Err(GenericArgCountMismatch::default())
5664 let substs = self_ctor_substs.unwrap_or_else(|| {
5665 AstConv::create_substs_for_generic_args(
5672 // Provide the generic args, and whether types should be inferred.
5674 if let Some(&PathSeg(_, index)) =
5675 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5677 // If we've encountered an `impl Trait`-related error, we're just
5678 // going to infer the arguments for better error messages.
5679 if !infer_args_for_err.contains(&index) {
5680 // Check whether the user has provided generic arguments.
5681 if let Some(ref data) = segments[index].args {
5682 return (Some(data), segments[index].infer_args);
5685 return (None, segments[index].infer_args);
5690 // Provide substitutions for parameters for which (valid) arguments have been provided.
5691 |param, arg| match (¶m.kind, arg) {
5692 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5693 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5695 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5696 self.to_ty(ty).into()
5698 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5699 self.const_arg_to_const(&ct.value, param.def_id).into()
5701 _ => unreachable!(),
5703 // Provide substitutions for parameters for which arguments are inferred.
5704 |substs, param, infer_args| {
5706 GenericParamDefKind::Lifetime => {
5707 self.re_infer(Some(param), span).unwrap().into()
5709 GenericParamDefKind::Type { has_default, .. } => {
5710 if !infer_args && has_default {
5711 // If we have a default, then we it doesn't matter that we're not
5712 // inferring the type arguments: we provide the default where any
5714 let default = tcx.type_of(param.def_id);
5717 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5721 // If no type arguments were provided, we have to infer them.
5722 // This case also occurs as a result of some malformed input, e.g.
5723 // a lifetime argument being given instead of a type parameter.
5724 // Using inference instead of `Error` gives better error messages.
5725 self.var_for_def(span, param)
5728 GenericParamDefKind::Const => {
5729 // FIXME(const_generics:defaults)
5730 // No const parameters were provided, we have to infer them.
5731 self.var_for_def(span, param)
5737 assert!(!substs.has_escaping_bound_vars());
5738 assert!(!ty.has_escaping_bound_vars());
5740 // First, store the "user substs" for later.
5741 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5743 self.add_required_obligations(span, def_id, &substs);
5745 // Substitute the values for the type parameters into the type of
5746 // the referenced item.
5747 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5749 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5750 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5751 // is inherent, there is no `Self` parameter; instead, the impl needs
5752 // type parameters, which we can infer by unifying the provided `Self`
5753 // with the substituted impl type.
5754 // This also occurs for an enum variant on a type alias.
5755 let ty = tcx.type_of(impl_def_id);
5757 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5758 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5759 Ok(ok) => self.register_infer_ok_obligations(ok),
5761 self.tcx.sess.delay_span_bug(
5764 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5773 self.check_rustc_args_require_const(def_id, hir_id, span);
5775 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5776 self.write_substs(hir_id, substs);
5778 (ty_substituted, res)
5781 /// Add all the obligations that are required, substituting and normalized appropriately.
5782 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5783 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5785 for (i, mut obligation) in traits::predicates_for_generics(
5786 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5792 // This makes the error point at the bound, but we want to point at the argument
5793 if let Some(span) = spans.get(i) {
5794 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
5796 self.register_predicate(obligation);
5800 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5801 // We're only interested in functions tagged with
5802 // #[rustc_args_required_const], so ignore anything that's not.
5803 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5807 // If our calling expression is indeed the function itself, we're good!
5808 // If not, generate an error that this can only be called directly.
5809 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5810 if let ExprKind::Call(ref callee, ..) = expr.kind {
5811 if callee.hir_id == hir_id {
5817 self.tcx.sess.span_err(
5819 "this function can only be invoked directly, not through a function pointer",
5823 /// Resolves `typ` by a single level if `typ` is a type variable.
5824 /// If no resolution is possible, then an error is reported.
5825 /// Numeric inference variables may be left unresolved.
5826 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5827 let ty = self.resolve_vars_with_obligations(ty);
5828 if !ty.is_ty_var() {
5831 if !self.is_tainted_by_errors() {
5832 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5833 .note("type must be known at this point")
5836 let err = self.tcx.ty_error();
5837 self.demand_suptype(sp, err, ty);
5842 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5845 ctxt: BreakableCtxt<'tcx>,
5847 ) -> (BreakableCtxt<'tcx>, R) {
5850 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5851 index = enclosing_breakables.stack.len();
5852 enclosing_breakables.by_id.insert(id, index);
5853 enclosing_breakables.stack.push(ctxt);
5857 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5858 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5859 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5860 enclosing_breakables.stack.pop().expect("missing breakable context")
5865 /// Instantiate a QueryResponse in a probe context, without a
5866 /// good ObligationCause.
5867 fn probe_instantiate_query_response(
5870 original_values: &OriginalQueryValues<'tcx>,
5871 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5872 ) -> InferResult<'tcx, Ty<'tcx>> {
5873 self.instantiate_query_response_and_region_obligations(
5874 &traits::ObligationCause::misc(span, self.body_id),
5881 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5882 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5883 let mut contained_in_place = false;
5885 while let hir::Node::Expr(parent_expr) =
5886 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5888 match &parent_expr.kind {
5889 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5890 if lhs.hir_id == expr_id {
5891 contained_in_place = true;
5897 expr_id = parent_expr.hir_id;
5904 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5905 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5907 assert_eq!(generics.parent, None);
5909 if generics.own_counts().types == 0 {
5913 let mut params_used = BitSet::new_empty(generics.params.len());
5915 if ty.references_error() {
5916 // If there is already another error, do not emit
5917 // an error for not using a type parameter.
5918 assert!(tcx.sess.has_errors());
5922 for leaf in ty.walk() {
5923 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5924 if let ty::Param(param) = leaf_ty.kind {
5925 debug!("found use of ty param {:?}", param);
5926 params_used.insert(param.index);
5931 for param in &generics.params {
5932 if !params_used.contains(param.index) {
5933 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5934 let span = tcx.def_span(param.def_id);
5939 "type parameter `{}` is unused",
5942 .span_label(span, "unused type parameter")
5949 fn fatally_break_rust(sess: &Session) {
5950 let handler = sess.diagnostic();
5951 handler.span_bug_no_panic(
5953 "It looks like you're trying to break rust; would you like some ICE?",
5955 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5956 handler.note_without_error(
5957 "we would appreciate a joke overview: \
5958 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5960 handler.note_without_error(&format!(
5961 "rustc {} running on {}",
5962 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5963 config::host_triple(),
5967 fn potentially_plural_count(count: usize, word: &str) -> String {
5968 format!("{} {}{}", count, word, pluralize!(count))