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.skip_binders() {
2404 ty::PredicateAtom::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::PredicateAtom::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.skip_binders() {
2942 ty::PredicateAtom::Trait(data, _) if data.self_ty().is_param(index) => {
2943 // HACK(eddyb) should get the original `Span`.
2944 let span = tcx.def_span(def_id);
2945 Some((predicate, span))
2954 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2956 Some(def) => infer::EarlyBoundRegion(span, def.name),
2957 None => infer::MiscVariable(span),
2959 Some(self.next_region_var(v))
2962 fn allow_ty_infer(&self) -> bool {
2966 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2967 if let Some(param) = param {
2968 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2973 self.next_ty_var(TypeVariableOrigin {
2974 kind: TypeVariableOriginKind::TypeInference,
2983 param: Option<&ty::GenericParamDef>,
2985 ) -> &'tcx Const<'tcx> {
2986 if let Some(param) = param {
2987 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2992 self.next_const_var(
2994 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2999 fn projected_ty_from_poly_trait_ref(
3003 item_segment: &hir::PathSegment<'_>,
3004 poly_trait_ref: ty::PolyTraitRef<'tcx>,
3006 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
3008 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
3012 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
3021 self.tcx().mk_projection(item_def_id, item_substs)
3024 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
3025 if ty.has_escaping_bound_vars() {
3026 ty // FIXME: normalization and escaping regions
3028 self.normalize_associated_types_in(span, &ty)
3032 fn set_tainted_by_errors(&self) {
3033 self.infcx.set_tainted_by_errors()
3036 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
3037 self.write_ty(hir_id, ty)
3041 /// Controls whether the arguments are tupled. This is used for the call
3044 /// Tupling means that all call-side arguments are packed into a tuple and
3045 /// passed as a single parameter. For example, if tupling is enabled, this
3048 /// fn f(x: (isize, isize))
3050 /// Can be called as:
3057 #[derive(Clone, Eq, PartialEq)]
3058 enum TupleArgumentsFlag {
3063 /// Controls how we perform fallback for unconstrained
3066 /// Do not fallback type variables to opaque types.
3068 /// Perform all possible kinds of fallback, including
3069 /// turning type variables to opaque types.
3073 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3075 inh: &'a Inherited<'a, 'tcx>,
3076 param_env: ty::ParamEnv<'tcx>,
3077 body_id: hir::HirId,
3078 ) -> FnCtxt<'a, 'tcx> {
3082 err_count_on_creation: inh.tcx.sess.err_count(),
3084 ret_coercion_span: RefCell::new(None),
3085 resume_yield_tys: None,
3086 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
3087 diverges: Cell::new(Diverges::Maybe),
3088 has_errors: Cell::new(false),
3089 enclosing_breakables: RefCell::new(EnclosingBreakables {
3091 by_id: Default::default(),
3097 pub fn sess(&self) -> &Session {
3101 pub fn errors_reported_since_creation(&self) -> bool {
3102 self.tcx.sess.err_count() > self.err_count_on_creation
3105 /// Produces warning on the given node, if the current point in the
3106 /// function is unreachable, and there hasn't been another warning.
3107 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
3108 // FIXME: Combine these two 'if' expressions into one once
3109 // let chains are implemented
3110 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
3111 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
3112 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
3113 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
3114 if !span.is_desugaring(DesugaringKind::CondTemporary)
3115 && !span.is_desugaring(DesugaringKind::Async)
3116 && !orig_span.is_desugaring(DesugaringKind::Await)
3118 self.diverges.set(Diverges::WarnedAlways);
3120 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
3122 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
3123 let msg = format!("unreachable {}", kind);
3125 .span_label(span, &msg)
3129 .unwrap_or("any code following this expression is unreachable"),
3137 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
3138 ObligationCause::new(span, self.body_id, code)
3141 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
3142 self.cause(span, ObligationCauseCode::MiscObligation)
3145 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
3146 /// version (resolve_vars_if_possible), this version will
3147 /// also select obligations if it seems useful, in an effort
3148 /// to get more type information.
3149 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3150 debug!("resolve_vars_with_obligations(ty={:?})", ty);
3152 // No Infer()? Nothing needs doing.
3153 if !ty.has_infer_types_or_consts() {
3154 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3158 // If `ty` is a type variable, see whether we already know what it is.
3159 ty = self.resolve_vars_if_possible(&ty);
3160 if !ty.has_infer_types_or_consts() {
3161 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3165 // If not, try resolving pending obligations as much as
3166 // possible. This can help substantially when there are
3167 // indirect dependencies that don't seem worth tracking
3169 self.select_obligations_where_possible(false, |_| {});
3170 ty = self.resolve_vars_if_possible(&ty);
3172 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3176 fn record_deferred_call_resolution(
3178 closure_def_id: DefId,
3179 r: DeferredCallResolution<'tcx>,
3181 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3182 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3185 fn remove_deferred_call_resolutions(
3187 closure_def_id: DefId,
3188 ) -> Vec<DeferredCallResolution<'tcx>> {
3189 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3190 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3193 pub fn tag(&self) -> String {
3194 format!("{:p}", self)
3197 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3198 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3199 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3204 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3206 "write_ty({:?}, {:?}) in fcx {}",
3208 self.resolve_vars_if_possible(&ty),
3211 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
3213 if ty.references_error() {
3214 self.has_errors.set(true);
3215 self.set_tainted_by_errors();
3219 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3220 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
3223 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3224 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3227 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3228 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3229 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3230 self.write_substs(hir_id, method.substs);
3232 // When the method is confirmed, the `method.substs` includes
3233 // parameters from not just the method, but also the impl of
3234 // the method -- in particular, the `Self` type will be fully
3235 // resolved. However, those are not something that the "user
3236 // specified" -- i.e., those types come from the inferred type
3237 // of the receiver, not something the user wrote. So when we
3238 // create the user-substs, we want to replace those earlier
3239 // types with just the types that the user actually wrote --
3240 // that is, those that appear on the *method itself*.
3242 // As an example, if the user wrote something like
3243 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3244 // type of `foo` (possibly adjusted), but we don't want to
3245 // include that. We want just the `[_, u32]` part.
3246 if !method.substs.is_noop() {
3247 let method_generics = self.tcx.generics_of(method.def_id);
3248 if !method_generics.params.is_empty() {
3249 let user_type_annotation = self.infcx.probe(|_| {
3250 let user_substs = UserSubsts {
3251 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3252 let i = param.index as usize;
3253 if i < method_generics.parent_count {
3254 self.infcx.var_for_def(DUMMY_SP, param)
3259 user_self_ty: None, // not relevant here
3262 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3268 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3269 self.write_user_type_annotation(hir_id, user_type_annotation);
3274 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3275 if !substs.is_noop() {
3276 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3278 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
3282 /// Given the substs that we just converted from the HIR, try to
3283 /// canonicalize them and store them as user-given substitutions
3284 /// (i.e., substitutions that must be respected by the NLL check).
3286 /// This should be invoked **before any unifications have
3287 /// occurred**, so that annotations like `Vec<_>` are preserved
3289 pub fn write_user_type_annotation_from_substs(
3293 substs: SubstsRef<'tcx>,
3294 user_self_ty: Option<UserSelfTy<'tcx>>,
3297 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3298 user_self_ty={:?} in fcx {}",
3306 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3307 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3309 UserSubsts { substs, user_self_ty },
3311 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3312 self.write_user_type_annotation(hir_id, canonicalized);
3316 pub fn write_user_type_annotation(
3319 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3322 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3324 canonical_user_type_annotation,
3328 if !canonical_user_type_annotation.is_identity() {
3331 .user_provided_types_mut()
3332 .insert(hir_id, canonical_user_type_annotation);
3334 debug!("write_user_type_annotation: skipping identity substs");
3338 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3339 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3345 let autoborrow_mut = adj.iter().any(|adj| {
3346 matches!(adj, &Adjustment {
3347 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
3352 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3353 Entry::Vacant(entry) => {
3356 Entry::Occupied(mut entry) => {
3357 debug!(" - composing on top of {:?}", entry.get());
3358 match (&entry.get()[..], &adj[..]) {
3359 // Applying any adjustment on top of a NeverToAny
3360 // is a valid NeverToAny adjustment, because it can't
3362 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3364 Adjustment { kind: Adjust::Deref(_), .. },
3365 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3367 Adjustment { kind: Adjust::Deref(_), .. },
3368 .. // Any following adjustments are allowed.
3370 // A reborrow has no effect before a dereference.
3372 // FIXME: currently we never try to compose autoderefs
3373 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3375 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3376 expr, entry.get(), adj)
3378 *entry.get_mut() = adj;
3382 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
3383 // In this case implicit use of `Deref` and `Index` within `<expr>` should
3384 // instead be `DerefMut` and `IndexMut`, so fix those up.
3386 self.convert_place_derefs_to_mutable(expr);
3390 /// Basically whenever we are converting from a type scheme into
3391 /// the fn body space, we always want to normalize associated
3392 /// types as well. This function combines the two.
3393 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3395 T: TypeFoldable<'tcx>,
3397 let value = value.subst(self.tcx, substs);
3398 let result = self.normalize_associated_types_in(span, &value);
3399 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3403 /// As `instantiate_type_scheme`, but for the bounds found in a
3404 /// generic type scheme.
3405 fn instantiate_bounds(
3409 substs: SubstsRef<'tcx>,
3410 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3411 let bounds = self.tcx.predicates_of(def_id);
3412 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3413 let result = bounds.instantiate(self.tcx, substs);
3414 let result = self.normalize_associated_types_in(span, &result);
3416 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3417 bounds, substs, result, spans,
3422 /// Replaces the opaque types from the given value with type variables,
3423 /// and records the `OpaqueTypeMap` for later use during writeback. See
3424 /// `InferCtxt::instantiate_opaque_types` for more details.
3425 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3427 parent_id: hir::HirId,
3431 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3433 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3434 parent_def_id, value
3437 let (value, opaque_type_map) =
3438 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3446 let mut opaque_types = self.opaque_types.borrow_mut();
3447 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3448 for (ty, decl) in opaque_type_map {
3449 let _ = opaque_types.insert(ty, decl);
3450 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3456 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3458 T: TypeFoldable<'tcx>,
3460 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3463 fn normalize_associated_types_in_as_infer_ok<T>(
3467 ) -> InferOk<'tcx, T>
3469 T: TypeFoldable<'tcx>,
3471 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3474 pub fn require_type_meets(
3478 code: traits::ObligationCauseCode<'tcx>,
3481 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3484 pub fn require_type_is_sized(
3488 code: traits::ObligationCauseCode<'tcx>,
3490 if !ty.references_error() {
3491 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3492 self.require_type_meets(ty, span, code, lang_item);
3496 pub fn require_type_is_sized_deferred(
3500 code: traits::ObligationCauseCode<'tcx>,
3502 if !ty.references_error() {
3503 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3507 pub fn register_bound(
3511 cause: traits::ObligationCause<'tcx>,
3513 if !ty.references_error() {
3514 self.fulfillment_cx.borrow_mut().register_bound(
3524 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3525 let t = AstConv::ast_ty_to_ty(self, ast_t);
3526 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3530 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3531 let ty = self.to_ty(ast_ty);
3532 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3534 if Self::can_contain_user_lifetime_bounds(ty) {
3535 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3536 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3537 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3543 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3544 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3545 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3546 self.register_wf_obligation(
3548 self.tcx.hir().span(ast_c.hir_id),
3549 ObligationCauseCode::MiscObligation,
3554 pub fn const_arg_to_const(
3556 ast_c: &hir::AnonConst,
3557 param_def_id: DefId,
3558 ) -> &'tcx ty::Const<'tcx> {
3559 let const_def = ty::WithOptConstParam {
3560 did: self.tcx.hir().local_def_id(ast_c.hir_id),
3561 const_param_did: Some(param_def_id),
3563 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
3564 self.register_wf_obligation(
3566 self.tcx.hir().span(ast_c.hir_id),
3567 ObligationCauseCode::MiscObligation,
3572 // If the type given by the user has free regions, save it for later, since
3573 // NLL would like to enforce those. Also pass in types that involve
3574 // projections, since those can resolve to `'static` bounds (modulo #54940,
3575 // which hopefully will be fixed by the time you see this comment, dear
3576 // reader, although I have my doubts). Also pass in types with inference
3577 // types, because they may be repeated. Other sorts of things are already
3578 // sufficiently enforced with erased regions. =)
3579 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3581 T: TypeFoldable<'tcx>,
3583 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3586 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3587 match self.typeck_results.borrow().node_types().get(id) {
3589 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
3592 "no type for node {}: {} in fcx {}",
3594 self.tcx.hir().node_to_string(id),
3601 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3602 pub fn register_wf_obligation(
3604 arg: subst::GenericArg<'tcx>,
3606 code: traits::ObligationCauseCode<'tcx>,
3608 // WF obligations never themselves fail, so no real need to give a detailed cause:
3609 let cause = traits::ObligationCause::new(span, self.body_id, code);
3610 self.register_predicate(traits::Obligation::new(
3613 ty::PredicateAtom::WellFormed(arg).to_predicate(self.tcx),
3617 /// Registers obligations that all `substs` are well-formed.
3618 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3619 for arg in substs.iter().filter(|arg| {
3620 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3622 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3626 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3627 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3628 /// trait/region obligations.
3630 /// For example, if there is a function:
3633 /// fn foo<'a,T:'a>(...)
3636 /// and a reference:
3642 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3643 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3644 pub fn add_obligations_for_parameters(
3646 cause: traits::ObligationCause<'tcx>,
3647 predicates: ty::InstantiatedPredicates<'tcx>,
3649 assert!(!predicates.has_escaping_bound_vars());
3651 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3653 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3654 self.register_predicate(obligation);
3658 // FIXME(arielb1): use this instead of field.ty everywhere
3659 // Only for fields! Returns <none> for methods>
3660 // Indifferent to privacy flags
3664 field: &'tcx ty::FieldDef,
3665 substs: SubstsRef<'tcx>,
3667 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3670 fn check_casts(&self) {
3671 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3672 for cast in deferred_cast_checks.drain(..) {
3677 fn resolve_generator_interiors(&self, def_id: DefId) {
3678 let mut generators = self.deferred_generator_interiors.borrow_mut();
3679 for (body_id, interior, kind) in generators.drain(..) {
3680 self.select_obligations_where_possible(false, |_| {});
3681 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3685 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3687 // - Unconstrained ints are replaced with `i32`.
3689 // - Unconstrained floats are replaced with with `f64`.
3691 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3692 // is enabled. Otherwise, they are replaced with `()`.
3694 // Fallback becomes very dubious if we have encountered type-checking errors.
3695 // In that case, fallback to Error.
3696 // The return value indicates whether fallback has occurred.
3697 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3698 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3699 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3701 assert!(ty.is_ty_infer());
3702 let fallback = match self.type_is_unconstrained_numeric(ty) {
3703 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
3704 UnconstrainedInt => self.tcx.types.i32,
3705 UnconstrainedFloat => self.tcx.types.f64,
3706 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3708 // This type variable was created from the instantiation of an opaque
3709 // type. The fact that we're attempting to perform fallback for it
3710 // means that the function neither constrained it to a concrete
3711 // type, nor to the opaque type itself.
3713 // For example, in this code:
3716 // type MyType = impl Copy;
3717 // fn defining_use() -> MyType { true }
3718 // fn other_use() -> MyType { defining_use() }
3721 // `defining_use` will constrain the instantiated inference
3722 // variable to `bool`, while `other_use` will constrain
3723 // the instantiated inference variable to `MyType`.
3725 // When we process opaque types during writeback, we
3726 // will handle cases like `other_use`, and not count
3727 // them as defining usages
3729 // However, we also need to handle cases like this:
3732 // pub type Foo = impl Copy;
3733 // fn produce() -> Option<Foo> {
3738 // In the above snippet, the inference variable created by
3739 // instantiating `Option<Foo>` will be completely unconstrained.
3740 // We treat this as a non-defining use by making the inference
3741 // variable fall back to the opaque type itself.
3742 if let FallbackMode::All = mode {
3743 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3745 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3757 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3758 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3762 fn select_all_obligations_or_error(&self) {
3763 debug!("select_all_obligations_or_error");
3764 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3765 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3769 /// Select as many obligations as we can at present.
3770 fn select_obligations_where_possible(
3772 fallback_has_occurred: bool,
3773 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3775 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3776 if let Err(mut errors) = result {
3777 mutate_fullfillment_errors(&mut errors);
3778 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3782 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3783 /// returns a type of `&T`, but the actual type we assign to the
3784 /// *expression* is `T`. So this function just peels off the return
3785 /// type by one layer to yield `T`.
3786 fn make_overloaded_place_return_type(
3788 method: MethodCallee<'tcx>,
3789 ) -> ty::TypeAndMut<'tcx> {
3790 // extract method return type, which will be &T;
3791 let ret_ty = method.sig.output();
3793 // method returns &T, but the type as visible to user is T, so deref
3794 ret_ty.builtin_deref(true).unwrap()
3797 fn check_method_argument_types(
3800 expr: &'tcx hir::Expr<'tcx>,
3801 method: Result<MethodCallee<'tcx>, ()>,
3802 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3803 tuple_arguments: TupleArgumentsFlag,
3804 expected: Expectation<'tcx>,
3806 let has_error = match method {
3807 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3811 let err_inputs = self.err_args(args_no_rcvr.len());
3813 let err_inputs = match tuple_arguments {
3814 DontTupleArguments => err_inputs,
3815 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3818 self.check_argument_types(
3828 return self.tcx.ty_error();
3831 let method = method.unwrap();
3832 // HACK(eddyb) ignore self in the definition (see above).
3833 let expected_arg_tys = self.expected_inputs_for_expected_output(
3836 method.sig.output(),
3837 &method.sig.inputs()[1..],
3839 self.check_argument_types(
3842 &method.sig.inputs()[1..],
3843 &expected_arg_tys[..],
3845 method.sig.c_variadic,
3847 self.tcx.hir().span_if_local(method.def_id),
3852 fn self_type_matches_expected_vid(
3854 trait_ref: ty::PolyTraitRef<'tcx>,
3855 expected_vid: ty::TyVid,
3857 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3859 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3860 trait_ref, self_ty, expected_vid
3862 match self_ty.kind {
3863 ty::Infer(ty::TyVar(found_vid)) => {
3864 // FIXME: consider using `sub_root_var` here so we
3865 // can see through subtyping.
3866 let found_vid = self.root_var(found_vid);
3867 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3868 expected_vid == found_vid
3874 fn obligations_for_self_ty<'b>(
3877 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3880 // FIXME: consider using `sub_root_var` here so we
3881 // can see through subtyping.
3882 let ty_var_root = self.root_var(self_ty);
3884 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3887 self.fulfillment_cx.borrow().pending_obligations()
3892 .pending_obligations()
3894 .filter_map(move |obligation| {
3895 match obligation.predicate.skip_binders() {
3896 ty::PredicateAtom::Projection(data) => {
3897 Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation))
3899 ty::PredicateAtom::Trait(data, _) => {
3900 Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation))
3902 ty::PredicateAtom::Subtype(..) => None,
3903 ty::PredicateAtom::RegionOutlives(..) => None,
3904 ty::PredicateAtom::TypeOutlives(..) => None,
3905 ty::PredicateAtom::WellFormed(..) => None,
3906 ty::PredicateAtom::ObjectSafe(..) => None,
3907 ty::PredicateAtom::ConstEvaluatable(..) => None,
3908 ty::PredicateAtom::ConstEquate(..) => None,
3909 // N.B., this predicate is created by breaking down a
3910 // `ClosureType: FnFoo()` predicate, where
3911 // `ClosureType` represents some `Closure`. It can't
3912 // possibly be referring to the current closure,
3913 // because we haven't produced the `Closure` for
3914 // this closure yet; this is exactly why the other
3915 // code is looking for a self type of a unresolved
3916 // inference variable.
3917 ty::PredicateAtom::ClosureKind(..) => None,
3920 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3923 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3924 self.obligations_for_self_ty(self_ty)
3925 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3928 /// Generic function that factors out common logic from function calls,
3929 /// method calls and overloaded operators.
3930 fn check_argument_types(
3933 expr: &'tcx hir::Expr<'tcx>,
3934 fn_inputs: &[Ty<'tcx>],
3935 expected_arg_tys: &[Ty<'tcx>],
3936 args: &'tcx [hir::Expr<'tcx>],
3938 tuple_arguments: TupleArgumentsFlag,
3939 def_span: Option<Span>,
3942 // Grab the argument types, supplying fresh type variables
3943 // if the wrong number of arguments were supplied
3944 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3946 // All the input types from the fn signature must outlive the call
3947 // so as to validate implied bounds.
3948 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3949 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3952 let expected_arg_count = fn_inputs.len();
3954 let param_count_error = |expected_count: usize,
3959 let (span, start_span, args) = match &expr.kind {
3960 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3961 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
3963 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3966 .and_then(|args| args.args.iter().last())
3967 // Account for `foo.bar::<T>()`.
3969 // Skip the closing `>`.
3972 .next_point(tcx.sess.source_map().next_point(arg.span()))
3975 &args[1..], // Skip the receiver.
3977 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3979 let arg_spans = if args.is_empty() {
3981 // ^^^-- supplied 0 arguments
3983 // expected 2 arguments
3984 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3987 // ^^^ - - - supplied 3 arguments
3989 // expected 2 arguments
3990 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
3993 let mut err = tcx.sess.struct_span_err_with_code(
3996 "this function takes {}{} but {} {} supplied",
3997 if c_variadic { "at least " } else { "" },
3998 potentially_plural_count(expected_count, "argument"),
3999 potentially_plural_count(arg_count, "argument"),
4000 if arg_count == 1 { "was" } else { "were" }
4002 DiagnosticId::Error(error_code.to_owned()),
4004 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
4005 for (i, span) in arg_spans.into_iter().enumerate() {
4008 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
4012 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
4013 err.span_label(def_s, "defined here");
4016 let sugg_span = tcx.sess.source_map().end_point(expr.span);
4017 // remove closing `)` from the span
4018 let sugg_span = sugg_span.shrink_to_lo();
4019 err.span_suggestion(
4021 "expected the unit value `()`; create it with empty parentheses",
4023 Applicability::MachineApplicable,
4030 if c_variadic { "at least " } else { "" },
4031 potentially_plural_count(expected_count, "argument")
4038 let mut expected_arg_tys = expected_arg_tys.to_vec();
4040 let formal_tys = if tuple_arguments == TupleArguments {
4041 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4042 match tuple_type.kind {
4043 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4044 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4045 expected_arg_tys = vec![];
4046 self.err_args(args.len())
4048 ty::Tuple(arg_types) => {
4049 expected_arg_tys = match expected_arg_tys.get(0) {
4050 Some(&ty) => match ty.kind {
4051 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4056 arg_types.iter().map(|k| k.expect_ty()).collect()
4063 "cannot use call notation; the first type parameter \
4064 for the function trait is neither a tuple nor unit"
4067 expected_arg_tys = vec![];
4068 self.err_args(args.len())
4071 } else if expected_arg_count == supplied_arg_count {
4073 } else if c_variadic {
4074 if supplied_arg_count >= expected_arg_count {
4077 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4078 expected_arg_tys = vec![];
4079 self.err_args(supplied_arg_count)
4082 // is the missing argument of type `()`?
4083 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4084 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4085 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4086 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4090 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4092 expected_arg_tys = vec![];
4093 self.err_args(supplied_arg_count)
4097 "check_argument_types: formal_tys={:?}",
4098 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4101 // If there is no expectation, expect formal_tys.
4102 let expected_arg_tys =
4103 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4105 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4107 // Check the arguments.
4108 // We do this in a pretty awful way: first we type-check any arguments
4109 // that are not closures, then we type-check the closures. This is so
4110 // that we have more information about the types of arguments when we
4111 // type-check the functions. This isn't really the right way to do this.
4112 for &check_closures in &[false, true] {
4113 debug!("check_closures={}", check_closures);
4115 // More awful hacks: before we check argument types, try to do
4116 // an "opportunistic" trait resolution of any trait bounds on
4117 // the call. This helps coercions.
4119 self.select_obligations_where_possible(false, |errors| {
4120 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4121 self.point_at_arg_instead_of_call_if_possible(
4123 &final_arg_types[..],
4130 // For C-variadic functions, we don't have a declared type for all of
4131 // the arguments hence we only do our usual type checking with
4132 // the arguments who's types we do know.
4133 let t = if c_variadic {
4135 } else if tuple_arguments == TupleArguments {
4140 for (i, arg) in args.iter().take(t).enumerate() {
4141 // Warn only for the first loop (the "no closures" one).
4142 // Closure arguments themselves can't be diverging, but
4143 // a previous argument can, e.g., `foo(panic!(), || {})`.
4144 if !check_closures {
4145 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4148 let is_closure = match arg.kind {
4149 ExprKind::Closure(..) => true,
4153 if is_closure != check_closures {
4157 debug!("checking the argument");
4158 let formal_ty = formal_tys[i];
4160 // The special-cased logic below has three functions:
4161 // 1. Provide as good of an expected type as possible.
4162 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4164 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4166 // 2. Coerce to the most detailed type that could be coerced
4167 // to, which is `expected_ty` if `rvalue_hint` returns an
4168 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4169 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4170 // We're processing function arguments so we definitely want to use
4171 // two-phase borrows.
4172 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
4173 final_arg_types.push((i, checked_ty, coerce_ty));
4175 // 3. Relate the expected type and the formal one,
4176 // if the expected type was used for the coercion.
4177 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4181 // We also need to make sure we at least write the ty of the other
4182 // arguments which we skipped above.
4184 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4185 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4186 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4189 for arg in args.iter().skip(expected_arg_count) {
4190 let arg_ty = self.check_expr(&arg);
4192 // There are a few types which get autopromoted when passed via varargs
4193 // in C but we just error out instead and require explicit casts.
4194 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4196 ty::Float(ast::FloatTy::F32) => {
4197 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4199 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4200 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4202 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4203 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4206 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4207 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4208 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4216 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4217 vec![self.tcx.ty_error(); len]
4220 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4221 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4222 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4223 /// can be not easily comparable with predicate type (because of coercion). If the types match
4224 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4225 /// the corresponding argument's expression span instead of the `fn` call path span.
4226 fn point_at_arg_instead_of_call_if_possible(
4228 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4229 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4231 args: &'tcx [hir::Expr<'tcx>],
4233 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4234 // the `?` operator.
4235 if call_sp.desugaring_kind().is_some() {
4239 for error in errors {
4240 // Only if the cause is somewhere inside the expression we want try to point at arg.
4241 // Otherwise, it means that the cause is somewhere else and we should not change
4242 // anything because we can break the correct span.
4243 if !call_sp.contains(error.obligation.cause.span) {
4247 if let ty::PredicateAtom::Trait(predicate, _) =
4248 error.obligation.predicate.skip_binders()
4250 // Collect the argument position for all arguments that could have caused this
4251 // `FulfillmentError`.
4252 let mut referenced_in = final_arg_types
4254 .map(|&(i, checked_ty, _)| (i, checked_ty))
4255 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4256 .flat_map(|(i, ty)| {
4257 let ty = self.resolve_vars_if_possible(&ty);
4258 // We walk the argument type because the argument's type could have
4259 // been `Option<T>`, but the `FulfillmentError` references `T`.
4260 if ty.walk().any(|arg| arg == predicate.self_ty().into()) {
4266 .collect::<Vec<_>>();
4268 // Both checked and coerced types could have matched, thus we need to remove
4270 referenced_in.sort();
4271 referenced_in.dedup();
4273 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4274 // We make sure that only *one* argument matches the obligation failure
4275 // and we assign the obligation's span to its expression's.
4276 error.obligation.cause.make_mut().span = args[ref_in].span;
4277 error.points_at_arg_span = true;
4283 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4284 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4285 /// were caused by them. If they were, we point at the corresponding type argument's span
4286 /// instead of the `fn` call path span.
4287 fn point_at_type_arg_instead_of_call_if_possible(
4289 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4290 call_expr: &'tcx hir::Expr<'tcx>,
4292 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4293 if let hir::ExprKind::Path(qpath) = &path.kind {
4294 if let hir::QPath::Resolved(_, path) = &qpath {
4295 for error in errors {
4296 if let ty::PredicateAtom::Trait(predicate, _) =
4297 error.obligation.predicate.skip_binders()
4299 // If any of the type arguments in this path segment caused the
4300 // `FullfillmentError`, point at its span (#61860).
4304 .filter_map(|seg| seg.args.as_ref())
4305 .flat_map(|a| a.args.iter())
4307 if let hir::GenericArg::Type(hir_ty) = &arg {
4308 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4311 // Avoid ICE with associated types. As this is best
4312 // effort only, it's ok to ignore the case. It
4313 // would trigger in `is_send::<T::AssocType>();`
4314 // from `typeck-default-trait-impl-assoc-type.rs`.
4316 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4317 let ty = self.resolve_vars_if_possible(&ty);
4318 if ty == predicate.self_ty() {
4319 error.obligation.cause.make_mut().span = hir_ty.span;
4331 // AST fragment checking
4332 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4336 ast::LitKind::Str(..) => tcx.mk_static_str(),
4337 ast::LitKind::ByteStr(ref v) => {
4338 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4340 ast::LitKind::Byte(_) => tcx.types.u8,
4341 ast::LitKind::Char(_) => tcx.types.char,
4342 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4343 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4344 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4345 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4346 ty::Int(_) | ty::Uint(_) => Some(ty),
4347 ty::Char => Some(tcx.types.u8),
4348 ty::RawPtr(..) => Some(tcx.types.usize),
4349 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4352 opt_ty.unwrap_or_else(|| self.next_int_var())
4354 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4355 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4356 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4357 ty::Float(_) => Some(ty),
4360 opt_ty.unwrap_or_else(|| self.next_float_var())
4362 ast::LitKind::Bool(_) => tcx.types.bool,
4363 ast::LitKind::Err(_) => tcx.ty_error(),
4367 /// Unifies the output type with the expected type early, for more coercions
4368 /// and forward type information on the input expressions.
4369 fn expected_inputs_for_expected_output(
4372 expected_ret: Expectation<'tcx>,
4373 formal_ret: Ty<'tcx>,
4374 formal_args: &[Ty<'tcx>],
4375 ) -> Vec<Ty<'tcx>> {
4376 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4377 let ret_ty = match expected_ret.only_has_type(self) {
4379 None => return Vec::new(),
4381 let expect_args = self
4382 .fudge_inference_if_ok(|| {
4383 // Attempt to apply a subtyping relationship between the formal
4384 // return type (likely containing type variables if the function
4385 // is polymorphic) and the expected return type.
4386 // No argument expectations are produced if unification fails.
4387 let origin = self.misc(call_span);
4388 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4390 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4391 // to identity so the resulting type is not constrained.
4394 // Process any obligations locally as much as
4395 // we can. We don't care if some things turn
4396 // out unconstrained or ambiguous, as we're
4397 // just trying to get hints here.
4398 self.save_and_restore_in_snapshot_flag(|_| {
4399 let mut fulfill = TraitEngine::new(self.tcx);
4400 for obligation in ok.obligations {
4401 fulfill.register_predicate_obligation(self, obligation);
4403 fulfill.select_where_possible(self)
4407 Err(_) => return Err(()),
4410 // Record all the argument types, with the substitutions
4411 // produced from the above subtyping unification.
4412 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4414 .unwrap_or_default();
4416 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4417 formal_args, formal_ret, expect_args, expected_ret
4422 pub fn check_struct_path(
4426 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4427 let path_span = match *qpath {
4428 QPath::Resolved(_, ref path) => path.span,
4429 QPath::TypeRelative(ref qself, _) => qself.span,
4431 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4432 let variant = match def {
4434 self.set_tainted_by_errors();
4437 Res::Def(DefKind::Variant, _) => match ty.kind {
4438 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4439 _ => bug!("unexpected type: {:?}", ty),
4441 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4442 | Res::SelfTy(..) => match ty.kind {
4443 ty::Adt(adt, substs) if !adt.is_enum() => {
4444 Some((adt.non_enum_variant(), adt.did, substs))
4448 _ => bug!("unexpected definition: {:?}", def),
4451 if let Some((variant, did, substs)) = variant {
4452 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4453 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4455 // Check bounds on type arguments used in the path.
4456 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4458 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4459 self.add_obligations_for_parameters(cause, bounds);
4467 "expected struct, variant or union type, found {}",
4468 ty.sort_string(self.tcx)
4470 .span_label(path_span, "not a struct")
4476 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4477 // The newly resolved definition is written into `type_dependent_defs`.
4478 fn finish_resolving_struct_path(
4483 ) -> (Res, Ty<'tcx>) {
4485 QPath::Resolved(ref maybe_qself, ref path) => {
4486 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4487 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4490 QPath::TypeRelative(ref qself, ref segment) => {
4491 let ty = self.to_ty(qself);
4493 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4499 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4500 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
4501 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4503 // Write back the new resolution.
4504 self.write_resolution(hir_id, result);
4506 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4511 /// Resolves an associated value path into a base type and associated constant, or method
4512 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4513 pub fn resolve_ty_and_res_ufcs<'b>(
4515 qpath: &'b QPath<'b>,
4518 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4519 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4520 let (ty, qself, item_segment) = match *qpath {
4521 QPath::Resolved(ref opt_qself, ref path) => {
4524 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4528 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4530 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
4532 // Return directly on cache hit. This is useful to avoid doubly reporting
4533 // errors with default match binding modes. See #44614.
4535 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4536 return (def, Some(ty), slice::from_ref(&**item_segment));
4538 let item_name = item_segment.ident;
4539 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4540 let result = match error {
4541 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4542 _ => Err(ErrorReported),
4544 if item_name.name != kw::Invalid {
4545 if let Some(mut e) = self.report_method_error(
4549 SelfSource::QPath(qself),
4559 // Write back the new resolution.
4560 self.write_resolution(hir_id, result);
4562 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4564 slice::from_ref(&**item_segment),
4568 pub fn check_decl_initializer(
4570 local: &'tcx hir::Local<'tcx>,
4571 init: &'tcx hir::Expr<'tcx>,
4573 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4574 // for #42640 (default match binding modes).
4577 let ref_bindings = local.pat.contains_explicit_ref_binding();
4579 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4580 if let Some(m) = ref_bindings {
4581 // Somewhat subtle: if we have a `ref` binding in the pattern,
4582 // we want to avoid introducing coercions for the RHS. This is
4583 // both because it helps preserve sanity and, in the case of
4584 // ref mut, for soundness (issue #23116). In particular, in
4585 // the latter case, we need to be clear that the type of the
4586 // referent for the reference that results is *equal to* the
4587 // type of the place it is referencing, and not some
4588 // supertype thereof.
4589 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4590 self.demand_eqtype(init.span, local_ty, init_ty);
4593 self.check_expr_coercable_to_type(init, local_ty, None)
4597 /// Type check a `let` statement.
4598 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4599 // Determine and write the type which we'll check the pattern against.
4600 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4601 self.write_ty(local.hir_id, ty);
4603 // Type check the initializer.
4604 if let Some(ref init) = local.init {
4605 let init_ty = self.check_decl_initializer(local, &init);
4606 self.overwrite_local_ty_if_err(local, ty, init_ty);
4609 // Does the expected pattern type originate from an expression and what is the span?
4610 let (origin_expr, ty_span) = match (local.ty, local.init) {
4611 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4612 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4613 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4616 // Type check the pattern. Override if necessary to avoid knock-on errors.
4617 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4618 let pat_ty = self.node_ty(local.pat.hir_id);
4619 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4622 fn overwrite_local_ty_if_err(
4624 local: &'tcx hir::Local<'tcx>,
4628 if ty.references_error() {
4629 // Override the types everywhere with `err()` to avoid knock on errors.
4630 self.write_ty(local.hir_id, ty);
4631 self.write_ty(local.pat.hir_id, ty);
4632 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4633 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4634 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4638 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4639 err.span_suggestion_short(
4640 span.shrink_to_hi(),
4641 "consider using a semicolon here",
4643 Applicability::MachineApplicable,
4647 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4648 // Don't do all the complex logic below for `DeclItem`.
4650 hir::StmtKind::Item(..) => return,
4651 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4654 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4656 // Hide the outer diverging and `has_errors` flags.
4657 let old_diverges = self.diverges.replace(Diverges::Maybe);
4658 let old_has_errors = self.has_errors.replace(false);
4661 hir::StmtKind::Local(ref l) => {
4662 self.check_decl_local(&l);
4665 hir::StmtKind::Item(_) => {}
4666 hir::StmtKind::Expr(ref expr) => {
4667 // Check with expected type of `()`.
4668 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4669 self.suggest_semicolon_at_end(expr.span, err);
4672 hir::StmtKind::Semi(ref expr) => {
4673 self.check_expr(&expr);
4677 // Combine the diverging and `has_error` flags.
4678 self.diverges.set(self.diverges.get() | old_diverges);
4679 self.has_errors.set(self.has_errors.get() | old_has_errors);
4682 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4683 let unit = self.tcx.mk_unit();
4684 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4686 // if the block produces a `!` value, that can always be
4687 // (effectively) coerced to unit.
4689 self.demand_suptype(blk.span, unit, ty);
4693 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4694 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4695 /// when given code like the following:
4697 /// if false { return 0i32; } else { 1u32 }
4698 /// // ^^^^ point at this instead of the whole `if` expression
4700 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4701 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4702 let arm_spans: Vec<Span> = arms
4705 self.in_progress_typeck_results
4706 .and_then(|typeck_results| {
4707 typeck_results.borrow().node_type_opt(arm.body.hir_id)
4709 .and_then(|arm_ty| {
4710 if arm_ty.is_never() {
4713 Some(match &arm.body.kind {
4714 // Point at the tail expression when possible.
4715 hir::ExprKind::Block(block, _) => {
4716 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4724 if arm_spans.len() == 1 {
4725 return arm_spans[0];
4731 fn check_block_with_expected(
4733 blk: &'tcx hir::Block<'tcx>,
4734 expected: Expectation<'tcx>,
4737 let mut fcx_ps = self.ps.borrow_mut();
4738 let unsafety_state = fcx_ps.recurse(blk);
4739 replace(&mut *fcx_ps, unsafety_state)
4742 // In some cases, blocks have just one exit, but other blocks
4743 // can be targeted by multiple breaks. This can happen both
4744 // with labeled blocks as well as when we desugar
4745 // a `try { ... }` expression.
4749 // 'a: { if true { break 'a Err(()); } Ok(()) }
4751 // Here we would wind up with two coercions, one from
4752 // `Err(())` and the other from the tail expression
4753 // `Ok(())`. If the tail expression is omitted, that's a
4754 // "forced unit" -- unless the block diverges, in which
4755 // case we can ignore the tail expression (e.g., `'a: {
4756 // break 'a 22; }` would not force the type of the block
4758 let tail_expr = blk.expr.as_ref();
4759 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4760 let coerce = if blk.targeted_by_break {
4761 CoerceMany::new(coerce_to_ty)
4763 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4764 Some(e) => slice::from_ref(e),
4767 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4770 let prev_diverges = self.diverges.get();
4771 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4773 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4774 for s in blk.stmts {
4778 // check the tail expression **without** holding the
4779 // `enclosing_breakables` lock below.
4780 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4782 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4783 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4784 let coerce = ctxt.coerce.as_mut().unwrap();
4785 if let Some(tail_expr_ty) = tail_expr_ty {
4786 let tail_expr = tail_expr.unwrap();
4787 let span = self.get_expr_coercion_span(tail_expr);
4788 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4789 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4791 // Subtle: if there is no explicit tail expression,
4792 // that is typically equivalent to a tail expression
4793 // of `()` -- except if the block diverges. In that
4794 // case, there is no value supplied from the tail
4795 // expression (assuming there are no other breaks,
4796 // this implies that the type of the block will be
4799 // #41425 -- label the implicit `()` as being the
4800 // "found type" here, rather than the "expected type".
4801 if !self.diverges.get().is_always() {
4802 // #50009 -- Do not point at the entire fn block span, point at the return type
4803 // span, as it is the cause of the requirement, and
4804 // `consider_hint_about_removing_semicolon` will point at the last expression
4805 // if it were a relevant part of the error. This improves usability in editors
4806 // that highlight errors inline.
4807 let mut sp = blk.span;
4808 let mut fn_span = None;
4809 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4810 let ret_sp = decl.output.span();
4811 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4812 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4813 // output would otherwise be incorrect and even misleading. Make sure
4814 // the span we're aiming at correspond to a `fn` body.
4815 if block_sp == blk.span {
4817 fn_span = Some(ident.span);
4821 coerce.coerce_forced_unit(
4825 if let Some(expected_ty) = expected.only_has_type(self) {
4826 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4828 if let Some(fn_span) = fn_span {
4831 "implicitly returns `()` as its body has no tail or `return` \
4843 // If we can break from the block, then the block's exit is always reachable
4844 // (... as long as the entry is reachable) - regardless of the tail of the block.
4845 self.diverges.set(prev_diverges);
4848 let mut ty = ctxt.coerce.unwrap().complete(self);
4850 if self.has_errors.get() || ty.references_error() {
4851 ty = self.tcx.ty_error()
4854 self.write_ty(blk.hir_id, ty);
4856 *self.ps.borrow_mut() = prev;
4860 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4861 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4863 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4864 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4865 let body = self.tcx.hir().body(body_id);
4866 if let ExprKind::Block(block, _) = &body.value.kind {
4867 return Some(block.span);
4875 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4876 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4877 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4878 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4881 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4882 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4884 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4885 // This is less than ideal, it will not suggest a return type span on any
4886 // method called `main`, regardless of whether it is actually the entry point,
4887 // but it will still present it as the reason for the expected type.
4888 Some((&sig.decl, ident, ident.name != sym::main))
4890 Node::TraitItem(&hir::TraitItem {
4892 kind: hir::TraitItemKind::Fn(ref sig, ..),
4894 }) => Some((&sig.decl, ident, true)),
4895 Node::ImplItem(&hir::ImplItem {
4897 kind: hir::ImplItemKind::Fn(ref sig, ..),
4899 }) => Some((&sig.decl, ident, false)),
4904 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4905 /// suggestion can be made, `None` otherwise.
4906 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4907 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4908 // `while` before reaching it, as block tail returns are not available in them.
4909 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4910 let parent = self.tcx.hir().get(blk_id);
4911 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4915 /// On implicit return expressions with mismatched types, provides the following suggestions:
4917 /// - Points out the method's return type as the reason for the expected type.
4918 /// - Possible missing semicolon.
4919 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4920 pub fn suggest_mismatched_types_on_tail(
4922 err: &mut DiagnosticBuilder<'_>,
4923 expr: &'tcx hir::Expr<'tcx>,
4929 let expr = expr.peel_drop_temps();
4930 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4931 let mut pointing_at_return_type = false;
4932 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4933 pointing_at_return_type =
4934 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4936 pointing_at_return_type
4939 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4940 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4942 /// fn foo(x: usize) -> usize { x }
4943 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4947 err: &mut DiagnosticBuilder<'_>,
4948 expr: &hir::Expr<'_>,
4952 let hir = self.tcx.hir();
4953 let (def_id, sig) = match found.kind {
4954 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4955 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4959 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4960 let sig = self.normalize_associated_types_in(expr.span, &sig);
4961 if self.can_coerce(sig.output(), expected) {
4962 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4963 (String::new(), Applicability::MachineApplicable)
4965 ("...".to_string(), Applicability::HasPlaceholders)
4967 let mut msg = "call this function";
4968 match hir.get_if_local(def_id) {
4970 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4971 | Node::ImplItem(hir::ImplItem {
4972 kind: hir::ImplItemKind::Fn(_, body_id), ..
4974 | Node::TraitItem(hir::TraitItem {
4975 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4979 let body = hir.body(*body_id);
4983 .map(|param| match ¶m.pat.kind {
4984 hir::PatKind::Binding(_, _, ident, None)
4985 if ident.name != kw::SelfLower =>
4989 _ => "_".to_string(),
4991 .collect::<Vec<_>>()
4994 Some(Node::Expr(hir::Expr {
4995 kind: ExprKind::Closure(_, _, body_id, _, _),
4996 span: full_closure_span,
4999 if *full_closure_span == expr.span {
5002 msg = "call this closure";
5003 let body = hir.body(*body_id);
5007 .map(|param| match ¶m.pat.kind {
5008 hir::PatKind::Binding(_, _, ident, None)
5009 if ident.name != kw::SelfLower =>
5013 _ => "_".to_string(),
5015 .collect::<Vec<_>>()
5018 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
5019 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
5020 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
5021 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
5022 msg = "instantiate this tuple variant";
5024 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
5025 msg = "instantiate this tuple struct";
5030 Some(Node::ForeignItem(hir::ForeignItem {
5031 kind: hir::ForeignItemKind::Fn(_, idents, _),
5037 if ident.name != kw::SelfLower {
5043 .collect::<Vec<_>>()
5046 Some(Node::TraitItem(hir::TraitItem {
5047 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5053 if ident.name != kw::SelfLower {
5059 .collect::<Vec<_>>()
5064 err.span_suggestion_verbose(
5065 expr.span.shrink_to_hi(),
5066 &format!("use parentheses to {}", msg),
5067 format!("({})", sugg_call),
5075 pub fn suggest_deref_ref_or_into(
5077 err: &mut DiagnosticBuilder<'_>,
5078 expr: &hir::Expr<'_>,
5081 expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
5083 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5084 err.span_suggestion(sp, msg, suggestion, applicability);
5085 } else if let (ty::FnDef(def_id, ..), true) =
5086 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5088 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5089 let sp = self.sess().source_map().guess_head_span(sp);
5090 err.span_label(sp, &format!("{} defined here", found));
5092 } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
5093 let is_struct_pat_shorthand_field =
5094 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5095 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5096 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5097 let mut suggestions = iter::repeat(&expr_text)
5098 .zip(methods.iter())
5099 .filter_map(|(receiver, method)| {
5100 let method_call = format!(".{}()", method.ident);
5101 if receiver.ends_with(&method_call) {
5102 None // do not suggest code that is already there (#53348)
5104 let method_call_list = [".to_vec()", ".to_string()"];
5105 let sugg = if receiver.ends_with(".clone()")
5106 && method_call_list.contains(&method_call.as_str())
5108 let max_len = receiver.rfind('.').unwrap();
5109 format!("{}{}", &receiver[..max_len], method_call)
5111 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5112 format!("({}){}", receiver, method_call)
5114 format!("{}{}", receiver, method_call)
5117 Some(if is_struct_pat_shorthand_field {
5118 format!("{}: {}", receiver, sugg)
5125 if suggestions.peek().is_some() {
5126 err.span_suggestions(
5128 "try using a conversion method",
5130 Applicability::MaybeIncorrect,
5137 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5138 /// in the heap by calling `Box::new()`.
5139 fn suggest_boxing_when_appropriate(
5141 err: &mut DiagnosticBuilder<'_>,
5142 expr: &hir::Expr<'_>,
5146 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5147 // Do not suggest `Box::new` in const context.
5150 if !expected.is_box() || found.is_box() {
5153 let boxed_found = self.tcx.mk_box(found);
5154 if let (true, Ok(snippet)) = (
5155 self.can_coerce(boxed_found, expected),
5156 self.sess().source_map().span_to_snippet(expr.span),
5158 err.span_suggestion(
5160 "store this in the heap by calling `Box::new`",
5161 format!("Box::new({})", snippet),
5162 Applicability::MachineApplicable,
5165 "for more on the distinction between the stack and the heap, read \
5166 https://doc.rust-lang.org/book/ch15-01-box.html, \
5167 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5168 https://doc.rust-lang.org/std/boxed/index.html",
5173 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5174 fn suggest_calling_boxed_future_when_appropriate(
5176 err: &mut DiagnosticBuilder<'_>,
5177 expr: &hir::Expr<'_>,
5183 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5184 // Do not suggest `Box::new` in const context.
5187 let pin_did = self.tcx.lang_items().pin_type();
5188 match expected.kind {
5189 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5190 // This guards the `unwrap` and `mk_box` below.
5191 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5194 let boxed_found = self.tcx.mk_box(found);
5195 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5196 if let (true, Ok(snippet)) = (
5197 self.can_coerce(new_found, expected),
5198 self.sess().source_map().span_to_snippet(expr.span),
5201 ty::Adt(def, _) if def.is_box() => {
5202 err.help("use `Box::pin`");
5205 err.span_suggestion(
5207 "you need to pin and box this expression",
5208 format!("Box::pin({})", snippet),
5209 Applicability::MachineApplicable,
5219 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5223 /// bar_that_returns_u32()
5227 /// This routine checks if the return expression in a block would make sense on its own as a
5228 /// statement and the return type has been left as default or has been specified as `()`. If so,
5229 /// it suggests adding a semicolon.
5230 fn suggest_missing_semicolon(
5232 err: &mut DiagnosticBuilder<'_>,
5233 expression: &'tcx hir::Expr<'tcx>,
5237 if expected.is_unit() {
5238 // `BlockTailExpression` only relevant if the tail expr would be
5239 // useful on its own.
5240 match expression.kind {
5242 | ExprKind::MethodCall(..)
5243 | ExprKind::Loop(..)
5244 | ExprKind::Match(..)
5245 | ExprKind::Block(..) => {
5246 err.span_suggestion(
5247 cause_span.shrink_to_hi(),
5248 "try adding a semicolon",
5250 Applicability::MachineApplicable,
5258 /// A possible error is to forget to add a return type that is needed:
5262 /// bar_that_returns_u32()
5266 /// This routine checks if the return type is left as default, the method is not part of an
5267 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5269 fn suggest_missing_return_type(
5271 err: &mut DiagnosticBuilder<'_>,
5272 fn_decl: &hir::FnDecl<'_>,
5277 // Only suggest changing the return type for methods that
5278 // haven't set a return type at all (and aren't `fn main()` or an impl).
5279 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5280 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5281 err.span_suggestion(
5283 "try adding a return type",
5284 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5285 Applicability::MachineApplicable,
5289 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5290 err.span_label(span, "possibly return type missing here?");
5293 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5294 // `fn main()` must return `()`, do not suggest changing return type
5295 err.span_label(span, "expected `()` because of default return type");
5298 // expectation was caused by something else, not the default return
5299 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5300 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5301 // Only point to return type if the expected type is the return type, as if they
5302 // are not, the expectation must have been caused by something else.
5303 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5305 let ty = AstConv::ast_ty_to_ty(self, ty);
5306 debug!("suggest_missing_return_type: return type {:?}", ty);
5307 debug!("suggest_missing_return_type: expected type {:?}", ty);
5308 if ty.kind == expected.kind {
5309 err.span_label(sp, format!("expected `{}` because of return type", expected));
5317 /// A possible error is to forget to add `.await` when using futures:
5320 /// async fn make_u32() -> u32 {
5324 /// fn take_u32(x: u32) {}
5326 /// async fn foo() {
5327 /// let x = make_u32();
5332 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5333 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5334 /// `.await` to the tail of the expression.
5335 fn suggest_missing_await(
5337 err: &mut DiagnosticBuilder<'_>,
5338 expr: &hir::Expr<'_>,
5342 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5343 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5344 // body isn't `async`.
5345 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5346 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5347 let body = self.tcx().hir().body(body_id);
5348 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5350 // Check for `Future` implementations by constructing a predicate to
5351 // prove: `<T as Future>::Output == U`
5352 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5353 let item_def_id = self
5355 .associated_items(future_trait)
5356 .in_definition_order()
5360 // `<T as Future>::Output`
5361 let projection_ty = ty::ProjectionTy {
5365 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5370 let predicate = ty::PredicateAtom::Projection(ty::ProjectionPredicate {
5374 .potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
5375 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5377 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5379 if self.infcx.predicate_may_hold(&obligation) {
5380 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5381 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5382 err.span_suggestion(
5384 "consider using `.await` here",
5385 format!("{}.await", code),
5386 Applicability::MaybeIncorrect,
5389 debug!("suggest_missing_await: no snippet for {:?}", sp);
5392 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5398 fn note_need_for_fn_pointer(
5400 err: &mut DiagnosticBuilder<'_>,
5404 let (sig, did, substs) = match (&expected.kind, &found.kind) {
5405 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
5406 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
5407 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
5412 "different `fn` items always have unique types, even if their signatures are \
5415 (sig1, *did1, substs1)
5417 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
5418 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
5422 (sig1, *did, substs)
5426 err.help(&format!("change the expected type to be function pointer `{}`", sig));
5428 "if the expected type is due to type inference, cast the expected `fn` to a function \
5429 pointer: `{} as {}`",
5430 self.tcx.def_path_str_with_substs(did, substs),
5435 /// A common error is to add an extra semicolon:
5438 /// fn foo() -> usize {
5443 /// This routine checks if the final statement in a block is an
5444 /// expression with an explicit semicolon whose type is compatible
5445 /// with `expected_ty`. If so, it suggests removing the semicolon.
5446 fn consider_hint_about_removing_semicolon(
5448 blk: &'tcx hir::Block<'tcx>,
5449 expected_ty: Ty<'tcx>,
5450 err: &mut DiagnosticBuilder<'_>,
5452 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5453 err.span_suggestion(
5455 "consider removing this semicolon",
5457 Applicability::MachineApplicable,
5462 fn could_remove_semicolon(
5464 blk: &'tcx hir::Block<'tcx>,
5465 expected_ty: Ty<'tcx>,
5467 // Be helpful when the user wrote `{... expr;}` and
5468 // taking the `;` off is enough to fix the error.
5469 let last_stmt = blk.stmts.last()?;
5470 let last_expr = match last_stmt.kind {
5471 hir::StmtKind::Semi(ref e) => e,
5474 let last_expr_ty = self.node_ty(last_expr.hir_id);
5475 if matches!(last_expr_ty.kind, ty::Error(_))
5476 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5480 let original_span = original_sp(last_stmt.span, blk.span);
5481 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5484 // Instantiates the given path, which must refer to an item with the given
5485 // number of type parameters and type.
5486 pub fn instantiate_value_path(
5488 segments: &[hir::PathSegment<'_>],
5489 self_ty: Option<Ty<'tcx>>,
5493 ) -> (Ty<'tcx>, Res) {
5495 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5496 segments, self_ty, res, hir_id,
5501 let path_segs = match res {
5502 Res::Local(_) | Res::SelfCtor(_) => vec![],
5503 Res::Def(kind, def_id) => {
5504 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5506 _ => bug!("instantiate_value_path on {:?}", res),
5509 let mut user_self_ty = None;
5510 let mut is_alias_variant_ctor = false;
5512 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5513 if let Some(self_ty) = self_ty {
5514 let adt_def = self_ty.ty_adt_def().unwrap();
5515 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5516 is_alias_variant_ctor = true;
5519 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5520 let container = tcx.associated_item(def_id).container;
5521 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5523 ty::TraitContainer(trait_did) => {
5524 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5526 ty::ImplContainer(impl_def_id) => {
5527 if segments.len() == 1 {
5528 // `<T>::assoc` will end up here, and so
5529 // can `T::assoc`. It this came from an
5530 // inherent impl, we need to record the
5531 // `T` for posterity (see `UserSelfTy` for
5533 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5534 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5542 // Now that we have categorized what space the parameters for each
5543 // segment belong to, let's sort out the parameters that the user
5544 // provided (if any) into their appropriate spaces. We'll also report
5545 // errors if type parameters are provided in an inappropriate place.
5547 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5548 let generics_has_err = AstConv::prohibit_generics(
5550 segments.iter().enumerate().filter_map(|(index, seg)| {
5551 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5559 if let Res::Local(hid) = res {
5560 let ty = self.local_ty(span, hid).decl_ty;
5561 let ty = self.normalize_associated_types_in(span, &ty);
5562 self.write_ty(hir_id, ty);
5566 if generics_has_err {
5567 // Don't try to infer type parameters when prohibited generic arguments were given.
5568 user_self_ty = None;
5571 // Now we have to compare the types that the user *actually*
5572 // provided against the types that were *expected*. If the user
5573 // did not provide any types, then we want to substitute inference
5574 // variables. If the user provided some types, we may still need
5575 // to add defaults. If the user provided *too many* types, that's
5578 let mut infer_args_for_err = FxHashSet::default();
5579 for &PathSeg(def_id, index) in &path_segs {
5580 let seg = &segments[index];
5581 let generics = tcx.generics_of(def_id);
5582 // Argument-position `impl Trait` is treated as a normal generic
5583 // parameter internally, but we don't allow users to specify the
5584 // parameter's value explicitly, so we have to do some error-
5586 if let GenericArgCountResult {
5587 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5589 } = AstConv::check_generic_arg_count_for_call(
5590 tcx, span, &generics, &seg, false, // `is_method_call`
5592 infer_args_for_err.insert(index);
5593 self.set_tainted_by_errors(); // See issue #53251.
5597 let has_self = path_segs
5599 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5602 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5603 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5605 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5606 let variant = adt_def.non_enum_variant();
5607 let ctor_def_id = variant.ctor_def_id.unwrap();
5609 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5614 let mut err = tcx.sess.struct_span_err(
5616 "the `Self` constructor can only be used with tuple or unit structs",
5618 if let Some(adt_def) = ty.ty_adt_def() {
5619 match adt_def.adt_kind() {
5621 err.help("did you mean to use one of the enum's variants?");
5623 AdtKind::Struct | AdtKind::Union => {
5624 err.span_suggestion(
5626 "use curly brackets",
5627 String::from("Self { /* fields */ }"),
5628 Applicability::HasPlaceholders,
5635 return (tcx.ty_error(), res);
5641 let def_id = res.def_id();
5643 // The things we are substituting into the type should not contain
5644 // escaping late-bound regions, and nor should the base type scheme.
5645 let ty = tcx.type_of(def_id);
5647 let arg_count = GenericArgCountResult {
5648 explicit_late_bound: ExplicitLateBound::No,
5649 correct: if infer_args_for_err.is_empty() {
5652 Err(GenericArgCountMismatch::default())
5656 let substs = self_ctor_substs.unwrap_or_else(|| {
5657 AstConv::create_substs_for_generic_args(
5664 // Provide the generic args, and whether types should be inferred.
5666 if let Some(&PathSeg(_, index)) =
5667 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5669 // If we've encountered an `impl Trait`-related error, we're just
5670 // going to infer the arguments for better error messages.
5671 if !infer_args_for_err.contains(&index) {
5672 // Check whether the user has provided generic arguments.
5673 if let Some(ref data) = segments[index].args {
5674 return (Some(data), segments[index].infer_args);
5677 return (None, segments[index].infer_args);
5682 // Provide substitutions for parameters for which (valid) arguments have been provided.
5683 |param, arg| match (¶m.kind, arg) {
5684 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5685 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5687 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5688 self.to_ty(ty).into()
5690 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5691 self.const_arg_to_const(&ct.value, param.def_id).into()
5693 _ => unreachable!(),
5695 // Provide substitutions for parameters for which arguments are inferred.
5696 |substs, param, infer_args| {
5698 GenericParamDefKind::Lifetime => {
5699 self.re_infer(Some(param), span).unwrap().into()
5701 GenericParamDefKind::Type { has_default, .. } => {
5702 if !infer_args && has_default {
5703 // If we have a default, then we it doesn't matter that we're not
5704 // inferring the type arguments: we provide the default where any
5706 let default = tcx.type_of(param.def_id);
5709 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5713 // If no type arguments were provided, we have to infer them.
5714 // This case also occurs as a result of some malformed input, e.g.
5715 // a lifetime argument being given instead of a type parameter.
5716 // Using inference instead of `Error` gives better error messages.
5717 self.var_for_def(span, param)
5720 GenericParamDefKind::Const => {
5721 // FIXME(const_generics:defaults)
5722 // No const parameters were provided, we have to infer them.
5723 self.var_for_def(span, param)
5729 assert!(!substs.has_escaping_bound_vars());
5730 assert!(!ty.has_escaping_bound_vars());
5732 // First, store the "user substs" for later.
5733 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5735 self.add_required_obligations(span, def_id, &substs);
5737 // Substitute the values for the type parameters into the type of
5738 // the referenced item.
5739 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5741 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5742 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5743 // is inherent, there is no `Self` parameter; instead, the impl needs
5744 // type parameters, which we can infer by unifying the provided `Self`
5745 // with the substituted impl type.
5746 // This also occurs for an enum variant on a type alias.
5747 let ty = tcx.type_of(impl_def_id);
5749 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5750 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5751 Ok(ok) => self.register_infer_ok_obligations(ok),
5753 self.tcx.sess.delay_span_bug(
5756 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5765 self.check_rustc_args_require_const(def_id, hir_id, span);
5767 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5768 self.write_substs(hir_id, substs);
5770 (ty_substituted, res)
5773 /// Add all the obligations that are required, substituting and normalized appropriately.
5774 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5775 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5777 for (i, mut obligation) in traits::predicates_for_generics(
5778 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5784 // This makes the error point at the bound, but we want to point at the argument
5785 if let Some(span) = spans.get(i) {
5786 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
5788 self.register_predicate(obligation);
5792 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5793 // We're only interested in functions tagged with
5794 // #[rustc_args_required_const], so ignore anything that's not.
5795 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5799 // If our calling expression is indeed the function itself, we're good!
5800 // If not, generate an error that this can only be called directly.
5801 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5802 if let ExprKind::Call(ref callee, ..) = expr.kind {
5803 if callee.hir_id == hir_id {
5809 self.tcx.sess.span_err(
5811 "this function can only be invoked directly, not through a function pointer",
5815 /// Resolves `typ` by a single level if `typ` is a type variable.
5816 /// If no resolution is possible, then an error is reported.
5817 /// Numeric inference variables may be left unresolved.
5818 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5819 let ty = self.resolve_vars_with_obligations(ty);
5820 if !ty.is_ty_var() {
5823 if !self.is_tainted_by_errors() {
5824 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5825 .note("type must be known at this point")
5828 let err = self.tcx.ty_error();
5829 self.demand_suptype(sp, err, ty);
5834 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5837 ctxt: BreakableCtxt<'tcx>,
5839 ) -> (BreakableCtxt<'tcx>, R) {
5842 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5843 index = enclosing_breakables.stack.len();
5844 enclosing_breakables.by_id.insert(id, index);
5845 enclosing_breakables.stack.push(ctxt);
5849 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5850 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5851 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5852 enclosing_breakables.stack.pop().expect("missing breakable context")
5857 /// Instantiate a QueryResponse in a probe context, without a
5858 /// good ObligationCause.
5859 fn probe_instantiate_query_response(
5862 original_values: &OriginalQueryValues<'tcx>,
5863 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5864 ) -> InferResult<'tcx, Ty<'tcx>> {
5865 self.instantiate_query_response_and_region_obligations(
5866 &traits::ObligationCause::misc(span, self.body_id),
5873 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5874 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5875 let mut contained_in_place = false;
5877 while let hir::Node::Expr(parent_expr) =
5878 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5880 match &parent_expr.kind {
5881 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5882 if lhs.hir_id == expr_id {
5883 contained_in_place = true;
5889 expr_id = parent_expr.hir_id;
5896 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5897 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5899 assert_eq!(generics.parent, None);
5901 if generics.own_counts().types == 0 {
5905 let mut params_used = BitSet::new_empty(generics.params.len());
5907 if ty.references_error() {
5908 // If there is already another error, do not emit
5909 // an error for not using a type parameter.
5910 assert!(tcx.sess.has_errors());
5914 for leaf in ty.walk() {
5915 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5916 if let ty::Param(param) = leaf_ty.kind {
5917 debug!("found use of ty param {:?}", param);
5918 params_used.insert(param.index);
5923 for param in &generics.params {
5924 if !params_used.contains(param.index) {
5925 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5926 let span = tcx.def_span(param.def_id);
5931 "type parameter `{}` is unused",
5934 .span_label(span, "unused type parameter")
5941 fn fatally_break_rust(sess: &Session) {
5942 let handler = sess.diagnostic();
5943 handler.span_bug_no_panic(
5945 "It looks like you're trying to break rust; would you like some ICE?",
5947 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5948 handler.note_without_error(
5949 "we would appreciate a joke overview: \
5950 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5952 handler.note_without_error(&format!(
5953 "rustc {} running on {}",
5954 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5955 config::host_triple(),
5959 fn potentially_plural_count(count: usize, word: &str) -> String {
5960 format!("{} {}{}", count, word, pluralize!(count))