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 // TODO: forall (we could keep the current behavior and just skip binders eagerly,
2404 // not sure if we want to though)
2405 match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
2406 ty::PredicateKind::Trait(trait_predicate, _) => {
2407 let entry = types.entry(trait_predicate.self_ty()).or_default();
2408 let def_id = trait_predicate.def_id();
2409 if Some(def_id) != tcx.lang_items().sized_trait() {
2410 // Type params are `Sized` by default, do not add that restriction to the list
2411 // if it is a positive requirement.
2412 entry.push(trait_predicate.def_id());
2415 ty::PredicateKind::Projection(projection_pred) => {
2416 projections.push(ty::Binder::bind(projection_pred));
2421 let generics = if types.is_empty() {
2428 .filter_map(|t| match t.kind {
2429 ty::Param(_) => Some(t.to_string()),
2430 // Avoid suggesting the following:
2431 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2434 .collect::<Vec<_>>()
2438 let mut where_clauses = vec![];
2439 for (ty, bounds) in types {
2440 for bound in &bounds {
2441 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2444 for projection in &projections {
2445 let p = projection.skip_binder();
2446 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2447 // insert the associated types where they correspond, but for now let's be "lazy" and
2448 // propose this instead of the following valid resugaring:
2449 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2450 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2452 let where_clauses = if where_clauses.is_empty() {
2455 format!(" where {}", where_clauses.join(", "))
2457 (generics, where_clauses)
2460 /// Return placeholder code for the given function.
2461 fn fn_sig_suggestion<'tcx>(
2463 sig: ty::FnSig<'tcx>,
2465 predicates: ty::GenericPredicates<'tcx>,
2466 assoc: &ty::AssocItem,
2473 Some(match ty.kind {
2474 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
2475 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
2476 let reg = match &format!("{}", reg)[..] {
2477 "'_" | "" => String::new(),
2478 reg => format!("{} ", reg),
2480 if assoc.fn_has_self_parameter {
2482 ty::Param(param) if param.name == kw::SelfUpper => {
2483 format!("&{}{}self", reg, mutability.prefix_str())
2486 _ => format!("self: {}", ty),
2489 format!("_: {:?}", ty)
2493 if assoc.fn_has_self_parameter && i == 0 {
2494 format!("self: {:?}", ty)
2496 format!("_: {:?}", ty)
2501 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2502 .filter_map(|arg| arg)
2503 .collect::<Vec<String>>()
2505 let output = sig.output();
2506 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2508 let unsafety = sig.unsafety.prefix_str();
2509 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2511 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2512 // not be present in the `fn` definition, not will we account for renamed
2513 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2514 // fill in a significant portion of the missing code, and other subsequent
2515 // suggestions can help the user fix the code.
2517 "{}fn {}{}({}){}{} {{ todo!() }}",
2518 unsafety, ident, generics, args, output, where_clauses
2522 /// Return placeholder code for the given associated item.
2523 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2524 /// structured suggestion.
2525 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2527 ty::AssocKind::Fn => {
2528 // We skip the binder here because the binder would deanonymize all
2529 // late-bound regions, and we don't want method signatures to show up
2530 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2531 // regions just fine, showing `fn(&MyType)`.
2534 tcx.fn_sig(assoc.def_id).skip_binder(),
2536 tcx.predicates_of(assoc.def_id),
2540 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2541 ty::AssocKind::Const => {
2542 let ty = tcx.type_of(assoc.def_id);
2543 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2544 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2549 /// Checks whether a type can be represented in memory. In particular, it
2550 /// identifies types that contain themselves without indirection through a
2551 /// pointer, which would mean their size is unbounded.
2552 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
2553 let rty = tcx.type_of(item_def_id);
2555 // Check that it is possible to represent this type. This call identifies
2556 // (1) types that contain themselves and (2) types that contain a different
2557 // recursive type. It is only necessary to throw an error on those that
2558 // contain themselves. For case 2, there must be an inner type that will be
2559 // caught by case 1.
2560 match rty.is_representable(tcx, sp) {
2561 Representability::SelfRecursive(spans) => {
2562 recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
2565 Representability::Representable | Representability::ContainsRecursive => (),
2570 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
2571 let t = tcx.type_of(def_id);
2572 if let ty::Adt(def, substs) = t.kind {
2573 if def.is_struct() {
2574 let fields = &def.non_enum_variant().fields;
2575 if fields.is_empty() {
2576 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2579 let e = fields[0].ty(tcx, substs);
2580 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2581 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2582 .span_label(sp, "SIMD elements must have the same type")
2587 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2588 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2594 "SIMD vector element type should be machine type"
2604 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
2605 let repr = def.repr;
2607 for attr in tcx.get_attrs(def.did).iter() {
2608 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2609 if let attr::ReprPacked(pack) = r {
2610 if let Some(repr_pack) = repr.pack {
2611 if pack as u64 != repr_pack.bytes() {
2616 "type has conflicting packed representation hints"
2624 if repr.align.is_some() {
2629 "type has conflicting packed and align representation hints"
2633 if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
2634 let mut err = struct_span_err!(
2638 "packed type cannot transitively contain a `#[repr(align)]` type"
2642 tcx.def_span(def_spans[0].0),
2644 "`{}` has a `#[repr(align)]` attribute",
2645 tcx.item_name(def_spans[0].0)
2649 if def_spans.len() > 2 {
2650 let mut first = true;
2651 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2652 let ident = tcx.item_name(*adt_def);
2657 "`{}` contains a field of type `{}`",
2658 tcx.type_of(def.did),
2662 format!("...which contains a field of type `{}`", ident)
2675 fn check_packed_inner(
2678 stack: &mut Vec<DefId>,
2679 ) -> Option<Vec<(DefId, Span)>> {
2680 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2681 if def.is_struct() || def.is_union() {
2682 if def.repr.align.is_some() {
2683 return Some(vec![(def.did, DUMMY_SP)]);
2687 for field in &def.non_enum_variant().fields {
2688 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2689 if !stack.contains(&def.did) {
2690 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2691 defs.push((def.did, field.ident.span));
2704 /// Emit an error when encountering more or less than one variant in a transparent enum.
2705 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2706 let variant_spans: Vec<_> = adt
2709 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2711 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2712 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2713 err.span_label(sp, &msg);
2714 if let [start @ .., end] = &*variant_spans {
2715 for variant_span in start {
2716 err.span_label(*variant_span, "");
2718 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2723 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2725 fn bad_non_zero_sized_fields<'tcx>(
2727 adt: &'tcx ty::AdtDef,
2729 field_spans: impl Iterator<Item = Span>,
2732 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2733 let mut err = struct_span_err!(
2737 "{}transparent {} {}",
2738 if adt.is_enum() { "the variant of a " } else { "" },
2742 err.span_label(sp, &msg);
2743 for sp in field_spans {
2744 err.span_label(sp, "this field is non-zero-sized");
2749 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
2750 if !adt.repr.transparent() {
2753 let sp = tcx.sess.source_map().guess_head_span(sp);
2755 if adt.is_union() && !tcx.features().transparent_unions {
2757 &tcx.sess.parse_sess,
2758 sym::transparent_unions,
2760 "transparent unions are unstable",
2765 if adt.variants.len() != 1 {
2766 bad_variant_count(tcx, adt, sp, adt.did);
2767 if adt.variants.is_empty() {
2768 // Don't bother checking the fields. No variants (and thus no fields) exist.
2773 // For each field, figure out if it's known to be a ZST and align(1)
2774 let field_infos = adt.all_fields().map(|field| {
2775 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2776 let param_env = tcx.param_env(field.did);
2777 let layout = tcx.layout_of(param_env.and(ty));
2778 // We are currently checking the type this field came from, so it must be local
2779 let span = tcx.hir().span_if_local(field.did).unwrap();
2780 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2781 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2785 let non_zst_fields =
2786 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2787 let non_zst_count = non_zst_fields.clone().count();
2788 if non_zst_count != 1 {
2789 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2791 for (span, zst, align1) in field_infos {
2797 "zero-sized field in transparent {} has alignment larger than 1",
2800 .span_label(span, "has alignment larger than 1")
2806 #[allow(trivial_numeric_casts)]
2807 pub fn check_enum<'tcx>(
2810 vs: &'tcx [hir::Variant<'tcx>],
2813 let def_id = tcx.hir().local_def_id(id);
2814 let def = tcx.adt_def(def_id);
2815 def.destructor(tcx); // force the destructor to be evaluated
2818 let attributes = tcx.get_attrs(def_id.to_def_id());
2819 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2824 "unsupported representation for zero-variant enum"
2826 .span_label(sp, "zero-variant enum")
2831 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2832 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2833 if !tcx.features().repr128 {
2835 &tcx.sess.parse_sess,
2838 "repr with 128-bit type is unstable",
2845 if let Some(ref e) = v.disr_expr {
2846 tcx.ensure().typeck(tcx.hir().local_def_id(e.hir_id));
2850 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2851 let is_unit = |var: &hir::Variant<'_>| match var.data {
2852 hir::VariantData::Unit(..) => true,
2856 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2857 let has_non_units = vs.iter().any(|var| !is_unit(var));
2858 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2859 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2861 if disr_non_unit || (disr_units && has_non_units) {
2863 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2868 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2869 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2870 // Check for duplicate discriminant values
2871 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2872 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2873 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did.expect_local());
2874 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2875 let i_span = match variant_i.disr_expr {
2876 Some(ref expr) => tcx.hir().span(expr.hir_id),
2877 None => tcx.hir().span(variant_i_hir_id),
2879 let span = match v.disr_expr {
2880 Some(ref expr) => tcx.hir().span(expr.hir_id),
2887 "discriminant value `{}` already exists",
2890 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2891 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2894 disr_vals.push(discr);
2897 check_representable(tcx, sp, def_id);
2898 check_transparent(tcx, sp, def);
2901 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
2906 "expected unit struct, unit variant or constant, found {}{}",
2908 tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)),
2913 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2914 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2918 fn item_def_id(&self) -> Option<DefId> {
2922 fn default_constness_for_trait_bounds(&self) -> hir::Constness {
2923 // FIXME: refactor this into a method
2924 let node = self.tcx.hir().get(self.body_id);
2925 if let Some(fn_like) = FnLikeNode::from_node(node) {
2928 hir::Constness::NotConst
2932 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2934 let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
2935 let item_id = tcx.hir().ty_param_owner(hir_id);
2936 let item_def_id = tcx.hir().local_def_id(item_id);
2937 let generics = tcx.generics_of(item_def_id);
2938 let index = generics.param_def_id_to_index[&def_id];
2939 ty::GenericPredicates {
2941 predicates: tcx.arena.alloc_from_iter(
2942 self.param_env.caller_bounds().iter().filter_map(|predicate| {
2943 match predicate.kind() {
2944 ty::PredicateKind::Trait(ref data, _)
2945 if data.skip_binder().self_ty().is_param(index) =>
2947 // HACK(eddyb) should get the original `Span`.
2948 let span = tcx.def_span(def_id);
2949 Some((predicate, span))
2958 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2960 Some(def) => infer::EarlyBoundRegion(span, def.name),
2961 None => infer::MiscVariable(span),
2963 Some(self.next_region_var(v))
2966 fn allow_ty_infer(&self) -> bool {
2970 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2971 if let Some(param) = param {
2972 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2977 self.next_ty_var(TypeVariableOrigin {
2978 kind: TypeVariableOriginKind::TypeInference,
2987 param: Option<&ty::GenericParamDef>,
2989 ) -> &'tcx Const<'tcx> {
2990 if let Some(param) = param {
2991 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2996 self.next_const_var(
2998 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
3003 fn projected_ty_from_poly_trait_ref(
3007 item_segment: &hir::PathSegment<'_>,
3008 poly_trait_ref: ty::PolyTraitRef<'tcx>,
3010 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
3012 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
3016 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
3025 self.tcx().mk_projection(item_def_id, item_substs)
3028 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
3029 if ty.has_escaping_bound_vars() {
3030 ty // FIXME: normalization and escaping regions
3032 self.normalize_associated_types_in(span, &ty)
3036 fn set_tainted_by_errors(&self) {
3037 self.infcx.set_tainted_by_errors()
3040 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
3041 self.write_ty(hir_id, ty)
3045 /// Controls whether the arguments are tupled. This is used for the call
3048 /// Tupling means that all call-side arguments are packed into a tuple and
3049 /// passed as a single parameter. For example, if tupling is enabled, this
3052 /// fn f(x: (isize, isize))
3054 /// Can be called as:
3061 #[derive(Clone, Eq, PartialEq)]
3062 enum TupleArgumentsFlag {
3067 /// Controls how we perform fallback for unconstrained
3070 /// Do not fallback type variables to opaque types.
3072 /// Perform all possible kinds of fallback, including
3073 /// turning type variables to opaque types.
3077 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3079 inh: &'a Inherited<'a, 'tcx>,
3080 param_env: ty::ParamEnv<'tcx>,
3081 body_id: hir::HirId,
3082 ) -> FnCtxt<'a, 'tcx> {
3086 err_count_on_creation: inh.tcx.sess.err_count(),
3088 ret_coercion_span: RefCell::new(None),
3089 resume_yield_tys: None,
3090 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
3091 diverges: Cell::new(Diverges::Maybe),
3092 has_errors: Cell::new(false),
3093 enclosing_breakables: RefCell::new(EnclosingBreakables {
3095 by_id: Default::default(),
3101 pub fn sess(&self) -> &Session {
3105 pub fn errors_reported_since_creation(&self) -> bool {
3106 self.tcx.sess.err_count() > self.err_count_on_creation
3109 /// Produces warning on the given node, if the current point in the
3110 /// function is unreachable, and there hasn't been another warning.
3111 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
3112 // FIXME: Combine these two 'if' expressions into one once
3113 // let chains are implemented
3114 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
3115 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
3116 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
3117 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
3118 if !span.is_desugaring(DesugaringKind::CondTemporary)
3119 && !span.is_desugaring(DesugaringKind::Async)
3120 && !orig_span.is_desugaring(DesugaringKind::Await)
3122 self.diverges.set(Diverges::WarnedAlways);
3124 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
3126 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
3127 let msg = format!("unreachable {}", kind);
3129 .span_label(span, &msg)
3133 .unwrap_or("any code following this expression is unreachable"),
3141 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
3142 ObligationCause::new(span, self.body_id, code)
3145 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
3146 self.cause(span, ObligationCauseCode::MiscObligation)
3149 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
3150 /// version (resolve_vars_if_possible), this version will
3151 /// also select obligations if it seems useful, in an effort
3152 /// to get more type information.
3153 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3154 debug!("resolve_vars_with_obligations(ty={:?})", ty);
3156 // No Infer()? Nothing needs doing.
3157 if !ty.has_infer_types_or_consts() {
3158 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3162 // If `ty` is a type variable, see whether we already know what it is.
3163 ty = self.resolve_vars_if_possible(&ty);
3164 if !ty.has_infer_types_or_consts() {
3165 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3169 // If not, try resolving pending obligations as much as
3170 // possible. This can help substantially when there are
3171 // indirect dependencies that don't seem worth tracking
3173 self.select_obligations_where_possible(false, |_| {});
3174 ty = self.resolve_vars_if_possible(&ty);
3176 debug!("resolve_vars_with_obligations: ty={:?}", ty);
3180 fn record_deferred_call_resolution(
3182 closure_def_id: DefId,
3183 r: DeferredCallResolution<'tcx>,
3185 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3186 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
3189 fn remove_deferred_call_resolutions(
3191 closure_def_id: DefId,
3192 ) -> Vec<DeferredCallResolution<'tcx>> {
3193 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
3194 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
3197 pub fn tag(&self) -> String {
3198 format!("{:p}", self)
3201 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
3202 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
3203 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
3208 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
3210 "write_ty({:?}, {:?}) in fcx {}",
3212 self.resolve_vars_if_possible(&ty),
3215 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
3217 if ty.references_error() {
3218 self.has_errors.set(true);
3219 self.set_tainted_by_errors();
3223 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
3224 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
3227 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
3228 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
3231 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
3232 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
3233 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
3234 self.write_substs(hir_id, method.substs);
3236 // When the method is confirmed, the `method.substs` includes
3237 // parameters from not just the method, but also the impl of
3238 // the method -- in particular, the `Self` type will be fully
3239 // resolved. However, those are not something that the "user
3240 // specified" -- i.e., those types come from the inferred type
3241 // of the receiver, not something the user wrote. So when we
3242 // create the user-substs, we want to replace those earlier
3243 // types with just the types that the user actually wrote --
3244 // that is, those that appear on the *method itself*.
3246 // As an example, if the user wrote something like
3247 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3248 // type of `foo` (possibly adjusted), but we don't want to
3249 // include that. We want just the `[_, u32]` part.
3250 if !method.substs.is_noop() {
3251 let method_generics = self.tcx.generics_of(method.def_id);
3252 if !method_generics.params.is_empty() {
3253 let user_type_annotation = self.infcx.probe(|_| {
3254 let user_substs = UserSubsts {
3255 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3256 let i = param.index as usize;
3257 if i < method_generics.parent_count {
3258 self.infcx.var_for_def(DUMMY_SP, param)
3263 user_self_ty: None, // not relevant here
3266 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3272 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3273 self.write_user_type_annotation(hir_id, user_type_annotation);
3278 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3279 if !substs.is_noop() {
3280 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3282 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
3286 /// Given the substs that we just converted from the HIR, try to
3287 /// canonicalize them and store them as user-given substitutions
3288 /// (i.e., substitutions that must be respected by the NLL check).
3290 /// This should be invoked **before any unifications have
3291 /// occurred**, so that annotations like `Vec<_>` are preserved
3293 pub fn write_user_type_annotation_from_substs(
3297 substs: SubstsRef<'tcx>,
3298 user_self_ty: Option<UserSelfTy<'tcx>>,
3301 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3302 user_self_ty={:?} in fcx {}",
3310 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3311 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3313 UserSubsts { substs, user_self_ty },
3315 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3316 self.write_user_type_annotation(hir_id, canonicalized);
3320 pub fn write_user_type_annotation(
3323 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3326 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3328 canonical_user_type_annotation,
3332 if !canonical_user_type_annotation.is_identity() {
3335 .user_provided_types_mut()
3336 .insert(hir_id, canonical_user_type_annotation);
3338 debug!("write_user_type_annotation: skipping identity substs");
3342 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3343 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3349 let autoborrow_mut = adj.iter().any(|adj| {
3350 matches!(adj, &Adjustment {
3351 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
3356 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3357 Entry::Vacant(entry) => {
3360 Entry::Occupied(mut entry) => {
3361 debug!(" - composing on top of {:?}", entry.get());
3362 match (&entry.get()[..], &adj[..]) {
3363 // Applying any adjustment on top of a NeverToAny
3364 // is a valid NeverToAny adjustment, because it can't
3366 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3368 Adjustment { kind: Adjust::Deref(_), .. },
3369 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3371 Adjustment { kind: Adjust::Deref(_), .. },
3372 .. // Any following adjustments are allowed.
3374 // A reborrow has no effect before a dereference.
3376 // FIXME: currently we never try to compose autoderefs
3377 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3379 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3380 expr, entry.get(), adj)
3382 *entry.get_mut() = adj;
3386 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
3387 // In this case implicit use of `Deref` and `Index` within `<expr>` should
3388 // instead be `DerefMut` and `IndexMut`, so fix those up.
3390 self.convert_place_derefs_to_mutable(expr);
3394 /// Basically whenever we are converting from a type scheme into
3395 /// the fn body space, we always want to normalize associated
3396 /// types as well. This function combines the two.
3397 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3399 T: TypeFoldable<'tcx>,
3401 let value = value.subst(self.tcx, substs);
3402 let result = self.normalize_associated_types_in(span, &value);
3403 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3407 /// As `instantiate_type_scheme`, but for the bounds found in a
3408 /// generic type scheme.
3409 fn instantiate_bounds(
3413 substs: SubstsRef<'tcx>,
3414 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3415 let bounds = self.tcx.predicates_of(def_id);
3416 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3417 let result = bounds.instantiate(self.tcx, substs);
3418 let result = self.normalize_associated_types_in(span, &result);
3420 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3421 bounds, substs, result, spans,
3426 /// Replaces the opaque types from the given value with type variables,
3427 /// and records the `OpaqueTypeMap` for later use during writeback. See
3428 /// `InferCtxt::instantiate_opaque_types` for more details.
3429 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3431 parent_id: hir::HirId,
3435 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3437 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3438 parent_def_id, value
3441 let (value, opaque_type_map) =
3442 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3450 let mut opaque_types = self.opaque_types.borrow_mut();
3451 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3452 for (ty, decl) in opaque_type_map {
3453 let _ = opaque_types.insert(ty, decl);
3454 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3460 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3462 T: TypeFoldable<'tcx>,
3464 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3467 fn normalize_associated_types_in_as_infer_ok<T>(
3471 ) -> InferOk<'tcx, T>
3473 T: TypeFoldable<'tcx>,
3475 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3478 pub fn require_type_meets(
3482 code: traits::ObligationCauseCode<'tcx>,
3485 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3488 pub fn require_type_is_sized(
3492 code: traits::ObligationCauseCode<'tcx>,
3494 if !ty.references_error() {
3495 let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None);
3496 self.require_type_meets(ty, span, code, lang_item);
3500 pub fn require_type_is_sized_deferred(
3504 code: traits::ObligationCauseCode<'tcx>,
3506 if !ty.references_error() {
3507 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3511 pub fn register_bound(
3515 cause: traits::ObligationCause<'tcx>,
3517 if !ty.references_error() {
3518 self.fulfillment_cx.borrow_mut().register_bound(
3528 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3529 let t = AstConv::ast_ty_to_ty(self, ast_t);
3530 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
3534 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3535 let ty = self.to_ty(ast_ty);
3536 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3538 if Self::can_contain_user_lifetime_bounds(ty) {
3539 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3540 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3541 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3547 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
3548 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
3549 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
3550 self.register_wf_obligation(
3552 self.tcx.hir().span(ast_c.hir_id),
3553 ObligationCauseCode::MiscObligation,
3558 pub fn const_arg_to_const(
3560 ast_c: &hir::AnonConst,
3561 param_def_id: DefId,
3562 ) -> &'tcx ty::Const<'tcx> {
3563 let const_def = ty::WithOptConstParam {
3564 did: self.tcx.hir().local_def_id(ast_c.hir_id),
3565 const_param_did: Some(param_def_id),
3567 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
3568 self.register_wf_obligation(
3570 self.tcx.hir().span(ast_c.hir_id),
3571 ObligationCauseCode::MiscObligation,
3576 // If the type given by the user has free regions, save it for later, since
3577 // NLL would like to enforce those. Also pass in types that involve
3578 // projections, since those can resolve to `'static` bounds (modulo #54940,
3579 // which hopefully will be fixed by the time you see this comment, dear
3580 // reader, although I have my doubts). Also pass in types with inference
3581 // types, because they may be repeated. Other sorts of things are already
3582 // sufficiently enforced with erased regions. =)
3583 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3585 T: TypeFoldable<'tcx>,
3587 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3590 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3591 match self.typeck_results.borrow().node_types().get(id) {
3593 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
3596 "no type for node {}: {} in fcx {}",
3598 self.tcx.hir().node_to_string(id),
3605 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
3606 pub fn register_wf_obligation(
3608 arg: subst::GenericArg<'tcx>,
3610 code: traits::ObligationCauseCode<'tcx>,
3612 // WF obligations never themselves fail, so no real need to give a detailed cause:
3613 let cause = traits::ObligationCause::new(span, self.body_id, code);
3614 self.register_predicate(traits::Obligation::new(
3617 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
3621 /// Registers obligations that all `substs` are well-formed.
3622 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3623 for arg in substs.iter().filter(|arg| {
3624 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
3626 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
3630 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3631 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3632 /// trait/region obligations.
3634 /// For example, if there is a function:
3637 /// fn foo<'a,T:'a>(...)
3640 /// and a reference:
3646 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3647 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3648 pub fn add_obligations_for_parameters(
3650 cause: traits::ObligationCause<'tcx>,
3651 predicates: ty::InstantiatedPredicates<'tcx>,
3653 assert!(!predicates.has_escaping_bound_vars());
3655 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3657 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3658 self.register_predicate(obligation);
3662 // FIXME(arielb1): use this instead of field.ty everywhere
3663 // Only for fields! Returns <none> for methods>
3664 // Indifferent to privacy flags
3668 field: &'tcx ty::FieldDef,
3669 substs: SubstsRef<'tcx>,
3671 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3674 fn check_casts(&self) {
3675 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3676 for cast in deferred_cast_checks.drain(..) {
3681 fn resolve_generator_interiors(&self, def_id: DefId) {
3682 let mut generators = self.deferred_generator_interiors.borrow_mut();
3683 for (body_id, interior, kind) in generators.drain(..) {
3684 self.select_obligations_where_possible(false, |_| {});
3685 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3689 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3691 // - Unconstrained ints are replaced with `i32`.
3693 // - Unconstrained floats are replaced with with `f64`.
3695 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3696 // is enabled. Otherwise, they are replaced with `()`.
3698 // Fallback becomes very dubious if we have encountered type-checking errors.
3699 // In that case, fallback to Error.
3700 // The return value indicates whether fallback has occurred.
3701 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3702 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
3703 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3705 assert!(ty.is_ty_infer());
3706 let fallback = match self.type_is_unconstrained_numeric(ty) {
3707 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
3708 UnconstrainedInt => self.tcx.types.i32,
3709 UnconstrainedFloat => self.tcx.types.f64,
3710 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3712 // This type variable was created from the instantiation of an opaque
3713 // type. The fact that we're attempting to perform fallback for it
3714 // means that the function neither constrained it to a concrete
3715 // type, nor to the opaque type itself.
3717 // For example, in this code:
3720 // type MyType = impl Copy;
3721 // fn defining_use() -> MyType { true }
3722 // fn other_use() -> MyType { defining_use() }
3725 // `defining_use` will constrain the instantiated inference
3726 // variable to `bool`, while `other_use` will constrain
3727 // the instantiated inference variable to `MyType`.
3729 // When we process opaque types during writeback, we
3730 // will handle cases like `other_use`, and not count
3731 // them as defining usages
3733 // However, we also need to handle cases like this:
3736 // pub type Foo = impl Copy;
3737 // fn produce() -> Option<Foo> {
3742 // In the above snippet, the inference variable created by
3743 // instantiating `Option<Foo>` will be completely unconstrained.
3744 // We treat this as a non-defining use by making the inference
3745 // variable fall back to the opaque type itself.
3746 if let FallbackMode::All = mode {
3747 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3749 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3761 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3762 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3766 fn select_all_obligations_or_error(&self) {
3767 debug!("select_all_obligations_or_error");
3768 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3769 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3773 /// Select as many obligations as we can at present.
3774 fn select_obligations_where_possible(
3776 fallback_has_occurred: bool,
3777 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3779 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3780 if let Err(mut errors) = result {
3781 mutate_fullfillment_errors(&mut errors);
3782 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3786 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3787 /// returns a type of `&T`, but the actual type we assign to the
3788 /// *expression* is `T`. So this function just peels off the return
3789 /// type by one layer to yield `T`.
3790 fn make_overloaded_place_return_type(
3792 method: MethodCallee<'tcx>,
3793 ) -> ty::TypeAndMut<'tcx> {
3794 // extract method return type, which will be &T;
3795 let ret_ty = method.sig.output();
3797 // method returns &T, but the type as visible to user is T, so deref
3798 ret_ty.builtin_deref(true).unwrap()
3801 fn check_method_argument_types(
3804 expr: &'tcx hir::Expr<'tcx>,
3805 method: Result<MethodCallee<'tcx>, ()>,
3806 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3807 tuple_arguments: TupleArgumentsFlag,
3808 expected: Expectation<'tcx>,
3810 let has_error = match method {
3811 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3815 let err_inputs = self.err_args(args_no_rcvr.len());
3817 let err_inputs = match tuple_arguments {
3818 DontTupleArguments => err_inputs,
3819 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3822 self.check_argument_types(
3832 return self.tcx.ty_error();
3835 let method = method.unwrap();
3836 // HACK(eddyb) ignore self in the definition (see above).
3837 let expected_arg_tys = self.expected_inputs_for_expected_output(
3840 method.sig.output(),
3841 &method.sig.inputs()[1..],
3843 self.check_argument_types(
3846 &method.sig.inputs()[1..],
3847 &expected_arg_tys[..],
3849 method.sig.c_variadic,
3851 self.tcx.hir().span_if_local(method.def_id),
3856 fn self_type_matches_expected_vid(
3858 trait_ref: ty::PolyTraitRef<'tcx>,
3859 expected_vid: ty::TyVid,
3861 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
3863 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3864 trait_ref, self_ty, expected_vid
3866 match self_ty.kind {
3867 ty::Infer(ty::TyVar(found_vid)) => {
3868 // FIXME: consider using `sub_root_var` here so we
3869 // can see through subtyping.
3870 let found_vid = self.root_var(found_vid);
3871 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3872 expected_vid == found_vid
3878 fn obligations_for_self_ty<'b>(
3881 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3884 // FIXME: consider using `sub_root_var` here so we
3885 // can see through subtyping.
3886 let ty_var_root = self.root_var(self_ty);
3888 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3891 self.fulfillment_cx.borrow().pending_obligations()
3896 .pending_obligations()
3899 .filter_map(move |obligation| {
3900 match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
3901 ty::PredicateKind::ForAll(_) => {
3902 bug!("unexpected predicate: {:?}", obligation.predicate)
3904 &ty::PredicateKind::Projection(data) => {
3905 Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation))
3907 &ty::PredicateKind::Trait(data, _) => {
3908 Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation))
3910 ty::PredicateKind::Subtype(..) => None,
3911 ty::PredicateKind::RegionOutlives(..) => None,
3912 ty::PredicateKind::TypeOutlives(..) => None,
3913 ty::PredicateKind::WellFormed(..) => None,
3914 ty::PredicateKind::ObjectSafe(..) => None,
3915 ty::PredicateKind::ConstEvaluatable(..) => None,
3916 ty::PredicateKind::ConstEquate(..) => None,
3917 // N.B., this predicate is created by breaking down a
3918 // `ClosureType: FnFoo()` predicate, where
3919 // `ClosureType` represents some `Closure`. It can't
3920 // possibly be referring to the current closure,
3921 // because we haven't produced the `Closure` for
3922 // this closure yet; this is exactly why the other
3923 // code is looking for a self type of a unresolved
3924 // inference variable.
3925 ty::PredicateKind::ClosureKind(..) => None,
3928 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3931 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3932 self.obligations_for_self_ty(self_ty)
3933 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3936 /// Generic function that factors out common logic from function calls,
3937 /// method calls and overloaded operators.
3938 fn check_argument_types(
3941 expr: &'tcx hir::Expr<'tcx>,
3942 fn_inputs: &[Ty<'tcx>],
3943 expected_arg_tys: &[Ty<'tcx>],
3944 args: &'tcx [hir::Expr<'tcx>],
3946 tuple_arguments: TupleArgumentsFlag,
3947 def_span: Option<Span>,
3950 // Grab the argument types, supplying fresh type variables
3951 // if the wrong number of arguments were supplied
3952 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3954 // All the input types from the fn signature must outlive the call
3955 // so as to validate implied bounds.
3956 for (&fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3957 self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
3960 let expected_arg_count = fn_inputs.len();
3962 let param_count_error = |expected_count: usize,
3967 let (span, start_span, args) = match &expr.kind {
3968 hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
3969 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
3971 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
3974 .and_then(|args| args.args.iter().last())
3975 // Account for `foo.bar::<T>()`.
3977 // Skip the closing `>`.
3980 .next_point(tcx.sess.source_map().next_point(arg.span()))
3983 &args[1..], // Skip the receiver.
3985 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
3987 let arg_spans = if args.is_empty() {
3989 // ^^^-- supplied 0 arguments
3991 // expected 2 arguments
3992 vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
3995 // ^^^ - - - supplied 3 arguments
3997 // expected 2 arguments
3998 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
4001 let mut err = tcx.sess.struct_span_err_with_code(
4004 "this function takes {}{} but {} {} supplied",
4005 if c_variadic { "at least " } else { "" },
4006 potentially_plural_count(expected_count, "argument"),
4007 potentially_plural_count(arg_count, "argument"),
4008 if arg_count == 1 { "was" } else { "were" }
4010 DiagnosticId::Error(error_code.to_owned()),
4012 let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
4013 for (i, span) in arg_spans.into_iter().enumerate() {
4016 if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
4020 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().guess_head_span(sp)) {
4021 err.span_label(def_s, "defined here");
4024 let sugg_span = tcx.sess.source_map().end_point(expr.span);
4025 // remove closing `)` from the span
4026 let sugg_span = sugg_span.shrink_to_lo();
4027 err.span_suggestion(
4029 "expected the unit value `()`; create it with empty parentheses",
4031 Applicability::MachineApplicable,
4038 if c_variadic { "at least " } else { "" },
4039 potentially_plural_count(expected_count, "argument")
4046 let mut expected_arg_tys = expected_arg_tys.to_vec();
4048 let formal_tys = if tuple_arguments == TupleArguments {
4049 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
4050 match tuple_type.kind {
4051 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
4052 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
4053 expected_arg_tys = vec![];
4054 self.err_args(args.len())
4056 ty::Tuple(arg_types) => {
4057 expected_arg_tys = match expected_arg_tys.get(0) {
4058 Some(&ty) => match ty.kind {
4059 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
4064 arg_types.iter().map(|k| k.expect_ty()).collect()
4071 "cannot use call notation; the first type parameter \
4072 for the function trait is neither a tuple nor unit"
4075 expected_arg_tys = vec![];
4076 self.err_args(args.len())
4079 } else if expected_arg_count == supplied_arg_count {
4081 } else if c_variadic {
4082 if supplied_arg_count >= expected_arg_count {
4085 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
4086 expected_arg_tys = vec![];
4087 self.err_args(supplied_arg_count)
4090 // is the missing argument of type `()`?
4091 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
4092 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
4093 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
4094 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
4098 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
4100 expected_arg_tys = vec![];
4101 self.err_args(supplied_arg_count)
4105 "check_argument_types: formal_tys={:?}",
4106 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
4109 // If there is no expectation, expect formal_tys.
4110 let expected_arg_tys =
4111 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
4113 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
4115 // Check the arguments.
4116 // We do this in a pretty awful way: first we type-check any arguments
4117 // that are not closures, then we type-check the closures. This is so
4118 // that we have more information about the types of arguments when we
4119 // type-check the functions. This isn't really the right way to do this.
4120 for &check_closures in &[false, true] {
4121 debug!("check_closures={}", check_closures);
4123 // More awful hacks: before we check argument types, try to do
4124 // an "opportunistic" trait resolution of any trait bounds on
4125 // the call. This helps coercions.
4127 self.select_obligations_where_possible(false, |errors| {
4128 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
4129 self.point_at_arg_instead_of_call_if_possible(
4131 &final_arg_types[..],
4138 // For C-variadic functions, we don't have a declared type for all of
4139 // the arguments hence we only do our usual type checking with
4140 // the arguments who's types we do know.
4141 let t = if c_variadic {
4143 } else if tuple_arguments == TupleArguments {
4148 for (i, arg) in args.iter().take(t).enumerate() {
4149 // Warn only for the first loop (the "no closures" one).
4150 // Closure arguments themselves can't be diverging, but
4151 // a previous argument can, e.g., `foo(panic!(), || {})`.
4152 if !check_closures {
4153 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
4156 let is_closure = match arg.kind {
4157 ExprKind::Closure(..) => true,
4161 if is_closure != check_closures {
4165 debug!("checking the argument");
4166 let formal_ty = formal_tys[i];
4168 // The special-cased logic below has three functions:
4169 // 1. Provide as good of an expected type as possible.
4170 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
4172 let checked_ty = self.check_expr_with_expectation(&arg, expected);
4174 // 2. Coerce to the most detailed type that could be coerced
4175 // to, which is `expected_ty` if `rvalue_hint` returns an
4176 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4177 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4178 // We're processing function arguments so we definitely want to use
4179 // two-phase borrows.
4180 self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
4181 final_arg_types.push((i, checked_ty, coerce_ty));
4183 // 3. Relate the expected type and the formal one,
4184 // if the expected type was used for the coercion.
4185 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4189 // We also need to make sure we at least write the ty of the other
4190 // arguments which we skipped above.
4192 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4193 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4194 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4197 for arg in args.iter().skip(expected_arg_count) {
4198 let arg_ty = self.check_expr(&arg);
4200 // There are a few types which get autopromoted when passed via varargs
4201 // in C but we just error out instead and require explicit casts.
4202 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4204 ty::Float(ast::FloatTy::F32) => {
4205 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4207 ty::Int(ast::IntTy::I8 | ast::IntTy::I16) | ty::Bool => {
4208 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4210 ty::Uint(ast::UintTy::U8 | ast::UintTy::U16) => {
4211 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4214 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4215 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4216 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4224 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4225 vec![self.tcx.ty_error(); len]
4228 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4229 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4230 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4231 /// can be not easily comparable with predicate type (because of coercion). If the types match
4232 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4233 /// the corresponding argument's expression span instead of the `fn` call path span.
4234 fn point_at_arg_instead_of_call_if_possible(
4236 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4237 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4239 args: &'tcx [hir::Expr<'tcx>],
4241 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4242 // the `?` operator.
4243 if call_sp.desugaring_kind().is_some() {
4247 for error in errors {
4248 // Only if the cause is somewhere inside the expression we want try to point at arg.
4249 // Otherwise, it means that the cause is somewhere else and we should not change
4250 // anything because we can break the correct span.
4251 if !call_sp.contains(error.obligation.cause.span) {
4255 if let ty::PredicateKind::Trait(predicate, _) =
4256 error.obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
4258 // Collect the argument position for all arguments that could have caused this
4259 // `FulfillmentError`.
4260 let mut referenced_in = final_arg_types
4262 .map(|&(i, checked_ty, _)| (i, checked_ty))
4263 .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
4264 .flat_map(|(i, ty)| {
4265 let ty = self.resolve_vars_if_possible(&ty);
4266 // We walk the argument type because the argument's type could have
4267 // been `Option<T>`, but the `FulfillmentError` references `T`.
4268 if ty.walk().any(|arg| arg == predicate.self_ty().into()) {
4274 .collect::<Vec<_>>();
4276 // Both checked and coerced types could have matched, thus we need to remove
4278 referenced_in.sort();
4279 referenced_in.dedup();
4281 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4282 // We make sure that only *one* argument matches the obligation failure
4283 // and we assign the obligation's span to its expression's.
4284 error.obligation.cause.make_mut().span = args[ref_in].span;
4285 error.points_at_arg_span = true;
4291 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4292 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4293 /// were caused by them. If they were, we point at the corresponding type argument's span
4294 /// instead of the `fn` call path span.
4295 fn point_at_type_arg_instead_of_call_if_possible(
4297 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
4298 call_expr: &'tcx hir::Expr<'tcx>,
4300 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4301 if let hir::ExprKind::Path(qpath) = &path.kind {
4302 if let hir::QPath::Resolved(_, path) = &qpath {
4303 for error in errors {
4304 if let ty::PredicateKind::Trait(predicate, _) = error
4307 .ignore_qualifiers(self.tcx)
4311 // If any of the type arguments in this path segment caused the
4312 // `FullfillmentError`, point at its span (#61860).
4316 .filter_map(|seg| seg.args.as_ref())
4317 .flat_map(|a| a.args.iter())
4319 if let hir::GenericArg::Type(hir_ty) = &arg {
4320 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4323 // Avoid ICE with associated types. As this is best
4324 // effort only, it's ok to ignore the case. It
4325 // would trigger in `is_send::<T::AssocType>();`
4326 // from `typeck-default-trait-impl-assoc-type.rs`.
4328 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4329 let ty = self.resolve_vars_if_possible(&ty);
4330 if ty == predicate.self_ty() {
4331 error.obligation.cause.make_mut().span = hir_ty.span;
4343 // AST fragment checking
4344 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4348 ast::LitKind::Str(..) => tcx.mk_static_str(),
4349 ast::LitKind::ByteStr(ref v) => {
4350 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4352 ast::LitKind::Byte(_) => tcx.types.u8,
4353 ast::LitKind::Char(_) => tcx.types.char,
4354 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4355 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4356 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4357 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4358 ty::Int(_) | ty::Uint(_) => Some(ty),
4359 ty::Char => Some(tcx.types.u8),
4360 ty::RawPtr(..) => Some(tcx.types.usize),
4361 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4364 opt_ty.unwrap_or_else(|| self.next_int_var())
4366 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4367 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4368 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4369 ty::Float(_) => Some(ty),
4372 opt_ty.unwrap_or_else(|| self.next_float_var())
4374 ast::LitKind::Bool(_) => tcx.types.bool,
4375 ast::LitKind::Err(_) => tcx.ty_error(),
4379 /// Unifies the output type with the expected type early, for more coercions
4380 /// and forward type information on the input expressions.
4381 fn expected_inputs_for_expected_output(
4384 expected_ret: Expectation<'tcx>,
4385 formal_ret: Ty<'tcx>,
4386 formal_args: &[Ty<'tcx>],
4387 ) -> Vec<Ty<'tcx>> {
4388 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4389 let ret_ty = match expected_ret.only_has_type(self) {
4391 None => return Vec::new(),
4393 let expect_args = self
4394 .fudge_inference_if_ok(|| {
4395 // Attempt to apply a subtyping relationship between the formal
4396 // return type (likely containing type variables if the function
4397 // is polymorphic) and the expected return type.
4398 // No argument expectations are produced if unification fails.
4399 let origin = self.misc(call_span);
4400 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4402 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4403 // to identity so the resulting type is not constrained.
4406 // Process any obligations locally as much as
4407 // we can. We don't care if some things turn
4408 // out unconstrained or ambiguous, as we're
4409 // just trying to get hints here.
4410 self.save_and_restore_in_snapshot_flag(|_| {
4411 let mut fulfill = TraitEngine::new(self.tcx);
4412 for obligation in ok.obligations {
4413 fulfill.register_predicate_obligation(self, obligation);
4415 fulfill.select_where_possible(self)
4419 Err(_) => return Err(()),
4422 // Record all the argument types, with the substitutions
4423 // produced from the above subtyping unification.
4424 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4426 .unwrap_or_default();
4428 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4429 formal_args, formal_ret, expect_args, expected_ret
4434 pub fn check_struct_path(
4438 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4439 let path_span = match *qpath {
4440 QPath::Resolved(_, ref path) => path.span,
4441 QPath::TypeRelative(ref qself, _) => qself.span,
4443 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4444 let variant = match def {
4446 self.set_tainted_by_errors();
4449 Res::Def(DefKind::Variant, _) => match ty.kind {
4450 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4451 _ => bug!("unexpected type: {:?}", ty),
4453 Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
4454 | Res::SelfTy(..) => match ty.kind {
4455 ty::Adt(adt, substs) if !adt.is_enum() => {
4456 Some((adt.non_enum_variant(), adt.did, substs))
4460 _ => bug!("unexpected definition: {:?}", def),
4463 if let Some((variant, did, substs)) = variant {
4464 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4465 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4467 // Check bounds on type arguments used in the path.
4468 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4470 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4471 self.add_obligations_for_parameters(cause, bounds);
4479 "expected struct, variant or union type, found {}",
4480 ty.sort_string(self.tcx)
4482 .span_label(path_span, "not a struct")
4488 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4489 // The newly resolved definition is written into `type_dependent_defs`.
4490 fn finish_resolving_struct_path(
4495 ) -> (Res, Ty<'tcx>) {
4497 QPath::Resolved(ref maybe_qself, ref path) => {
4498 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4499 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4502 QPath::TypeRelative(ref qself, ref segment) => {
4503 let ty = self.to_ty(qself);
4505 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4511 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4512 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
4513 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4515 // Write back the new resolution.
4516 self.write_resolution(hir_id, result);
4518 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4523 /// Resolves an associated value path into a base type and associated constant, or method
4524 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4525 pub fn resolve_ty_and_res_ufcs<'b>(
4527 qpath: &'b QPath<'b>,
4530 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4531 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4532 let (ty, qself, item_segment) = match *qpath {
4533 QPath::Resolved(ref opt_qself, ref path) => {
4536 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4540 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4542 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
4544 // Return directly on cache hit. This is useful to avoid doubly reporting
4545 // errors with default match binding modes. See #44614.
4547 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4548 return (def, Some(ty), slice::from_ref(&**item_segment));
4550 let item_name = item_segment.ident;
4551 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4552 let result = match error {
4553 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4554 _ => Err(ErrorReported),
4556 if item_name.name != kw::Invalid {
4557 if let Some(mut e) = self.report_method_error(
4561 SelfSource::QPath(qself),
4571 // Write back the new resolution.
4572 self.write_resolution(hir_id, result);
4574 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4576 slice::from_ref(&**item_segment),
4580 pub fn check_decl_initializer(
4582 local: &'tcx hir::Local<'tcx>,
4583 init: &'tcx hir::Expr<'tcx>,
4585 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4586 // for #42640 (default match binding modes).
4589 let ref_bindings = local.pat.contains_explicit_ref_binding();
4591 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4592 if let Some(m) = ref_bindings {
4593 // Somewhat subtle: if we have a `ref` binding in the pattern,
4594 // we want to avoid introducing coercions for the RHS. This is
4595 // both because it helps preserve sanity and, in the case of
4596 // ref mut, for soundness (issue #23116). In particular, in
4597 // the latter case, we need to be clear that the type of the
4598 // referent for the reference that results is *equal to* the
4599 // type of the place it is referencing, and not some
4600 // supertype thereof.
4601 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4602 self.demand_eqtype(init.span, local_ty, init_ty);
4605 self.check_expr_coercable_to_type(init, local_ty, None)
4609 /// Type check a `let` statement.
4610 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4611 // Determine and write the type which we'll check the pattern against.
4612 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4613 self.write_ty(local.hir_id, ty);
4615 // Type check the initializer.
4616 if let Some(ref init) = local.init {
4617 let init_ty = self.check_decl_initializer(local, &init);
4618 self.overwrite_local_ty_if_err(local, ty, init_ty);
4621 // Does the expected pattern type originate from an expression and what is the span?
4622 let (origin_expr, ty_span) = match (local.ty, local.init) {
4623 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4624 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4625 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4628 // Type check the pattern. Override if necessary to avoid knock-on errors.
4629 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4630 let pat_ty = self.node_ty(local.pat.hir_id);
4631 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4634 fn overwrite_local_ty_if_err(
4636 local: &'tcx hir::Local<'tcx>,
4640 if ty.references_error() {
4641 // Override the types everywhere with `err()` to avoid knock on errors.
4642 self.write_ty(local.hir_id, ty);
4643 self.write_ty(local.pat.hir_id, ty);
4644 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4645 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4646 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4650 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4651 err.span_suggestion_short(
4652 span.shrink_to_hi(),
4653 "consider using a semicolon here",
4655 Applicability::MachineApplicable,
4659 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4660 // Don't do all the complex logic below for `DeclItem`.
4662 hir::StmtKind::Item(..) => return,
4663 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4666 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4668 // Hide the outer diverging and `has_errors` flags.
4669 let old_diverges = self.diverges.replace(Diverges::Maybe);
4670 let old_has_errors = self.has_errors.replace(false);
4673 hir::StmtKind::Local(ref l) => {
4674 self.check_decl_local(&l);
4677 hir::StmtKind::Item(_) => {}
4678 hir::StmtKind::Expr(ref expr) => {
4679 // Check with expected type of `()`.
4680 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4681 self.suggest_semicolon_at_end(expr.span, err);
4684 hir::StmtKind::Semi(ref expr) => {
4685 self.check_expr(&expr);
4689 // Combine the diverging and `has_error` flags.
4690 self.diverges.set(self.diverges.get() | old_diverges);
4691 self.has_errors.set(self.has_errors.get() | old_has_errors);
4694 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4695 let unit = self.tcx.mk_unit();
4696 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4698 // if the block produces a `!` value, that can always be
4699 // (effectively) coerced to unit.
4701 self.demand_suptype(blk.span, unit, ty);
4705 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4706 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4707 /// when given code like the following:
4709 /// if false { return 0i32; } else { 1u32 }
4710 /// // ^^^^ point at this instead of the whole `if` expression
4712 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4713 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4714 let arm_spans: Vec<Span> = arms
4717 self.in_progress_typeck_results
4718 .and_then(|typeck_results| {
4719 typeck_results.borrow().node_type_opt(arm.body.hir_id)
4721 .and_then(|arm_ty| {
4722 if arm_ty.is_never() {
4725 Some(match &arm.body.kind {
4726 // Point at the tail expression when possible.
4727 hir::ExprKind::Block(block, _) => {
4728 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4736 if arm_spans.len() == 1 {
4737 return arm_spans[0];
4743 fn check_block_with_expected(
4745 blk: &'tcx hir::Block<'tcx>,
4746 expected: Expectation<'tcx>,
4749 let mut fcx_ps = self.ps.borrow_mut();
4750 let unsafety_state = fcx_ps.recurse(blk);
4751 replace(&mut *fcx_ps, unsafety_state)
4754 // In some cases, blocks have just one exit, but other blocks
4755 // can be targeted by multiple breaks. This can happen both
4756 // with labeled blocks as well as when we desugar
4757 // a `try { ... }` expression.
4761 // 'a: { if true { break 'a Err(()); } Ok(()) }
4763 // Here we would wind up with two coercions, one from
4764 // `Err(())` and the other from the tail expression
4765 // `Ok(())`. If the tail expression is omitted, that's a
4766 // "forced unit" -- unless the block diverges, in which
4767 // case we can ignore the tail expression (e.g., `'a: {
4768 // break 'a 22; }` would not force the type of the block
4770 let tail_expr = blk.expr.as_ref();
4771 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4772 let coerce = if blk.targeted_by_break {
4773 CoerceMany::new(coerce_to_ty)
4775 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4776 Some(e) => slice::from_ref(e),
4779 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4782 let prev_diverges = self.diverges.get();
4783 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4785 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4786 for s in blk.stmts {
4790 // check the tail expression **without** holding the
4791 // `enclosing_breakables` lock below.
4792 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4794 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4795 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4796 let coerce = ctxt.coerce.as_mut().unwrap();
4797 if let Some(tail_expr_ty) = tail_expr_ty {
4798 let tail_expr = tail_expr.unwrap();
4799 let span = self.get_expr_coercion_span(tail_expr);
4800 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4801 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4803 // Subtle: if there is no explicit tail expression,
4804 // that is typically equivalent to a tail expression
4805 // of `()` -- except if the block diverges. In that
4806 // case, there is no value supplied from the tail
4807 // expression (assuming there are no other breaks,
4808 // this implies that the type of the block will be
4811 // #41425 -- label the implicit `()` as being the
4812 // "found type" here, rather than the "expected type".
4813 if !self.diverges.get().is_always() {
4814 // #50009 -- Do not point at the entire fn block span, point at the return type
4815 // span, as it is the cause of the requirement, and
4816 // `consider_hint_about_removing_semicolon` will point at the last expression
4817 // if it were a relevant part of the error. This improves usability in editors
4818 // that highlight errors inline.
4819 let mut sp = blk.span;
4820 let mut fn_span = None;
4821 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4822 let ret_sp = decl.output.span();
4823 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4824 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4825 // output would otherwise be incorrect and even misleading. Make sure
4826 // the span we're aiming at correspond to a `fn` body.
4827 if block_sp == blk.span {
4829 fn_span = Some(ident.span);
4833 coerce.coerce_forced_unit(
4837 if let Some(expected_ty) = expected.only_has_type(self) {
4838 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4840 if let Some(fn_span) = fn_span {
4843 "implicitly returns `()` as its body has no tail or `return` \
4855 // If we can break from the block, then the block's exit is always reachable
4856 // (... as long as the entry is reachable) - regardless of the tail of the block.
4857 self.diverges.set(prev_diverges);
4860 let mut ty = ctxt.coerce.unwrap().complete(self);
4862 if self.has_errors.get() || ty.references_error() {
4863 ty = self.tcx.ty_error()
4866 self.write_ty(blk.hir_id, ty);
4868 *self.ps.borrow_mut() = prev;
4872 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4873 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4875 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4876 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
4877 let body = self.tcx.hir().body(body_id);
4878 if let ExprKind::Block(block, _) = &body.value.kind {
4879 return Some(block.span);
4887 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4888 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
4889 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4890 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4893 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4894 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
4896 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4897 // This is less than ideal, it will not suggest a return type span on any
4898 // method called `main`, regardless of whether it is actually the entry point,
4899 // but it will still present it as the reason for the expected type.
4900 Some((&sig.decl, ident, ident.name != sym::main))
4902 Node::TraitItem(&hir::TraitItem {
4904 kind: hir::TraitItemKind::Fn(ref sig, ..),
4906 }) => Some((&sig.decl, ident, true)),
4907 Node::ImplItem(&hir::ImplItem {
4909 kind: hir::ImplItemKind::Fn(ref sig, ..),
4911 }) => Some((&sig.decl, ident, false)),
4916 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4917 /// suggestion can be made, `None` otherwise.
4918 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4919 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4920 // `while` before reaching it, as block tail returns are not available in them.
4921 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4922 let parent = self.tcx.hir().get(blk_id);
4923 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4927 /// On implicit return expressions with mismatched types, provides the following suggestions:
4929 /// - Points out the method's return type as the reason for the expected type.
4930 /// - Possible missing semicolon.
4931 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4932 pub fn suggest_mismatched_types_on_tail(
4934 err: &mut DiagnosticBuilder<'_>,
4935 expr: &'tcx hir::Expr<'tcx>,
4941 let expr = expr.peel_drop_temps();
4942 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4943 let mut pointing_at_return_type = false;
4944 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4945 pointing_at_return_type =
4946 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4948 pointing_at_return_type
4951 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4952 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4954 /// fn foo(x: usize) -> usize { x }
4955 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4959 err: &mut DiagnosticBuilder<'_>,
4960 expr: &hir::Expr<'_>,
4964 let hir = self.tcx.hir();
4965 let (def_id, sig) = match found.kind {
4966 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4967 ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig()),
4971 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4972 let sig = self.normalize_associated_types_in(expr.span, &sig);
4973 if self.can_coerce(sig.output(), expected) {
4974 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4975 (String::new(), Applicability::MachineApplicable)
4977 ("...".to_string(), Applicability::HasPlaceholders)
4979 let mut msg = "call this function";
4980 match hir.get_if_local(def_id) {
4982 Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. })
4983 | Node::ImplItem(hir::ImplItem {
4984 kind: hir::ImplItemKind::Fn(_, body_id), ..
4986 | Node::TraitItem(hir::TraitItem {
4987 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Provided(body_id)),
4991 let body = hir.body(*body_id);
4995 .map(|param| match ¶m.pat.kind {
4996 hir::PatKind::Binding(_, _, ident, None)
4997 if ident.name != kw::SelfLower =>
5001 _ => "_".to_string(),
5003 .collect::<Vec<_>>()
5006 Some(Node::Expr(hir::Expr {
5007 kind: ExprKind::Closure(_, _, body_id, _, _),
5008 span: full_closure_span,
5011 if *full_closure_span == expr.span {
5014 msg = "call this closure";
5015 let body = hir.body(*body_id);
5019 .map(|param| match ¶m.pat.kind {
5020 hir::PatKind::Binding(_, _, ident, None)
5021 if ident.name != kw::SelfLower =>
5025 _ => "_".to_string(),
5027 .collect::<Vec<_>>()
5030 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
5031 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
5032 match def_id.as_local().map(|def_id| hir.def_kind(def_id)) {
5033 Some(DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
5034 msg = "instantiate this tuple variant";
5036 Some(DefKind::Ctor(CtorOf::Struct, _)) => {
5037 msg = "instantiate this tuple struct";
5042 Some(Node::ForeignItem(hir::ForeignItem {
5043 kind: hir::ForeignItemKind::Fn(_, idents, _),
5049 if ident.name != kw::SelfLower {
5055 .collect::<Vec<_>>()
5058 Some(Node::TraitItem(hir::TraitItem {
5059 kind: hir::TraitItemKind::Fn(.., hir::TraitFn::Required(idents)),
5065 if ident.name != kw::SelfLower {
5071 .collect::<Vec<_>>()
5076 err.span_suggestion_verbose(
5077 expr.span.shrink_to_hi(),
5078 &format!("use parentheses to {}", msg),
5079 format!("({})", sugg_call),
5087 pub fn suggest_deref_ref_or_into(
5089 err: &mut DiagnosticBuilder<'_>,
5090 expr: &hir::Expr<'_>,
5093 expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
5095 if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
5096 err.span_suggestion(sp, msg, suggestion, applicability);
5097 } else if let (ty::FnDef(def_id, ..), true) =
5098 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
5100 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
5101 let sp = self.sess().source_map().guess_head_span(sp);
5102 err.span_label(sp, &format!("{} defined here", found));
5104 } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
5105 let is_struct_pat_shorthand_field =
5106 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
5107 let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
5108 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5109 let mut suggestions = iter::repeat(&expr_text)
5110 .zip(methods.iter())
5111 .filter_map(|(receiver, method)| {
5112 let method_call = format!(".{}()", method.ident);
5113 if receiver.ends_with(&method_call) {
5114 None // do not suggest code that is already there (#53348)
5116 let method_call_list = [".to_vec()", ".to_string()"];
5117 let sugg = if receiver.ends_with(".clone()")
5118 && method_call_list.contains(&method_call.as_str())
5120 let max_len = receiver.rfind('.').unwrap();
5121 format!("{}{}", &receiver[..max_len], method_call)
5123 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
5124 format!("({}){}", receiver, method_call)
5126 format!("{}{}", receiver, method_call)
5129 Some(if is_struct_pat_shorthand_field {
5130 format!("{}: {}", receiver, sugg)
5137 if suggestions.peek().is_some() {
5138 err.span_suggestions(
5140 "try using a conversion method",
5142 Applicability::MaybeIncorrect,
5149 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5150 /// in the heap by calling `Box::new()`.
5151 fn suggest_boxing_when_appropriate(
5153 err: &mut DiagnosticBuilder<'_>,
5154 expr: &hir::Expr<'_>,
5158 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5159 // Do not suggest `Box::new` in const context.
5162 if !expected.is_box() || found.is_box() {
5165 let boxed_found = self.tcx.mk_box(found);
5166 if let (true, Ok(snippet)) = (
5167 self.can_coerce(boxed_found, expected),
5168 self.sess().source_map().span_to_snippet(expr.span),
5170 err.span_suggestion(
5172 "store this in the heap by calling `Box::new`",
5173 format!("Box::new({})", snippet),
5174 Applicability::MachineApplicable,
5177 "for more on the distinction between the stack and the heap, read \
5178 https://doc.rust-lang.org/book/ch15-01-box.html, \
5179 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5180 https://doc.rust-lang.org/std/boxed/index.html",
5185 /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
5186 fn suggest_calling_boxed_future_when_appropriate(
5188 err: &mut DiagnosticBuilder<'_>,
5189 expr: &hir::Expr<'_>,
5195 if self.tcx.hir().is_inside_const_context(expr.hir_id) {
5196 // Do not suggest `Box::new` in const context.
5199 let pin_did = self.tcx.lang_items().pin_type();
5200 match expected.kind {
5201 ty::Adt(def, _) if Some(def.did) != pin_did => return false,
5202 // This guards the `unwrap` and `mk_box` below.
5203 _ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
5206 let boxed_found = self.tcx.mk_box(found);
5207 let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap();
5208 if let (true, Ok(snippet)) = (
5209 self.can_coerce(new_found, expected),
5210 self.sess().source_map().span_to_snippet(expr.span),
5213 ty::Adt(def, _) if def.is_box() => {
5214 err.help("use `Box::pin`");
5217 err.span_suggestion(
5219 "you need to pin and box this expression",
5220 format!("Box::pin({})", snippet),
5221 Applicability::MachineApplicable,
5231 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5235 /// bar_that_returns_u32()
5239 /// This routine checks if the return expression in a block would make sense on its own as a
5240 /// statement and the return type has been left as default or has been specified as `()`. If so,
5241 /// it suggests adding a semicolon.
5242 fn suggest_missing_semicolon(
5244 err: &mut DiagnosticBuilder<'_>,
5245 expression: &'tcx hir::Expr<'tcx>,
5249 if expected.is_unit() {
5250 // `BlockTailExpression` only relevant if the tail expr would be
5251 // useful on its own.
5252 match expression.kind {
5254 | ExprKind::MethodCall(..)
5255 | ExprKind::Loop(..)
5256 | ExprKind::Match(..)
5257 | ExprKind::Block(..) => {
5258 err.span_suggestion(
5259 cause_span.shrink_to_hi(),
5260 "try adding a semicolon",
5262 Applicability::MachineApplicable,
5270 /// A possible error is to forget to add a return type that is needed:
5274 /// bar_that_returns_u32()
5278 /// This routine checks if the return type is left as default, the method is not part of an
5279 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5281 fn suggest_missing_return_type(
5283 err: &mut DiagnosticBuilder<'_>,
5284 fn_decl: &hir::FnDecl<'_>,
5289 // Only suggest changing the return type for methods that
5290 // haven't set a return type at all (and aren't `fn main()` or an impl).
5291 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5292 (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
5293 err.span_suggestion(
5295 "try adding a return type",
5296 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5297 Applicability::MachineApplicable,
5301 (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
5302 err.span_label(span, "possibly return type missing here?");
5305 (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
5306 // `fn main()` must return `()`, do not suggest changing return type
5307 err.span_label(span, "expected `()` because of default return type");
5310 // expectation was caused by something else, not the default return
5311 (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
5312 (&hir::FnRetTy::Return(ref ty), _, _, _) => {
5313 // Only point to return type if the expected type is the return type, as if they
5314 // are not, the expectation must have been caused by something else.
5315 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5317 let ty = AstConv::ast_ty_to_ty(self, ty);
5318 debug!("suggest_missing_return_type: return type {:?}", ty);
5319 debug!("suggest_missing_return_type: expected type {:?}", ty);
5320 if ty.kind == expected.kind {
5321 err.span_label(sp, format!("expected `{}` because of return type", expected));
5329 /// A possible error is to forget to add `.await` when using futures:
5332 /// async fn make_u32() -> u32 {
5336 /// fn take_u32(x: u32) {}
5338 /// async fn foo() {
5339 /// let x = make_u32();
5344 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5345 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5346 /// `.await` to the tail of the expression.
5347 fn suggest_missing_await(
5349 err: &mut DiagnosticBuilder<'_>,
5350 expr: &hir::Expr<'_>,
5354 debug!("suggest_missing_await: expr={:?} expected={:?}, found={:?}", expr, expected, found);
5355 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5356 // body isn't `async`.
5357 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5358 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5359 let body = self.tcx().hir().body(body_id);
5360 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5362 // Check for `Future` implementations by constructing a predicate to
5363 // prove: `<T as Future>::Output == U`
5364 let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp));
5365 let item_def_id = self
5367 .associated_items(future_trait)
5368 .in_definition_order()
5372 // `<T as Future>::Output`
5373 let projection_ty = ty::ProjectionTy {
5377 .mk_substs_trait(found, self.fresh_substs_for_item(sp, item_def_id)),
5382 let predicate = ty::PredicateKind::Projection(ty::ProjectionPredicate {
5386 .to_predicate(self.tcx)
5387 .potentially_qualified(self.tcx, ty::PredicateKind::ForAll);
5388 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5390 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5392 if self.infcx.predicate_may_hold(&obligation) {
5393 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5394 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5395 err.span_suggestion(
5397 "consider using `.await` here",
5398 format!("{}.await", code),
5399 Applicability::MaybeIncorrect,
5402 debug!("suggest_missing_await: no snippet for {:?}", sp);
5405 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5411 fn note_need_for_fn_pointer(
5413 err: &mut DiagnosticBuilder<'_>,
5417 let (sig, did, substs) = match (&expected.kind, &found.kind) {
5418 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
5419 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
5420 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
5425 "different `fn` items always have unique types, even if their signatures are \
5428 (sig1, *did1, substs1)
5430 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
5431 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
5435 (sig1, *did, substs)
5439 err.help(&format!("change the expected type to be function pointer `{}`", sig));
5441 "if the expected type is due to type inference, cast the expected `fn` to a function \
5442 pointer: `{} as {}`",
5443 self.tcx.def_path_str_with_substs(did, substs),
5448 /// A common error is to add an extra semicolon:
5451 /// fn foo() -> usize {
5456 /// This routine checks if the final statement in a block is an
5457 /// expression with an explicit semicolon whose type is compatible
5458 /// with `expected_ty`. If so, it suggests removing the semicolon.
5459 fn consider_hint_about_removing_semicolon(
5461 blk: &'tcx hir::Block<'tcx>,
5462 expected_ty: Ty<'tcx>,
5463 err: &mut DiagnosticBuilder<'_>,
5465 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5466 err.span_suggestion(
5468 "consider removing this semicolon",
5470 Applicability::MachineApplicable,
5475 fn could_remove_semicolon(
5477 blk: &'tcx hir::Block<'tcx>,
5478 expected_ty: Ty<'tcx>,
5480 // Be helpful when the user wrote `{... expr;}` and
5481 // taking the `;` off is enough to fix the error.
5482 let last_stmt = blk.stmts.last()?;
5483 let last_expr = match last_stmt.kind {
5484 hir::StmtKind::Semi(ref e) => e,
5487 let last_expr_ty = self.node_ty(last_expr.hir_id);
5488 if matches!(last_expr_ty.kind, ty::Error(_))
5489 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err()
5493 let original_span = original_sp(last_stmt.span, blk.span);
5494 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5497 // Instantiates the given path, which must refer to an item with the given
5498 // number of type parameters and type.
5499 pub fn instantiate_value_path(
5501 segments: &[hir::PathSegment<'_>],
5502 self_ty: Option<Ty<'tcx>>,
5506 ) -> (Ty<'tcx>, Res) {
5508 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5509 segments, self_ty, res, hir_id,
5514 let path_segs = match res {
5515 Res::Local(_) | Res::SelfCtor(_) => vec![],
5516 Res::Def(kind, def_id) => {
5517 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5519 _ => bug!("instantiate_value_path on {:?}", res),
5522 let mut user_self_ty = None;
5523 let mut is_alias_variant_ctor = false;
5525 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5526 if let Some(self_ty) = self_ty {
5527 let adt_def = self_ty.ty_adt_def().unwrap();
5528 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5529 is_alias_variant_ctor = true;
5532 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
5533 let container = tcx.associated_item(def_id).container;
5534 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5536 ty::TraitContainer(trait_did) => {
5537 callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
5539 ty::ImplContainer(impl_def_id) => {
5540 if segments.len() == 1 {
5541 // `<T>::assoc` will end up here, and so
5542 // can `T::assoc`. It this came from an
5543 // inherent impl, we need to record the
5544 // `T` for posterity (see `UserSelfTy` for
5546 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5547 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5555 // Now that we have categorized what space the parameters for each
5556 // segment belong to, let's sort out the parameters that the user
5557 // provided (if any) into their appropriate spaces. We'll also report
5558 // errors if type parameters are provided in an inappropriate place.
5560 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5561 let generics_has_err = AstConv::prohibit_generics(
5563 segments.iter().enumerate().filter_map(|(index, seg)| {
5564 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5572 if let Res::Local(hid) = res {
5573 let ty = self.local_ty(span, hid).decl_ty;
5574 let ty = self.normalize_associated_types_in(span, &ty);
5575 self.write_ty(hir_id, ty);
5579 if generics_has_err {
5580 // Don't try to infer type parameters when prohibited generic arguments were given.
5581 user_self_ty = None;
5584 // Now we have to compare the types that the user *actually*
5585 // provided against the types that were *expected*. If the user
5586 // did not provide any types, then we want to substitute inference
5587 // variables. If the user provided some types, we may still need
5588 // to add defaults. If the user provided *too many* types, that's
5591 let mut infer_args_for_err = FxHashSet::default();
5592 for &PathSeg(def_id, index) in &path_segs {
5593 let seg = &segments[index];
5594 let generics = tcx.generics_of(def_id);
5595 // Argument-position `impl Trait` is treated as a normal generic
5596 // parameter internally, but we don't allow users to specify the
5597 // parameter's value explicitly, so we have to do some error-
5599 if let GenericArgCountResult {
5600 correct: Err(GenericArgCountMismatch { reported: Some(ErrorReported), .. }),
5602 } = AstConv::check_generic_arg_count_for_call(
5603 tcx, span, &generics, &seg, false, // `is_method_call`
5605 infer_args_for_err.insert(index);
5606 self.set_tainted_by_errors(); // See issue #53251.
5610 let has_self = path_segs
5612 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5615 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5616 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
5618 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5619 let variant = adt_def.non_enum_variant();
5620 let ctor_def_id = variant.ctor_def_id.unwrap();
5622 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5627 let mut err = tcx.sess.struct_span_err(
5629 "the `Self` constructor can only be used with tuple or unit structs",
5631 if let Some(adt_def) = ty.ty_adt_def() {
5632 match adt_def.adt_kind() {
5634 err.help("did you mean to use one of the enum's variants?");
5636 AdtKind::Struct | AdtKind::Union => {
5637 err.span_suggestion(
5639 "use curly brackets",
5640 String::from("Self { /* fields */ }"),
5641 Applicability::HasPlaceholders,
5648 return (tcx.ty_error(), res);
5654 let def_id = res.def_id();
5656 // The things we are substituting into the type should not contain
5657 // escaping late-bound regions, and nor should the base type scheme.
5658 let ty = tcx.type_of(def_id);
5660 let arg_count = GenericArgCountResult {
5661 explicit_late_bound: ExplicitLateBound::No,
5662 correct: if infer_args_for_err.is_empty() {
5665 Err(GenericArgCountMismatch::default())
5669 let substs = self_ctor_substs.unwrap_or_else(|| {
5670 AstConv::create_substs_for_generic_args(
5677 // Provide the generic args, and whether types should be inferred.
5679 if let Some(&PathSeg(_, index)) =
5680 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5682 // If we've encountered an `impl Trait`-related error, we're just
5683 // going to infer the arguments for better error messages.
5684 if !infer_args_for_err.contains(&index) {
5685 // Check whether the user has provided generic arguments.
5686 if let Some(ref data) = segments[index].args {
5687 return (Some(data), segments[index].infer_args);
5690 return (None, segments[index].infer_args);
5695 // Provide substitutions for parameters for which (valid) arguments have been provided.
5696 |param, arg| match (¶m.kind, arg) {
5697 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5698 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5700 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5701 self.to_ty(ty).into()
5703 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5704 self.const_arg_to_const(&ct.value, param.def_id).into()
5706 _ => unreachable!(),
5708 // Provide substitutions for parameters for which arguments are inferred.
5709 |substs, param, infer_args| {
5711 GenericParamDefKind::Lifetime => {
5712 self.re_infer(Some(param), span).unwrap().into()
5714 GenericParamDefKind::Type { has_default, .. } => {
5715 if !infer_args && has_default {
5716 // If we have a default, then we it doesn't matter that we're not
5717 // inferring the type arguments: we provide the default where any
5719 let default = tcx.type_of(param.def_id);
5722 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5726 // If no type arguments were provided, we have to infer them.
5727 // This case also occurs as a result of some malformed input, e.g.
5728 // a lifetime argument being given instead of a type parameter.
5729 // Using inference instead of `Error` gives better error messages.
5730 self.var_for_def(span, param)
5733 GenericParamDefKind::Const => {
5734 // FIXME(const_generics:defaults)
5735 // No const parameters were provided, we have to infer them.
5736 self.var_for_def(span, param)
5742 assert!(!substs.has_escaping_bound_vars());
5743 assert!(!ty.has_escaping_bound_vars());
5745 // First, store the "user substs" for later.
5746 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5748 self.add_required_obligations(span, def_id, &substs);
5750 // Substitute the values for the type parameters into the type of
5751 // the referenced item.
5752 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5754 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5755 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5756 // is inherent, there is no `Self` parameter; instead, the impl needs
5757 // type parameters, which we can infer by unifying the provided `Self`
5758 // with the substituted impl type.
5759 // This also occurs for an enum variant on a type alias.
5760 let ty = tcx.type_of(impl_def_id);
5762 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5763 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5764 Ok(ok) => self.register_infer_ok_obligations(ok),
5766 self.tcx.sess.delay_span_bug(
5769 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5778 self.check_rustc_args_require_const(def_id, hir_id, span);
5780 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5781 self.write_substs(hir_id, substs);
5783 (ty_substituted, res)
5786 /// Add all the obligations that are required, substituting and normalized appropriately.
5787 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5788 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5790 for (i, mut obligation) in traits::predicates_for_generics(
5791 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5797 // This makes the error point at the bound, but we want to point at the argument
5798 if let Some(span) = spans.get(i) {
5799 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
5801 self.register_predicate(obligation);
5805 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5806 // We're only interested in functions tagged with
5807 // #[rustc_args_required_const], so ignore anything that's not.
5808 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5812 // If our calling expression is indeed the function itself, we're good!
5813 // If not, generate an error that this can only be called directly.
5814 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5815 if let ExprKind::Call(ref callee, ..) = expr.kind {
5816 if callee.hir_id == hir_id {
5822 self.tcx.sess.span_err(
5824 "this function can only be invoked directly, not through a function pointer",
5828 /// Resolves `typ` by a single level if `typ` is a type variable.
5829 /// If no resolution is possible, then an error is reported.
5830 /// Numeric inference variables may be left unresolved.
5831 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5832 let ty = self.resolve_vars_with_obligations(ty);
5833 if !ty.is_ty_var() {
5836 if !self.is_tainted_by_errors() {
5837 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5838 .note("type must be known at this point")
5841 let err = self.tcx.ty_error();
5842 self.demand_suptype(sp, err, ty);
5847 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5850 ctxt: BreakableCtxt<'tcx>,
5852 ) -> (BreakableCtxt<'tcx>, R) {
5855 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5856 index = enclosing_breakables.stack.len();
5857 enclosing_breakables.by_id.insert(id, index);
5858 enclosing_breakables.stack.push(ctxt);
5862 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5863 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5864 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5865 enclosing_breakables.stack.pop().expect("missing breakable context")
5870 /// Instantiate a QueryResponse in a probe context, without a
5871 /// good ObligationCause.
5872 fn probe_instantiate_query_response(
5875 original_values: &OriginalQueryValues<'tcx>,
5876 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5877 ) -> InferResult<'tcx, Ty<'tcx>> {
5878 self.instantiate_query_response_and_region_obligations(
5879 &traits::ObligationCause::misc(span, self.body_id),
5886 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5887 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5888 let mut contained_in_place = false;
5890 while let hir::Node::Expr(parent_expr) =
5891 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5893 match &parent_expr.kind {
5894 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5895 if lhs.hir_id == expr_id {
5896 contained_in_place = true;
5902 expr_id = parent_expr.hir_id;
5909 fn check_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5910 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
5912 assert_eq!(generics.parent, None);
5914 if generics.own_counts().types == 0 {
5918 let mut params_used = BitSet::new_empty(generics.params.len());
5920 if ty.references_error() {
5921 // If there is already another error, do not emit
5922 // an error for not using a type parameter.
5923 assert!(tcx.sess.has_errors());
5927 for leaf in ty.walk() {
5928 if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
5929 if let ty::Param(param) = leaf_ty.kind {
5930 debug!("found use of ty param {:?}", param);
5931 params_used.insert(param.index);
5936 for param in &generics.params {
5937 if !params_used.contains(param.index) {
5938 if let ty::GenericParamDefKind::Type { .. } = param.kind {
5939 let span = tcx.def_span(param.def_id);
5944 "type parameter `{}` is unused",
5947 .span_label(span, "unused type parameter")
5954 fn fatally_break_rust(sess: &Session) {
5955 let handler = sess.diagnostic();
5956 handler.span_bug_no_panic(
5958 "It looks like you're trying to break rust; would you like some ICE?",
5960 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5961 handler.note_without_error(
5962 "we would appreciate a joke overview: \
5963 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5965 handler.note_without_error(&format!(
5966 "rustc {} running on {}",
5967 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5968 config::host_triple(),
5972 fn potentially_plural_count(count: usize, word: &str) -> String {
5973 format!("{} {}{}", count, word, pluralize!(count))