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 body_id: Option<hir::BodyId>,
262 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
263 type Target = InferCtxt<'a, 'tcx>;
264 fn deref(&self) -> &Self::Target {
269 /// When type-checking an expression, we propagate downward
270 /// whatever type hint we are able in the form of an `Expectation`.
271 #[derive(Copy, Clone, Debug)]
272 pub enum Expectation<'tcx> {
273 /// We know nothing about what type this expression should have.
276 /// This expression should have the type given (or some subtype).
277 ExpectHasType(Ty<'tcx>),
279 /// This expression will be cast to the `Ty`.
280 ExpectCastableToType(Ty<'tcx>),
282 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
283 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
284 ExpectRvalueLikeUnsized(Ty<'tcx>),
287 impl<'a, 'tcx> Expectation<'tcx> {
288 // Disregard "castable to" expectations because they
289 // can lead us astray. Consider for example `if cond
290 // {22} else {c} as u8` -- if we propagate the
291 // "castable to u8" constraint to 22, it will pick the
292 // type 22u8, which is overly constrained (c might not
293 // be a u8). In effect, the problem is that the
294 // "castable to" expectation is not the tightest thing
295 // we can say, so we want to drop it in this case.
296 // The tightest thing we can say is "must unify with
297 // else branch". Note that in the case of a "has type"
298 // constraint, this limitation does not hold.
300 // If the expected type is just a type variable, then don't use
301 // an expected type. Otherwise, we might write parts of the type
302 // when checking the 'then' block which are incompatible with the
304 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
306 ExpectHasType(ety) => {
307 let ety = fcx.shallow_resolve(ety);
308 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
310 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
315 /// Provides an expectation for an rvalue expression given an *optional*
316 /// hint, which is not required for type safety (the resulting type might
317 /// be checked higher up, as is the case with `&expr` and `box expr`), but
318 /// is useful in determining the concrete type.
320 /// The primary use case is where the expected type is a fat pointer,
321 /// like `&[isize]`. For example, consider the following statement:
323 /// let x: &[isize] = &[1, 2, 3];
325 /// In this case, the expected type for the `&[1, 2, 3]` expression is
326 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
327 /// expectation `ExpectHasType([isize])`, that would be too strong --
328 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
329 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
330 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
331 /// which still is useful, because it informs integer literals and the like.
332 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
333 /// for examples of where this comes up,.
334 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
335 match fcx.tcx.struct_tail_without_normalization(ty).kind {
336 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
337 _ => ExpectHasType(ty),
341 // Resolves `expected` by a single level if it is a variable. If
342 // there is no expected type or resolution is not possible (e.g.,
343 // no constraints yet present), just returns `None`.
344 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
346 NoExpectation => NoExpectation,
347 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
348 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
349 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
353 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
354 match self.resolve(fcx) {
355 NoExpectation => None,
356 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
360 /// It sometimes happens that we want to turn an expectation into
361 /// a **hard constraint** (i.e., something that must be satisfied
362 /// for the program to type-check). `only_has_type` will return
363 /// such a constraint, if it exists.
364 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
365 match self.resolve(fcx) {
366 ExpectHasType(ty) => Some(ty),
367 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
371 /// Like `only_has_type`, but instead of returning `None` if no
372 /// hard constraint exists, creates a fresh type variable.
373 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
374 self.only_has_type(fcx).unwrap_or_else(|| {
375 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
380 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
387 fn maybe_mut_place(m: hir::Mutability) -> Self {
389 hir::Mutability::Mut => Needs::MutPlace,
390 hir::Mutability::Not => Needs::None,
395 #[derive(Copy, Clone)]
396 pub struct UnsafetyState {
398 pub unsafety: hir::Unsafety,
399 pub unsafe_push_count: u32,
404 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
405 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
408 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
409 use hir::BlockCheckMode;
410 match self.unsafety {
411 // If this unsafe, then if the outer function was already marked as
412 // unsafe we shouldn't attribute the unsafe'ness to the block. This
413 // way the block can be warned about instead of ignoring this
414 // extraneous block (functions are never warned about).
415 hir::Unsafety::Unsafe if self.from_fn => *self,
418 let (unsafety, def, count) = match blk.rules {
419 BlockCheckMode::PushUnsafeBlock(..) => {
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
422 BlockCheckMode::PopUnsafeBlock(..) => {
423 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
425 BlockCheckMode::UnsafeBlock(..) => {
426 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
428 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
430 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
436 #[derive(Debug, Copy, Clone)]
442 /// Tracks whether executing a node may exit normally (versus
443 /// return/break/panic, which "diverge", leaving dead code in their
444 /// wake). Tracked semi-automatically (through type variables marked
445 /// as diverging), with some manual adjustments for control-flow
446 /// primitives (approximating a CFG).
447 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
449 /// Potentially unknown, some cases converge,
450 /// others require a CFG to determine them.
453 /// Definitely known to diverge and therefore
454 /// not reach the next sibling or its parent.
456 /// The `Span` points to the expression
457 /// that caused us to diverge
458 /// (e.g. `return`, `break`, etc).
460 /// In some cases (e.g. a `match` expression
461 /// where all arms diverge), we may be
462 /// able to provide a more informative
463 /// message to the user.
464 /// If this is `None`, a default message
465 /// will be generated, which is suitable
467 custom_note: Option<&'static str>,
470 /// Same as `Always` but with a reachability
471 /// warning already emitted.
475 // Convenience impls for combining `Diverges`.
477 impl ops::BitAnd for Diverges {
479 fn bitand(self, other: Self) -> Self {
480 cmp::min(self, other)
484 impl ops::BitOr for Diverges {
486 fn bitor(self, other: Self) -> Self {
487 cmp::max(self, other)
491 impl ops::BitAndAssign for Diverges {
492 fn bitand_assign(&mut self, other: Self) {
493 *self = *self & other;
497 impl ops::BitOrAssign for Diverges {
498 fn bitor_assign(&mut self, other: Self) {
499 *self = *self | other;
504 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
505 fn always(span: Span) -> Diverges {
506 Diverges::Always { span, custom_note: None }
509 fn is_always(self) -> bool {
510 // Enum comparison ignores the
511 // contents of fields, so we just
512 // fill them in with garbage here.
513 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
517 pub struct BreakableCtxt<'tcx> {
520 // this is `null` for loops where break with a value is illegal,
521 // such as `while`, `for`, and `while let`
522 coerce: Option<DynamicCoerceMany<'tcx>>,
525 pub struct EnclosingBreakables<'tcx> {
526 stack: Vec<BreakableCtxt<'tcx>>,
527 by_id: HirIdMap<usize>,
530 impl<'tcx> EnclosingBreakables<'tcx> {
531 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
532 self.opt_find_breakable(target_id).unwrap_or_else(|| {
533 bug!("could not find enclosing breakable with id {}", target_id);
537 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
538 match self.by_id.get(&target_id) {
539 Some(ix) => Some(&mut self.stack[*ix]),
545 pub struct FnCtxt<'a, 'tcx> {
548 /// The parameter environment used for proving trait obligations
549 /// in this function. This can change when we descend into
550 /// closures (as they bring new things into scope), hence it is
551 /// not part of `Inherited` (as of the time of this writing,
552 /// closures do not yet change the environment, but they will
554 param_env: ty::ParamEnv<'tcx>,
556 /// Number of errors that had been reported when we started
557 /// checking this function. On exit, if we find that *more* errors
558 /// have been reported, we will skip regionck and other work that
559 /// expects the types within the function to be consistent.
560 // FIXME(matthewjasper) This should not exist, and it's not correct
561 // if type checking is run in parallel.
562 err_count_on_creation: usize,
564 /// If `Some`, this stores coercion information for returned
565 /// expressions. If `None`, this is in a context where return is
566 /// inappropriate, such as a const expression.
568 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
569 /// can track all the return expressions and then use them to
570 /// compute a useful coercion from the set, similar to a match
571 /// expression or other branching context. You can use methods
572 /// like `expected_ty` to access the declared return type (if
574 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
576 /// First span of a return site that we find. Used in error messages.
577 ret_coercion_span: RefCell<Option<Span>>,
579 resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
581 ps: RefCell<UnsafetyState>,
583 /// Whether the last checked node generates a divergence (e.g.,
584 /// `return` will set this to `Always`). In general, when entering
585 /// an expression or other node in the tree, the initial value
586 /// indicates whether prior parts of the containing expression may
587 /// have diverged. It is then typically set to `Maybe` (and the
588 /// old value remembered) for processing the subparts of the
589 /// current expression. As each subpart is processed, they may set
590 /// the flag to `Always`, etc. Finally, at the end, we take the
591 /// result and "union" it with the original value, so that when we
592 /// return the flag indicates if any subpart of the parent
593 /// expression (up to and including this part) has diverged. So,
594 /// if you read it after evaluating a subexpression `X`, the value
595 /// you get indicates whether any subexpression that was
596 /// evaluating up to and including `X` diverged.
598 /// We currently use this flag only for diagnostic purposes:
600 /// - To warn about unreachable code: if, after processing a
601 /// sub-expression but before we have applied the effects of the
602 /// current node, we see that the flag is set to `Always`, we
603 /// can issue a warning. This corresponds to something like
604 /// `foo(return)`; we warn on the `foo()` expression. (We then
605 /// update the flag to `WarnedAlways` to suppress duplicate
606 /// reports.) Similarly, if we traverse to a fresh statement (or
607 /// tail expression) from a `Always` setting, we will issue a
608 /// warning. This corresponds to something like `{return;
609 /// foo();}` or `{return; 22}`, where we would warn on the
612 /// An expression represents dead code if, after checking it,
613 /// the diverges flag is set to something other than `Maybe`.
614 diverges: Cell<Diverges>,
616 /// Whether any child nodes have any type errors.
617 has_errors: Cell<bool>,
619 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
621 inh: &'a Inherited<'a, 'tcx>,
624 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
625 type Target = Inherited<'a, 'tcx>;
626 fn deref(&self) -> &Self::Target {
631 /// Helper type of a temporary returned by `Inherited::build(...)`.
632 /// Necessary because we can't write the following bound:
633 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
634 pub struct InheritedBuilder<'tcx> {
635 infcx: infer::InferCtxtBuilder<'tcx>,
639 impl Inherited<'_, 'tcx> {
640 pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
641 let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;
644 infcx: tcx.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner),
650 impl<'tcx> InheritedBuilder<'tcx> {
651 fn enter<F, R>(&mut self, f: F) -> R
653 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
655 let def_id = self.def_id;
656 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
660 impl Inherited<'a, 'tcx> {
661 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
663 let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
664 let body_id = tcx.hir().maybe_body_owned_by(item_id);
667 typeck_results: MaybeInProgressTables {
668 maybe_typeck_results: infcx.in_progress_typeck_results,
671 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
672 locals: RefCell::new(Default::default()),
673 deferred_sized_obligations: RefCell::new(Vec::new()),
674 deferred_call_resolutions: RefCell::new(Default::default()),
675 deferred_cast_checks: RefCell::new(Vec::new()),
676 deferred_generator_interiors: RefCell::new(Vec::new()),
677 opaque_types: RefCell::new(Default::default()),
678 opaque_types_vars: RefCell::new(Default::default()),
683 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
684 debug!("register_predicate({:?})", obligation);
685 if obligation.has_escaping_bound_vars() {
686 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
688 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
691 fn register_predicates<I>(&self, obligations: I)
693 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
695 for obligation in obligations {
696 self.register_predicate(obligation);
700 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
701 self.register_predicates(infer_ok.obligations);
705 fn normalize_associated_types_in<T>(
709 param_env: ty::ParamEnv<'tcx>,
713 T: TypeFoldable<'tcx>,
715 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
716 self.register_infer_ok_obligations(ok)
720 struct CheckItemTypesVisitor<'tcx> {
724 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
725 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
726 check_item_type(self.tcx, i);
728 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
729 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
732 pub fn check_wf_new(tcx: TyCtxt<'_>) {
733 let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
734 tcx.hir().krate().par_visit_all_item_likes(&visit);
737 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
738 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
741 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
742 debug_assert!(crate_num == LOCAL_CRATE);
743 tcx.par_body_owners(|body_owner_def_id| {
744 tcx.ensure().typeck(body_owner_def_id);
748 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
749 wfcheck::check_item_well_formed(tcx, def_id);
752 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
753 wfcheck::check_trait_item(tcx, def_id);
756 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
757 wfcheck::check_impl_item(tcx, def_id);
760 pub fn provide(providers: &mut Providers) {
761 method::provide(providers);
762 *providers = Providers {
766 diagnostic_only_typeck,
770 check_item_well_formed,
771 check_trait_item_well_formed,
772 check_impl_item_well_formed,
773 check_mod_item_types,
778 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
779 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
782 /// If this `DefId` is a "primary tables entry", returns
783 /// `Some((body_id, header, decl))` with information about
784 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
787 /// If this function returns `Some`, then `typeck_results(def_id)` will
788 /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
789 /// may not succeed. In some cases where this function returns `None`
790 /// (notably closures), `typeck_results(def_id)` would wind up
791 /// redirecting to the owning function.
795 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
796 match tcx.hir().get(id) {
797 Node::Item(item) => match item.kind {
798 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
799 Some((body, Some(ty), None, None))
801 hir::ItemKind::Fn(ref sig, .., body) => {
802 Some((body, None, Some(&sig.header), Some(&sig.decl)))
806 Node::TraitItem(item) => match item.kind {
807 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
808 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
809 Some((body, None, Some(&sig.header), Some(&sig.decl)))
813 Node::ImplItem(item) => match item.kind {
814 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
815 hir::ImplItemKind::Fn(ref sig, body) => {
816 Some((body, None, Some(&sig.header), Some(&sig.decl)))
820 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
825 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
826 // Closures' typeck results come from their outermost function,
827 // as they are part of the same "inference environment".
828 let outer_def_id = tcx.closure_base_def_id(def_id);
829 if outer_def_id != def_id {
830 return tcx.has_typeck_results(outer_def_id);
833 if let Some(def_id) = def_id.as_local() {
834 let id = tcx.hir().local_def_id_to_hir_id(def_id);
835 primary_body_of(tcx, id).is_some()
841 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
842 &*tcx.typeck(def_id).used_trait_imports
845 /// Inspects the substs of opaque types, replacing any inference variables
846 /// with proper generic parameter from the identity substs.
848 /// This is run after we normalize the function signature, to fix any inference
849 /// variables introduced by the projection of associated types. This ensures that
850 /// any opaque types used in the signature continue to refer to generic parameters,
851 /// allowing them to be considered for defining uses in the function body
853 /// For example, consider this code.
858 /// fn use_it(self) -> Self::MyItem
860 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
861 /// type MyItem = impl Iterator<Item = I>;
862 /// fn use_it(self) -> Self::MyItem {
868 /// When we normalize the signature of `use_it` from the impl block,
869 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
870 /// However, this projection result may contain inference variables, due
871 /// to the way that projection works. We didn't have any inference variables
872 /// in the signature to begin with - leaving them in will cause us to incorrectly
873 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
874 /// variables back to the actual generic parameters, we will correctly see that
875 /// we have a defining use of `MyItem`
876 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
878 T: TypeFoldable<'tcx>,
880 struct FixupFolder<'tcx> {
884 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
885 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
889 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
891 ty::Opaque(def_id, substs) => {
892 debug!("fixup_opaque_types: found type {:?}", ty);
893 // Here, we replace any inference variables that occur within
894 // the substs of an opaque type. By definition, any type occurring
895 // in the substs has a corresponding generic parameter, which is what
896 // we replace it with.
897 // This replacement is only run on the function signature, so any
898 // inference variables that we come across must be the rust of projection
899 // (there's no other way for a user to get inference variables into
900 // a function signature).
901 if ty.needs_infer() {
902 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
903 let old_param = substs[param.index as usize];
904 match old_param.unpack() {
905 GenericArgKind::Type(old_ty) => {
906 if let ty::Infer(_) = old_ty.kind {
907 // Replace inference type with a generic parameter
908 self.tcx.mk_param_from_def(param)
910 old_param.fold_with(self)
913 GenericArgKind::Const(old_const) => {
914 if let ty::ConstKind::Infer(_) = old_const.val {
915 // This should never happen - we currently do not support
916 // 'const projections', e.g.:
917 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
918 // which should be the only way for us to end up with a const inference
919 // variable after projection. If Rust ever gains support for this kind
920 // of projection, this should *probably* be changed to
921 // `self.tcx.mk_param_from_def(param)`
923 "Found infer const: `{:?}` in opaque type: {:?}",
928 old_param.fold_with(self)
931 GenericArgKind::Lifetime(old_region) => {
932 if let RegionKind::ReVar(_) = old_region {
933 self.tcx.mk_param_from_def(param)
935 old_param.fold_with(self)
940 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
941 debug!("fixup_opaque_types: new type: {:?}", new_ty);
947 _ => ty.super_fold_with(self),
952 debug!("fixup_opaque_types({:?})", val);
953 val.fold_with(&mut FixupFolder { tcx })
956 fn typeck_const_arg<'tcx>(
958 (did, param_did): (LocalDefId, DefId),
959 ) -> &ty::TypeckResults<'tcx> {
960 let fallback = move || tcx.type_of(param_did);
961 typeck_with_fallback(tcx, did, fallback)
964 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
965 if let Some(param_did) = tcx.opt_const_param_of(def_id) {
966 tcx.typeck_const_arg((def_id, param_did))
968 let fallback = move || tcx.type_of(def_id.to_def_id());
969 typeck_with_fallback(tcx, def_id, fallback)
973 /// Used only to get `TypeckResults` for type inference during error recovery.
974 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
975 fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
976 let fallback = move || {
977 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id));
978 tcx.ty_error_with_message(span, "diagnostic only typeck table used")
980 typeck_with_fallback(tcx, def_id, fallback)
983 fn typeck_with_fallback<'tcx>(
986 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
987 ) -> &'tcx ty::TypeckResults<'tcx> {
988 // Closures' typeck results come from their outermost function,
989 // as they are part of the same "inference environment".
990 let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
991 if outer_def_id != def_id {
992 return tcx.typeck(outer_def_id);
995 let id = tcx.hir().as_local_hir_id(def_id);
996 let span = tcx.hir().span(id);
998 // Figure out what primary body this item has.
999 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
1000 span_bug!(span, "can't type-check body of {:?}", def_id);
1002 let body = tcx.hir().body(body_id);
1004 let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
1005 let param_env = tcx.param_env(def_id);
1006 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1007 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1008 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1014 &hir::Generics::empty(),
1021 check_abi(tcx, span, fn_sig.abi());
1023 // Compute the fty from point of view of inside the fn.
1024 let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), &fn_sig);
1025 let fn_sig = inh.normalize_associated_types_in(
1032 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1034 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1037 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1038 let expected_type = body_ty
1039 .and_then(|ty| match ty.kind {
1040 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1043 .unwrap_or_else(fallback);
1044 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1045 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1047 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1048 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1053 // Gather locals in statics (because of block expressions).
1054 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1056 fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
1058 fcx.write_ty(id, revealed_ty);
1063 // All type checking constraints were added, try to fallback unsolved variables.
1064 fcx.select_obligations_where_possible(false, |_| {});
1065 let mut fallback_has_occurred = false;
1067 // We do fallback in two passes, to try to generate
1068 // better error messages.
1069 // The first time, we do *not* replace opaque types.
1070 for ty in &fcx.unsolved_variables() {
1071 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1073 // We now see if we can make progress. This might
1074 // cause us to unify inference variables for opaque types,
1075 // since we may have unified some other type variables
1076 // during the first phase of fallback.
1077 // This means that we only replace inference variables with their underlying
1078 // opaque types as a last resort.
1080 // In code like this:
1083 // type MyType = impl Copy;
1084 // fn produce() -> MyType { true }
1085 // fn bad_produce() -> MyType { panic!() }
1088 // we want to unify the opaque inference variable in `bad_produce`
1089 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1090 // This will produce a nice error message about conflicting concrete
1091 // types for `MyType`.
1093 // If we had tried to fallback the opaque inference variable to `MyType`,
1094 // we will generate a confusing type-check error that does not explicitly
1095 // refer to opaque types.
1096 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1098 // We now run fallback again, but this time we allow it to replace
1099 // unconstrained opaque type variables, in addition to performing
1100 // other kinds of fallback.
1101 for ty in &fcx.unsolved_variables() {
1102 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1105 // See if we can make any more progress.
1106 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1108 // Even though coercion casts provide type hints, we check casts after fallback for
1109 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1112 // Closure and generator analysis may run after fallback
1113 // because they don't constrain other type variables.
1114 fcx.closure_analyze(body);
1115 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1116 fcx.resolve_generator_interiors(def_id.to_def_id());
1118 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1119 let ty = fcx.normalize_ty(span, ty);
1120 fcx.require_type_is_sized(ty, span, code);
1123 fcx.select_all_obligations_or_error();
1125 if fn_decl.is_some() {
1126 fcx.regionck_fn(id, body);
1128 fcx.regionck_expr(body);
1131 fcx.resolve_type_vars_in_body(body)
1134 // Consistency check our TypeckResults instance can hold all ItemLocalIds
1135 // it will need to hold.
1136 assert_eq!(typeck_results.hir_owner, id.owner);
1141 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1142 if !tcx.sess.target.target.is_abi_supported(abi) {
1147 "The ABI `{}` is not supported for the current target",
1154 struct GatherLocalsVisitor<'a, 'tcx> {
1155 fcx: &'a FnCtxt<'a, 'tcx>,
1156 parent_id: hir::HirId,
1159 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1160 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1163 // Infer the variable's type.
1164 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1165 kind: TypeVariableOriginKind::TypeInference,
1171 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1175 // Take type that the user specified.
1176 self.fcx.locals.borrow_mut().insert(nid, typ);
1183 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1184 type Map = intravisit::ErasedMap<'tcx>;
1186 fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
1187 NestedVisitorMap::None
1190 // Add explicitly-declared locals.
1191 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1192 let local_ty = match local.ty {
1194 let o_ty = self.fcx.to_ty(&ty);
1196 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1197 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1206 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1208 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1209 ty.hir_id, o_ty, revealed_ty, c_ty
1214 .user_provided_types_mut()
1215 .insert(ty.hir_id, c_ty);
1217 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1221 self.assign(local.span, local.hir_id, local_ty);
1224 "local variable {:?} is assigned type {}",
1226 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1228 intravisit::walk_local(self, local);
1231 // Add pattern bindings.
1232 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1233 if let PatKind::Binding(_, _, ident, _) = p.kind {
1234 let var_ty = self.assign(p.span, p.hir_id, None);
1236 if !self.fcx.tcx.features().unsized_locals {
1237 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1241 "pattern binding {} is assigned to {} with type {:?}",
1243 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1247 intravisit::walk_pat(self, p);
1250 // Don't descend into the bodies of nested closures.
1253 _: intravisit::FnKind<'tcx>,
1254 _: &'tcx hir::FnDecl<'tcx>,
1262 /// When `check_fn` is invoked on a generator (i.e., a body that
1263 /// includes yield), it returns back some information about the yield
1265 struct GeneratorTypes<'tcx> {
1266 /// Type of generator argument / values returned by `yield`.
1267 resume_ty: Ty<'tcx>,
1269 /// Type of value that is yielded.
1272 /// Types that are captured (see `GeneratorInterior` for more).
1275 /// Indicates if the generator is movable or static (immovable).
1276 movability: hir::Movability,
1279 /// Helper used for fns and closures. Does the grungy work of checking a function
1280 /// body and returns the function context used for that purpose, since in the case of a fn item
1281 /// there is still a bit more to do.
1284 /// * inherited: other fields inherited from the enclosing fn (if any)
1285 fn check_fn<'a, 'tcx>(
1286 inherited: &'a Inherited<'a, 'tcx>,
1287 param_env: ty::ParamEnv<'tcx>,
1288 fn_sig: ty::FnSig<'tcx>,
1289 decl: &'tcx hir::FnDecl<'tcx>,
1291 body: &'tcx hir::Body<'tcx>,
1292 can_be_generator: Option<hir::Movability>,
1293 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1294 let mut fn_sig = fn_sig;
1296 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1298 // Create the function context. This is either derived from scratch or,
1299 // in the case of closures, based on the outer context.
1300 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1301 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1304 let sess = tcx.sess;
1305 let hir = tcx.hir();
1307 let declared_ret_ty = fn_sig.output();
1308 let revealed_ret_ty =
1309 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1310 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1311 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1312 fn_sig = tcx.mk_fn_sig(
1313 fn_sig.inputs().iter().cloned(),
1320 let span = body.value.span;
1322 fn_maybe_err(tcx, span, fn_sig.abi);
1324 if body.generator_kind.is_some() && can_be_generator.is_some() {
1326 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1327 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1329 // Resume type defaults to `()` if the generator has no argument.
1330 let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
1332 fcx.resume_yield_tys = Some((resume_ty, yield_ty));
1335 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
1336 let outer_hir_id = hir.as_local_hir_id(outer_def_id);
1337 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1339 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1340 // (as it's created inside the body itself, not passed in from outside).
1341 let maybe_va_list = if fn_sig.c_variadic {
1342 let span = body.params.last().unwrap().span;
1343 let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
1344 let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
1346 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1351 // Add formal parameters.
1352 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1353 let inputs_fn = fn_sig.inputs().iter().copied();
1354 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1355 // Check the pattern.
1356 let ty_span = try { inputs_hir?.get(idx)?.span };
1357 fcx.check_pat_top(¶m.pat, param_ty, ty_span, false);
1359 // Check that argument is Sized.
1360 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1361 // for simple cases like `fn foo(x: Trait)`,
1362 // where we would error once on the parameter as a whole, and once on the binding `x`.
1363 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1364 fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
1367 fcx.write_ty(param.hir_id, param_ty);
1370 inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1372 if let ty::Dynamic(..) = declared_ret_ty.kind {
1373 // FIXME: We need to verify that the return type is `Sized` after the return expression has
1374 // been evaluated so that we have types available for all the nodes being returned, but that
1375 // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
1376 // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
1377 // while keeping the current ordering we will ignore the tail expression's type because we
1378 // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
1379 // because we will trigger "unreachable expression" lints unconditionally.
1380 // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
1381 // case that a newcomer might make, returning a bare trait, and in that case we populate
1382 // the tail expression's type so that the suggestion will be correct, but ignore all other
1384 fcx.check_expr(&body.value);
1385 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1386 tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type");
1388 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1389 fcx.check_return_expr(&body.value);
1392 // We insert the deferred_generator_interiors entry after visiting the body.
1393 // This ensures that all nested generators appear before the entry of this generator.
1394 // resolve_generator_interiors relies on this property.
1395 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1397 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1398 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1400 let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
1401 Some(GeneratorTypes {
1405 movability: can_be_generator.unwrap(),
1411 // Finalize the return check by taking the LUB of the return types
1412 // we saw and assigning it to the expected return type. This isn't
1413 // really expected to fail, since the coercions would have failed
1414 // earlier when trying to find a LUB.
1416 // However, the behavior around `!` is sort of complex. In the
1417 // event that the `actual_return_ty` comes back as `!`, that
1418 // indicates that the fn either does not return or "returns" only
1419 // values of type `!`. In this case, if there is an expected
1420 // return type that is *not* `!`, that should be ok. But if the
1421 // return type is being inferred, we want to "fallback" to `!`:
1423 // let x = move || panic!();
1425 // To allow for that, I am creating a type variable with diverging
1426 // fallback. This was deemed ever so slightly better than unifying
1427 // the return value with `!` because it allows for the caller to
1428 // make more assumptions about the return type (e.g., they could do
1430 // let y: Option<u32> = Some(x());
1432 // which would then cause this return type to become `u32`, not
1434 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1435 let mut actual_return_ty = coercion.complete(&fcx);
1436 if actual_return_ty.is_never() {
1437 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1438 kind: TypeVariableOriginKind::DivergingFn,
1442 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1444 // Check that the main return type implements the termination trait.
1445 if let Some(term_id) = tcx.lang_items().termination() {
1446 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1447 let main_id = hir.as_local_hir_id(def_id);
1448 if main_id == fn_id {
1449 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1450 let trait_ref = ty::TraitRef::new(term_id, substs);
1451 let return_ty_span = decl.output.span();
1452 let cause = traits::ObligationCause::new(
1455 ObligationCauseCode::MainFunctionType,
1458 inherited.register_predicate(traits::Obligation::new(
1461 trait_ref.without_const().to_predicate(tcx),
1467 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1468 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1469 if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
1470 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1471 if declared_ret_ty.kind != ty::Never {
1472 sess.span_err(decl.output.span(), "return type should be `!`");
1475 let inputs = fn_sig.inputs();
1476 let span = hir.span(fn_id);
1477 if inputs.len() == 1 {
1478 let arg_is_panic_info = match inputs[0].kind {
1479 ty::Ref(region, ty, mutbl) => match ty.kind {
1480 ty::Adt(ref adt, _) => {
1481 adt.did == panic_info_did
1482 && mutbl == hir::Mutability::Not
1483 && *region != RegionKind::ReStatic
1490 if !arg_is_panic_info {
1491 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1494 if let Node::Item(item) = hir.get(fn_id) {
1495 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1496 if !generics.params.is_empty() {
1497 sess.span_err(span, "should have no type parameters");
1502 let span = sess.source_map().guess_head_span(span);
1503 sess.span_err(span, "function should have one argument");
1506 sess.err("language item required, but not found: `panic_info`");
1511 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1512 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1513 if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
1514 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1515 if declared_ret_ty.kind != ty::Never {
1516 sess.span_err(decl.output.span(), "return type should be `!`");
1519 let inputs = fn_sig.inputs();
1520 let span = hir.span(fn_id);
1521 if inputs.len() == 1 {
1522 let arg_is_alloc_layout = match inputs[0].kind {
1523 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1527 if !arg_is_alloc_layout {
1528 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1531 if let Node::Item(item) = hir.get(fn_id) {
1532 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1533 if !generics.params.is_empty() {
1536 "`#[alloc_error_handler]` function should have no type \
1543 let span = sess.source_map().guess_head_span(span);
1544 sess.span_err(span, "function should have one argument");
1547 sess.err("language item required, but not found: `alloc_layout`");
1555 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1556 let def_id = tcx.hir().local_def_id(id);
1557 let def = tcx.adt_def(def_id);
1558 def.destructor(tcx); // force the destructor to be evaluated
1559 check_representable(tcx, span, def_id);
1561 if def.repr.simd() {
1562 check_simd(tcx, span, def_id);
1565 check_transparent(tcx, span, def);
1566 check_packed(tcx, span, def);
1569 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1570 let def_id = tcx.hir().local_def_id(id);
1571 let def = tcx.adt_def(def_id);
1572 def.destructor(tcx); // force the destructor to be evaluated
1573 check_representable(tcx, span, def_id);
1574 check_transparent(tcx, span, def);
1575 check_union_fields(tcx, span, def_id);
1576 check_packed(tcx, span, def);
1579 /// When the `#![feature(untagged_unions)]` gate is active,
1580 /// check that the fields of the `union` does not contain fields that need dropping.
1581 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
1582 let item_type = tcx.type_of(item_def_id);
1583 if let ty::Adt(def, substs) = item_type.kind {
1584 assert!(def.is_union());
1585 let fields = &def.non_enum_variant().fields;
1586 let param_env = tcx.param_env(item_def_id);
1587 for field in fields {
1588 let field_ty = field.ty(tcx, substs);
1589 // We are currently checking the type this field came from, so it must be local.
1590 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1591 if field_ty.needs_drop(tcx, param_env) {
1596 "unions may not contain fields that need dropping"
1598 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1604 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1609 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1610 /// projections that would result in "inheriting lifetimes".
1611 fn check_opaque<'tcx>(
1614 substs: SubstsRef<'tcx>,
1616 origin: &hir::OpaqueTyOrigin,
1618 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1619 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1622 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1623 /// in "inheriting lifetimes".
1624 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1625 let item = tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id));
1627 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1632 struct ProhibitOpaqueVisitor<'tcx> {
1633 opaque_identity_ty: Ty<'tcx>,
1634 generics: &'tcx ty::Generics,
1635 ty: Option<Ty<'tcx>>,
1638 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1639 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1640 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1641 if t != self.opaque_identity_ty && t.super_visit_with(self) {
1648 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1649 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1650 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1651 return *index < self.generics.parent_count as u32;
1654 r.super_visit_with(self)
1657 fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
1658 if let ty::ConstKind::Unevaluated(..) = c.val {
1659 // FIXME(#72219) We currenctly don't detect lifetimes within substs
1660 // which would violate this check. Even though the particular substitution is not used
1661 // within the const, this should still be fixed.
1664 c.super_visit_with(self)
1668 if let ItemKind::OpaqueTy(hir::OpaqueTy {
1669 origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
1673 let mut visitor = ProhibitOpaqueVisitor {
1674 opaque_identity_ty: tcx.mk_opaque(
1676 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
1678 generics: tcx.generics_of(def_id),
1681 let prohibit_opaque = tcx
1682 .predicates_of(def_id)
1685 .any(|(predicate, _)| predicate.visit_with(&mut visitor));
1687 "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}",
1688 prohibit_opaque, visitor
1691 if prohibit_opaque {
1692 let is_async = match item.kind {
1693 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1694 hir::OpaqueTyOrigin::AsyncFn => true,
1697 _ => unreachable!(),
1700 let mut err = struct_span_err!(
1704 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1706 if is_async { "async fn" } else { "impl Trait" },
1709 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
1710 if snippet == "Self" {
1711 if let Some(ty) = visitor.ty {
1712 err.span_suggestion(
1714 "consider spelling out the type instead",
1715 format!("{:?}", ty),
1716 Applicability::MaybeIncorrect,
1726 /// Given a `DefId` for an opaque type in return position, find its parent item's return
1728 fn get_owner_return_paths(
1731 ) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
1732 let hir_id = tcx.hir().as_local_hir_id(def_id);
1733 let id = tcx.hir().get_parent_item(hir_id);
1737 .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
1738 .map(|(hir_id, body_id)| {
1739 let body = tcx.hir().body(body_id);
1740 let mut visitor = ReturnsVisitor::default();
1741 visitor.visit_body(body);
1746 /// Emit an error for recursive opaque types.
1748 /// If this is a return `impl Trait`, find the item's return expressions and point at them. For
1749 /// direct recursion this is enough, but for indirect recursion also point at the last intermediary
1752 /// If all the return expressions evaluate to `!`, then we explain that the error will go away
1753 /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
1754 fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1755 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1757 let mut label = false;
1758 if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
1759 let typeck_results = tcx.typeck(tcx.hir().local_def_id(hir_id));
1763 .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1764 .all(|ty| matches!(ty.kind, ty::Never))
1769 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1770 .map(|expr| expr.span)
1771 .collect::<Vec<Span>>();
1772 let span_len = spans.len();
1774 err.span_label(spans[0], "this returned value is of `!` type");
1776 let mut multispan: MultiSpan = spans.clone().into();
1779 .push_span_label(span, "this returned value is of `!` type".to_string());
1781 err.span_note(multispan, "these returned values have a concrete \"never\" type");
1783 err.help("this error will resolve once the item's body returns a concrete type");
1785 let mut seen = FxHashSet::default();
1787 err.span_label(span, "recursive opaque type");
1789 for (sp, ty) in visitor
1792 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1793 .filter(|(_, ty)| !matches!(ty.kind, ty::Never))
1795 struct VisitTypes(Vec<DefId>);
1796 impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes {
1797 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1799 ty::Opaque(def, _) => {
1803 _ => t.super_visit_with(self),
1807 let mut visitor = VisitTypes(vec![]);
1808 ty.visit_with(&mut visitor);
1809 for def_id in visitor.0 {
1810 let ty_span = tcx.def_span(def_id);
1811 if !seen.contains(&ty_span) {
1812 err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
1813 seen.insert(ty_span);
1815 err.span_label(sp, &format!("returning here with type `{}`", ty));
1821 err.span_label(span, "cannot resolve opaque type");
1826 /// Emit an error for recursive opaque types in a `let` binding.
1827 fn binding_opaque_type_cycle_error(
1831 partially_expanded_type: Ty<'tcx>,
1833 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1834 err.span_label(span, "cannot resolve opaque type");
1835 // Find the the owner that declared this `impl Trait` type.
1836 let hir_id = tcx.hir().as_local_hir_id(def_id);
1837 let mut prev_hir_id = hir_id;
1838 let mut hir_id = tcx.hir().get_parent_node(hir_id);
1839 while let Some(node) = tcx.hir().find(hir_id) {
1841 hir::Node::Local(hir::Local {
1845 source: hir::LocalSource::Normal,
1848 err.span_label(pat.span, "this binding might not have a concrete type");
1849 err.span_suggestion_verbose(
1850 ty.span.shrink_to_hi(),
1851 "set the binding to a value for a concrete type to be resolved",
1852 " = /* value */".to_string(),
1853 Applicability::HasPlaceholders,
1856 hir::Node::Local(hir::Local {
1858 source: hir::LocalSource::Normal,
1861 let hir_id = tcx.hir().as_local_hir_id(def_id);
1862 let typeck_results =
1863 tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
1864 if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
1868 "this is of type `{}`, which doesn't constrain \
1869 `{}` enough to arrive to a concrete type",
1870 ty, partially_expanded_type
1877 if prev_hir_id == hir_id {
1880 prev_hir_id = hir_id;
1881 hir_id = tcx.hir().get_parent_node(hir_id);
1886 fn async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span) {
1887 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
1888 .span_label(span, "recursive `async fn`")
1889 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1893 /// Checks that an opaque type does not contain cycles.
1894 fn check_opaque_for_cycles<'tcx>(
1897 substs: SubstsRef<'tcx>,
1899 origin: &hir::OpaqueTyOrigin,
1901 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
1904 hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
1905 hir::OpaqueTyOrigin::Binding => {
1906 binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
1908 _ => opaque_type_cycle_error(tcx, def_id, span),
1913 // Forbid defining intrinsics in Rust code,
1914 // as they must always be defined by the compiler.
1915 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1916 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1917 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1921 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1923 "check_item_type(it.hir_id={}, it.name={})",
1925 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id).to_def_id())
1927 let _indenter = indenter();
1929 // Consts can play a role in type-checking, so they are included here.
1930 hir::ItemKind::Static(..) => {
1931 let def_id = tcx.hir().local_def_id(it.hir_id);
1932 tcx.ensure().typeck(def_id);
1933 maybe_check_static_with_link_section(tcx, def_id, it.span);
1935 hir::ItemKind::Const(..) => {
1936 tcx.ensure().typeck(tcx.hir().local_def_id(it.hir_id));
1938 hir::ItemKind::Enum(ref enum_definition, _) => {
1939 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1941 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1942 hir::ItemKind::Impl { ref items, .. } => {
1943 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1944 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1945 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1946 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1947 let trait_def_id = impl_trait_ref.def_id;
1948 check_on_unimplemented(tcx, trait_def_id, it);
1951 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1952 let def_id = tcx.hir().local_def_id(it.hir_id);
1953 check_on_unimplemented(tcx, def_id.to_def_id(), it);
1955 for item in items.iter() {
1956 let item = tcx.hir().trait_item(item.id);
1957 if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
1958 let abi = sig.header.abi;
1959 fn_maybe_err(tcx, item.ident.span, abi);
1963 hir::ItemKind::Struct(..) => {
1964 check_struct(tcx, it.hir_id, it.span);
1966 hir::ItemKind::Union(..) => {
1967 check_union(tcx, it.hir_id, it.span);
1969 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1970 let def_id = tcx.hir().local_def_id(it.hir_id);
1972 let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1973 check_opaque(tcx, def_id, substs, it.span, &origin);
1975 hir::ItemKind::TyAlias(..) => {
1976 let def_id = tcx.hir().local_def_id(it.hir_id);
1977 let pty_ty = tcx.type_of(def_id);
1978 let generics = tcx.generics_of(def_id);
1979 check_type_params_are_used(tcx, &generics, pty_ty);
1981 hir::ItemKind::ForeignMod(ref m) => {
1982 check_abi(tcx, it.span, m.abi);
1984 if m.abi == Abi::RustIntrinsic {
1985 for item in m.items {
1986 intrinsic::check_intrinsic_type(tcx, item);
1988 } else if m.abi == Abi::PlatformIntrinsic {
1989 for item in m.items {
1990 intrinsic::check_platform_intrinsic_type(tcx, item);
1993 for item in m.items {
1994 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1995 let own_counts = generics.own_counts();
1996 if generics.params.len() - own_counts.lifetimes != 0 {
1997 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1998 (_, 0) => ("type", "types", Some("u32")),
1999 // We don't specify an example value, because we can't generate
2000 // a valid value for any type.
2001 (0, _) => ("const", "consts", None),
2002 _ => ("type or const", "types or consts", None),
2008 "foreign items may not have {} parameters",
2011 .span_label(item.span, &format!("can't have {} parameters", kinds))
2013 // FIXME: once we start storing spans for type arguments, turn this
2014 // into a suggestion.
2016 "replace the {} parameters with concrete {}{}",
2019 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
2025 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
2026 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
2031 _ => { /* nothing to do */ }
2035 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
2036 // Only restricted on wasm32 target for now
2037 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
2041 // If `#[link_section]` is missing, then nothing to verify
2042 let attrs = tcx.codegen_fn_attrs(id);
2043 if attrs.link_section.is_none() {
2047 // For the wasm32 target statics with `#[link_section]` are placed into custom
2048 // sections of the final output file, but this isn't link custom sections of
2049 // other executable formats. Namely we can only embed a list of bytes,
2050 // nothing with pointers to anything else or relocations. If any relocation
2051 // show up, reject them here.
2052 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
2053 // the consumer's responsibility to ensure all bytes that have been read
2054 // have defined values.
2055 match tcx.const_eval_poly(id.to_def_id()) {
2056 Ok(ConstValue::ByRef { alloc, .. }) => {
2057 if alloc.relocations().len() != 0 {
2058 let msg = "statics with a custom `#[link_section]` must be a \
2059 simple list of bytes on the wasm target with no \
2060 extra levels of indirection such as references";
2061 tcx.sess.span_err(span, msg);
2064 Ok(_) => bug!("Matching on non-ByRef static"),
2069 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
2070 let item_def_id = tcx.hir().local_def_id(item.hir_id);
2071 // an error would be reported if this fails.
2072 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id.to_def_id());
2075 fn report_forbidden_specialization(
2077 impl_item: &hir::ImplItem<'_>,
2080 let mut err = struct_span_err!(
2084 "`{}` specializes an item from a parent `impl`, but \
2085 that item is not marked `default`",
2088 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
2090 match tcx.span_of_impl(parent_impl) {
2092 err.span_label(span, "parent `impl` is here");
2094 "to specialize, `{}` in the parent `impl` must be marked `default`",
2099 err.note(&format!("parent implementation is in crate `{}`", cname));
2106 fn check_specialization_validity<'tcx>(
2108 trait_def: &ty::TraitDef,
2109 trait_item: &ty::AssocItem,
2111 impl_item: &hir::ImplItem<'_>,
2113 let kind = match impl_item.kind {
2114 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
2115 hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
2116 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
2119 let ancestors = match trait_def.ancestors(tcx, impl_id) {
2120 Ok(ancestors) => ancestors,
2123 let mut ancestor_impls = ancestors
2125 .filter_map(|parent| {
2126 if parent.is_from_trait() {
2129 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
2134 if ancestor_impls.peek().is_none() {
2135 // No parent, nothing to specialize.
2139 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
2141 // Parent impl exists, and contains the parent item we're trying to specialize, but
2142 // doesn't mark it `default`.
2143 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
2144 Some(Err(parent_impl.def_id()))
2147 // Parent impl contains item and makes it specializable.
2148 Some(_) => Some(Ok(())),
2150 // Parent impl doesn't mention the item. This means it's inherited from the
2151 // grandparent. In that case, if parent is a `default impl`, inherited items use the
2152 // "defaultness" from the grandparent, else they are final.
2154 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
2157 Some(Err(parent_impl.def_id()))
2163 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
2164 // item. This is allowed, the item isn't actually getting specialized here.
2165 let result = opt_result.unwrap_or(Ok(()));
2167 if let Err(parent_impl) = result {
2168 report_forbidden_specialization(tcx, impl_item, parent_impl);
2172 fn check_impl_items_against_trait<'tcx>(
2174 full_impl_span: Span,
2175 impl_id: LocalDefId,
2176 impl_trait_ref: ty::TraitRef<'tcx>,
2177 impl_item_refs: &[hir::ImplItemRef<'_>],
2179 let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
2181 // If the trait reference itself is erroneous (so the compilation is going
2182 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
2183 // isn't populated for such impls.
2184 if impl_trait_ref.references_error() {
2188 // Negative impls are not expected to have any items
2189 match tcx.impl_polarity(impl_id) {
2190 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
2191 ty::ImplPolarity::Negative => {
2192 if let [first_item_ref, ..] = impl_item_refs {
2193 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
2198 "negative impls cannot have any items"
2206 // Locate trait definition and items
2207 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
2209 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
2211 // Check existing impl methods to see if they are both present in trait
2212 // and compatible with trait signature
2213 for impl_item in impl_items() {
2214 let namespace = impl_item.kind.namespace();
2215 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
2216 let ty_trait_item = tcx
2217 .associated_items(impl_trait_ref.def_id)
2218 .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id)
2220 // Not compatible, but needed for the error message
2221 tcx.associated_items(impl_trait_ref.def_id)
2222 .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id)
2226 // Check that impl definition matches trait definition
2227 if let Some(ty_trait_item) = ty_trait_item {
2228 match impl_item.kind {
2229 hir::ImplItemKind::Const(..) => {
2230 // Find associated const definition.
2231 if ty_trait_item.kind == ty::AssocKind::Const {
2240 let mut err = struct_span_err!(
2244 "item `{}` is an associated const, \
2245 which doesn't match its trait `{}`",
2247 impl_trait_ref.print_only_trait_path()
2249 err.span_label(impl_item.span, "does not match trait");
2250 // We can only get the spans from local trait definition
2251 // Same for E0324 and E0325
2252 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2253 err.span_label(trait_span, "item in trait");
2258 hir::ImplItemKind::Fn(..) => {
2259 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2260 if ty_trait_item.kind == ty::AssocKind::Fn {
2261 compare_impl_method(
2270 let mut err = struct_span_err!(
2274 "item `{}` is an associated method, \
2275 which doesn't match its trait `{}`",
2277 impl_trait_ref.print_only_trait_path()
2279 err.span_label(impl_item.span, "does not match trait");
2280 if let Some(trait_span) = opt_trait_span {
2281 err.span_label(trait_span, "item in trait");
2286 hir::ImplItemKind::TyAlias(_) => {
2287 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2288 if ty_trait_item.kind == ty::AssocKind::Type {
2298 let mut err = struct_span_err!(
2302 "item `{}` is an associated type, \
2303 which doesn't match its trait `{}`",
2305 impl_trait_ref.print_only_trait_path()
2307 err.span_label(impl_item.span, "does not match trait");
2308 if let Some(trait_span) = opt_trait_span {
2309 err.span_label(trait_span, "item in trait");
2316 check_specialization_validity(
2320 impl_id.to_def_id(),
2326 // Check for missing items from trait
2327 let mut missing_items = Vec::new();
2328 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
2329 for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
2330 let is_implemented = ancestors
2331 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2332 .map(|node_item| !node_item.defining_node.is_from_trait())
2335 if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
2336 if !trait_item.defaultness.has_value() {
2337 missing_items.push(*trait_item);
2343 if !missing_items.is_empty() {
2344 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2348 fn missing_items_err(
2351 missing_items: &[ty::AssocItem],
2352 full_impl_span: Span,
2354 let missing_items_msg = missing_items
2356 .map(|trait_item| trait_item.ident.to_string())
2357 .collect::<Vec<_>>()
2360 let mut err = struct_span_err!(
2364 "not all trait items implemented, missing: `{}`",
2367 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2369 // `Span` before impl block closing brace.
2370 let hi = full_impl_span.hi() - BytePos(1);
2371 // Point at the place right before the closing brace of the relevant `impl` to suggest
2372 // adding the associated item at the end of its body.
2373 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2374 // Obtain the level of indentation ending in `sugg_sp`.
2375 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2376 // Make the whitespace that will make the suggestion have the right indentation.
2377 let padding: String = (0..indentation).map(|_| " ").collect();
2379 for trait_item in missing_items {
2380 let snippet = suggestion_signature(&trait_item, tcx);
2381 let code = format!("{}{}\n{}", padding, snippet, padding);
2382 let msg = format!("implement the missing item: `{}`", snippet);
2383 let appl = Applicability::HasPlaceholders;
2384 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2385 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2386 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2388 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2394 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2395 fn bounds_from_generic_predicates<'tcx>(
2397 predicates: ty::GenericPredicates<'tcx>,
2398 ) -> (String, String) {
2399 let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
2400 let mut projections = vec![];
2401 for (predicate, _) in predicates.predicates {
2402 debug!("predicate {:?}", predicate);
2403 match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
2404 ty::PredicateKind::Trait(trait_predicate, _) => {
2405 let entry = types.entry(trait_predicate.self_ty()).or_default();
2406 let def_id = trait_predicate.def_id();
2407 if Some(def_id) != tcx.lang_items().sized_trait() {
2408 // Type params are `Sized` by default, do not add that restriction to the list
2409 // if it is a positive requirement.
2410 entry.push(trait_predicate.def_id());
2413 ty::PredicateKind::Projection(projection_pred) => {
2414 projections.push(ty::Binder::bind(projection_pred));
2419 let generics = if types.is_empty() {
2426 .filter_map(|t| match t.kind {
2427 ty::Param(_) => Some(t.to_string()),
2428 // Avoid suggesting the following:
2429 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2432 .collect::<Vec<_>>()
2436 let mut where_clauses = vec![];
2437 for (ty, bounds) in types {
2438 for bound in &bounds {
2439 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2442 for projection in &projections {
2443 let p = projection.skip_binder();
2444 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2445 // insert the associated types where they correspond, but for now let's be "lazy" and
2446 // propose this instead of the following valid resugaring:
2447 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2448 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2450 let where_clauses = if where_clauses.is_empty() {
2453 format!(" where {}", where_clauses.join(", "))
2455 (generics, where_clauses)
2458 /// Return placeholder code for the given function.
2459 fn fn_sig_suggestion<'tcx>(
2461 sig: ty::FnSig<'tcx>,
2463 predicates: ty::GenericPredicates<'tcx>,
2464 assoc: &ty::AssocItem,
2471 Some(match ty.kind {
2472 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2473 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2474 let reg = match &format!("{}", reg)[..] {
2475 "'_" | "" => String::new(),
2476 reg => format!("{} ", reg),
2478 if assoc.fn_has_self_parameter {
2480 ty::Param(param) if param.name == kw::SelfUpper => {
2481 format!("&{}{}self", reg, mutability.prefix_str())
2484 _ => format!("self: {}", ty),
2487 format!("_: {:?}", ty)
2491 if assoc.fn_has_self_parameter && i == 0 {
2492 format!("self: {:?}", ty)
2494 format!("_: {:?}", ty)
2499 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2500 .filter_map(|arg| arg)
2501 .collect::<Vec<String>>()
2503 let output = sig.output();
2504 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2506 let unsafety = sig.unsafety.prefix_str();
2507 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2509 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2510 // not be present in the `fn` definition, not will we account for renamed
2511 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2512 // fill in a significant portion of the missing code, and other subsequent
2513 // suggestions can help the user fix the code.
2515 "{}fn {}{}({}){}{} {{ todo!() }}",
2516 unsafety, ident, generics, args, output, where_clauses
2520 /// Return placeholder code for the given associated item.
2521 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2522 /// structured suggestion.
2523 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2525 ty::AssocKind::Fn => {
2526 // We skip the binder here because the binder would deanonymize all
2527 // late-bound regions, and we don't want method signatures to show up
2528 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2529 // regions just fine, showing `fn(&MyType)`.
2532 tcx.fn_sig(assoc.def_id).skip_binder(),
2534 tcx.predicates_of(assoc.def_id),
2538 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2539 ty::AssocKind::Const => {
2540 let ty = tcx.type_of(assoc.def_id);
2541 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2542 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2547 /// Checks whether a type can be represented in memory. In particular, it
2548 /// identifies types that contain themselves without indirection through a
2549 /// pointer, which would mean their size is unbounded.
2550 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2551 let rty = tcx.type_of(item_def_id);
2553 // Check that it is possible to represent this type. This call identifies
2554 // (1) types that contain themselves and (2) types that contain a different
2555 // recursive type. It is only necessary to throw an error on those that
2556 // contain themselves. For case 2, there must be an inner type that will be
2557 // caught by case 1.
2558 match rty.is_representable(tcx, sp) {
2559 Representability::SelfRecursive(spans) => {
2560 recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
2563 Representability::Representable | Representability::ContainsRecursive => (),
2568 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2569 let t = tcx.type_of(def_id);
2570 if let ty::Adt(def, substs) = t.kind {
2571 if def.is_struct() {
2572 let fields = &def.non_enum_variant().fields;
2573 if fields.is_empty() {
2574 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2577 let e = fields[0].ty(tcx, substs);
2578 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2579 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2580 .span_label(sp, "SIMD elements must have the same type")
2585 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2586 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2592 "SIMD vector element type should be machine type"
2602 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2603 let repr = def.repr;
2605 for attr in tcx.get_attrs(def.did).iter() {
2606 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2607 if let attr::ReprPacked(pack) = r {
2608 if let Some(repr_pack) = repr.pack {
2609 if pack as u64 != repr_pack.bytes() {
2614 "type has conflicting packed representation hints"
2622 if repr.align.is_some() {
2627 "type has conflicting packed and align representation hints"
2631 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2632 let mut err = struct_span_err!(
2636 "packed type cannot transitively contain a `#[repr(align)]` type"
2640 tcx.def_span(def_spans[0].0),
2642 "`{}` has a `#[repr(align)]` attribute",
2643 tcx.item_name(def_spans[0].0)
2647 if def_spans.len() > 2 {
2648 let mut first = true;
2649 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2650 let ident = tcx.item_name(*adt_def);
2655 "`{}` contains a field of type `{}`",
2656 tcx.type_of(def.did),
2660 format!("...which contains a field of type `{}`", ident)
2673 fn check_packed_inner(
2676 stack: &mut Vec<DefId>,
2677 ) -> Option<Vec<(DefId, Span)>> {
2678 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2679 if def.is_struct() || def.is_union() {
2680 if def.repr.align.is_some() {
2681 return Some(vec![(def.did, DUMMY_SP)]);
2685 for field in &def.non_enum_variant().fields {
2686 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2687 if !stack.contains(&def.did) {
2688 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2689 defs.push((def.did, field.ident.span));
2702 /// Emit an error when encountering more or less than one variant in a transparent enum.
2703 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2704 let variant_spans: Vec<_> = adt
2707 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2709 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2710 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2711 err.span_label(sp, &msg);
2712 if let [start @ .., end] = &*variant_spans {
2713 for variant_span in start {
2714 err.span_label(*variant_span, "");
2716 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2721 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2723 fn bad_non_zero_sized_fields<'tcx>(
2725 adt: &'tcx ty::AdtDef,
2727 field_spans: impl Iterator<Item = Span>,
2730 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2731 let mut err = struct_span_err!(
2735 "{}transparent {} {}",
2736 if adt.is_enum() { "the variant of a " } else { "" },
2740 err.span_label(sp, &msg);
2741 for sp in field_spans {
2742 err.span_label(sp, "this field is non-zero-sized");
2747 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2748 if !adt.repr.transparent() {
2751 let sp = tcx.sess.source_map().guess_head_span(sp);
2753 if adt.is_union() && !tcx.features().transparent_unions {
2755 &tcx.sess.parse_sess,
2756 sym::transparent_unions,
2758 "transparent unions are unstable",
2763 if adt.variants.len() != 1 {
2764 bad_variant_count(tcx, adt, sp, adt.did);
2765 if adt.variants.is_empty() {
2766 // Don't bother checking the fields. No variants (and thus no fields) exist.
2771 // For each field, figure out if it's known to be a ZST and align(1)
2772 let field_infos = adt.all_fields().map(|field| {
2773 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2774 let param_env = tcx.param_env(field.did);
2775 let layout = tcx.layout_of(param_env.and(ty));
2776 // We are currently checking the type this field came from, so it must be local
2777 let span = tcx.hir().span_if_local(field.did).unwrap();
2778 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2779 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2783 let non_zst_fields =
2784 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2785 let non_zst_count = non_zst_fields.clone().count();
2786 if non_zst_count != 1 {
2787 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2789 for (span, zst, align1) in field_infos {
2795 "zero-sized field in transparent {} has alignment larger than 1",
2798 .span_label(span, "has alignment larger than 1")
2804 #[allow(trivial_numeric_casts)]
2805 pub fn check_enum<'tcx>(
2808 vs: &'tcx [hir::Variant<'tcx>],
2811 let def_id = tcx.hir().local_def_id(id);
2812 let def = tcx.adt_def(def_id);
2813 def.destructor(tcx); // force the destructor to be evaluated
2816 let attributes = tcx.get_attrs(def_id.to_def_id());
2817 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2822 "unsupported representation for zero-variant enum"
2824 .span_label(sp, "zero-variant enum")
2829 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2830 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2831 if !tcx.features().repr128 {
2833 &tcx.sess.parse_sess,
2836 "repr with 128-bit type is unstable",
2843 if let Some(ref e) = v.disr_expr {
2844 tcx.ensure().typeck(tcx.hir().local_def_id(e.hir_id));
2848 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2849 let is_unit = |var: &hir::Variant<'_>| match var.data {
2850 hir::VariantData::Unit(..) => true,
2854 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2855 let has_non_units = vs.iter().any(|var| !is_unit(var));
2856 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2857 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2859 if disr_non_unit || (disr_units && has_non_units) {
2861 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2866 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2867 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2868 // Check for duplicate discriminant values
2869 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2870 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2871 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2872 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2873 let i_span = match variant_i.disr_expr {
2874 Some(ref expr) => tcx.hir().span(expr.hir_id),
2875 None => tcx.hir().span(variant_i_hir_id),
2877 let span = match v.disr_expr {
2878 Some(ref expr) => tcx.hir().span(expr.hir_id),
2885 "discriminant value `{}` already exists",
2888 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2889 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2892 disr_vals.push(discr);
2895 check_representable(tcx, sp, def_id);
2896 check_transparent(tcx, sp, def);
2899 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2904 "expected unit struct, unit variant or constant, found {}{}",
2906 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2911 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2912 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2916 fn item_def_id(&self) -> Option<DefId> {
2920 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2921 // FIXME: refactor this into a method
2922 let node = self.tcx.hir().get(self.body_id);
2923 if let Some(fn_like) = FnLikeNode::from_node(node) {
2926 hir::Constness::NotConst
2930 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2932 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2933 let item_id = tcx.hir().ty_param_owner(hir_id);
2934 let item_def_id = tcx.hir().local_def_id(item_id);
2935 let generics = tcx.generics_of(item_def_id);
2936 let index = generics.param_def_id_to_index[&def_id];
2937 ty::GenericPredicates {
2939 predicates: tcx.arena.alloc_from_iter(
2940 self.param_env.caller_bounds().iter().filter_map(|predicate| {
2941 match predicate.kind() {
2942 ty::PredicateKind::Trait(ref data, _)
2943 if data.skip_binder().self_ty().is_param(index) =>
2945 // HACK(eddyb) should get the original `Span`.
2946 let span = tcx.def_span(def_id);
2947 Some((predicate, span))
2956 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2958 Some(def) => infer::EarlyBoundRegion(span, def.name),
2959 None => infer::MiscVariable(span),
2961 Some(self.next_region_var(v))
2964 fn allow_ty_infer(&self) -> bool {
2968 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2969 if let Some(param) = param {
2970 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2975 self.next_ty_var(TypeVariableOrigin {
2976 kind: TypeVariableOriginKind::TypeInference,
2985 param: Option<&ty::GenericParamDef>,
2987 ) -> &'tcx Const<'tcx> {
2988 if let Some(param) = param {
2989 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2994 self.next_const_var(
2996 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
3001 fn projected_ty_from_poly_trait_ref(
3005 item_segment: &hir::PathSegment<'_>,
3006 poly_trait_ref: ty::PolyTraitRef<'tcx>,
3008 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
3010 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
3014 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
3023 self.tcx().mk_projection(item_def_id, item_substs)
3026 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
3027 if ty.has_escaping_bound_vars() {
3028 ty // FIXME: normalization and escaping regions
3030 self.normalize_associated_types_in(span, &ty)
3034 fn set_tainted_by_errors(&self) {
3035 self.infcx.set_tainted_by_errors()
3038 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
3039 self.write_ty(hir_id, ty)
3043 /// Controls whether the arguments are tupled. This is used for the call
3046 /// Tupling means that all call-side arguments are packed into a tuple and
3047 /// passed as a single parameter. For example, if tupling is enabled, this
3050 /// fn f(x: (isize, isize))
3052 /// Can be called as:
3059 #[derive(Clone, Eq, PartialEq)]
3060 enum TupleArgumentsFlag {
3065 /// Controls how we perform fallback for unconstrained
3068 /// Do not fallback type variables to opaque types.
3070 /// Perform all possible kinds of fallback, including
3071 /// turning type variables to opaque types.
3075 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3077 inh: &'a Inherited<'a, 'tcx>,
3078 param_env: ty::ParamEnv<'tcx>,
3079 body_id: hir::HirId,
3080 ) -> FnCtxt<'a, 'tcx> {
3084 err_count_on_creation: inh.tcx.sess.err_count(),
3086 ret_coercion_span: RefCell::new(None),
3087 resume_yield_tys: None,
3088 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
3089 diverges: Cell::new(Diverges::Maybe),
3090 has_errors: Cell::new(false),
3091 enclosing_breakables: RefCell::new(EnclosingBreakables {
3093 by_id: Default::default(),
3099 pub fn sess(&self) -> &Session {
3103 pub fn errors_reported_since_creation(&self) -> bool {
3104 self.tcx.sess.err_count() > self.err_count_on_creation
3107 /// Produces warning on the given node, if the current point in the
3108 /// function is unreachable, and there hasn't been another warning.
3109 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
3110 // FIXME: Combine these two 'if' expressions into one once
3111 // let chains are implemented
3112 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
3113 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
3114 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
3115 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
3116 if !span.is_desugaring(DesugaringKind::CondTemporary)
3117 && !span.is_desugaring(DesugaringKind::Async)
3118 && !orig_span.is_desugaring(DesugaringKind::Await)
3120 self.diverges.set(Diverges::WarnedAlways);
3122 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
3124 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
3125 let msg = format!("unreachable {}", kind);
3127 .span_label(span, &msg)
3131 .unwrap_or("any code following this expression is unreachable"),
3139 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
3140 ObligationCause::new(span, self.body_id, code)
3143 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
3144 self.cause(span, ObligationCauseCode::MiscObligation)
3147 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
3148 /// version (resolve_vars_if_possible), this version will
3149 /// also select obligations if it seems useful, in an effort
3150 /// to get more type information.
3151 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3152 debug!("resolve_vars_with_obligations(ty={:?})", ty);
3154 // No Infer()? Nothing needs doing.
3155 if !ty.has_infer_types_or_consts() {
3156 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3160 // If `ty` is a type variable, see whether we already know what it is.
3161 ty = self.resolve_vars_if_possible(&ty);
3162 if !ty.has_infer_types_or_consts() {
3163 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3167 // If not, try resolving pending obligations as much as
3168 // possible. This can help substantially when there are
3169 // indirect dependencies that don't seem worth tracking
3171 self.select_obligations_where_possible(false, |_| {});
3172 ty = self.resolve_vars_if_possible(&ty);
3174 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3178 fn record_deferred_call_resolution(
3180 closure_def_id: DefId,
3181 r: DeferredCallResolution<'tcx>,
3183 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3184 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3187 fn remove_deferred_call_resolutions(
3189 closure_def_id: DefId,
3190 ) -> Vec<DeferredCallResolution<'tcx>> {
3191 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3192 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3195 pub fn tag(&self) -> String {
3196 format!("{:p}", self)
3199 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3200 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3201 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3206 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3208 "write_ty({:?}, {:?}) in fcx {}",
3210 self.resolve_vars_if_possible(&ty),
3213 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
3215 if ty.references_error() {
3216 self.has_errors.set(true);
3217 self.set_tainted_by_errors();
3221 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3222 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
3225 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3226 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3229 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3230 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3231 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3232 self.write_substs(hir_id, method.substs);
3234 // When the method is confirmed, the `method.substs` includes
3235 // parameters from not just the method, but also the impl of
3236 // the method -- in particular, the `Self` type will be fully
3237 // resolved. However, those are not something that the "user
3238 // specified" -- i.e., those types come from the inferred type
3239 // of the receiver, not something the user wrote. So when we
3240 // create the user-substs, we want to replace those earlier
3241 // types with just the types that the user actually wrote --
3242 // that is, those that appear on the *method itself*.
3244 // As an example, if the user wrote something like
3245 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3246 // type of `foo` (possibly adjusted), but we don't want to
3247 // include that. We want just the `[_, u32]` part.
3248 if !method.substs.is_noop() {
3249 let method_generics = self.tcx.generics_of(method.def_id);
3250 if !method_generics.params.is_empty() {
3251 let user_type_annotation = self.infcx.probe(|_| {
3252 let user_substs = UserSubsts {
3253 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3254 let i = param.index as usize;
3255 if i < method_generics.parent_count {
3256 self.infcx.var_for_def(DUMMY_SP, param)
3261 user_self_ty: None, // not relevant here
3264 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3270 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3271 self.write_user_type_annotation(hir_id, user_type_annotation);
3276 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3277 if !substs.is_noop() {
3278 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3280 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
3284 /// Given the substs that we just converted from the HIR, try to
3285 /// canonicalize them and store them as user-given substitutions
3286 /// (i.e., substitutions that must be respected by the NLL check).
3288 /// This should be invoked **before any unifications have
3289 /// occurred**, so that annotations like `Vec<_>` are preserved
3291 pub fn write_user_type_annotation_from_substs(
3295 substs: SubstsRef<'tcx>,
3296 user_self_ty: Option<UserSelfTy<'tcx>>,
3299 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3300 user_self_ty={:?} in fcx {}",
3308 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3309 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3311 UserSubsts { substs, user_self_ty },
3313 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3314 self.write_user_type_annotation(hir_id, canonicalized);
3318 pub fn write_user_type_annotation(
3321 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3324 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3326 canonical_user_type_annotation,
3330 if !canonical_user_type_annotation.is_identity() {
3333 .user_provided_types_mut()
3334 .insert(hir_id, canonical_user_type_annotation);
3336 debug!("write_user_type_annotation: skipping identity substs");
3340 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3341 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3347 let autoborrow_mut = adj.iter().any(|adj| {
3348 matches!(adj, &Adjustment {
3349 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
3354 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3355 Entry::Vacant(entry) => {
3358 Entry::Occupied(mut entry) => {
3359 debug!(" - composing on top of {:?}", entry.get());
3360 match (&entry.get()[..], &adj[..]) {
3361 // Applying any adjustment on top of a NeverToAny
3362 // is a valid NeverToAny adjustment, because it can't
3364 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3366 Adjustment { kind: Adjust::Deref(_), .. },
3367 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3369 Adjustment { kind: Adjust::Deref(_), .. },
3370 .. // Any following adjustments are allowed.
3372 // A reborrow has no effect before a dereference.
3374 // FIXME: currently we never try to compose autoderefs
3375 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3377 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3378 expr, entry.get(), adj)
3380 *entry.get_mut() = adj;
3384 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
3385 // In this case implicit use of `Deref` and `Index` within `<expr>` should
3386 // instead be `DerefMut` and `IndexMut`, so fix those up.
3388 self.convert_place_derefs_to_mutable(expr);
3392 /// Basically whenever we are converting from a type scheme into
3393 /// the fn body space, we always want to normalize associated
3394 /// types as well. This function combines the two.
3395 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3397 T: TypeFoldable<'tcx>,
3399 let value = value.subst(self.tcx, substs);
3400 let result = self.normalize_associated_types_in(span, &value);
3401 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3405 /// As `instantiate_type_scheme`, but for the bounds found in a
3406 /// generic type scheme.
3407 fn instantiate_bounds(
3411 substs: SubstsRef<'tcx>,
3412 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3413 let bounds = self.tcx.predicates_of(def_id);
3414 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3415 let result = bounds.instantiate(self.tcx, substs);
3416 let result = self.normalize_associated_types_in(span, &result);
3418 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3419 bounds, substs, result, spans,
3424 /// Replaces the opaque types from the given value with type variables,
3425 /// and records the `OpaqueTypeMap` for later use during writeback. See
3426 /// `InferCtxt::instantiate_opaque_types` for more details.
3427 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3429 parent_id: hir::HirId,
3433 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3435 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3436 parent_def_id, value
3439 let (value, opaque_type_map) =
3440 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3448 let mut opaque_types = self.opaque_types.borrow_mut();
3449 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3450 for (ty, decl) in opaque_type_map {
3451 let _ = opaque_types.insert(ty, decl);
3452 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3458 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3460 T: TypeFoldable<'tcx>,
3462 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3465 fn normalize_associated_types_in_as_infer_ok<T>(
3469 ) -> InferOk<'tcx, T>
3471 T: TypeFoldable<'tcx>,
3473 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3476 pub fn require_type_meets(
3480 code: traits::ObligationCauseCode<'tcx>,
3483 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3486 pub fn require_type_is_sized(
3490 code: traits::ObligationCauseCode<'tcx>,
3492 if !ty.references_error() {
3493 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3494 self.require_type_meets(ty, span, code, lang_item);
3498 pub fn require_type_is_sized_deferred(
3502 code: traits::ObligationCauseCode<'tcx>,
3504 if !ty.references_error() {
3505 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3509 pub fn register_bound(
3513 cause: traits::ObligationCause<'tcx>,
3515 if !ty.references_error() {
3516 self.fulfillment_cx.borrow_mut().register_bound(
3526 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3527 let t = AstConv::ast_ty_to_ty(self, ast_t);
3528 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3532 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3533 let ty = self.to_ty(ast_ty);
3534 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3536 if Self::can_contain_user_lifetime_bounds(ty) {
3537 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3538 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3539 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3545 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3546 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3547 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3548 self.register_wf_obligation(
3550 self.tcx.hir().span(ast_c.hir_id),
3551 ObligationCauseCode::MiscObligation,
3556 pub fn const_arg_to_const(
3558 ast_c: &hir::AnonConst,
3559 param_def_id: DefId,
3560 ) -> &'tcx ty::Const<'tcx> {
3561 let const_def = ty::WithOptConstParam {
3562 did: self.tcx.hir().local_def_id(ast_c.hir_id),
3563 const_param_did: Some(param_def_id),
3565 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
3566 self.register_wf_obligation(
3568 self.tcx.hir().span(ast_c.hir_id),
3569 ObligationCauseCode::MiscObligation,
3574 // If the type given by the user has free regions, save it for later, since
3575 // NLL would like to enforce those. Also pass in types that involve
3576 // projections, since those can resolve to `'static` bounds (modulo #54940,
3577 // which hopefully will be fixed by the time you see this comment, dear
3578 // reader, although I have my doubts). Also pass in types with inference
3579 // types, because they may be repeated. Other sorts of things are already
3580 // sufficiently enforced with erased regions. =)
3581 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3583 T: TypeFoldable<'tcx>,
3585 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3588 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3589 match self.typeck_results.borrow().node_types().get(id) {
3591 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
3594 "no type for node {}: {} in fcx {}",
3596 self.tcx.hir().node_to_string(id),
3603 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3604 pub fn register_wf_obligation(
3606 arg: subst::GenericArg<'tcx>,
3608 code: traits::ObligationCauseCode<'tcx>,
3610 // WF obligations never themselves fail, so no real need to give a detailed cause:
3611 let cause = traits::ObligationCause::new(span, self.body_id, code);
3612 self.register_predicate(traits::Obligation::new(
3615 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3619 /// Registers obligations that all `substs` are well-formed.
3620 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3621 for arg in substs.iter().filter(|arg| {
3622 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3624 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3628 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3629 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3630 /// trait/region obligations.
3632 /// For example, if there is a function:
3635 /// fn foo<'a,T:'a>(...)
3638 /// and a reference:
3644 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3645 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3646 pub fn add_obligations_for_parameters(
3648 cause: traits::ObligationCause<'tcx>,
3649 predicates: ty::InstantiatedPredicates<'tcx>,
3651 assert!(!predicates.has_escaping_bound_vars());
3653 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3655 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3656 self.register_predicate(obligation);
3660 // FIXME(arielb1): use this instead of field.ty everywhere
3661 // Only for fields! Returns <none> for methods>
3662 // Indifferent to privacy flags
3666 field: &'tcx ty::FieldDef,
3667 substs: SubstsRef<'tcx>,
3669 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3672 fn check_casts(&self) {
3673 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3674 for cast in deferred_cast_checks.drain(..) {
3679 fn resolve_generator_interiors(&self, def_id: DefId) {
3680 let mut generators = self.deferred_generator_interiors.borrow_mut();
3681 for (body_id, interior, kind) in generators.drain(..) {
3682 self.select_obligations_where_possible(false, |_| {});
3683 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3687 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3689 // - Unconstrained ints are replaced with `i32`.
3691 // - Unconstrained floats are replaced with with `f64`.
3693 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3694 // is enabled. Otherwise, they are replaced with `()`.
3696 // Fallback becomes very dubious if we have encountered type-checking errors.
3697 // In that case, fallback to Error.
3698 // The return value indicates whether fallback has occurred.
3699 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3700 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3701 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3703 assert!(ty.is_ty_infer());
3704 let fallback = match self.type_is_unconstrained_numeric(ty) {
3705 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
3706 UnconstrainedInt => self.tcx.types.i32,
3707 UnconstrainedFloat => self.tcx.types.f64,
3708 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3710 // This type variable was created from the instantiation of an opaque
3711 // type. The fact that we're attempting to perform fallback for it
3712 // means that the function neither constrained it to a concrete
3713 // type, nor to the opaque type itself.
3715 // For example, in this code:
3718 // type MyType = impl Copy;
3719 // fn defining_use() -> MyType { true }
3720 // fn other_use() -> MyType { defining_use() }
3723 // `defining_use` will constrain the instantiated inference
3724 // variable to `bool`, while `other_use` will constrain
3725 // the instantiated inference variable to `MyType`.
3727 // When we process opaque types during writeback, we
3728 // will handle cases like `other_use`, and not count
3729 // them as defining usages
3731 // However, we also need to handle cases like this:
3734 // pub type Foo = impl Copy;
3735 // fn produce() -> Option<Foo> {
3740 // In the above snippet, the inference variable created by
3741 // instantiating `Option<Foo>` will be completely unconstrained.
3742 // We treat this as a non-defining use by making the inference
3743 // variable fall back to the opaque type itself.
3744 if let FallbackMode::All = mode {
3745 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3747 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3759 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3760 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3764 fn select_all_obligations_or_error(&self) {
3765 debug!("select_all_obligations_or_error");
3766 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3767 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3771 /// Select as many obligations as we can at present.
3772 fn select_obligations_where_possible(
3774 fallback_has_occurred: bool,
3775 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3777 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3778 if let Err(mut errors) = result {
3779 mutate_fullfillment_errors(&mut errors);
3780 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3784 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3785 /// returns a type of `&T`, but the actual type we assign to the
3786 /// *expression* is `T`. So this function just peels off the return
3787 /// type by one layer to yield `T`.
3788 fn make_overloaded_place_return_type(
3790 method: MethodCallee<'tcx>,
3791 ) -> ty::TypeAndMut<'tcx> {
3792 // extract method return type, which will be &T;
3793 let ret_ty = method.sig.output();
3795 // method returns &T, but the type as visible to user is T, so deref
3796 ret_ty.builtin_deref(true).unwrap()
3799 fn check_method_argument_types(
3802 expr: &'tcx hir::Expr<'tcx>,
3803 method: Result<MethodCallee<'tcx>, ()>,
3804 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3805 tuple_arguments: TupleArgumentsFlag,
3806 expected: Expectation<'tcx>,
3808 let has_error = match method {
3809 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3813 let err_inputs = self.err_args(args_no_rcvr.len());
3815 let err_inputs = match tuple_arguments {
3816 DontTupleArguments => err_inputs,
3817 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3820 self.check_argument_types(
3830 return self.tcx.ty_error();
3833 let method = method.unwrap();
3834 // HACK(eddyb) ignore self in the definition (see above).
3835 let expected_arg_tys = self.expected_inputs_for_expected_output(
3838 method.sig.output(),
3839 &method.sig.inputs()[1..],
3841 self.check_argument_types(
3844 &method.sig.inputs()[1..],
3845 &expected_arg_tys[..],
3847 method.sig.c_variadic,
3849 self.tcx.hir().span_if_local(method.def_id),
3854 fn self_type_matches_expected_vid(
3856 trait_ref: ty::PolyTraitRef<'tcx>,
3857 expected_vid: ty::TyVid,
3859 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3861 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3862 trait_ref, self_ty, expected_vid
3864 match self_ty.kind {
3865 ty::Infer(ty::TyVar(found_vid)) => {
3866 // FIXME: consider using `sub_root_var` here so we
3867 // can see through subtyping.
3868 let found_vid = self.root_var(found_vid);
3869 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3870 expected_vid == found_vid
3876 fn obligations_for_self_ty<'b>(
3879 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3882 // FIXME: consider using `sub_root_var` here so we
3883 // can see through subtyping.
3884 let ty_var_root = self.root_var(self_ty);
3886 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3889 self.fulfillment_cx.borrow().pending_obligations()
3894 .pending_obligations()
3896 .filter_map(move |obligation| {
3897 match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
3898 ty::PredicateKind::ForAll(_) => {
3899 bug!("unexpected predicate: {:?}", obligation.predicate)
3901 &ty::PredicateKind::Projection(data) => {
3902 Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation))
3904 &ty::PredicateKind::Trait(data, _) => {
3905 Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation))
3907 ty::PredicateKind::Subtype(..) => None,
3908 ty::PredicateKind::RegionOutlives(..) => None,
3909 ty::PredicateKind::TypeOutlives(..) => None,
3910 ty::PredicateKind::WellFormed(..) => None,
3911 ty::PredicateKind::ObjectSafe(..) => None,
3912 ty::PredicateKind::ConstEvaluatable(..) => None,
3913 ty::PredicateKind::ConstEquate(..) => None,
3914 // N.B., this predicate is created by breaking down a
3915 // `ClosureType: FnFoo()` predicate, where
3916 // `ClosureType` represents some `Closure`. It can't
3917 // possibly be referring to the current closure,
3918 // because we haven't produced the `Closure` for
3919 // this closure yet; this is exactly why the other
3920 // code is looking for a self type of a unresolved
3921 // inference variable.
3922 ty::PredicateKind::ClosureKind(..) => None,
3925 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3928 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3929 self.obligations_for_self_ty(self_ty)
3930 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3933 /// Generic function that factors out common logic from function calls,
3934 /// method calls and overloaded operators.
3935 fn check_argument_types(
3938 expr: &'tcx hir::Expr<'tcx>,
3939 fn_inputs: &[Ty<'tcx>],
3940 expected_arg_tys: &[Ty<'tcx>],
3941 args: &'tcx [hir::Expr<'tcx>],
3943 tuple_arguments: TupleArgumentsFlag,
3944 def_span: Option<Span>,
3947 // Grab the argument types, supplying fresh type variables
3948 // if the wrong number of arguments were supplied
3949 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3951 // All the input types from the fn signature must outlive the call
3952 // so as to validate implied bounds.
3953 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3954 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3957 let expected_arg_count = fn_inputs.len();
3959 let param_count_error = |expected_count: usize,
3964 let (span, start_span, args) = match &expr.kind {
3965 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3966 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
3968 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3971 .and_then(|args| args.args.iter().last())
3972 // Account for `foo.bar::<T>()`.
3974 // Skip the closing `>`.
3977 .next_point(tcx.sess.source_map().next_point(arg.span()))
3980 &args[1..], // Skip the receiver.
3982 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3984 let arg_spans = if args.is_empty() {
3986 // ^^^-- supplied 0 arguments
3988 // expected 2 arguments
3989 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3992 // ^^^ - - - supplied 3 arguments
3994 // expected 2 arguments
3995 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3998 let mut err = tcx.sess.struct_span_err_with_code(
4001 "this function takes {}{} but {} {} supplied",
4002 if c_variadic { "at least " } else { "" },
4003 potentially_plural_count(expected_count, "argument"),
4004 potentially_plural_count(arg_count, "argument"),
4005 if arg_count == 1 { "was" } else { "were" }
4007 DiagnosticId::Error(error_code.to_owned()),
4009 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
4010 for (i, span) in arg_spans.into_iter().enumerate() {
4013 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
4017 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
4018 err.span_label(def_s, "defined here");
4021 let sugg_span = tcx.sess.source_map().end_point(expr.span);
4022 // remove closing `)` from the span
4023 let sugg_span = sugg_span.shrink_to_lo();
4024 err.span_suggestion(
4026 "expected the unit value `()`; create it with empty parentheses",
4028 Applicability::MachineApplicable,
4035 if c_variadic { "at least " } else { "" },
4036 potentially_plural_count(expected_count, "argument")
4043 let mut expected_arg_tys = expected_arg_tys.to_vec();
4045 let formal_tys = if tuple_arguments == TupleArguments {
4046 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4047 match tuple_type.kind {
4048 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4049 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4050 expected_arg_tys = vec![];
4051 self.err_args(args.len())
4053 ty::Tuple(arg_types) => {
4054 expected_arg_tys = match expected_arg_tys.get(0) {
4055 Some(&ty) => match ty.kind {
4056 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4061 arg_types.iter().map(|k| k.expect_ty()).collect()
4068 "cannot use call notation; the first type parameter \
4069 for the function trait is neither a tuple nor unit"
4072 expected_arg_tys = vec![];
4073 self.err_args(args.len())
4076 } else if expected_arg_count == supplied_arg_count {
4078 } else if c_variadic {
4079 if supplied_arg_count >= expected_arg_count {
4082 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4083 expected_arg_tys = vec![];
4084 self.err_args(supplied_arg_count)
4087 // is the missing argument of type `()`?
4088 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4089 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4090 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4091 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4095 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4097 expected_arg_tys = vec![];
4098 self.err_args(supplied_arg_count)
4102 "check_argument_types: formal_tys={:?}",
4103 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4106 // If there is no expectation, expect formal_tys.
4107 let expected_arg_tys =
4108 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4110 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4112 // Check the arguments.
4113 // We do this in a pretty awful way: first we type-check any arguments
4114 // that are not closures, then we type-check the closures. This is so
4115 // that we have more information about the types of arguments when we
4116 // type-check the functions. This isn't really the right way to do this.
4117 for &check_closures in &[false, true] {
4118 debug!("check_closures={}", check_closures);
4120 // More awful hacks: before we check argument types, try to do
4121 // an "opportunistic" trait resolution of any trait bounds on
4122 // the call. This helps coercions.
4124 self.select_obligations_where_possible(false, |errors| {
4125 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4126 self.point_at_arg_instead_of_call_if_possible(
4128 &final_arg_types[..],
4135 // For C-variadic functions, we don't have a declared type for all of
4136 // the arguments hence we only do our usual type checking with
4137 // the arguments who's types we do know.
4138 let t = if c_variadic {
4140 } else if tuple_arguments == TupleArguments {
4145 for (i, arg) in args.iter().take(t).enumerate() {
4146 // Warn only for the first loop (the "no closures" one).
4147 // Closure arguments themselves can't be diverging, but
4148 // a previous argument can, e.g., `foo(panic!(), || {})`.
4149 if !check_closures {
4150 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4153 let is_closure = match arg.kind {
4154 ExprKind::Closure(..) => true,
4158 if is_closure != check_closures {
4162 debug!("checking the argument");
4163 let formal_ty = formal_tys[i];
4165 // The special-cased logic below has three functions:
4166 // 1. Provide as good of an expected type as possible.
4167 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4169 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4171 // 2. Coerce to the most detailed type that could be coerced
4172 // to, which is `expected_ty` if `rvalue_hint` returns an
4173 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4174 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4175 // We're processing function arguments so we definitely want to use
4176 // two-phase borrows.
4177 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
4178 final_arg_types.push((i, checked_ty, coerce_ty));
4180 // 3. Relate the expected type and the formal one,
4181 // if the expected type was used for the coercion.
4182 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4186 // We also need to make sure we at least write the ty of the other
4187 // arguments which we skipped above.
4189 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4190 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4191 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4194 for arg in args.iter().skip(expected_arg_count) {
4195 let arg_ty = self.check_expr(&arg);
4197 // There are a few types which get autopromoted when passed via varargs
4198 // in C but we just error out instead and require explicit casts.
4199 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4201 ty::Float(ast::FloatTy::F32) => {
4202 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4204 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4205 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4207 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4208 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4211 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4212 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4213 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4221 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4222 vec![self.tcx.ty_error(); len]
4225 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4226 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4227 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4228 /// can be not easily comparable with predicate type (because of coercion). If the types match
4229 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4230 /// the corresponding argument's expression span instead of the `fn` call path span.
4231 fn point_at_arg_instead_of_call_if_possible(
4233 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4234 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4236 args: &'tcx [hir::Expr<'tcx>],
4238 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4239 // the `?` operator.
4240 if call_sp.desugaring_kind().is_some() {
4244 for error in errors {
4245 // Only if the cause is somewhere inside the expression we want try to point at arg.
4246 // Otherwise, it means that the cause is somewhere else and we should not change
4247 // anything because we can break the correct span.
4248 if !call_sp.contains(error.obligation.cause.span) {
4252 if let ty::PredicateKind::Trait(predicate, _) =
4253 error.obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
4255 // Collect the argument position for all arguments that could have caused this
4256 // `FulfillmentError`.
4257 let mut referenced_in = final_arg_types
4259 .map(|&(i, checked_ty, _)| (i, checked_ty))
4260 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4261 .flat_map(|(i, ty)| {
4262 let ty = self.resolve_vars_if_possible(&ty);
4263 // We walk the argument type because the argument's type could have
4264 // been `Option<T>`, but the `FulfillmentError` references `T`.
4265 if ty.walk().any(|arg| arg == predicate.self_ty().into()) {
4271 .collect::<Vec<_>>();
4273 // Both checked and coerced types could have matched, thus we need to remove
4275 referenced_in.sort();
4276 referenced_in.dedup();
4278 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4279 // We make sure that only *one* argument matches the obligation failure
4280 // and we assign the obligation's span to its expression's.
4281 error.obligation.cause.make_mut().span = args[ref_in].span;
4282 error.points_at_arg_span = true;
4288 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4289 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4290 /// were caused by them. If they were, we point at the corresponding type argument's span
4291 /// instead of the `fn` call path span.
4292 fn point_at_type_arg_instead_of_call_if_possible(
4294 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4295 call_expr: &'tcx hir::Expr<'tcx>,
4297 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4298 if let hir::ExprKind::Path(qpath) = &path.kind {
4299 if let hir::QPath::Resolved(_, path) = &qpath {
4300 for error in errors {
4301 if let ty::PredicateKind::Trait(predicate, _) = error
4304 .ignore_qualifiers(self.tcx)
4308 // If any of the type arguments in this path segment caused the
4309 // `FullfillmentError`, point at its span (#61860).
4313 .filter_map(|seg| seg.args.as_ref())
4314 .flat_map(|a| a.args.iter())
4316 if let hir::GenericArg::Type(hir_ty) = &arg {
4317 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4320 // Avoid ICE with associated types. As this is best
4321 // effort only, it's ok to ignore the case. It
4322 // would trigger in `is_send::<T::AssocType>();`
4323 // from `typeck-default-trait-impl-assoc-type.rs`.
4325 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4326 let ty = self.resolve_vars_if_possible(&ty);
4327 if ty == predicate.self_ty() {
4328 error.obligation.cause.make_mut().span = hir_ty.span;
4340 // AST fragment checking
4341 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4345 ast::LitKind::Str(..) => tcx.mk_static_str(),
4346 ast::LitKind::ByteStr(ref v) => {
4347 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4349 ast::LitKind::Byte(_) => tcx.types.u8,
4350 ast::LitKind::Char(_) => tcx.types.char,
4351 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4352 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4353 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4354 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4355 ty::Int(_) | ty::Uint(_) => Some(ty),
4356 ty::Char => Some(tcx.types.u8),
4357 ty::RawPtr(..) => Some(tcx.types.usize),
4358 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4361 opt_ty.unwrap_or_else(|| self.next_int_var())
4363 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4364 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4365 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4366 ty::Float(_) => Some(ty),
4369 opt_ty.unwrap_or_else(|| self.next_float_var())
4371 ast::LitKind::Bool(_) => tcx.types.bool,
4372 ast::LitKind::Err(_) => tcx.ty_error(),
4376 /// Unifies the output type with the expected type early, for more coercions
4377 /// and forward type information on the input expressions.
4378 fn expected_inputs_for_expected_output(
4381 expected_ret: Expectation<'tcx>,
4382 formal_ret: Ty<'tcx>,
4383 formal_args: &[Ty<'tcx>],
4384 ) -> Vec<Ty<'tcx>> {
4385 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4386 let ret_ty = match expected_ret.only_has_type(self) {
4388 None => return Vec::new(),
4390 let expect_args = self
4391 .fudge_inference_if_ok(|| {
4392 // Attempt to apply a subtyping relationship between the formal
4393 // return type (likely containing type variables if the function
4394 // is polymorphic) and the expected return type.
4395 // No argument expectations are produced if unification fails.
4396 let origin = self.misc(call_span);
4397 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4399 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4400 // to identity so the resulting type is not constrained.
4403 // Process any obligations locally as much as
4404 // we can. We don't care if some things turn
4405 // out unconstrained or ambiguous, as we're
4406 // just trying to get hints here.
4407 self.save_and_restore_in_snapshot_flag(|_| {
4408 let mut fulfill = TraitEngine::new(self.tcx);
4409 for obligation in ok.obligations {
4410 fulfill.register_predicate_obligation(self, obligation);
4412 fulfill.select_where_possible(self)
4416 Err(_) => return Err(()),
4419 // Record all the argument types, with the substitutions
4420 // produced from the above subtyping unification.
4421 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4423 .unwrap_or_default();
4425 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4426 formal_args, formal_ret, expect_args, expected_ret
4431 pub fn check_struct_path(
4435 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4436 let path_span = match *qpath {
4437 QPath::Resolved(_, ref path) => path.span,
4438 QPath::TypeRelative(ref qself, _) => qself.span,
4440 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4441 let variant = match def {
4443 self.set_tainted_by_errors();
4446 Res::Def(DefKind::Variant, _) => match ty.kind {
4447 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4448 _ => bug!("unexpected type: {:?}", ty),
4450 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4451 | Res::SelfTy(..) => match ty.kind {
4452 ty::Adt(adt, substs) if !adt.is_enum() => {
4453 Some((adt.non_enum_variant(), adt.did, substs))
4457 _ => bug!("unexpected definition: {:?}", def),
4460 if let Some((variant, did, substs)) = variant {
4461 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4462 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4464 // Check bounds on type arguments used in the path.
4465 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4467 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4468 self.add_obligations_for_parameters(cause, bounds);
4476 "expected struct, variant or union type, found {}",
4477 ty.sort_string(self.tcx)
4479 .span_label(path_span, "not a struct")
4485 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4486 // The newly resolved definition is written into `type_dependent_defs`.
4487 fn finish_resolving_struct_path(
4492 ) -> (Res, Ty<'tcx>) {
4494 QPath::Resolved(ref maybe_qself, ref path) => {
4495 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4496 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4499 QPath::TypeRelative(ref qself, ref segment) => {
4500 let ty = self.to_ty(qself);
4502 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4508 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4509 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
4510 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4512 // Write back the new resolution.
4513 self.write_resolution(hir_id, result);
4515 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4520 /// Resolves an associated value path into a base type and associated constant, or method
4521 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4522 pub fn resolve_ty_and_res_ufcs<'b>(
4524 qpath: &'b QPath<'b>,
4527 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4528 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4529 let (ty, qself, item_segment) = match *qpath {
4530 QPath::Resolved(ref opt_qself, ref path) => {
4533 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4537 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4539 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
4541 // Return directly on cache hit. This is useful to avoid doubly reporting
4542 // errors with default match binding modes. See #44614.
4544 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4545 return (def, Some(ty), slice::from_ref(&**item_segment));
4547 let item_name = item_segment.ident;
4548 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4549 let result = match error {
4550 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4551 _ => Err(ErrorReported),
4553 if item_name.name != kw::Invalid {
4554 if let Some(mut e) = self.report_method_error(
4558 SelfSource::QPath(qself),
4568 // Write back the new resolution.
4569 self.write_resolution(hir_id, result);
4571 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4573 slice::from_ref(&**item_segment),
4577 pub fn check_decl_initializer(
4579 local: &'tcx hir::Local<'tcx>,
4580 init: &'tcx hir::Expr<'tcx>,
4582 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4583 // for #42640 (default match binding modes).
4586 let ref_bindings = local.pat.contains_explicit_ref_binding();
4588 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4589 if let Some(m) = ref_bindings {
4590 // Somewhat subtle: if we have a `ref` binding in the pattern,
4591 // we want to avoid introducing coercions for the RHS. This is
4592 // both because it helps preserve sanity and, in the case of
4593 // ref mut, for soundness (issue #23116). In particular, in
4594 // the latter case, we need to be clear that the type of the
4595 // referent for the reference that results is *equal to* the
4596 // type of the place it is referencing, and not some
4597 // supertype thereof.
4598 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4599 self.demand_eqtype(init.span, local_ty, init_ty);
4602 self.check_expr_coercable_to_type(init, local_ty, None)
4606 /// Type check a `let` statement.
4607 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4608 // Determine and write the type which we'll check the pattern against.
4609 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4610 self.write_ty(local.hir_id, ty);
4612 // Type check the initializer.
4613 if let Some(ref init) = local.init {
4614 let init_ty = self.check_decl_initializer(local, &init);
4615 self.overwrite_local_ty_if_err(local, ty, init_ty);
4618 // Does the expected pattern type originate from an expression and what is the span?
4619 let (origin_expr, ty_span) = match (local.ty, local.init) {
4620 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4621 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4622 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4625 // Type check the pattern. Override if necessary to avoid knock-on errors.
4626 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4627 let pat_ty = self.node_ty(local.pat.hir_id);
4628 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4631 fn overwrite_local_ty_if_err(
4633 local: &'tcx hir::Local<'tcx>,
4637 if ty.references_error() {
4638 // Override the types everywhere with `err()` to avoid knock on errors.
4639 self.write_ty(local.hir_id, ty);
4640 self.write_ty(local.pat.hir_id, ty);
4641 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4642 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4643 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4647 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4648 err.span_suggestion_short(
4649 span.shrink_to_hi(),
4650 "consider using a semicolon here",
4652 Applicability::MachineApplicable,
4656 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4657 // Don't do all the complex logic below for `DeclItem`.
4659 hir::StmtKind::Item(..) => return,
4660 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4663 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4665 // Hide the outer diverging and `has_errors` flags.
4666 let old_diverges = self.diverges.replace(Diverges::Maybe);
4667 let old_has_errors = self.has_errors.replace(false);
4670 hir::StmtKind::Local(ref l) => {
4671 self.check_decl_local(&l);
4674 hir::StmtKind::Item(_) => {}
4675 hir::StmtKind::Expr(ref expr) => {
4676 // Check with expected type of `()`.
4677 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4678 self.suggest_semicolon_at_end(expr.span, err);
4681 hir::StmtKind::Semi(ref expr) => {
4682 self.check_expr(&expr);
4686 // Combine the diverging and `has_error` flags.
4687 self.diverges.set(self.diverges.get() | old_diverges);
4688 self.has_errors.set(self.has_errors.get() | old_has_errors);
4691 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4692 let unit = self.tcx.mk_unit();
4693 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4695 // if the block produces a `!` value, that can always be
4696 // (effectively) coerced to unit.
4698 self.demand_suptype(blk.span, unit, ty);
4702 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4703 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4704 /// when given code like the following:
4706 /// if false { return 0i32; } else { 1u32 }
4707 /// // ^^^^ point at this instead of the whole `if` expression
4709 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4710 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4711 let arm_spans: Vec<Span> = arms
4714 self.in_progress_typeck_results
4715 .and_then(|typeck_results| {
4716 typeck_results.borrow().node_type_opt(arm.body.hir_id)
4718 .and_then(|arm_ty| {
4719 if arm_ty.is_never() {
4722 Some(match &arm.body.kind {
4723 // Point at the tail expression when possible.
4724 hir::ExprKind::Block(block, _) => {
4725 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4733 if arm_spans.len() == 1 {
4734 return arm_spans[0];
4740 fn check_block_with_expected(
4742 blk: &'tcx hir::Block<'tcx>,
4743 expected: Expectation<'tcx>,
4746 let mut fcx_ps = self.ps.borrow_mut();
4747 let unsafety_state = fcx_ps.recurse(blk);
4748 replace(&mut *fcx_ps, unsafety_state)
4751 // In some cases, blocks have just one exit, but other blocks
4752 // can be targeted by multiple breaks. This can happen both
4753 // with labeled blocks as well as when we desugar
4754 // a `try { ... }` expression.
4758 // 'a: { if true { break 'a Err(()); } Ok(()) }
4760 // Here we would wind up with two coercions, one from
4761 // `Err(())` and the other from the tail expression
4762 // `Ok(())`. If the tail expression is omitted, that's a
4763 // "forced unit" -- unless the block diverges, in which
4764 // case we can ignore the tail expression (e.g., `'a: {
4765 // break 'a 22; }` would not force the type of the block
4767 let tail_expr = blk.expr.as_ref();
4768 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4769 let coerce = if blk.targeted_by_break {
4770 CoerceMany::new(coerce_to_ty)
4772 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4773 Some(e) => slice::from_ref(e),
4776 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4779 let prev_diverges = self.diverges.get();
4780 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4782 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4783 for s in blk.stmts {
4787 // check the tail expression **without** holding the
4788 // `enclosing_breakables` lock below.
4789 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4791 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4792 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4793 let coerce = ctxt.coerce.as_mut().unwrap();
4794 if let Some(tail_expr_ty) = tail_expr_ty {
4795 let tail_expr = tail_expr.unwrap();
4796 let span = self.get_expr_coercion_span(tail_expr);
4797 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4798 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4800 // Subtle: if there is no explicit tail expression,
4801 // that is typically equivalent to a tail expression
4802 // of `()` -- except if the block diverges. In that
4803 // case, there is no value supplied from the tail
4804 // expression (assuming there are no other breaks,
4805 // this implies that the type of the block will be
4808 // #41425 -- label the implicit `()` as being the
4809 // "found type" here, rather than the "expected type".
4810 if !self.diverges.get().is_always() {
4811 // #50009 -- Do not point at the entire fn block span, point at the return type
4812 // span, as it is the cause of the requirement, and
4813 // `consider_hint_about_removing_semicolon` will point at the last expression
4814 // if it were a relevant part of the error. This improves usability in editors
4815 // that highlight errors inline.
4816 let mut sp = blk.span;
4817 let mut fn_span = None;
4818 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4819 let ret_sp = decl.output.span();
4820 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4821 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4822 // output would otherwise be incorrect and even misleading. Make sure
4823 // the span we're aiming at correspond to a `fn` body.
4824 if block_sp == blk.span {
4826 fn_span = Some(ident.span);
4830 coerce.coerce_forced_unit(
4834 if let Some(expected_ty) = expected.only_has_type(self) {
4835 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4837 if let Some(fn_span) = fn_span {
4840 "implicitly returns `()` as its body has no tail or `return` \
4852 // If we can break from the block, then the block's exit is always reachable
4853 // (... as long as the entry is reachable) - regardless of the tail of the block.
4854 self.diverges.set(prev_diverges);
4857 let mut ty = ctxt.coerce.unwrap().complete(self);
4859 if self.has_errors.get() || ty.references_error() {
4860 ty = self.tcx.ty_error()
4863 self.write_ty(blk.hir_id, ty);
4865 *self.ps.borrow_mut() = prev;
4869 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4870 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4872 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4873 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4874 let body = self.tcx.hir().body(body_id);
4875 if let ExprKind::Block(block, _) = &body.value.kind {
4876 return Some(block.span);
4884 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4885 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4886 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4887 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4890 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4891 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4893 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4894 // This is less than ideal, it will not suggest a return type span on any
4895 // method called `main`, regardless of whether it is actually the entry point,
4896 // but it will still present it as the reason for the expected type.
4897 Some((&sig.decl, ident, ident.name != sym::main))
4899 Node::TraitItem(&hir::TraitItem {
4901 kind: hir::TraitItemKind::Fn(ref sig, ..),
4903 }) => Some((&sig.decl, ident, true)),
4904 Node::ImplItem(&hir::ImplItem {
4906 kind: hir::ImplItemKind::Fn(ref sig, ..),
4908 }) => Some((&sig.decl, ident, false)),
4913 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4914 /// suggestion can be made, `None` otherwise.
4915 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4916 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4917 // `while` before reaching it, as block tail returns are not available in them.
4918 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4919 let parent = self.tcx.hir().get(blk_id);
4920 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4924 /// On implicit return expressions with mismatched types, provides the following suggestions:
4926 /// - Points out the method's return type as the reason for the expected type.
4927 /// - Possible missing semicolon.
4928 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4929 pub fn suggest_mismatched_types_on_tail(
4931 err: &mut DiagnosticBuilder<'_>,
4932 expr: &'tcx hir::Expr<'tcx>,
4938 let expr = expr.peel_drop_temps();
4939 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4940 let mut pointing_at_return_type = false;
4941 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4942 pointing_at_return_type =
4943 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4945 pointing_at_return_type
4948 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4949 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4951 /// fn foo(x: usize) -> usize { x }
4952 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4956 err: &mut DiagnosticBuilder<'_>,
4957 expr: &hir::Expr<'_>,
4961 let hir = self.tcx.hir();
4962 let (def_id, sig) = match found.kind {
4963 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4964 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4968 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4969 let sig = self.normalize_associated_types_in(expr.span, &sig);
4970 if self.can_coerce(sig.output(), expected) {
4971 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4972 (String::new(), Applicability::MachineApplicable)
4974 ("...".to_string(), Applicability::HasPlaceholders)
4976 let mut msg = "call this function";
4977 match hir.get_if_local(def_id) {
4979 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4980 | Node::ImplItem(hir::ImplItem {
4981 kind: hir::ImplItemKind::Fn(_, body_id), ..
4983 | Node::TraitItem(hir::TraitItem {
4984 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4988 let body = hir.body(*body_id);
4992 .map(|param| match ¶m.pat.kind {
4993 hir::PatKind::Binding(_, _, ident, None)
4994 if ident.name != kw::SelfLower =>
4998 _ => "_".to_string(),
5000 .collect::<Vec<_>>()
5003 Some(Node::Expr(hir::Expr {
5004 kind: ExprKind::Closure(_, _, body_id, _, _),
5005 span: full_closure_span,
5008 if *full_closure_span == expr.span {
5011 msg = "call this closure";
5012 let body = hir.body(*body_id);
5016 .map(|param| match ¶m.pat.kind {
5017 hir::PatKind::Binding(_, _, ident, None)
5018 if ident.name != kw::SelfLower =>
5022 _ => "_".to_string(),
5024 .collect::<Vec<_>>()
5027 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
5028 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
5029 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
5030 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
5031 msg = "instantiate this tuple variant";
5033 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
5034 msg = "instantiate this tuple struct";
5039 Some(Node::ForeignItem(hir::ForeignItem {
5040 kind: hir::ForeignItemKind::Fn(_, idents, _),
5046 if ident.name != kw::SelfLower {
5052 .collect::<Vec<_>>()
5055 Some(Node::TraitItem(hir::TraitItem {
5056 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5062 if ident.name != kw::SelfLower {
5068 .collect::<Vec<_>>()
5073 err.span_suggestion_verbose(
5074 expr.span.shrink_to_hi(),
5075 &format!("use parentheses to {}", msg),
5076 format!("({})", sugg_call),
5084 pub fn suggest_deref_ref_or_into(
5086 err: &mut DiagnosticBuilder<'_>,
5087 expr: &hir::Expr<'_>,
5090 expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
5092 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5093 err.span_suggestion(sp, msg, suggestion, applicability);
5094 } else if let (ty::FnDef(def_id, ..), true) =
5095 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5097 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5098 let sp = self.sess().source_map().guess_head_span(sp);
5099 err.span_label(sp, &format!("{} defined here", found));
5101 } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
5102 let is_struct_pat_shorthand_field =
5103 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5104 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5105 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5106 let mut suggestions = iter::repeat(&expr_text)
5107 .zip(methods.iter())
5108 .filter_map(|(receiver, method)| {
5109 let method_call = format!(".{}()", method.ident);
5110 if receiver.ends_with(&method_call) {
5111 None // do not suggest code that is already there (#53348)
5113 let method_call_list = [".to_vec()", ".to_string()"];
5114 let sugg = if receiver.ends_with(".clone()")
5115 && method_call_list.contains(&method_call.as_str())
5117 let max_len = receiver.rfind('.').unwrap();
5118 format!("{}{}", &receiver[..max_len], method_call)
5120 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5121 format!("({}){}", receiver, method_call)
5123 format!("{}{}", receiver, method_call)
5126 Some(if is_struct_pat_shorthand_field {
5127 format!("{}: {}", receiver, sugg)
5134 if suggestions.peek().is_some() {
5135 err.span_suggestions(
5137 "try using a conversion method",
5139 Applicability::MaybeIncorrect,
5146 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5147 /// in the heap by calling `Box::new()`.
5148 fn suggest_boxing_when_appropriate(
5150 err: &mut DiagnosticBuilder<'_>,
5151 expr: &hir::Expr<'_>,
5155 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5156 // Do not suggest `Box::new` in const context.
5159 if !expected.is_box() || found.is_box() {
5162 let boxed_found = self.tcx.mk_box(found);
5163 if let (true, Ok(snippet)) = (
5164 self.can_coerce(boxed_found, expected),
5165 self.sess().source_map().span_to_snippet(expr.span),
5167 err.span_suggestion(
5169 "store this in the heap by calling `Box::new`",
5170 format!("Box::new({})", snippet),
5171 Applicability::MachineApplicable,
5174 "for more on the distinction between the stack and the heap, read \
5175 https://doc.rust-lang.org/book/ch15-01-box.html, \
5176 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5177 https://doc.rust-lang.org/std/boxed/index.html",
5182 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5183 fn suggest_calling_boxed_future_when_appropriate(
5185 err: &mut DiagnosticBuilder<'_>,
5186 expr: &hir::Expr<'_>,
5192 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5193 // Do not suggest `Box::new` in const context.
5196 let pin_did = self.tcx.lang_items().pin_type();
5197 match expected.kind {
5198 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5199 // This guards the `unwrap` and `mk_box` below.
5200 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5203 let boxed_found = self.tcx.mk_box(found);
5204 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5205 if let (true, Ok(snippet)) = (
5206 self.can_coerce(new_found, expected),
5207 self.sess().source_map().span_to_snippet(expr.span),
5210 ty::Adt(def, _) if def.is_box() => {
5211 err.help("use `Box::pin`");
5214 err.span_suggestion(
5216 "you need to pin and box this expression",
5217 format!("Box::pin({})", snippet),
5218 Applicability::MachineApplicable,
5228 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5232 /// bar_that_returns_u32()
5236 /// This routine checks if the return expression in a block would make sense on its own as a
5237 /// statement and the return type has been left as default or has been specified as `()`. If so,
5238 /// it suggests adding a semicolon.
5239 fn suggest_missing_semicolon(
5241 err: &mut DiagnosticBuilder<'_>,
5242 expression: &'tcx hir::Expr<'tcx>,
5246 if expected.is_unit() {
5247 // `BlockTailExpression` only relevant if the tail expr would be
5248 // useful on its own.
5249 match expression.kind {
5251 | ExprKind::MethodCall(..)
5252 | ExprKind::Loop(..)
5253 | ExprKind::Match(..)
5254 | ExprKind::Block(..) => {
5255 err.span_suggestion(
5256 cause_span.shrink_to_hi(),
5257 "try adding a semicolon",
5259 Applicability::MachineApplicable,
5267 /// A possible error is to forget to add a return type that is needed:
5271 /// bar_that_returns_u32()
5275 /// This routine checks if the return type is left as default, the method is not part of an
5276 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5278 fn suggest_missing_return_type(
5280 err: &mut DiagnosticBuilder<'_>,
5281 fn_decl: &hir::FnDecl<'_>,
5286 // Only suggest changing the return type for methods that
5287 // haven't set a return type at all (and aren't `fn main()` or an impl).
5288 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5289 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5290 err.span_suggestion(
5292 "try adding a return type",
5293 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5294 Applicability::MachineApplicable,
5298 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5299 err.span_label(span, "possibly return type missing here?");
5302 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5303 // `fn main()` must return `()`, do not suggest changing return type
5304 err.span_label(span, "expected `()` because of default return type");
5307 // expectation was caused by something else, not the default return
5308 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5309 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5310 // Only point to return type if the expected type is the return type, as if they
5311 // are not, the expectation must have been caused by something else.
5312 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5314 let ty = AstConv::ast_ty_to_ty(self, ty);
5315 debug!("suggest_missing_return_type: return type {:?}", ty);
5316 debug!("suggest_missing_return_type: expected type {:?}", ty);
5317 if ty.kind == expected.kind {
5318 err.span_label(sp, format!("expected `{}` because of return type", expected));
5326 /// A possible error is to forget to add `.await` when using futures:
5329 /// async fn make_u32() -> u32 {
5333 /// fn take_u32(x: u32) {}
5335 /// async fn foo() {
5336 /// let x = make_u32();
5341 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5342 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5343 /// `.await` to the tail of the expression.
5344 fn suggest_missing_await(
5346 err: &mut DiagnosticBuilder<'_>,
5347 expr: &hir::Expr<'_>,
5351 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5352 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5353 // body isn't `async`.
5354 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5355 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5356 let body = self.tcx().hir().body(body_id);
5357 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5359 // Check for `Future` implementations by constructing a predicate to
5360 // prove: `<T as Future>::Output == U`
5361 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5362 let item_def_id = self
5364 .associated_items(future_trait)
5365 .in_definition_order()
5369 // `<T as Future>::Output`
5370 let projection_ty = ty::ProjectionTy {
5374 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5379 let predicate = ty::PredicateKind::Projection(ty::ProjectionPredicate {
5383 .to_predicate(self.tcx)
5384 .potentially_qualified(self.tcx, ty::PredicateKind::ForAll);
5385 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5387 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5389 if self.infcx.predicate_may_hold(&obligation) {
5390 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5391 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5392 err.span_suggestion(
5394 "consider using `.await` here",
5395 format!("{}.await", code),
5396 Applicability::MaybeIncorrect,
5399 debug!("suggest_missing_await: no snippet for {:?}", sp);
5402 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5408 fn note_need_for_fn_pointer(
5410 err: &mut DiagnosticBuilder<'_>,
5414 let (sig, did, substs) = match (&expected.kind, &found.kind) {
5415 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
5416 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
5417 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
5422 "different `fn` items always have unique types, even if their signatures are \
5425 (sig1, *did1, substs1)
5427 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
5428 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
5432 (sig1, *did, substs)
5436 err.help(&format!("change the expected type to be function pointer `{}`", sig));
5438 "if the expected type is due to type inference, cast the expected `fn` to a function \
5439 pointer: `{} as {}`",
5440 self.tcx.def_path_str_with_substs(did, substs),
5445 /// A common error is to add an extra semicolon:
5448 /// fn foo() -> usize {
5453 /// This routine checks if the final statement in a block is an
5454 /// expression with an explicit semicolon whose type is compatible
5455 /// with `expected_ty`. If so, it suggests removing the semicolon.
5456 fn consider_hint_about_removing_semicolon(
5458 blk: &'tcx hir::Block<'tcx>,
5459 expected_ty: Ty<'tcx>,
5460 err: &mut DiagnosticBuilder<'_>,
5462 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5463 err.span_suggestion(
5465 "consider removing this semicolon",
5467 Applicability::MachineApplicable,
5472 fn could_remove_semicolon(
5474 blk: &'tcx hir::Block<'tcx>,
5475 expected_ty: Ty<'tcx>,
5477 // Be helpful when the user wrote `{... expr;}` and
5478 // taking the `;` off is enough to fix the error.
5479 let last_stmt = blk.stmts.last()?;
5480 let last_expr = match last_stmt.kind {
5481 hir::StmtKind::Semi(ref e) => e,
5484 let last_expr_ty = self.node_ty(last_expr.hir_id);
5485 if matches!(last_expr_ty.kind, ty::Error(_))
5486 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5490 let original_span = original_sp(last_stmt.span, blk.span);
5491 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5494 // Instantiates the given path, which must refer to an item with the given
5495 // number of type parameters and type.
5496 pub fn instantiate_value_path(
5498 segments: &[hir::PathSegment<'_>],
5499 self_ty: Option<Ty<'tcx>>,
5503 ) -> (Ty<'tcx>, Res) {
5505 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5506 segments, self_ty, res, hir_id,
5511 let path_segs = match res {
5512 Res::Local(_) | Res::SelfCtor(_) => vec![],
5513 Res::Def(kind, def_id) => {
5514 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5516 _ => bug!("instantiate_value_path on {:?}", res),
5519 let mut user_self_ty = None;
5520 let mut is_alias_variant_ctor = false;
5522 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5523 if let Some(self_ty) = self_ty {
5524 let adt_def = self_ty.ty_adt_def().unwrap();
5525 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5526 is_alias_variant_ctor = true;
5529 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5530 let container = tcx.associated_item(def_id).container;
5531 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5533 ty::TraitContainer(trait_did) => {
5534 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5536 ty::ImplContainer(impl_def_id) => {
5537 if segments.len() == 1 {
5538 // `<T>::assoc` will end up here, and so
5539 // can `T::assoc`. It this came from an
5540 // inherent impl, we need to record the
5541 // `T` for posterity (see `UserSelfTy` for
5543 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5544 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5552 // Now that we have categorized what space the parameters for each
5553 // segment belong to, let's sort out the parameters that the user
5554 // provided (if any) into their appropriate spaces. We'll also report
5555 // errors if type parameters are provided in an inappropriate place.
5557 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5558 let generics_has_err = AstConv::prohibit_generics(
5560 segments.iter().enumerate().filter_map(|(index, seg)| {
5561 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5569 if let Res::Local(hid) = res {
5570 let ty = self.local_ty(span, hid).decl_ty;
5571 let ty = self.normalize_associated_types_in(span, &ty);
5572 self.write_ty(hir_id, ty);
5576 if generics_has_err {
5577 // Don't try to infer type parameters when prohibited generic arguments were given.
5578 user_self_ty = None;
5581 // Now we have to compare the types that the user *actually*
5582 // provided against the types that were *expected*. If the user
5583 // did not provide any types, then we want to substitute inference
5584 // variables. If the user provided some types, we may still need
5585 // to add defaults. If the user provided *too many* types, that's
5588 let mut infer_args_for_err = FxHashSet::default();
5589 for &PathSeg(def_id, index) in &path_segs {
5590 let seg = &segments[index];
5591 let generics = tcx.generics_of(def_id);
5592 // Argument-position `impl Trait` is treated as a normal generic
5593 // parameter internally, but we don't allow users to specify the
5594 // parameter's value explicitly, so we have to do some error-
5596 if let GenericArgCountResult {
5597 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5599 } = AstConv::check_generic_arg_count_for_call(
5600 tcx, span, &generics, &seg, false, // `is_method_call`
5602 infer_args_for_err.insert(index);
5603 self.set_tainted_by_errors(); // See issue #53251.
5607 let has_self = path_segs
5609 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5612 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5613 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5615 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5616 let variant = adt_def.non_enum_variant();
5617 let ctor_def_id = variant.ctor_def_id.unwrap();
5619 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5624 let mut err = tcx.sess.struct_span_err(
5626 "the `Self` constructor can only be used with tuple or unit structs",
5628 if let Some(adt_def) = ty.ty_adt_def() {
5629 match adt_def.adt_kind() {
5631 err.help("did you mean to use one of the enum's variants?");
5633 AdtKind::Struct | AdtKind::Union => {
5634 err.span_suggestion(
5636 "use curly brackets",
5637 String::from("Self { /* fields */ }"),
5638 Applicability::HasPlaceholders,
5645 return (tcx.ty_error(), res);
5651 let def_id = res.def_id();
5653 // The things we are substituting into the type should not contain
5654 // escaping late-bound regions, and nor should the base type scheme.
5655 let ty = tcx.type_of(def_id);
5657 let arg_count = GenericArgCountResult {
5658 explicit_late_bound: ExplicitLateBound::No,
5659 correct: if infer_args_for_err.is_empty() {
5662 Err(GenericArgCountMismatch::default())
5666 let substs = self_ctor_substs.unwrap_or_else(|| {
5667 AstConv::create_substs_for_generic_args(
5674 // Provide the generic args, and whether types should be inferred.
5676 if let Some(&PathSeg(_, index)) =
5677 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5679 // If we've encountered an `impl Trait`-related error, we're just
5680 // going to infer the arguments for better error messages.
5681 if !infer_args_for_err.contains(&index) {
5682 // Check whether the user has provided generic arguments.
5683 if let Some(ref data) = segments[index].args {
5684 return (Some(data), segments[index].infer_args);
5687 return (None, segments[index].infer_args);
5692 // Provide substitutions for parameters for which (valid) arguments have been provided.
5693 |param, arg| match (¶m.kind, arg) {
5694 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5695 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5697 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5698 self.to_ty(ty).into()
5700 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5701 self.const_arg_to_const(&ct.value, param.def_id).into()
5703 _ => unreachable!(),
5705 // Provide substitutions for parameters for which arguments are inferred.
5706 |substs, param, infer_args| {
5708 GenericParamDefKind::Lifetime => {
5709 self.re_infer(Some(param), span).unwrap().into()
5711 GenericParamDefKind::Type { has_default, .. } => {
5712 if !infer_args && has_default {
5713 // If we have a default, then we it doesn't matter that we're not
5714 // inferring the type arguments: we provide the default where any
5716 let default = tcx.type_of(param.def_id);
5719 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5723 // If no type arguments were provided, we have to infer them.
5724 // This case also occurs as a result of some malformed input, e.g.
5725 // a lifetime argument being given instead of a type parameter.
5726 // Using inference instead of `Error` gives better error messages.
5727 self.var_for_def(span, param)
5730 GenericParamDefKind::Const => {
5731 // FIXME(const_generics:defaults)
5732 // No const parameters were provided, we have to infer them.
5733 self.var_for_def(span, param)
5739 assert!(!substs.has_escaping_bound_vars());
5740 assert!(!ty.has_escaping_bound_vars());
5742 // First, store the "user substs" for later.
5743 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5745 self.add_required_obligations(span, def_id, &substs);
5747 // Substitute the values for the type parameters into the type of
5748 // the referenced item.
5749 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5751 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5752 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5753 // is inherent, there is no `Self` parameter; instead, the impl needs
5754 // type parameters, which we can infer by unifying the provided `Self`
5755 // with the substituted impl type.
5756 // This also occurs for an enum variant on a type alias.
5757 let ty = tcx.type_of(impl_def_id);
5759 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5760 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5761 Ok(ok) => self.register_infer_ok_obligations(ok),
5763 self.tcx.sess.delay_span_bug(
5766 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5775 self.check_rustc_args_require_const(def_id, hir_id, span);
5777 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5778 self.write_substs(hir_id, substs);
5780 (ty_substituted, res)
5783 /// Add all the obligations that are required, substituting and normalized appropriately.
5784 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5785 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5787 for (i, mut obligation) in traits::predicates_for_generics(
5788 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5794 // This makes the error point at the bound, but we want to point at the argument
5795 if let Some(span) = spans.get(i) {
5796 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
5798 self.register_predicate(obligation);
5802 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5803 // We're only interested in functions tagged with
5804 // #[rustc_args_required_const], so ignore anything that's not.
5805 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5809 // If our calling expression is indeed the function itself, we're good!
5810 // If not, generate an error that this can only be called directly.
5811 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5812 if let ExprKind::Call(ref callee, ..) = expr.kind {
5813 if callee.hir_id == hir_id {
5819 self.tcx.sess.span_err(
5821 "this function can only be invoked directly, not through a function pointer",
5825 /// Resolves `typ` by a single level if `typ` is a type variable.
5826 /// If no resolution is possible, then an error is reported.
5827 /// Numeric inference variables may be left unresolved.
5828 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5829 let ty = self.resolve_vars_with_obligations(ty);
5830 if !ty.is_ty_var() {
5833 if !self.is_tainted_by_errors() {
5834 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5835 .note("type must be known at this point")
5838 let err = self.tcx.ty_error();
5839 self.demand_suptype(sp, err, ty);
5844 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5847 ctxt: BreakableCtxt<'tcx>,
5849 ) -> (BreakableCtxt<'tcx>, R) {
5852 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5853 index = enclosing_breakables.stack.len();
5854 enclosing_breakables.by_id.insert(id, index);
5855 enclosing_breakables.stack.push(ctxt);
5859 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5860 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5861 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5862 enclosing_breakables.stack.pop().expect("missing breakable context")
5867 /// Instantiate a QueryResponse in a probe context, without a
5868 /// good ObligationCause.
5869 fn probe_instantiate_query_response(
5872 original_values: &OriginalQueryValues<'tcx>,
5873 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5874 ) -> InferResult<'tcx, Ty<'tcx>> {
5875 self.instantiate_query_response_and_region_obligations(
5876 &traits::ObligationCause::misc(span, self.body_id),
5883 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5884 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5885 let mut contained_in_place = false;
5887 while let hir::Node::Expr(parent_expr) =
5888 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5890 match &parent_expr.kind {
5891 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5892 if lhs.hir_id == expr_id {
5893 contained_in_place = true;
5899 expr_id = parent_expr.hir_id;
5906 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5907 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5909 assert_eq!(generics.parent, None);
5911 if generics.own_counts().types == 0 {
5915 let mut params_used = BitSet::new_empty(generics.params.len());
5917 if ty.references_error() {
5918 // If there is already another error, do not emit
5919 // an error for not using a type parameter.
5920 assert!(tcx.sess.has_errors());
5924 for leaf in ty.walk() {
5925 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5926 if let ty::Param(param) = leaf_ty.kind {
5927 debug!("found use of ty param {:?}", param);
5928 params_used.insert(param.index);
5933 for param in &generics.params {
5934 if !params_used.contains(param.index) {
5935 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5936 let span = tcx.def_span(param.def_id);
5941 "type parameter `{}` is unused",
5944 .span_label(span, "unused type parameter")
5951 fn fatally_break_rust(sess: &Session) {
5952 let handler = sess.diagnostic();
5953 handler.span_bug_no_panic(
5955 "It looks like you're trying to break rust; would you like some ICE?",
5957 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5958 handler.note_without_error(
5959 "we would appreciate a joke overview: \
5960 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5962 handler.note_without_error(&format!(
5963 "rustc {} running on {}",
5964 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5965 config::host_triple(),
5969 fn potentially_plural_count(count: usize, word: &str) -> String {
5970 format!("{} {}{}", count, word, pluralize!(count))