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 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
80 mod generator_interior;
90 use crate::astconv::{AstConv, PathSeg};
91 use crate::middle::lang_items;
92 use crate::namespace::Namespace;
93 use rustc::hir::map::blocks::FnLikeNode;
94 use rustc::hir::map::Map;
95 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
96 use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
97 use rustc::infer::opaque_types::OpaqueTypeDecl;
98 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
99 use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
100 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
101 use rustc::middle::region;
102 use rustc::mir::interpret::ConstValue;
103 use rustc::session::parse::feature_err;
104 use rustc::traits::error_reporting::recursive_type_with_infinite_size_error;
105 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
106 use rustc::ty::adjustment::{
107 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
109 use rustc::ty::fold::{TypeFoldable, TypeFolder};
110 use rustc::ty::layout::VariantIdx;
111 use rustc::ty::query::Providers;
112 use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts};
113 use rustc::ty::util::{Discr, IntTypeExt, Representability};
115 self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
116 ToPredicate, Ty, TyCtxt, UserType, WithConstness,
118 use rustc_attr as attr;
119 use rustc_data_structures::captures::Captures;
120 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
121 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
122 use rustc_hir as hir;
123 use rustc_hir::def::{CtorOf, DefKind, Res};
124 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE};
125 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
126 use rustc_hir::itemlikevisit::ItemLikeVisitor;
127 use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
128 use rustc_index::vec::Idx;
129 use rustc_span::hygiene::DesugaringKind;
130 use rustc_span::source_map::{original_sp, DUMMY_SP};
131 use rustc_span::symbol::{kw, sym, Ident};
132 use rustc_span::{self, BytePos, MultiSpan, Span};
133 use rustc_target::spec::abi::Abi;
135 use syntax::util::parser::ExprPrecedence;
137 use std::cell::{Cell, Ref, RefCell, RefMut};
139 use std::collections::hash_map::Entry;
141 use std::mem::replace;
142 use std::ops::{self, Deref};
146 use crate::require_c_abi_if_c_variadic;
147 use crate::session::config::EntryFnType;
148 use crate::session::Session;
149 use crate::util::common::{indenter, ErrorReported};
150 use crate::TypeAndSubsts;
152 use self::autoderef::Autoderef;
153 use self::callee::DeferredCallResolution;
154 use self::coercion::{CoerceMany, DynamicCoerceMany};
155 use self::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
156 use self::method::{MethodCallee, SelfSource};
157 pub use self::Expectation::*;
158 use self::TupleArgumentsFlag::*;
161 macro_rules! type_error_struct {
162 ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
163 if $typ.references_error() {
164 $session.diagnostic().struct_dummy()
166 rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
171 /// The type of a local binding, including the revealed type for anon types.
172 #[derive(Copy, Clone, Debug)]
173 pub struct LocalTy<'tcx> {
175 revealed_ty: Ty<'tcx>,
178 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
179 #[derive(Copy, Clone)]
180 struct MaybeInProgressTables<'a, 'tcx> {
181 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
184 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
185 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
186 match self.maybe_tables {
187 Some(tables) => tables.borrow(),
188 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables"),
192 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
193 match self.maybe_tables {
194 Some(tables) => tables.borrow_mut(),
195 None => bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables"),
200 /// Closures defined within the function. For example:
203 /// bar(move|| { ... })
206 /// Here, the function `foo()` and the closure passed to
207 /// `bar()` will each have their own `FnCtxt`, but they will
208 /// share the inherited fields.
209 pub struct Inherited<'a, 'tcx> {
210 infcx: InferCtxt<'a, 'tcx>,
212 tables: MaybeInProgressTables<'a, 'tcx>,
214 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
216 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
218 // Some additional `Sized` obligations badly affect type inference.
219 // These obligations are added in a later stage of typeck.
220 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
222 // When we process a call like `c()` where `c` is a closure type,
223 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
224 // `FnOnce` closure. In that case, we defer full resolution of the
225 // call until upvar inference can kick in and make the
226 // decision. We keep these deferred resolutions grouped by the
227 // def-id of the closure, so that once we decide, we can easily go
228 // back and process them.
229 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
231 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
233 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
235 // Opaque types found in explicit return types and their
236 // associated fresh inference variable. Writeback resolves these
237 // variables to get the concrete type, which can be used to
238 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
239 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
241 /// A map from inference variables created from opaque
242 /// type instantiations (`ty::Infer`) to the actual opaque
243 /// type (`ty::Opaque`). Used during fallback to map unconstrained
244 /// opaque type inference variables to their corresponding
246 opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
248 /// Each type parameter has an implicit region bound that
249 /// indicates it must outlive at least the function body (the user
250 /// may specify stronger requirements). This field indicates the
251 /// region of the callee. If it is `None`, then the parameter
252 /// environment is for an item or something where the "callee" is
254 implicit_region_bound: Option<ty::Region<'tcx>>,
256 body_id: Option<hir::BodyId>,
259 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
260 type Target = InferCtxt<'a, 'tcx>;
261 fn deref(&self) -> &Self::Target {
266 /// When type-checking an expression, we propagate downward
267 /// whatever type hint we are able in the form of an `Expectation`.
268 #[derive(Copy, Clone, Debug)]
269 pub enum Expectation<'tcx> {
270 /// We know nothing about what type this expression should have.
273 /// This expression should have the type given (or some subtype).
274 ExpectHasType(Ty<'tcx>),
276 /// This expression will be cast to the `Ty`.
277 ExpectCastableToType(Ty<'tcx>),
279 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
280 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
281 ExpectRvalueLikeUnsized(Ty<'tcx>),
284 impl<'a, 'tcx> Expectation<'tcx> {
285 // Disregard "castable to" expectations because they
286 // can lead us astray. Consider for example `if cond
287 // {22} else {c} as u8` -- if we propagate the
288 // "castable to u8" constraint to 22, it will pick the
289 // type 22u8, which is overly constrained (c might not
290 // be a u8). In effect, the problem is that the
291 // "castable to" expectation is not the tightest thing
292 // we can say, so we want to drop it in this case.
293 // The tightest thing we can say is "must unify with
294 // else branch". Note that in the case of a "has type"
295 // constraint, this limitation does not hold.
297 // If the expected type is just a type variable, then don't use
298 // an expected type. Otherwise, we might write parts of the type
299 // when checking the 'then' block which are incompatible with the
301 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
303 ExpectHasType(ety) => {
304 let ety = fcx.shallow_resolve(ety);
305 if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
307 ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
312 /// Provides an expectation for an rvalue expression given an *optional*
313 /// hint, which is not required for type safety (the resulting type might
314 /// be checked higher up, as is the case with `&expr` and `box expr`), but
315 /// is useful in determining the concrete type.
317 /// The primary use case is where the expected type is a fat pointer,
318 /// like `&[isize]`. For example, consider the following statement:
320 /// let x: &[isize] = &[1, 2, 3];
322 /// In this case, the expected type for the `&[1, 2, 3]` expression is
323 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
324 /// expectation `ExpectHasType([isize])`, that would be too strong --
325 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
326 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
327 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
328 /// which still is useful, because it informs integer literals and the like.
329 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
330 /// for examples of where this comes up,.
331 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
332 match fcx.tcx.struct_tail_without_normalization(ty).kind {
333 ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty),
334 _ => ExpectHasType(ty),
338 // Resolves `expected` by a single level if it is a variable. If
339 // there is no expected type or resolution is not possible (e.g.,
340 // no constraints yet present), just returns `None`.
341 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
343 NoExpectation => NoExpectation,
344 ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(&t)),
345 ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(&t)),
346 ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t)),
350 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
351 match self.resolve(fcx) {
352 NoExpectation => None,
353 ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
357 /// It sometimes happens that we want to turn an expectation into
358 /// a **hard constraint** (i.e., something that must be satisfied
359 /// for the program to type-check). `only_has_type` will return
360 /// such a constraint, if it exists.
361 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
362 match self.resolve(fcx) {
363 ExpectHasType(ty) => Some(ty),
364 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
368 /// Like `only_has_type`, but instead of returning `None` if no
369 /// hard constraint exists, creates a fresh type variable.
370 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
371 self.only_has_type(fcx).unwrap_or_else(|| {
372 fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span })
377 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
384 fn maybe_mut_place(m: hir::Mutability) -> Self {
386 hir::Mutability::Mut => Needs::MutPlace,
387 hir::Mutability::Not => Needs::None,
392 #[derive(Copy, Clone)]
393 pub struct UnsafetyState {
395 pub unsafety: hir::Unsafety,
396 pub unsafe_push_count: u32,
401 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
402 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
405 pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
406 use hir::BlockCheckMode;
407 match self.unsafety {
408 // If this unsafe, then if the outer function was already marked as
409 // unsafe we shouldn't attribute the unsafe'ness to the block. This
410 // way the block can be warned about instead of ignoring this
411 // extraneous block (functions are never warned about).
412 hir::Unsafety::Unsafe if self.from_fn => *self,
415 let (unsafety, def, count) = match blk.rules {
416 BlockCheckMode::PushUnsafeBlock(..) => {
417 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap())
419 BlockCheckMode::PopUnsafeBlock(..) => {
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap())
422 BlockCheckMode::UnsafeBlock(..) => {
423 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count)
425 BlockCheckMode::DefaultBlock => (unsafety, self.def, self.unsafe_push_count),
427 UnsafetyState { def, unsafety, unsafe_push_count: count, from_fn: false }
433 #[derive(Debug, Copy, Clone)]
439 /// Tracks whether executing a node may exit normally (versus
440 /// return/break/panic, which "diverge", leaving dead code in their
441 /// wake). Tracked semi-automatically (through type variables marked
442 /// as diverging), with some manual adjustments for control-flow
443 /// primitives (approximating a CFG).
444 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
446 /// Potentially unknown, some cases converge,
447 /// others require a CFG to determine them.
450 /// Definitely known to diverge and therefore
451 /// not reach the next sibling or its parent.
453 /// The `Span` points to the expression
454 /// that caused us to diverge
455 /// (e.g. `return`, `break`, etc).
457 /// In some cases (e.g. a `match` expression
458 /// where all arms diverge), we may be
459 /// able to provide a more informative
460 /// message to the user.
461 /// If this is `None`, a default messsage
462 /// will be generated, which is suitable
464 custom_note: Option<&'static str>,
467 /// Same as `Always` but with a reachability
468 /// warning already emitted.
472 // Convenience impls for combining `Diverges`.
474 impl ops::BitAnd for Diverges {
476 fn bitand(self, other: Self) -> Self {
477 cmp::min(self, other)
481 impl ops::BitOr for Diverges {
483 fn bitor(self, other: Self) -> Self {
484 cmp::max(self, other)
488 impl ops::BitAndAssign for Diverges {
489 fn bitand_assign(&mut self, other: Self) {
490 *self = *self & other;
494 impl ops::BitOrAssign for Diverges {
495 fn bitor_assign(&mut self, other: Self) {
496 *self = *self | other;
501 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
502 fn always(span: Span) -> Diverges {
503 Diverges::Always { span, custom_note: None }
506 fn is_always(self) -> bool {
507 // Enum comparison ignores the
508 // contents of fields, so we just
509 // fill them in with garbage here.
510 self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
514 pub struct BreakableCtxt<'tcx> {
517 // this is `null` for loops where break with a value is illegal,
518 // such as `while`, `for`, and `while let`
519 coerce: Option<DynamicCoerceMany<'tcx>>,
522 pub struct EnclosingBreakables<'tcx> {
523 stack: Vec<BreakableCtxt<'tcx>>,
524 by_id: HirIdMap<usize>,
527 impl<'tcx> EnclosingBreakables<'tcx> {
528 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
529 self.opt_find_breakable(target_id).unwrap_or_else(|| {
530 bug!("could not find enclosing breakable with id {}", target_id);
534 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
535 match self.by_id.get(&target_id) {
536 Some(ix) => Some(&mut self.stack[*ix]),
542 pub struct FnCtxt<'a, 'tcx> {
545 /// The parameter environment used for proving trait obligations
546 /// in this function. This can change when we descend into
547 /// closures (as they bring new things into scope), hence it is
548 /// not part of `Inherited` (as of the time of this writing,
549 /// closures do not yet change the environment, but they will
551 param_env: ty::ParamEnv<'tcx>,
553 /// Number of errors that had been reported when we started
554 /// checking this function. On exit, if we find that *more* errors
555 /// have been reported, we will skip regionck and other work that
556 /// expects the types within the function to be consistent.
557 // FIXME(matthewjasper) This should not exist, and it's not correct
558 // if type checking is run in parallel.
559 err_count_on_creation: usize,
561 /// If `Some`, this stores coercion information for returned
562 /// expressions. If `None`, this is in a context where return is
563 /// inappropriate, such as a const expression.
565 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
566 /// can track all the return expressions and then use them to
567 /// compute a useful coercion from the set, similar to a match
568 /// expression or other branching context. You can use methods
569 /// like `expected_ty` to access the declared return type (if
571 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
573 /// First span of a return site that we find. Used in error messages.
574 ret_coercion_span: RefCell<Option<Span>>,
576 yield_ty: Option<Ty<'tcx>>,
578 ps: RefCell<UnsafetyState>,
580 /// Whether the last checked node generates a divergence (e.g.,
581 /// `return` will set this to `Always`). In general, when entering
582 /// an expression or other node in the tree, the initial value
583 /// indicates whether prior parts of the containing expression may
584 /// have diverged. It is then typically set to `Maybe` (and the
585 /// old value remembered) for processing the subparts of the
586 /// current expression. As each subpart is processed, they may set
587 /// the flag to `Always`, etc. Finally, at the end, we take the
588 /// result and "union" it with the original value, so that when we
589 /// return the flag indicates if any subpart of the parent
590 /// expression (up to and including this part) has diverged. So,
591 /// if you read it after evaluating a subexpression `X`, the value
592 /// you get indicates whether any subexpression that was
593 /// evaluating up to and including `X` diverged.
595 /// We currently use this flag only for diagnostic purposes:
597 /// - To warn about unreachable code: if, after processing a
598 /// sub-expression but before we have applied the effects of the
599 /// current node, we see that the flag is set to `Always`, we
600 /// can issue a warning. This corresponds to something like
601 /// `foo(return)`; we warn on the `foo()` expression. (We then
602 /// update the flag to `WarnedAlways` to suppress duplicate
603 /// reports.) Similarly, if we traverse to a fresh statement (or
604 /// tail expression) from a `Always` setting, we will issue a
605 /// warning. This corresponds to something like `{return;
606 /// foo();}` or `{return; 22}`, where we would warn on the
609 /// An expression represents dead code if, after checking it,
610 /// the diverges flag is set to something other than `Maybe`.
611 diverges: Cell<Diverges>,
613 /// Whether any child nodes have any type errors.
614 has_errors: Cell<bool>,
616 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
618 inh: &'a Inherited<'a, 'tcx>,
621 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
622 type Target = Inherited<'a, 'tcx>;
623 fn deref(&self) -> &Self::Target {
628 /// Helper type of a temporary returned by `Inherited::build(...)`.
629 /// Necessary because we can't write the following bound:
630 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
631 pub struct InheritedBuilder<'tcx> {
632 infcx: infer::InferCtxtBuilder<'tcx>,
636 impl Inherited<'_, 'tcx> {
637 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
638 let hir_id_root = if def_id.is_local() {
639 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
640 DefId::local(hir_id.owner)
646 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
652 impl<'tcx> InheritedBuilder<'tcx> {
653 fn enter<F, R>(&mut self, f: F) -> R
655 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
657 let def_id = self.def_id;
658 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
662 impl Inherited<'a, 'tcx> {
663 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
665 let item_id = tcx.hir().as_local_hir_id(def_id);
666 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
667 let implicit_region_bound = body_id.map(|body_id| {
668 let body = tcx.hir().body(body_id);
669 tcx.mk_region(ty::ReScope(region::Scope {
670 id: body.value.hir_id.local_id,
671 data: region::ScopeData::CallSite,
676 tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
678 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
679 locals: RefCell::new(Default::default()),
680 deferred_sized_obligations: RefCell::new(Vec::new()),
681 deferred_call_resolutions: RefCell::new(Default::default()),
682 deferred_cast_checks: RefCell::new(Vec::new()),
683 deferred_generator_interiors: RefCell::new(Vec::new()),
684 opaque_types: RefCell::new(Default::default()),
685 opaque_types_vars: RefCell::new(Default::default()),
686 implicit_region_bound,
691 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
692 debug!("register_predicate({:?})", obligation);
693 if obligation.has_escaping_bound_vars() {
694 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
696 self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
699 fn register_predicates<I>(&self, obligations: I)
701 I: IntoIterator<Item = traits::PredicateObligation<'tcx>>,
703 for obligation in obligations {
704 self.register_predicate(obligation);
708 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
709 self.register_predicates(infer_ok.obligations);
713 fn normalize_associated_types_in<T>(
717 param_env: ty::ParamEnv<'tcx>,
721 T: TypeFoldable<'tcx>,
723 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
724 self.register_infer_ok_obligations(ok)
728 struct CheckItemTypesVisitor<'tcx> {
732 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
733 fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
734 check_item_type(self.tcx, i);
736 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
737 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
740 pub fn check_wf_new(tcx: TyCtxt<'_>) {
741 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
742 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
745 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
746 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
749 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
750 debug_assert!(crate_num == LOCAL_CRATE);
751 tcx.par_body_owners(|body_owner_def_id| {
752 tcx.ensure().typeck_tables_of(body_owner_def_id);
756 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
757 wfcheck::check_item_well_formed(tcx, def_id);
760 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
761 wfcheck::check_trait_item(tcx, def_id);
764 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
765 wfcheck::check_impl_item(tcx, def_id);
768 pub fn provide(providers: &mut Providers<'_>) {
769 method::provide(providers);
770 *providers = Providers {
773 diagnostic_only_typeck_tables_of,
777 check_item_well_formed,
778 check_trait_item_well_formed,
779 check_impl_item_well_formed,
780 check_mod_item_types,
785 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
786 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
789 /// If this `DefId` is a "primary tables entry", returns
790 /// `Some((body_id, header, decl))` with information about
791 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
794 /// If this function returns `Some`, then `typeck_tables(def_id)` will
795 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
796 /// may not succeed. In some cases where this function returns `None`
797 /// (notably closures), `typeck_tables(def_id)` would wind up
798 /// redirecting to the owning function.
802 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
803 match tcx.hir().get(id) {
804 Node::Item(item) => match item.kind {
805 hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
806 Some((body, Some(ty), None, None))
808 hir::ItemKind::Fn(ref sig, .., body) => {
809 Some((body, None, Some(&sig.header), Some(&sig.decl)))
813 Node::TraitItem(item) => match item.kind {
814 hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
815 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
816 Some((body, None, Some(&sig.header), Some(&sig.decl)))
820 Node::ImplItem(item) => match item.kind {
821 hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
822 hir::ImplItemKind::Method(ref sig, body) => {
823 Some((body, None, Some(&sig.header), Some(&sig.decl)))
827 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
832 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
833 // Closures' tables come from their outermost function,
834 // as they are part of the same "inference environment".
835 let outer_def_id = tcx.closure_base_def_id(def_id);
836 if outer_def_id != def_id {
837 return tcx.has_typeck_tables(outer_def_id);
840 if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
841 primary_body_of(tcx, id).is_some()
847 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
848 &*tcx.typeck_tables_of(def_id).used_trait_imports
851 /// Inspects the substs of opaque types, replacing any inference variables
852 /// with proper generic parameter from the identity substs.
854 /// This is run after we normalize the function signature, to fix any inference
855 /// variables introduced by the projection of associated types. This ensures that
856 /// any opaque types used in the signature continue to refer to generic parameters,
857 /// allowing them to be considered for defining uses in the function body
859 /// For example, consider this code.
864 /// fn use_it(self) -> Self::MyItem
866 /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
867 /// type MyItem = impl Iterator<Item = I>;
868 /// fn use_it(self) -> Self::MyItem {
874 /// When we normalize the signature of `use_it` from the impl block,
875 /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
876 /// However, this projection result may contain inference variables, due
877 /// to the way that projection works. We didn't have any inference variables
878 /// in the signature to begin with - leaving them in will cause us to incorrectly
879 /// conclude that we don't have a defining use of `MyItem`. By mapping inference
880 /// variables back to the actual generic parameters, we will correctly see that
881 /// we have a defining use of `MyItem`
882 fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T
884 T: TypeFoldable<'tcx>,
886 struct FixupFolder<'tcx> {
890 impl<'tcx> TypeFolder<'tcx> for FixupFolder<'tcx> {
891 fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
895 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
897 ty::Opaque(def_id, substs) => {
898 debug!("fixup_opaque_types: found type {:?}", ty);
899 // Here, we replace any inference variables that occur within
900 // the substs of an opaque type. By definition, any type occuring
901 // in the substs has a corresponding generic parameter, which is what
902 // we replace it with.
903 // This replacement is only run on the function signature, so any
904 // inference variables that we come across must be the rust of projection
905 // (there's no other way for a user to get inference variables into
906 // a function signature).
907 if ty.needs_infer() {
908 let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
909 let old_param = substs[param.index as usize];
910 match old_param.unpack() {
911 GenericArgKind::Type(old_ty) => {
912 if let ty::Infer(_) = old_ty.kind {
913 // Replace inference type with a generic parameter
914 self.tcx.mk_param_from_def(param)
916 old_param.fold_with(self)
919 GenericArgKind::Const(old_const) => {
920 if let ty::ConstKind::Infer(_) = old_const.val {
921 // This should never happen - we currently do not support
922 // 'const projections', e.g.:
923 // `impl<T: SomeTrait> MyTrait for T where <T as SomeTrait>::MyConst == 25`
924 // which should be the only way for us to end up with a const inference
925 // variable after projection. If Rust ever gains support for this kind
926 // of projection, this should *probably* be changed to
927 // `self.tcx.mk_param_from_def(param)`
929 "Found infer const: `{:?}` in opaque type: {:?}",
934 old_param.fold_with(self)
937 GenericArgKind::Lifetime(old_region) => {
938 if let RegionKind::ReVar(_) = old_region {
939 self.tcx.mk_param_from_def(param)
941 old_param.fold_with(self)
946 let new_ty = self.tcx.mk_opaque(def_id, new_substs);
947 debug!("fixup_opaque_types: new type: {:?}", new_ty);
953 _ => ty.super_fold_with(self),
958 debug!("fixup_opaque_types({:?})", val);
959 val.fold_with(&mut FixupFolder { tcx })
962 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &ty::TypeckTables<'tcx> {
963 let fallback = move || tcx.type_of(def_id);
964 typeck_tables_of_with_fallback(tcx, def_id, fallback)
967 /// Used only to get `TypeckTables` for type inference during error recovery.
968 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
969 fn diagnostic_only_typeck_tables_of<'tcx>(
972 ) -> &ty::TypeckTables<'tcx> {
973 assert!(def_id.is_local());
974 let fallback = move || {
975 let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id).unwrap());
976 tcx.sess.delay_span_bug(span, "diagnostic only typeck table used");
979 typeck_tables_of_with_fallback(tcx, def_id, fallback)
982 fn typeck_tables_of_with_fallback<'tcx>(
985 fallback: impl Fn() -> Ty<'tcx> + 'tcx,
986 ) -> &'tcx ty::TypeckTables<'tcx> {
987 // Closures' tables come from their outermost function,
988 // as they are part of the same "inference environment".
989 let outer_def_id = tcx.closure_base_def_id(def_id);
990 if outer_def_id != def_id {
991 return tcx.typeck_tables_of(outer_def_id);
994 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
995 let span = tcx.hir().span(id);
997 // Figure out what primary body this item has.
998 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
999 span_bug!(span, "can't type-check body of {:?}", def_id);
1001 let body = tcx.hir().body(body_id);
1003 let tables = Inherited::build(tcx, def_id).enter(|inh| {
1004 let param_env = tcx.param_env(def_id);
1005 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
1006 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
1007 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1008 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl, &[], None)
1013 check_abi(tcx, span, fn_sig.abi());
1015 // Compute the fty from point of view of inside the fn.
1016 let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
1017 let fn_sig = inh.normalize_associated_types_in(
1024 let fn_sig = fixup_opaque_types(tcx, &fn_sig);
1026 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
1029 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1030 let expected_type = body_ty
1031 .and_then(|ty| match ty.kind {
1032 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
1035 .unwrap_or_else(fallback);
1036 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
1037 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
1039 let revealed_ty = if tcx.features().impl_trait_in_bindings {
1040 fcx.instantiate_opaque_types_from_value(id, &expected_type, body.value.span)
1045 // Gather locals in statics (because of block expressions).
1046 GatherLocalsVisitor { fcx: &fcx, parent_id: id }.visit_body(body);
1048 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
1050 fcx.write_ty(id, revealed_ty);
1055 // All type checking constraints were added, try to fallback unsolved variables.
1056 fcx.select_obligations_where_possible(false, |_| {});
1057 let mut fallback_has_occurred = false;
1059 // We do fallback in two passes, to try to generate
1060 // better error messages.
1061 // The first time, we do *not* replace opaque types.
1062 for ty in &fcx.unsolved_variables() {
1063 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
1065 // We now see if we can make progress. This might
1066 // cause us to unify inference variables for opaque types,
1067 // since we may have unified some other type variables
1068 // during the first phase of fallback.
1069 // This means that we only replace inference variables with their underlying
1070 // opaque types as a last resort.
1072 // In code like this:
1075 // type MyType = impl Copy;
1076 // fn produce() -> MyType { true }
1077 // fn bad_produce() -> MyType { panic!() }
1080 // we want to unify the opaque inference variable in `bad_produce`
1081 // with the diverging fallback for `panic!` (e.g. `()` or `!`).
1082 // This will produce a nice error message about conflicting concrete
1083 // types for `MyType`.
1085 // If we had tried to fallback the opaque inference variable to `MyType`,
1086 // we will generate a confusing type-check error that does not explicitly
1087 // refer to opaque types.
1088 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1090 // We now run fallback again, but this time we allow it to replace
1091 // unconstrained opaque type variables, in addition to performing
1092 // other kinds of fallback.
1093 for ty in &fcx.unsolved_variables() {
1094 fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
1097 // See if we can make any more progress.
1098 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
1100 // Even though coercion casts provide type hints, we check casts after fallback for
1101 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
1104 // Closure and generator analysis may run after fallback
1105 // because they don't constrain other type variables.
1106 fcx.closure_analyze(body);
1107 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
1108 fcx.resolve_generator_interiors(def_id);
1110 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
1111 let ty = fcx.normalize_ty(span, ty);
1112 fcx.require_type_is_sized(ty, span, code);
1115 fcx.select_all_obligations_or_error();
1117 if fn_decl.is_some() {
1118 fcx.regionck_fn(id, body);
1120 fcx.regionck_expr(body);
1123 fcx.resolve_type_vars_in_body(body)
1126 // Consistency check our TypeckTables instance can hold all ItemLocalIds
1127 // it will need to hold.
1128 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
1133 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
1134 if !tcx.sess.target.target.is_abi_supported(abi) {
1139 "The ABI `{}` is not supported for the current target",
1146 struct GatherLocalsVisitor<'a, 'tcx> {
1147 fcx: &'a FnCtxt<'a, 'tcx>,
1148 parent_id: hir::HirId,
1151 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
1152 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
1155 // infer the variable's type
1156 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
1157 kind: TypeVariableOriginKind::TypeInference,
1163 .insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
1167 // take type that the user specified
1168 self.fcx.locals.borrow_mut().insert(nid, typ);
1175 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1176 type Map = Map<'tcx>;
1178 fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> {
1179 NestedVisitorMap::None
1182 // Add explicitly-declared locals.
1183 fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1184 let local_ty = match local.ty {
1186 let o_ty = self.fcx.to_ty(&ty);
1188 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1189 self.fcx.instantiate_opaque_types_from_value(self.parent_id, &o_ty, ty.span)
1198 .canonicalize_user_type_annotation(&UserType::Ty(revealed_ty));
1200 "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1201 ty.hir_id, o_ty, revealed_ty, c_ty
1203 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1205 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1209 self.assign(local.span, local.hir_id, local_ty);
1212 "local variable {:?} is assigned type {}",
1214 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&local.hir_id).unwrap().decl_ty)
1216 intravisit::walk_local(self, local);
1219 // Add pattern bindings.
1220 fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
1221 if let PatKind::Binding(_, _, ident, _) = p.kind {
1222 let var_ty = self.assign(p.span, p.hir_id, None);
1224 if !self.fcx.tcx.features().unsized_locals {
1225 self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
1229 "pattern binding {} is assigned to {} with type {:?}",
1231 self.fcx.ty_to_string(&*self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
1235 intravisit::walk_pat(self, p);
1238 // Don't descend into the bodies of nested closures
1241 _: intravisit::FnKind<'tcx>,
1242 _: &'tcx hir::FnDecl<'tcx>,
1250 /// When `check_fn` is invoked on a generator (i.e., a body that
1251 /// includes yield), it returns back some information about the yield
1253 struct GeneratorTypes<'tcx> {
1254 /// Type of value that is yielded.
1257 /// Types that are captured (see `GeneratorInterior` for more).
1260 /// Indicates if the generator is movable or static (immovable).
1261 movability: hir::Movability,
1264 /// Helper used for fns and closures. Does the grungy work of checking a function
1265 /// body and returns the function context used for that purpose, since in the case of a fn item
1266 /// there is still a bit more to do.
1269 /// * inherited: other fields inherited from the enclosing fn (if any)
1270 fn check_fn<'a, 'tcx>(
1271 inherited: &'a Inherited<'a, 'tcx>,
1272 param_env: ty::ParamEnv<'tcx>,
1273 fn_sig: ty::FnSig<'tcx>,
1274 decl: &'tcx hir::FnDecl<'tcx>,
1276 body: &'tcx hir::Body<'tcx>,
1277 can_be_generator: Option<hir::Movability>,
1278 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1279 let mut fn_sig = fn_sig;
1281 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1283 // Create the function context. This is either derived from scratch or,
1284 // in the case of closures, based on the outer context.
1285 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1286 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1289 let sess = tcx.sess;
1290 let hir = tcx.hir();
1292 let declared_ret_ty = fn_sig.output();
1293 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1294 let revealed_ret_ty =
1295 fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
1296 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1297 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1298 fn_sig = tcx.mk_fn_sig(
1299 fn_sig.inputs().iter().cloned(),
1306 let span = body.value.span;
1308 fn_maybe_err(tcx, span, fn_sig.abi);
1310 if body.generator_kind.is_some() && can_be_generator.is_some() {
1312 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
1313 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1314 fcx.yield_ty = Some(yield_ty);
1317 let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
1318 let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap();
1319 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
1321 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1322 // (as it's created inside the body itself, not passed in from outside).
1323 let maybe_va_list = if fn_sig.c_variadic {
1324 let va_list_did = tcx.require_lang_item(
1325 lang_items::VaListTypeLangItem,
1326 Some(body.params.last().unwrap().span),
1328 let region = tcx.mk_region(ty::ReScope(region::Scope {
1329 id: body.value.hir_id.local_id,
1330 data: region::ScopeData::CallSite,
1333 Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
1338 // Add formal parameters.
1339 let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
1340 let inputs_fn = fn_sig.inputs().iter().copied();
1341 for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
1342 // Check the pattern.
1343 fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1345 // Check that argument is Sized.
1346 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1347 // for simple cases like `fn foo(x: Trait)`,
1348 // where we would error once on the parameter as a whole, and once on the binding `x`.
1349 if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1350 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1353 fcx.write_ty(param.hir_id, param_ty);
1356 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1358 fcx.check_return_expr(&body.value);
1360 // We insert the deferred_generator_interiors entry after visiting the body.
1361 // This ensures that all nested generators appear before the entry of this generator.
1362 // resolve_generator_interiors relies on this property.
1363 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1365 .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
1366 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1367 Some(GeneratorTypes {
1368 yield_ty: fcx.yield_ty.unwrap(),
1370 movability: can_be_generator.unwrap(),
1376 // Finalize the return check by taking the LUB of the return types
1377 // we saw and assigning it to the expected return type. This isn't
1378 // really expected to fail, since the coercions would have failed
1379 // earlier when trying to find a LUB.
1381 // However, the behavior around `!` is sort of complex. In the
1382 // event that the `actual_return_ty` comes back as `!`, that
1383 // indicates that the fn either does not return or "returns" only
1384 // values of type `!`. In this case, if there is an expected
1385 // return type that is *not* `!`, that should be ok. But if the
1386 // return type is being inferred, we want to "fallback" to `!`:
1388 // let x = move || panic!();
1390 // To allow for that, I am creating a type variable with diverging
1391 // fallback. This was deemed ever so slightly better than unifying
1392 // the return value with `!` because it allows for the caller to
1393 // make more assumptions about the return type (e.g., they could do
1395 // let y: Option<u32> = Some(x());
1397 // which would then cause this return type to become `u32`, not
1399 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1400 let mut actual_return_ty = coercion.complete(&fcx);
1401 if actual_return_ty.is_never() {
1402 actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
1403 kind: TypeVariableOriginKind::DivergingFn,
1407 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1409 // Check that the main return type implements the termination trait.
1410 if let Some(term_id) = tcx.lang_items().termination() {
1411 if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
1412 let main_id = hir.as_local_hir_id(def_id).unwrap();
1413 if main_id == fn_id {
1414 let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
1415 let trait_ref = ty::TraitRef::new(term_id, substs);
1416 let return_ty_span = decl.output.span();
1417 let cause = traits::ObligationCause::new(
1420 ObligationCauseCode::MainFunctionType,
1423 inherited.register_predicate(traits::Obligation::new(
1426 trait_ref.without_const().to_predicate(),
1432 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1433 if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
1434 if panic_impl_did == hir.local_def_id(fn_id) {
1435 if let Some(panic_info_did) = tcx.lang_items().panic_info() {
1436 if declared_ret_ty.kind != ty::Never {
1437 sess.span_err(decl.output.span(), "return type should be `!`");
1440 let inputs = fn_sig.inputs();
1441 let span = hir.span(fn_id);
1442 if inputs.len() == 1 {
1443 let arg_is_panic_info = match inputs[0].kind {
1444 ty::Ref(region, ty, mutbl) => match ty.kind {
1445 ty::Adt(ref adt, _) => {
1446 adt.did == panic_info_did
1447 && mutbl == hir::Mutability::Not
1448 && *region != RegionKind::ReStatic
1455 if !arg_is_panic_info {
1456 sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
1459 if let Node::Item(item) = hir.get(fn_id) {
1460 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1461 if !generics.params.is_empty() {
1462 sess.span_err(span, "should have no type parameters");
1467 let span = sess.source_map().def_span(span);
1468 sess.span_err(span, "function should have one argument");
1471 sess.err("language item required, but not found: `panic_info`");
1476 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1477 if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
1478 if alloc_error_handler_did == hir.local_def_id(fn_id) {
1479 if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
1480 if declared_ret_ty.kind != ty::Never {
1481 sess.span_err(decl.output.span(), "return type should be `!`");
1484 let inputs = fn_sig.inputs();
1485 let span = hir.span(fn_id);
1486 if inputs.len() == 1 {
1487 let arg_is_alloc_layout = match inputs[0].kind {
1488 ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
1492 if !arg_is_alloc_layout {
1493 sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
1496 if let Node::Item(item) = hir.get(fn_id) {
1497 if let ItemKind::Fn(_, ref generics, _) = item.kind {
1498 if !generics.params.is_empty() {
1501 "`#[alloc_error_handler]` function should have no type \
1508 let span = sess.source_map().def_span(span);
1509 sess.span_err(span, "function should have one argument");
1512 sess.err("language item required, but not found: `alloc_layout`");
1520 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1521 let def_id = tcx.hir().local_def_id(id);
1522 let def = tcx.adt_def(def_id);
1523 def.destructor(tcx); // force the destructor to be evaluated
1524 check_representable(tcx, span, def_id);
1526 if def.repr.simd() {
1527 check_simd(tcx, span, def_id);
1530 check_transparent(tcx, span, def_id);
1531 check_packed(tcx, span, def_id);
1534 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1535 let def_id = tcx.hir().local_def_id(id);
1536 let def = tcx.adt_def(def_id);
1537 def.destructor(tcx); // force the destructor to be evaluated
1538 check_representable(tcx, span, def_id);
1539 check_transparent(tcx, span, def_id);
1540 check_union_fields(tcx, span, def_id);
1541 check_packed(tcx, span, def_id);
1544 /// When the `#![feature(untagged_unions)]` gate is active,
1545 /// check that the fields of the `union` does not contain fields that need dropping.
1546 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1547 let item_type = tcx.type_of(item_def_id);
1548 if let ty::Adt(def, substs) = item_type.kind {
1549 assert!(def.is_union());
1550 let fields = &def.non_enum_variant().fields;
1551 for field in fields {
1552 let field_ty = field.ty(tcx, substs);
1553 // We are currently checking the type this field came from, so it must be local.
1554 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1555 let param_env = tcx.param_env(field.did);
1556 if field_ty.needs_drop(tcx, param_env) {
1561 "unions may not contain fields that need dropping"
1563 .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
1569 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1574 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1575 /// projections that would result in "inheriting lifetimes".
1576 fn check_opaque<'tcx>(
1579 substs: SubstsRef<'tcx>,
1581 origin: &hir::OpaqueTyOrigin,
1583 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1584 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1587 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1588 /// in "inheriting lifetimes".
1589 fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span: Span) {
1591 tcx.hir().expect_item(tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1593 "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1598 struct ProhibitOpaqueVisitor<'tcx> {
1599 opaque_identity_ty: Ty<'tcx>,
1600 generics: &'tcx ty::Generics,
1603 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1604 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1605 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1606 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1609 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1610 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1611 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1612 return *index < self.generics.parent_count as u32;
1615 r.super_visit_with(self)
1619 let prohibit_opaque = match item.kind {
1620 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. })
1621 | ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1622 let mut visitor = ProhibitOpaqueVisitor {
1623 opaque_identity_ty: tcx
1624 .mk_opaque(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1625 generics: tcx.generics_of(def_id),
1627 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1629 tcx.predicates_of(def_id)
1632 .any(|(predicate, _)| predicate.visit_with(&mut visitor))
1637 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1638 if prohibit_opaque {
1639 let is_async = match item.kind {
1640 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1641 hir::OpaqueTyOrigin::AsyncFn => true,
1644 _ => unreachable!(),
1647 tcx.sess.span_err(span, &format!(
1648 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1650 if is_async { "async fn" } else { "impl Trait" },
1655 /// Checks that an opaque type does not contain cycles.
1656 fn check_opaque_for_cycles<'tcx>(
1659 substs: SubstsRef<'tcx>,
1661 origin: &hir::OpaqueTyOrigin,
1663 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1664 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1665 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
1666 .span_label(span, "recursive `async fn`")
1667 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1671 struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
1672 err.span_label(span, "expands to a recursive type");
1673 if let ty::Opaque(..) = partially_expanded_type.kind {
1674 err.note("type resolves to itself");
1676 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1683 // Forbid defining intrinsics in Rust code,
1684 // as they must always be defined by the compiler.
1685 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1686 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1687 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1691 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
1693 "check_item_type(it.hir_id={}, it.name={})",
1695 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1697 let _indenter = indenter();
1699 // Consts can play a role in type-checking, so they are included here.
1700 hir::ItemKind::Static(..) => {
1701 let def_id = tcx.hir().local_def_id(it.hir_id);
1702 tcx.typeck_tables_of(def_id);
1703 maybe_check_static_with_link_section(tcx, def_id, it.span);
1705 hir::ItemKind::Const(..) => {
1706 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1708 hir::ItemKind::Enum(ref enum_definition, _) => {
1709 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1711 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1712 hir::ItemKind::Impl { ref items, .. } => {
1713 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1714 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1715 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1716 check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
1717 let trait_def_id = impl_trait_ref.def_id;
1718 check_on_unimplemented(tcx, trait_def_id, it);
1721 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1722 let def_id = tcx.hir().local_def_id(it.hir_id);
1723 check_on_unimplemented(tcx, def_id, it);
1725 for item in items.iter() {
1726 let item = tcx.hir().trait_item(item.id);
1727 if let hir::TraitItemKind::Method(sig, _) = &item.kind {
1728 let abi = sig.header.abi;
1729 fn_maybe_err(tcx, item.ident.span, abi);
1733 hir::ItemKind::Struct(..) => {
1734 check_struct(tcx, it.hir_id, it.span);
1736 hir::ItemKind::Union(..) => {
1737 check_union(tcx, it.hir_id, it.span);
1739 hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1740 let def_id = tcx.hir().local_def_id(it.hir_id);
1742 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1743 check_opaque(tcx, def_id, substs, it.span, &origin);
1745 hir::ItemKind::TyAlias(..) => {
1746 let def_id = tcx.hir().local_def_id(it.hir_id);
1747 let pty_ty = tcx.type_of(def_id);
1748 let generics = tcx.generics_of(def_id);
1749 check_bounds_are_used(tcx, &generics, pty_ty);
1751 hir::ItemKind::ForeignMod(ref m) => {
1752 check_abi(tcx, it.span, m.abi);
1754 if m.abi == Abi::RustIntrinsic {
1755 for item in m.items {
1756 intrinsic::check_intrinsic_type(tcx, item);
1758 } else if m.abi == Abi::PlatformIntrinsic {
1759 for item in m.items {
1760 intrinsic::check_platform_intrinsic_type(tcx, item);
1763 for item in m.items {
1764 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1765 let own_counts = generics.own_counts();
1766 if generics.params.len() - own_counts.lifetimes != 0 {
1767 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1768 (_, 0) => ("type", "types", Some("u32")),
1769 // We don't specify an example value, because we can't generate
1770 // a valid value for any type.
1771 (0, _) => ("const", "consts", None),
1772 _ => ("type or const", "types or consts", None),
1778 "foreign items may not have {} parameters",
1781 .span_label(item.span, &format!("can't have {} parameters", kinds))
1783 // FIXME: once we start storing spans for type arguments, turn this
1784 // into a suggestion.
1786 "replace the {} parameters with concrete {}{}",
1789 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1795 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1796 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1801 _ => { /* nothing to do */ }
1805 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1806 // Only restricted on wasm32 target for now
1807 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1811 // If `#[link_section]` is missing, then nothing to verify
1812 let attrs = tcx.codegen_fn_attrs(id);
1813 if attrs.link_section.is_none() {
1817 // For the wasm32 target statics with `#[link_section]` are placed into custom
1818 // sections of the final output file, but this isn't link custom sections of
1819 // other executable formats. Namely we can only embed a list of bytes,
1820 // nothing with pointers to anything else or relocations. If any relocation
1821 // show up, reject them here.
1822 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1823 // the consumer's responsibility to ensure all bytes that have been read
1824 // have defined values.
1825 if let Ok(static_) = tcx.const_eval_poly(id) {
1826 let alloc = if let ty::ConstKind::Value(ConstValue::ByRef { alloc, .. }) = static_.val {
1829 bug!("Matching on non-ByRef static")
1831 if alloc.relocations().len() != 0 {
1832 let msg = "statics with a custom `#[link_section]` must be a \
1833 simple list of bytes on the wasm target with no \
1834 extra levels of indirection such as references";
1835 tcx.sess.span_err(span, msg);
1840 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
1841 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1842 // an error would be reported if this fails.
1843 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1846 fn report_forbidden_specialization(
1848 impl_item: &hir::ImplItem<'_>,
1851 let mut err = struct_span_err!(
1855 "`{}` specializes an item from a parent `impl`, but \
1856 that item is not marked `default`",
1859 err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
1861 match tcx.span_of_impl(parent_impl) {
1863 err.span_label(span, "parent `impl` is here");
1865 "to specialize, `{}` in the parent `impl` must be marked `default`",
1870 err.note(&format!("parent implementation is in crate `{}`", cname));
1877 fn check_specialization_validity<'tcx>(
1879 trait_def: &ty::TraitDef,
1880 trait_item: &ty::AssocItem,
1882 impl_item: &hir::ImplItem<'_>,
1884 let kind = match impl_item.kind {
1885 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1886 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1887 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1888 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1891 let mut ancestor_impls = trait_def
1892 .ancestors(tcx, impl_id)
1894 .filter_map(|parent| {
1895 if parent.is_from_trait() {
1898 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1903 if ancestor_impls.peek().is_none() {
1904 // No parent, nothing to specialize.
1908 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1910 // Parent impl exists, and contains the parent item we're trying to specialize, but
1911 // doesn't mark it `default`.
1912 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1913 Some(Err(parent_impl.def_id()))
1916 // Parent impl contains item and makes it specializable.
1917 Some(_) => Some(Ok(())),
1919 // Parent impl doesn't mention the item. This means it's inherited from the
1920 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1921 // "defaultness" from the grandparent, else they are final.
1923 if traits::impl_is_default(tcx, parent_impl.def_id()) {
1926 Some(Err(parent_impl.def_id()))
1932 // If `opt_result` is `None`, we have only encoutered `default impl`s that don't contain the
1933 // item. This is allowed, the item isn't actually getting specialized here.
1934 let result = opt_result.unwrap_or(Ok(()));
1936 if let Err(parent_impl) = result {
1937 report_forbidden_specialization(tcx, impl_item, parent_impl);
1941 fn check_impl_items_against_trait<'tcx>(
1943 full_impl_span: Span,
1945 impl_trait_ref: ty::TraitRef<'tcx>,
1946 impl_item_refs: &[hir::ImplItemRef<'_>],
1948 let impl_span = tcx.sess.source_map().def_span(full_impl_span);
1950 // If the trait reference itself is erroneous (so the compilation is going
1951 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1952 // isn't populated for such impls.
1953 if impl_trait_ref.references_error() {
1957 // Locate trait definition and items
1958 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1959 let mut overridden_associated_type = None;
1961 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1963 // Check existing impl methods to see if they are both present in trait
1964 // and compatible with trait signature
1965 for impl_item in impl_items() {
1966 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id));
1967 let ty_trait_item = tcx
1968 .associated_items(impl_trait_ref.def_id)
1970 Namespace::from(&impl_item.kind) == Namespace::from(ac.kind)
1971 && tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id)
1974 // Not compatible, but needed for the error message
1975 tcx.associated_items(impl_trait_ref.def_id)
1976 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1979 // Check that impl definition matches trait definition
1980 if let Some(ty_trait_item) = ty_trait_item {
1981 match impl_item.kind {
1982 hir::ImplItemKind::Const(..) => {
1983 // Find associated const definition.
1984 if ty_trait_item.kind == ty::AssocKind::Const {
1993 let mut err = struct_span_err!(
1997 "item `{}` is an associated const, \
1998 which doesn't match its trait `{}`",
2000 impl_trait_ref.print_only_trait_path()
2002 err.span_label(impl_item.span, "does not match trait");
2003 // We can only get the spans from local trait definition
2004 // Same for E0324 and E0325
2005 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
2006 err.span_label(trait_span, "item in trait");
2011 hir::ImplItemKind::Method(..) => {
2012 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2013 if ty_trait_item.kind == ty::AssocKind::Method {
2014 compare_impl_method(
2023 let mut err = struct_span_err!(
2027 "item `{}` is an associated method, \
2028 which doesn't match its trait `{}`",
2030 impl_trait_ref.print_only_trait_path()
2032 err.span_label(impl_item.span, "does not match trait");
2033 if let Some(trait_span) = opt_trait_span {
2034 err.span_label(trait_span, "item in trait");
2039 hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {
2040 let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
2041 if ty_trait_item.kind == ty::AssocKind::Type {
2042 if ty_trait_item.defaultness.has_value() {
2043 overridden_associated_type = Some(impl_item);
2054 let mut err = struct_span_err!(
2058 "item `{}` is an associated type, \
2059 which doesn't match its trait `{}`",
2061 impl_trait_ref.print_only_trait_path()
2063 err.span_label(impl_item.span, "does not match trait");
2064 if let Some(trait_span) = opt_trait_span {
2065 err.span_label(trait_span, "item in trait");
2072 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
2076 // Check for missing items from trait
2077 let mut missing_items = Vec::new();
2078 let mut invalidated_items = Vec::new();
2079 let associated_type_overridden = overridden_associated_type.is_some();
2080 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
2081 let is_implemented = trait_def
2082 .ancestors(tcx, impl_id)
2083 .leaf_def(tcx, trait_item.ident, trait_item.kind)
2084 .map(|node_item| !node_item.node.is_from_trait())
2087 if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
2088 if !trait_item.defaultness.has_value() {
2089 missing_items.push(trait_item);
2090 } else if associated_type_overridden {
2091 invalidated_items.push(trait_item.ident);
2096 if !missing_items.is_empty() {
2097 missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
2100 if !invalidated_items.is_empty() {
2101 let invalidator = overridden_associated_type.unwrap();
2106 "the following trait items need to be reimplemented as `{}` was overridden: `{}`",
2108 invalidated_items.iter().map(|name| name.to_string()).collect::<Vec<_>>().join("`, `")
2114 fn missing_items_err(
2117 missing_items: &[ty::AssocItem],
2118 full_impl_span: Span,
2120 let missing_items_msg = missing_items
2122 .map(|trait_item| trait_item.ident.to_string())
2123 .collect::<Vec<_>>()
2126 let mut err = struct_span_err!(
2130 "not all trait items implemented, missing: `{}`",
2133 err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
2135 // `Span` before impl block closing brace.
2136 let hi = full_impl_span.hi() - BytePos(1);
2137 // Point at the place right before the closing brace of the relevant `impl` to suggest
2138 // adding the associated item at the end of its body.
2139 let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
2140 // Obtain the level of indentation ending in `sugg_sp`.
2141 let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
2142 // Make the whitespace that will make the suggestion have the right indentation.
2143 let padding: String = (0..indentation).map(|_| " ").collect();
2145 for trait_item in missing_items {
2146 let snippet = suggestion_signature(&trait_item, tcx);
2147 let code = format!("{}{}\n{}", padding, snippet, padding);
2148 let msg = format!("implement the missing item: `{}`", snippet);
2149 let appl = Applicability::HasPlaceholders;
2150 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
2151 err.span_label(span, format!("`{}` from trait", trait_item.ident));
2152 err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
2154 err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
2160 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
2161 fn bounds_from_generic_predicates(
2163 predicates: ty::GenericPredicates<'_>,
2164 ) -> (String, String) {
2165 let mut types: FxHashMap<Ty<'_>, Vec<DefId>> = FxHashMap::default();
2166 let mut projections = vec![];
2167 for (predicate, _) in predicates.predicates {
2168 debug!("predicate {:?}", predicate);
2170 ty::Predicate::Trait(trait_predicate, _) => {
2171 let entry = types.entry(trait_predicate.skip_binder().self_ty()).or_default();
2172 let def_id = trait_predicate.skip_binder().def_id();
2173 if Some(def_id) != tcx.lang_items().sized_trait() {
2174 // Type params are `Sized` by default, do not add that restriction to the list
2175 // if it is a positive requirement.
2176 entry.push(trait_predicate.skip_binder().def_id());
2179 ty::Predicate::Projection(projection_pred) => {
2180 projections.push(projection_pred);
2185 let generics = if types.is_empty() {
2192 .filter_map(|t| match t.kind {
2193 ty::Param(_) => Some(t.to_string()),
2194 // Avoid suggesting the following:
2195 // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
2198 .collect::<Vec<_>>()
2202 let mut where_clauses = vec![];
2203 for (ty, bounds) in types {
2204 for bound in &bounds {
2205 where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
2208 for projection in &projections {
2209 let p = projection.skip_binder();
2210 // FIXME: this is not currently supported syntax, we should be looking at the `types` and
2211 // insert the associated types where they correspond, but for now lets be "lazy" and
2212 // propose this instead of the following valid resugaring:
2213 // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
2214 where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
2216 let where_clauses = if where_clauses.is_empty() {
2219 format!(" where {}", where_clauses.join(", "))
2221 (generics, where_clauses)
2224 /// Return placeholder code for the given function.
2225 fn fn_sig_suggestion(
2227 sig: &ty::FnSig<'_>,
2229 predicates: ty::GenericPredicates<'_>,
2235 Some(match ty.kind {
2236 ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
2237 ty::Ref(reg, ref_ty, mutability) => {
2238 let reg = match &format!("{}", reg)[..] {
2239 "'_" | "" => String::new(),
2240 reg => format!("{} ", reg),
2243 ty::Param(param) if param.name == kw::SelfUpper => {
2244 format!("&{}{}self", reg, mutability.prefix_str())
2246 _ => format!("_: {:?}", ty),
2249 _ => format!("_: {:?}", ty),
2252 .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
2253 .filter_map(|arg| arg)
2254 .collect::<Vec<String>>()
2256 let output = sig.output();
2257 let output = if !output.is_unit() { format!(" -> {:?}", output) } else { String::new() };
2259 let unsafety = sig.unsafety.prefix_str();
2260 let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
2262 // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
2263 // not be present in the `fn` definition, not will we account for renamed
2264 // lifetimes between the `impl` and the `trait`, but this should be good enough to
2265 // fill in a significant portion of the missing code, and other subsequent
2266 // suggestions can help the user fix the code.
2268 "{}fn {}{}({}){}{} {{ unimplemented!() }}",
2269 unsafety, ident, generics, args, output, where_clauses
2273 /// Return placeholder code for the given associated item.
2274 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
2275 /// structured suggestion.
2276 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
2278 ty::AssocKind::Method => {
2279 // We skip the binder here because the binder would deanonymize all
2280 // late-bound regions, and we don't want method signatures to show up
2281 // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
2282 // regions just fine, showing `fn(&MyType)`.
2285 tcx.fn_sig(assoc.def_id).skip_binder(),
2287 tcx.predicates_of(assoc.def_id),
2290 ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
2291 // FIXME(type_alias_impl_trait): we should print bounds here too.
2292 ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
2293 ty::AssocKind::Const => {
2294 let ty = tcx.type_of(assoc.def_id);
2295 let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
2296 format!("const {}: {:?} = {};", assoc.ident, ty, val)
2301 /// Checks whether a type can be represented in memory. In particular, it
2302 /// identifies types that contain themselves without indirection through a
2303 /// pointer, which would mean their size is unbounded.
2304 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
2305 let rty = tcx.type_of(item_def_id);
2307 // Check that it is possible to represent this type. This call identifies
2308 // (1) types that contain themselves and (2) types that contain a different
2309 // recursive type. It is only necessary to throw an error on those that
2310 // contain themselves. For case 2, there must be an inner type that will be
2311 // caught by case 1.
2312 match rty.is_representable(tcx, sp) {
2313 Representability::SelfRecursive(spans) => {
2314 let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id);
2316 err.span_label(span, "recursive without indirection");
2321 Representability::Representable | Representability::ContainsRecursive => (),
2326 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2327 let t = tcx.type_of(def_id);
2328 if let ty::Adt(def, substs) = t.kind {
2329 if def.is_struct() {
2330 let fields = &def.non_enum_variant().fields;
2331 if fields.is_empty() {
2332 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
2335 let e = fields[0].ty(tcx, substs);
2336 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2337 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2338 .span_label(sp, "SIMD elements must have the same type")
2343 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2344 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2350 "SIMD vector element type should be machine type"
2360 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2361 let repr = tcx.adt_def(def_id).repr;
2363 for attr in tcx.get_attrs(def_id).iter() {
2364 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2365 if let attr::ReprPacked(pack) = r {
2366 if let Some(repr_pack) = repr.pack {
2367 if pack as u64 != repr_pack.bytes() {
2372 "type has conflicting packed representation hints"
2380 if repr.align.is_some() {
2385 "type has conflicting packed and align representation hints"
2389 if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) {
2390 let mut err = struct_span_err!(
2394 "packed type cannot transitively contain a `#[repr(align)]` type"
2397 let hir = tcx.hir();
2398 if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) {
2399 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2401 tcx.def_span(def_spans[0].0),
2402 &format!("`{}` has a `#[repr(align)]` attribute", ident),
2407 if def_spans.len() > 2 {
2408 let mut first = true;
2409 for (adt_def, span) in def_spans.iter().skip(1).rev() {
2410 if let Some(hir_id) = hir.as_local_hir_id(*adt_def) {
2411 if let Node::Item(Item { ident, .. }) = hir.get(hir_id) {
2416 "`{}` contains a field of type `{}`",
2417 tcx.type_of(def_id),
2421 format!("...which contains a field of type `{}`", ident)
2436 fn check_packed_inner(
2439 stack: &mut Vec<DefId>,
2440 ) -> Option<Vec<(DefId, Span)>> {
2441 if let ty::Adt(def, substs) = tcx.type_of(def_id).kind {
2442 if def.is_struct() || def.is_union() {
2443 if def.repr.align.is_some() {
2444 return Some(vec![(def.did, DUMMY_SP)]);
2448 for field in &def.non_enum_variant().fields {
2449 if let ty::Adt(def, _) = field.ty(tcx, substs).kind {
2450 if !stack.contains(&def.did) {
2451 if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
2452 defs.push((def.did, field.ident.span));
2465 /// Emit an error when encountering more or less than one variant in a transparent enum.
2466 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2467 let variant_spans: Vec<_> = adt
2470 .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
2472 let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
2473 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2474 err.span_label(sp, &msg);
2475 if let [start @ .., end] = &*variant_spans {
2476 for variant_span in start {
2477 err.span_label(*variant_span, "");
2479 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2484 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2486 fn bad_non_zero_sized_fields<'tcx>(
2488 adt: &'tcx ty::AdtDef,
2490 field_spans: impl Iterator<Item = Span>,
2493 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2494 let mut err = struct_span_err!(
2498 "{}transparent {} {}",
2499 if adt.is_enum() { "the variant of a " } else { "" },
2503 err.span_label(sp, &msg);
2504 for sp in field_spans {
2505 err.span_label(sp, "this field is non-zero-sized");
2510 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2511 let adt = tcx.adt_def(def_id);
2512 if !adt.repr.transparent() {
2515 let sp = tcx.sess.source_map().def_span(sp);
2517 if adt.is_union() && !tcx.features().transparent_unions {
2519 &tcx.sess.parse_sess,
2520 sym::transparent_unions,
2522 "transparent unions are unstable",
2527 if adt.variants.len() != 1 {
2528 bad_variant_count(tcx, adt, sp, def_id);
2529 if adt.variants.is_empty() {
2530 // Don't bother checking the fields. No variants (and thus no fields) exist.
2535 // For each field, figure out if it's known to be a ZST and align(1)
2536 let field_infos = adt.all_fields().map(|field| {
2537 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2538 let param_env = tcx.param_env(field.did);
2539 let layout = tcx.layout_of(param_env.and(ty));
2540 // We are currently checking the type this field came from, so it must be local
2541 let span = tcx.hir().span_if_local(field.did).unwrap();
2542 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2543 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2547 let non_zst_fields =
2548 field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
2549 let non_zst_count = non_zst_fields.clone().count();
2550 if non_zst_count != 1 {
2551 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2553 for (span, zst, align1) in field_infos {
2559 "zero-sized field in transparent {} has alignment larger than 1",
2562 .span_label(span, "has alignment larger than 1")
2568 #[allow(trivial_numeric_casts)]
2569 pub fn check_enum<'tcx>(
2572 vs: &'tcx [hir::Variant<'tcx>],
2575 let def_id = tcx.hir().local_def_id(id);
2576 let def = tcx.adt_def(def_id);
2577 def.destructor(tcx); // force the destructor to be evaluated
2580 let attributes = tcx.get_attrs(def_id);
2581 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2586 "unsupported representation for zero-variant enum"
2588 .span_label(sp, "zero-variant enum")
2593 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2594 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2595 if !tcx.features().repr128 {
2597 &tcx.sess.parse_sess,
2600 "repr with 128-bit type is unstable",
2607 if let Some(ref e) = v.disr_expr {
2608 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2612 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2613 let is_unit = |var: &hir::Variant<'_>| match var.data {
2614 hir::VariantData::Unit(..) => true,
2618 let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
2619 let has_non_units = vs.iter().any(|var| !is_unit(var));
2620 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2621 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2623 if disr_non_unit || (disr_units && has_non_units) {
2625 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
2630 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2631 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2632 // Check for duplicate discriminant values
2633 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2634 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2635 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2636 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2637 let i_span = match variant_i.disr_expr {
2638 Some(ref expr) => tcx.hir().span(expr.hir_id),
2639 None => tcx.hir().span(variant_i_hir_id),
2641 let span = match v.disr_expr {
2642 Some(ref expr) => tcx.hir().span(expr.hir_id),
2649 "discriminant value `{}` already exists",
2652 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2653 .span_label(span, format!("enum already has `{}`", disr_vals[i]))
2656 disr_vals.push(discr);
2659 check_representable(tcx, sp, def_id);
2660 check_transparent(tcx, sp, def_id);
2663 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath<'_>) {
2668 "expected unit struct, unit variant or constant, found {} `{}`",
2670 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false))
2675 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2676 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2680 fn item_def_id(&self) -> Option<DefId> {
2684 fn default_constness_for_trait_bounds(&self) -> ast::Constness {
2685 // FIXME: refactor this into a method
2686 let node = self.tcx.hir().get(self.body_id);
2687 if let Some(fn_like) = FnLikeNode::from_node(node) {
2690 ast::Constness::NotConst
2694 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2696 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2697 let item_id = tcx.hir().ty_param_owner(hir_id);
2698 let item_def_id = tcx.hir().local_def_id(item_id);
2699 let generics = tcx.generics_of(item_def_id);
2700 let index = generics.param_def_id_to_index[&def_id];
2701 ty::GenericPredicates {
2703 predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
2704 |&predicate| match predicate {
2705 ty::Predicate::Trait(ref data, _)
2706 if data.skip_binder().self_ty().is_param(index) =>
2708 // HACK(eddyb) should get the original `Span`.
2709 let span = tcx.def_span(def_id);
2710 Some((predicate, span))
2718 fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
2720 Some(def) => infer::EarlyBoundRegion(span, def.name),
2721 None => infer::MiscVariable(span),
2723 Some(self.next_region_var(v))
2726 fn allow_ty_infer(&self) -> bool {
2730 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2731 if let Some(param) = param {
2732 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2737 self.next_ty_var(TypeVariableOrigin {
2738 kind: TypeVariableOriginKind::TypeInference,
2747 param: Option<&ty::GenericParamDef>,
2749 ) -> &'tcx Const<'tcx> {
2750 if let Some(param) = param {
2751 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2756 self.next_const_var(
2758 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
2763 fn projected_ty_from_poly_trait_ref(
2767 item_segment: &hir::PathSegment<'_>,
2768 poly_trait_ref: ty::PolyTraitRef<'tcx>,
2770 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2772 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2776 let item_substs = <dyn AstConv<'tcx>>::create_substs_for_associated_item(
2785 self.tcx().mk_projection(item_def_id, item_substs)
2788 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2789 if ty.has_escaping_bound_vars() {
2790 ty // FIXME: normalization and escaping regions
2792 self.normalize_associated_types_in(span, &ty)
2796 fn set_tainted_by_errors(&self) {
2797 self.infcx.set_tainted_by_errors()
2800 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2801 self.write_ty(hir_id, ty)
2805 /// Controls whether the arguments are tupled. This is used for the call
2808 /// Tupling means that all call-side arguments are packed into a tuple and
2809 /// passed as a single parameter. For example, if tupling is enabled, this
2812 /// fn f(x: (isize, isize))
2814 /// Can be called as:
2821 #[derive(Clone, Eq, PartialEq)]
2822 enum TupleArgumentsFlag {
2827 /// Controls how we perform fallback for unconstrained
2830 /// Do not fallback type variables to opaque types.
2832 /// Perform all possible kinds of fallback, including
2833 /// turning type variables to opaque types.
2837 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2839 inh: &'a Inherited<'a, 'tcx>,
2840 param_env: ty::ParamEnv<'tcx>,
2841 body_id: hir::HirId,
2842 ) -> FnCtxt<'a, 'tcx> {
2846 err_count_on_creation: inh.tcx.sess.err_count(),
2848 ret_coercion_span: RefCell::new(None),
2850 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
2851 diverges: Cell::new(Diverges::Maybe),
2852 has_errors: Cell::new(false),
2853 enclosing_breakables: RefCell::new(EnclosingBreakables {
2855 by_id: Default::default(),
2861 pub fn sess(&self) -> &Session {
2865 pub fn errors_reported_since_creation(&self) -> bool {
2866 self.tcx.sess.err_count() > self.err_count_on_creation
2869 /// Produces warning on the given node, if the current point in the
2870 /// function is unreachable, and there hasn't been another warning.
2871 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2872 // FIXME: Combine these two 'if' expressions into one once
2873 // let chains are implemented
2874 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2875 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2876 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2877 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2878 if !span.is_desugaring(DesugaringKind::CondTemporary)
2879 && !span.is_desugaring(DesugaringKind::Async)
2880 && !orig_span.is_desugaring(DesugaringKind::Await)
2882 self.diverges.set(Diverges::WarnedAlways);
2884 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2886 let msg = format!("unreachable {}", kind);
2888 .struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
2889 .span_label(span, &msg)
2892 custom_note.unwrap_or("any code following this expression is unreachable"),
2899 pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
2900 ObligationCause::new(span, self.body_id, code)
2903 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2904 self.cause(span, ObligationCauseCode::MiscObligation)
2907 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2908 /// version (resolve_vars_if_possible), this version will
2909 /// also select obligations if it seems useful, in an effort
2910 /// to get more type information.
2911 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2912 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2914 // No Infer()? Nothing needs doing.
2915 if !ty.has_infer_types() && !ty.has_infer_consts() {
2916 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2920 // If `ty` is a type variable, see whether we already know what it is.
2921 ty = self.resolve_vars_if_possible(&ty);
2922 if !ty.has_infer_types() && !ty.has_infer_consts() {
2923 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2927 // If not, try resolving pending obligations as much as
2928 // possible. This can help substantially when there are
2929 // indirect dependencies that don't seem worth tracking
2931 self.select_obligations_where_possible(false, |_| {});
2932 ty = self.resolve_vars_if_possible(&ty);
2934 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2938 fn record_deferred_call_resolution(
2940 closure_def_id: DefId,
2941 r: DeferredCallResolution<'tcx>,
2943 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2944 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2947 fn remove_deferred_call_resolutions(
2949 closure_def_id: DefId,
2950 ) -> Vec<DeferredCallResolution<'tcx>> {
2951 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2952 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2955 pub fn tag(&self) -> String {
2956 format!("{:p}", self)
2959 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2960 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
2961 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
2966 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2968 "write_ty({:?}, {:?}) in fcx {}",
2970 self.resolve_vars_if_possible(&ty),
2973 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2975 if ty.references_error() {
2976 self.has_errors.set(true);
2977 self.set_tainted_by_errors();
2981 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2982 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2985 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2986 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2989 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
2990 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2991 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2992 self.write_substs(hir_id, method.substs);
2994 // When the method is confirmed, the `method.substs` includes
2995 // parameters from not just the method, but also the impl of
2996 // the method -- in particular, the `Self` type will be fully
2997 // resolved. However, those are not something that the "user
2998 // specified" -- i.e., those types come from the inferred type
2999 // of the receiver, not something the user wrote. So when we
3000 // create the user-substs, we want to replace those earlier
3001 // types with just the types that the user actually wrote --
3002 // that is, those that appear on the *method itself*.
3004 // As an example, if the user wrote something like
3005 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
3006 // type of `foo` (possibly adjusted), but we don't want to
3007 // include that. We want just the `[_, u32]` part.
3008 if !method.substs.is_noop() {
3009 let method_generics = self.tcx.generics_of(method.def_id);
3010 if !method_generics.params.is_empty() {
3011 let user_type_annotation = self.infcx.probe(|_| {
3012 let user_substs = UserSubsts {
3013 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
3014 let i = param.index as usize;
3015 if i < method_generics.parent_count {
3016 self.infcx.var_for_def(DUMMY_SP, param)
3021 user_self_ty: None, // not relevant here
3024 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3030 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
3031 self.write_user_type_annotation(hir_id, user_type_annotation);
3036 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
3037 if !substs.is_noop() {
3038 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
3040 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
3044 /// Given the substs that we just converted from the HIR, try to
3045 /// canonicalize them and store them as user-given substitutions
3046 /// (i.e., substitutions that must be respected by the NLL check).
3048 /// This should be invoked **before any unifications have
3049 /// occurred**, so that annotations like `Vec<_>` are preserved
3051 pub fn write_user_type_annotation_from_substs(
3055 substs: SubstsRef<'tcx>,
3056 user_self_ty: Option<UserSelfTy<'tcx>>,
3059 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
3060 user_self_ty={:?} in fcx {}",
3068 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
3069 let canonicalized = self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
3071 UserSubsts { substs, user_self_ty },
3073 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
3074 self.write_user_type_annotation(hir_id, canonicalized);
3078 pub fn write_user_type_annotation(
3081 canonical_user_type_annotation: CanonicalUserType<'tcx>,
3084 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
3086 canonical_user_type_annotation,
3090 if !canonical_user_type_annotation.is_identity() {
3093 .user_provided_types_mut()
3094 .insert(hir_id, canonical_user_type_annotation);
3096 debug!("write_user_type_annotation: skipping identity substs");
3100 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
3101 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
3107 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
3108 Entry::Vacant(entry) => {
3111 Entry::Occupied(mut entry) => {
3112 debug!(" - composing on top of {:?}", entry.get());
3113 match (&entry.get()[..], &adj[..]) {
3114 // Applying any adjustment on top of a NeverToAny
3115 // is a valid NeverToAny adjustment, because it can't
3117 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
3119 Adjustment { kind: Adjust::Deref(_), .. },
3120 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
3122 Adjustment { kind: Adjust::Deref(_), .. },
3123 .. // Any following adjustments are allowed.
3125 // A reborrow has no effect before a dereference.
3127 // FIXME: currently we never try to compose autoderefs
3128 // and ReifyFnPointer/UnsafeFnPointer, but we could.
3130 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
3131 expr, entry.get(), adj)
3133 *entry.get_mut() = adj;
3138 /// Basically whenever we are converting from a type scheme into
3139 /// the fn body space, we always want to normalize associated
3140 /// types as well. This function combines the two.
3141 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: &T) -> T
3143 T: TypeFoldable<'tcx>,
3145 let value = value.subst(self.tcx, substs);
3146 let result = self.normalize_associated_types_in(span, &value);
3147 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}", value, substs, result);
3151 /// As `instantiate_type_scheme`, but for the bounds found in a
3152 /// generic type scheme.
3153 fn instantiate_bounds(
3157 substs: SubstsRef<'tcx>,
3158 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
3159 let bounds = self.tcx.predicates_of(def_id);
3160 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
3161 let result = bounds.instantiate(self.tcx, substs);
3162 let result = self.normalize_associated_types_in(span, &result);
3164 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
3165 bounds, substs, result, spans,
3170 /// Replaces the opaque types from the given value with type variables,
3171 /// and records the `OpaqueTypeMap` for later use during writeback. See
3172 /// `InferCtxt::instantiate_opaque_types` for more details.
3173 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
3175 parent_id: hir::HirId,
3179 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
3181 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
3182 parent_def_id, value
3185 let (value, opaque_type_map) =
3186 self.register_infer_ok_obligations(self.instantiate_opaque_types(
3194 let mut opaque_types = self.opaque_types.borrow_mut();
3195 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
3196 for (ty, decl) in opaque_type_map {
3197 let _ = opaque_types.insert(ty, decl);
3198 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
3204 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
3206 T: TypeFoldable<'tcx>,
3208 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
3211 fn normalize_associated_types_in_as_infer_ok<T>(
3215 ) -> InferOk<'tcx, T>
3217 T: TypeFoldable<'tcx>,
3219 self.inh.partially_normalize_associated_types_in(span, self.body_id, self.param_env, value)
3222 pub fn require_type_meets(
3226 code: traits::ObligationCauseCode<'tcx>,
3229 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
3232 pub fn require_type_is_sized(
3236 code: traits::ObligationCauseCode<'tcx>,
3238 if !ty.references_error() {
3239 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
3240 self.require_type_meets(ty, span, code, lang_item);
3244 pub fn require_type_is_sized_deferred(
3248 code: traits::ObligationCauseCode<'tcx>,
3250 if !ty.references_error() {
3251 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
3255 pub fn register_bound(
3259 cause: traits::ObligationCause<'tcx>,
3261 if !ty.references_error() {
3262 self.fulfillment_cx.borrow_mut().register_bound(
3272 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
3273 let t = AstConv::ast_ty_to_ty(self, ast_t);
3274 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
3278 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
3279 let ty = self.to_ty(ast_ty);
3280 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
3282 if Self::can_contain_user_lifetime_bounds(ty) {
3283 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
3284 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
3285 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
3291 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
3292 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
3293 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
3296 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
3297 AstConv::ast_const_to_const(self, ast_c, ty)
3300 // If the type given by the user has free regions, save it for later, since
3301 // NLL would like to enforce those. Also pass in types that involve
3302 // projections, since those can resolve to `'static` bounds (modulo #54940,
3303 // which hopefully will be fixed by the time you see this comment, dear
3304 // reader, although I have my doubts). Also pass in types with inference
3305 // types, because they may be repeated. Other sorts of things are already
3306 // sufficiently enforced with erased regions. =)
3307 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
3309 T: TypeFoldable<'tcx>,
3311 t.has_free_regions() || t.has_projections() || t.has_infer_types()
3314 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
3315 match self.tables.borrow().node_types().get(id) {
3317 None if self.is_tainted_by_errors() => self.tcx.types.err,
3320 "no type for node {}: {} in fcx {}",
3322 self.tcx.hir().node_to_string(id),
3329 /// Registers an obligation for checking later, during regionck, that the type `ty` must
3330 /// outlive the region `r`.
3331 pub fn register_wf_obligation(
3335 code: traits::ObligationCauseCode<'tcx>,
3337 // WF obligations never themselves fail, so no real need to give a detailed cause:
3338 let cause = traits::ObligationCause::new(span, self.body_id, code);
3339 self.register_predicate(traits::Obligation::new(
3342 ty::Predicate::WellFormed(ty),
3346 /// Registers obligations that all types appearing in `substs` are well-formed.
3347 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
3348 for ty in substs.types() {
3349 if !ty.references_error() {
3350 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
3355 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
3356 /// type/region parameter was instantiated (`substs`), creates and registers suitable
3357 /// trait/region obligations.
3359 /// For example, if there is a function:
3362 /// fn foo<'a,T:'a>(...)
3365 /// and a reference:
3371 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
3372 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
3373 pub fn add_obligations_for_parameters(
3375 cause: traits::ObligationCause<'tcx>,
3376 predicates: &ty::InstantiatedPredicates<'tcx>,
3378 assert!(!predicates.has_escaping_bound_vars());
3380 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
3382 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
3383 self.register_predicate(obligation);
3387 // FIXME(arielb1): use this instead of field.ty everywhere
3388 // Only for fields! Returns <none> for methods>
3389 // Indifferent to privacy flags
3393 field: &'tcx ty::FieldDef,
3394 substs: SubstsRef<'tcx>,
3396 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
3399 fn check_casts(&self) {
3400 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3401 for cast in deferred_cast_checks.drain(..) {
3406 fn resolve_generator_interiors(&self, def_id: DefId) {
3407 let mut generators = self.deferred_generator_interiors.borrow_mut();
3408 for (body_id, interior, kind) in generators.drain(..) {
3409 self.select_obligations_where_possible(false, |_| {});
3410 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
3414 // Tries to apply a fallback to `ty` if it is an unsolved variable.
3416 // - Unconstrained ints are replaced with `i32`.
3418 // - Unconstrained floats are replaced with with `f64`.
3420 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3421 // is enabled. Otherwise, they are replaced with `()`.
3423 // Fallback becomes very dubious if we have encountered type-checking errors.
3424 // In that case, fallback to Error.
3425 // The return value indicates whether fallback has occurred.
3426 fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
3427 use rustc::ty::error::UnconstrainedNumeric::Neither;
3428 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
3430 assert!(ty.is_ty_infer());
3431 let fallback = match self.type_is_unconstrained_numeric(ty) {
3432 _ if self.is_tainted_by_errors() => self.tcx().types.err,
3433 UnconstrainedInt => self.tcx.types.i32,
3434 UnconstrainedFloat => self.tcx.types.f64,
3435 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
3437 // This type variable was created from the instantiation of an opaque
3438 // type. The fact that we're attempting to perform fallback for it
3439 // means that the function neither constrained it to a concrete
3440 // type, nor to the opaque type itself.
3442 // For example, in this code:
3445 // type MyType = impl Copy;
3446 // fn defining_use() -> MyType { true }
3447 // fn other_use() -> MyType { defining_use() }
3450 // `defining_use` will constrain the instantiated inference
3451 // variable to `bool`, while `other_use` will constrain
3452 // the instantiated inference variable to `MyType`.
3454 // When we process opaque types during writeback, we
3455 // will handle cases like `other_use`, and not count
3456 // them as defining usages
3458 // However, we also need to handle cases like this:
3461 // pub type Foo = impl Copy;
3462 // fn produce() -> Option<Foo> {
3467 // In the above snippet, the inference varaible created by
3468 // instantiating `Option<Foo>` will be completely unconstrained.
3469 // We treat this as a non-defining use by making the inference
3470 // variable fall back to the opaque type itself.
3471 if let FallbackMode::All = mode {
3472 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
3474 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
3486 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
3487 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
3491 fn select_all_obligations_or_error(&self) {
3492 debug!("select_all_obligations_or_error");
3493 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3494 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3498 /// Select as many obligations as we can at present.
3499 fn select_obligations_where_possible(
3501 fallback_has_occurred: bool,
3502 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3504 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3505 if let Err(mut errors) = result {
3506 mutate_fullfillment_errors(&mut errors);
3507 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3511 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3512 /// returns a type of `&T`, but the actual type we assign to the
3513 /// *expression* is `T`. So this function just peels off the return
3514 /// type by one layer to yield `T`.
3515 fn make_overloaded_place_return_type(
3517 method: MethodCallee<'tcx>,
3518 ) -> ty::TypeAndMut<'tcx> {
3519 // extract method return type, which will be &T;
3520 let ret_ty = method.sig.output();
3522 // method returns &T, but the type as visible to user is T, so deref
3523 ret_ty.builtin_deref(true).unwrap()
3528 expr: &hir::Expr<'_>,
3529 base_expr: &'tcx hir::Expr<'tcx>,
3533 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3534 // FIXME(#18741) -- this is almost but not quite the same as the
3535 // autoderef that normal method probing does. They could likely be
3538 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3539 let mut result = None;
3540 while result.is_none() && autoderef.next().is_some() {
3541 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3543 autoderef.finalize(self);
3547 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3548 /// (and otherwise adjust) `base_expr`, looking for a type which either
3549 /// supports builtin indexing or overloaded indexing.
3550 /// This loop implements one step in that search; the autoderef loop
3551 /// is implemented by `lookup_indexing`.
3554 expr: &hir::Expr<'_>,
3555 base_expr: &hir::Expr<'_>,
3556 autoderef: &Autoderef<'a, 'tcx>,
3559 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3560 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3562 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3564 expr, base_expr, adjusted_ty, index_ty
3567 for &unsize in &[false, true] {
3568 let mut self_ty = adjusted_ty;
3570 // We only unsize arrays here.
3571 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3572 self_ty = self.tcx.mk_slice(element_ty);
3578 // If some lookup succeeds, write callee into table and extract index/element
3579 // type from the method signature.
3580 // If some lookup succeeded, install method in table
3581 let input_ty = self.next_ty_var(TypeVariableOrigin {
3582 kind: TypeVariableOriginKind::AutoDeref,
3583 span: base_expr.span,
3585 let method = self.try_overloaded_place_op(
3593 let result = method.map(|ok| {
3594 debug!("try_index_step: success, using overloaded indexing");
3595 let method = self.register_infer_ok_obligations(ok);
3597 let mut adjustments = autoderef.adjust_steps(self, needs);
3598 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3599 let mutbl = match r_mutbl {
3600 hir::Mutability::Not => AutoBorrowMutability::Not,
3601 hir::Mutability::Mut => AutoBorrowMutability::Mut {
3602 // Indexing can be desugared to a method call,
3603 // so maybe we could use two-phase here.
3604 // See the documentation of AllowTwoPhase for why that's
3605 // not the case today.
3606 allow_two_phase_borrow: AllowTwoPhase::No,
3609 adjustments.push(Adjustment {
3610 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3613 .mk_ref(region, ty::TypeAndMut { mutbl: r_mutbl, ty: adjusted_ty }),
3617 adjustments.push(Adjustment {
3618 kind: Adjust::Pointer(PointerCast::Unsize),
3619 target: method.sig.inputs()[0],
3622 self.apply_adjustments(base_expr, adjustments);
3624 self.write_method_call(expr.hir_id, method);
3625 (input_ty, self.make_overloaded_place_return_type(method).ty)
3627 if result.is_some() {
3635 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3636 let (tr, name) = match (op, is_mut) {
3637 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3638 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3639 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3640 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3642 (tr, ast::Ident::with_dummy_span(name))
3645 fn try_overloaded_place_op(
3649 arg_tys: &[Ty<'tcx>],
3652 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
3653 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})", span, base_ty, needs, op);
3655 // Try Mut first, if needed.
3656 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3657 let method = match (needs, mut_tr) {
3658 (Needs::MutPlace, Some(trait_did)) => {
3659 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3664 // Otherwise, fall back to the immutable version.
3665 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3666 let method = match (method, imm_tr) {
3667 (None, Some(trait_did)) => {
3668 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3670 (method, _) => method,
3676 fn check_method_argument_types(
3679 expr: &'tcx hir::Expr<'tcx>,
3680 method: Result<MethodCallee<'tcx>, ()>,
3681 args_no_rcvr: &'tcx [hir::Expr<'tcx>],
3682 tuple_arguments: TupleArgumentsFlag,
3683 expected: Expectation<'tcx>,
3685 let has_error = match method {
3686 Ok(method) => method.substs.references_error() || method.sig.references_error(),
3690 let err_inputs = self.err_args(args_no_rcvr.len());
3692 let err_inputs = match tuple_arguments {
3693 DontTupleArguments => err_inputs,
3694 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3697 self.check_argument_types(
3707 return self.tcx.types.err;
3710 let method = method.unwrap();
3711 // HACK(eddyb) ignore self in the definition (see above).
3712 let expected_arg_tys = self.expected_inputs_for_expected_output(
3715 method.sig.output(),
3716 &method.sig.inputs()[1..],
3718 self.check_argument_types(
3721 &method.sig.inputs()[1..],
3722 &expected_arg_tys[..],
3724 method.sig.c_variadic,
3726 self.tcx.hir().span_if_local(method.def_id),
3731 fn self_type_matches_expected_vid(
3733 trait_ref: ty::PolyTraitRef<'tcx>,
3734 expected_vid: ty::TyVid,
3736 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3738 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3739 trait_ref, self_ty, expected_vid
3741 match self_ty.kind {
3742 ty::Infer(ty::TyVar(found_vid)) => {
3743 // FIXME: consider using `sub_root_var` here so we
3744 // can see through subtyping.
3745 let found_vid = self.root_var(found_vid);
3746 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3747 expected_vid == found_vid
3753 fn obligations_for_self_ty<'b>(
3756 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3759 // FIXME: consider using `sub_root_var` here so we
3760 // can see through subtyping.
3761 let ty_var_root = self.root_var(self_ty);
3763 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3766 self.fulfillment_cx.borrow().pending_obligations()
3771 .pending_obligations()
3773 .filter_map(move |obligation| match obligation.predicate {
3774 ty::Predicate::Projection(ref data) => {
3775 Some((data.to_poly_trait_ref(self.tcx), obligation))
3777 ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
3778 ty::Predicate::Subtype(..) => None,
3779 ty::Predicate::RegionOutlives(..) => None,
3780 ty::Predicate::TypeOutlives(..) => None,
3781 ty::Predicate::WellFormed(..) => None,
3782 ty::Predicate::ObjectSafe(..) => None,
3783 ty::Predicate::ConstEvaluatable(..) => None,
3784 // N.B., this predicate is created by breaking down a
3785 // `ClosureType: FnFoo()` predicate, where
3786 // `ClosureType` represents some `Closure`. It can't
3787 // possibly be referring to the current closure,
3788 // because we haven't produced the `Closure` for
3789 // this closure yet; this is exactly why the other
3790 // code is looking for a self type of a unresolved
3791 // inference variable.
3792 ty::Predicate::ClosureKind(..) => None,
3794 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3797 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3798 self.obligations_for_self_ty(self_ty)
3799 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
3802 /// Generic function that factors out common logic from function calls,
3803 /// method calls and overloaded operators.
3804 fn check_argument_types(
3807 expr: &'tcx hir::Expr<'tcx>,
3808 fn_inputs: &[Ty<'tcx>],
3809 expected_arg_tys: &[Ty<'tcx>],
3810 args: &'tcx [hir::Expr<'tcx>],
3812 tuple_arguments: TupleArgumentsFlag,
3813 def_span: Option<Span>,
3816 // Grab the argument types, supplying fresh type variables
3817 // if the wrong number of arguments were supplied
3818 let supplied_arg_count = if tuple_arguments == DontTupleArguments { args.len() } else { 1 };
3820 // All the input types from the fn signature must outlive the call
3821 // so as to validate implied bounds.
3822 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3823 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3826 let expected_arg_count = fn_inputs.len();
3828 let param_count_error = |expected_count: usize,
3833 let mut err = tcx.sess.struct_span_err_with_code(
3836 "this function takes {}{} but {} {} supplied",
3837 if c_variadic { "at least " } else { "" },
3838 potentially_plural_count(expected_count, "parameter"),
3839 potentially_plural_count(arg_count, "parameter"),
3840 if arg_count == 1 { "was" } else { "were" }
3842 DiagnosticId::Error(error_code.to_owned()),
3845 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3846 err.span_label(def_s, "defined here");
3849 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3850 // remove closing `)` from the span
3851 let sugg_span = sugg_span.shrink_to_lo();
3852 err.span_suggestion(
3854 "expected the unit value `()`; create it with empty parentheses",
3856 Applicability::MachineApplicable,
3863 if c_variadic { "at least " } else { "" },
3864 potentially_plural_count(expected_count, "parameter")
3871 let mut expected_arg_tys = expected_arg_tys.to_vec();
3873 let formal_tys = if tuple_arguments == TupleArguments {
3874 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3875 match tuple_type.kind {
3876 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3877 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3878 expected_arg_tys = vec![];
3879 self.err_args(args.len())
3881 ty::Tuple(arg_types) => {
3882 expected_arg_tys = match expected_arg_tys.get(0) {
3883 Some(&ty) => match ty.kind {
3884 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3889 arg_types.iter().map(|k| k.expect_ty()).collect()
3896 "cannot use call notation; the first type parameter \
3897 for the function trait is neither a tuple nor unit"
3900 expected_arg_tys = vec![];
3901 self.err_args(args.len())
3904 } else if expected_arg_count == supplied_arg_count {
3906 } else if c_variadic {
3907 if supplied_arg_count >= expected_arg_count {
3910 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3911 expected_arg_tys = vec![];
3912 self.err_args(supplied_arg_count)
3915 // is the missing argument of type `()`?
3916 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3917 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3918 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3919 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3923 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3925 expected_arg_tys = vec![];
3926 self.err_args(supplied_arg_count)
3930 "check_argument_types: formal_tys={:?}",
3931 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
3934 // If there is no expectation, expect formal_tys.
3935 let expected_arg_tys =
3936 if !expected_arg_tys.is_empty() { expected_arg_tys } else { formal_tys.clone() };
3938 let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
3940 // Check the arguments.
3941 // We do this in a pretty awful way: first we type-check any arguments
3942 // that are not closures, then we type-check the closures. This is so
3943 // that we have more information about the types of arguments when we
3944 // type-check the functions. This isn't really the right way to do this.
3945 for &check_closures in &[false, true] {
3946 debug!("check_closures={}", check_closures);
3948 // More awful hacks: before we check argument types, try to do
3949 // an "opportunistic" vtable resolution of any trait bounds on
3950 // the call. This helps coercions.
3952 self.select_obligations_where_possible(false, |errors| {
3953 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
3954 self.point_at_arg_instead_of_call_if_possible(
3956 &final_arg_types[..],
3963 // For C-variadic functions, we don't have a declared type for all of
3964 // the arguments hence we only do our usual type checking with
3965 // the arguments who's types we do know.
3966 let t = if c_variadic {
3968 } else if tuple_arguments == TupleArguments {
3973 for (i, arg) in args.iter().take(t).enumerate() {
3974 // Warn only for the first loop (the "no closures" one).
3975 // Closure arguments themselves can't be diverging, but
3976 // a previous argument can, e.g., `foo(panic!(), || {})`.
3977 if !check_closures {
3978 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3981 let is_closure = match arg.kind {
3982 ExprKind::Closure(..) => true,
3986 if is_closure != check_closures {
3990 debug!("checking the argument");
3991 let formal_ty = formal_tys[i];
3993 // The special-cased logic below has three functions:
3994 // 1. Provide as good of an expected type as possible.
3995 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3997 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3999 // 2. Coerce to the most detailed type that could be coerced
4000 // to, which is `expected_ty` if `rvalue_hint` returns an
4001 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
4002 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
4003 // We're processing function arguments so we definitely want to use
4004 // two-phase borrows.
4005 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
4006 final_arg_types.push((i, checked_ty, coerce_ty));
4008 // 3. Relate the expected type and the formal one,
4009 // if the expected type was used for the coercion.
4010 self.demand_suptype(arg.span, formal_ty, coerce_ty);
4014 // We also need to make sure we at least write the ty of the other
4015 // arguments which we skipped above.
4017 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
4018 use crate::structured_errors::{StructuredDiagnostic, VariadicError};
4019 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
4022 for arg in args.iter().skip(expected_arg_count) {
4023 let arg_ty = self.check_expr(&arg);
4025 // There are a few types which get autopromoted when passed via varargs
4026 // in C but we just error out instead and require explicit casts.
4027 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
4029 ty::Float(ast::FloatTy::F32) => {
4030 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
4032 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
4033 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
4035 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
4036 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
4039 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
4040 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
4041 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
4049 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
4050 vec![self.tcx.types.err; len]
4053 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
4054 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
4055 /// reference a type argument. The reason to walk also the checked type is that the coerced type
4056 /// can be not easily comparable with predicate type (because of coercion). If the types match
4057 /// for either checked or coerced type, and there's only *one* argument that does, we point at
4058 /// the corresponding argument's expression span instead of the `fn` call path span.
4059 fn point_at_arg_instead_of_call_if_possible(
4061 errors: &mut Vec<traits::FulfillmentError<'_>>,
4062 final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
4064 args: &'tcx [hir::Expr<'tcx>],
4066 // We *do not* do this for desugared call spans to keep good diagnostics when involving
4067 // the `?` operator.
4068 if call_sp.desugaring_kind().is_some() {
4072 for error in errors {
4073 // Only if the cause is somewhere inside the expression we want try to point at arg.
4074 // Otherwise, it means that the cause is somewhere else and we should not change
4075 // anything because we can break the correct span.
4076 if !call_sp.contains(error.obligation.cause.span) {
4080 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4081 // Collect the argument position for all arguments that could have caused this
4082 // `FulfillmentError`.
4083 let mut referenced_in = final_arg_types
4085 .map(|(i, checked_ty, _)| (i, checked_ty))
4086 .chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty)))
4087 .flat_map(|(i, ty)| {
4088 let ty = self.resolve_vars_if_possible(ty);
4089 // We walk the argument type because the argument's type could have
4090 // been `Option<T>`, but the `FulfillmentError` references `T`.
4092 .filter(|&ty| ty == predicate.skip_binder().self_ty())
4095 .collect::<Vec<_>>();
4097 // Both checked and coerced types could have matched, thus we need to remove
4099 referenced_in.dedup();
4101 if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
4102 // We make sure that only *one* argument matches the obligation failure
4103 // and we assign the obligation's span to its expression's.
4104 error.obligation.cause.span = args[ref_in].span;
4105 error.points_at_arg_span = true;
4111 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
4112 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
4113 /// were caused by them. If they were, we point at the corresponding type argument's span
4114 /// instead of the `fn` call path span.
4115 fn point_at_type_arg_instead_of_call_if_possible(
4117 errors: &mut Vec<traits::FulfillmentError<'_>>,
4118 call_expr: &'tcx hir::Expr<'tcx>,
4120 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
4121 if let hir::ExprKind::Path(qpath) = &path.kind {
4122 if let hir::QPath::Resolved(_, path) = &qpath {
4123 for error in errors {
4124 if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
4125 // If any of the type arguments in this path segment caused the
4126 // `FullfillmentError`, point at its span (#61860).
4130 .filter_map(|seg| seg.args.as_ref())
4131 .flat_map(|a| a.args.iter())
4133 if let hir::GenericArg::Type(hir_ty) = &arg {
4134 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
4137 // Avoid ICE with associated types. As this is best
4138 // effort only, it's ok to ignore the case. It
4139 // would trigger in `is_send::<T::AssocType>();`
4140 // from `typeck-default-trait-impl-assoc-type.rs`.
4142 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
4143 let ty = self.resolve_vars_if_possible(&ty);
4144 if ty == predicate.skip_binder().self_ty() {
4145 error.obligation.cause.span = hir_ty.span;
4157 // AST fragment checking
4158 fn check_lit(&self, lit: &hir::Lit, expected: Expectation<'tcx>) -> Ty<'tcx> {
4162 ast::LitKind::Str(..) => tcx.mk_static_str(),
4163 ast::LitKind::ByteStr(ref v) => {
4164 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
4166 ast::LitKind::Byte(_) => tcx.types.u8,
4167 ast::LitKind::Char(_) => tcx.types.char,
4168 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
4169 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
4170 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
4171 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4172 ty::Int(_) | ty::Uint(_) => Some(ty),
4173 ty::Char => Some(tcx.types.u8),
4174 ty::RawPtr(..) => Some(tcx.types.usize),
4175 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
4178 opt_ty.unwrap_or_else(|| self.next_int_var())
4180 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
4181 ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
4182 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind {
4183 ty::Float(_) => Some(ty),
4186 opt_ty.unwrap_or_else(|| self.next_float_var())
4188 ast::LitKind::Bool(_) => tcx.types.bool,
4189 ast::LitKind::Err(_) => tcx.types.err,
4193 // Determine the `Self` type, using fresh variables for all variables
4194 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
4195 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
4197 pub fn impl_self_ty(
4199 span: Span, // (potential) receiver for this impl
4201 ) -> TypeAndSubsts<'tcx> {
4202 let ity = self.tcx.type_of(did);
4203 debug!("impl_self_ty: ity={:?}", ity);
4205 let substs = self.fresh_substs_for_item(span, did);
4206 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
4208 TypeAndSubsts { substs: substs, ty: substd_ty }
4211 /// Unifies the output type with the expected type early, for more coercions
4212 /// and forward type information on the input expressions.
4213 fn expected_inputs_for_expected_output(
4216 expected_ret: Expectation<'tcx>,
4217 formal_ret: Ty<'tcx>,
4218 formal_args: &[Ty<'tcx>],
4219 ) -> Vec<Ty<'tcx>> {
4220 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
4221 let ret_ty = match expected_ret.only_has_type(self) {
4223 None => return Vec::new(),
4225 let expect_args = self
4226 .fudge_inference_if_ok(|| {
4227 // Attempt to apply a subtyping relationship between the formal
4228 // return type (likely containing type variables if the function
4229 // is polymorphic) and the expected return type.
4230 // No argument expectations are produced if unification fails.
4231 let origin = self.misc(call_span);
4232 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
4234 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
4235 // to identity so the resulting type is not constrained.
4238 // Process any obligations locally as much as
4239 // we can. We don't care if some things turn
4240 // out unconstrained or ambiguous, as we're
4241 // just trying to get hints here.
4242 self.save_and_restore_in_snapshot_flag(|_| {
4243 let mut fulfill = TraitEngine::new(self.tcx);
4244 for obligation in ok.obligations {
4245 fulfill.register_predicate_obligation(self, obligation);
4247 fulfill.select_where_possible(self)
4251 Err(_) => return Err(()),
4254 // Record all the argument types, with the substitutions
4255 // produced from the above subtyping unification.
4256 Ok(formal_args.iter().map(|ty| self.resolve_vars_if_possible(ty)).collect())
4258 .unwrap_or_default();
4260 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
4261 formal_args, formal_ret, expect_args, expected_ret
4266 pub fn check_struct_path(
4270 ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
4271 let path_span = match *qpath {
4272 QPath::Resolved(_, ref path) => path.span,
4273 QPath::TypeRelative(ref qself, _) => qself.span,
4275 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
4276 let variant = match def {
4278 self.set_tainted_by_errors();
4281 Res::Def(DefKind::Variant, _) => match ty.kind {
4282 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
4283 _ => bug!("unexpected type: {:?}", ty),
4285 Res::Def(DefKind::Struct, _)
4286 | Res::Def(DefKind::Union, _)
4287 | Res::Def(DefKind::TyAlias, _)
4288 | Res::Def(DefKind::AssocTy, _)
4289 | Res::SelfTy(..) => match ty.kind {
4290 ty::Adt(adt, substs) if !adt.is_enum() => {
4291 Some((adt.non_enum_variant(), adt.did, substs))
4295 _ => bug!("unexpected definition: {:?}", def),
4298 if let Some((variant, did, substs)) = variant {
4299 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
4300 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
4302 // Check bounds on type arguments used in the path.
4303 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
4305 traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
4306 self.add_obligations_for_parameters(cause, &bounds);
4314 "expected struct, variant or union type, found {}",
4315 ty.sort_string(self.tcx)
4317 .span_label(path_span, "not a struct")
4323 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4324 // The newly resolved definition is written into `type_dependent_defs`.
4325 fn finish_resolving_struct_path(
4330 ) -> (Res, Ty<'tcx>) {
4332 QPath::Resolved(ref maybe_qself, ref path) => {
4333 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4334 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4337 QPath::TypeRelative(ref qself, ref segment) => {
4338 let ty = self.to_ty(qself);
4340 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
4346 AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true);
4347 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4348 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4350 // Write back the new resolution.
4351 self.write_resolution(hir_id, result);
4353 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4358 /// Resolves an associated value path into a base type and associated constant, or method
4359 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4360 pub fn resolve_ty_and_res_ufcs<'b>(
4362 qpath: &'b QPath<'b>,
4365 ) -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]) {
4366 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4367 let (ty, qself, item_segment) = match *qpath {
4368 QPath::Resolved(ref opt_qself, ref path) => {
4371 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4375 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
4377 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4378 // Return directly on cache hit. This is useful to avoid doubly reporting
4379 // errors with default match binding modes. See #44614.
4381 cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err);
4382 return (def, Some(ty), slice::from_ref(&**item_segment));
4384 let item_name = item_segment.ident;
4385 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4386 let result = match error {
4387 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4388 _ => Err(ErrorReported),
4390 if item_name.name != kw::Invalid {
4391 self.report_method_error(
4395 SelfSource::QPath(qself),
4399 .map(|mut e| e.emit());
4404 // Write back the new resolution.
4405 self.write_resolution(hir_id, result);
4407 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4409 slice::from_ref(&**item_segment),
4413 pub fn check_decl_initializer(
4415 local: &'tcx hir::Local<'tcx>,
4416 init: &'tcx hir::Expr<'tcx>,
4418 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4419 // for #42640 (default match binding modes).
4422 let ref_bindings = local.pat.contains_explicit_ref_binding();
4424 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4425 if let Some(m) = ref_bindings {
4426 // Somewhat subtle: if we have a `ref` binding in the pattern,
4427 // we want to avoid introducing coercions for the RHS. This is
4428 // both because it helps preserve sanity and, in the case of
4429 // ref mut, for soundness (issue #23116). In particular, in
4430 // the latter case, we need to be clear that the type of the
4431 // referent for the reference that results is *equal to* the
4432 // type of the place it is referencing, and not some
4433 // supertype thereof.
4434 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4435 self.demand_eqtype(init.span, local_ty, init_ty);
4438 self.check_expr_coercable_to_type(init, local_ty)
4442 /// Type check a `let` statement.
4443 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
4444 // Determine and write the type which we'll check the pattern against.
4445 let ty = self.local_ty(local.span, local.hir_id).decl_ty;
4446 self.write_ty(local.hir_id, ty);
4448 // Type check the initializer.
4449 if let Some(ref init) = local.init {
4450 let init_ty = self.check_decl_initializer(local, &init);
4451 self.overwrite_local_ty_if_err(local, ty, init_ty);
4454 // Does the expected pattern type originate from an expression and what is the span?
4455 let (origin_expr, ty_span) = match (local.ty, local.init) {
4456 (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
4457 (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
4458 _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
4461 // Type check the pattern. Override if necessary to avoid knock-on errors.
4462 self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
4463 let pat_ty = self.node_ty(local.pat.hir_id);
4464 self.overwrite_local_ty_if_err(local, ty, pat_ty);
4467 fn overwrite_local_ty_if_err(
4469 local: &'tcx hir::Local<'tcx>,
4473 if ty.references_error() {
4474 // Override the types everywhere with `types.err` to avoid knock on errors.
4475 self.write_ty(local.hir_id, ty);
4476 self.write_ty(local.pat.hir_id, ty);
4477 let local_ty = LocalTy { decl_ty, revealed_ty: ty };
4478 self.locals.borrow_mut().insert(local.hir_id, local_ty);
4479 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
4483 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
4484 err.span_suggestion_short(
4485 span.shrink_to_hi(),
4486 "consider using a semicolon here",
4488 Applicability::MachineApplicable,
4492 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
4493 // Don't do all the complex logic below for `DeclItem`.
4495 hir::StmtKind::Item(..) => return,
4496 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4499 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4501 // Hide the outer diverging and `has_errors` flags.
4502 let old_diverges = self.diverges.replace(Diverges::Maybe);
4503 let old_has_errors = self.has_errors.replace(false);
4506 hir::StmtKind::Local(ref l) => {
4507 self.check_decl_local(&l);
4510 hir::StmtKind::Item(_) => {}
4511 hir::StmtKind::Expr(ref expr) => {
4512 // Check with expected type of `()`.
4513 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
4514 self.suggest_semicolon_at_end(expr.span, err);
4517 hir::StmtKind::Semi(ref expr) => {
4518 self.check_expr(&expr);
4522 // Combine the diverging and `has_error` flags.
4523 self.diverges.set(self.diverges.get() | old_diverges);
4524 self.has_errors.set(self.has_errors.get() | old_has_errors);
4527 pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
4528 let unit = self.tcx.mk_unit();
4529 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4531 // if the block produces a `!` value, that can always be
4532 // (effectively) coerced to unit.
4534 self.demand_suptype(blk.span, unit, ty);
4538 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4539 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4540 /// when given code like the following:
4542 /// if false { return 0i32; } else { 1u32 }
4543 /// // ^^^^ point at this instead of the whole `if` expression
4545 fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
4546 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4547 let arm_spans: Vec<Span> = arms
4550 self.in_progress_tables
4551 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4552 .and_then(|arm_ty| {
4553 if arm_ty.is_never() {
4556 Some(match &arm.body.kind {
4557 // Point at the tail expression when possible.
4558 hir::ExprKind::Block(block, _) => {
4559 block.expr.as_ref().map(|e| e.span).unwrap_or(block.span)
4567 if arm_spans.len() == 1 {
4568 return arm_spans[0];
4574 fn check_block_with_expected(
4576 blk: &'tcx hir::Block<'tcx>,
4577 expected: Expectation<'tcx>,
4580 let mut fcx_ps = self.ps.borrow_mut();
4581 let unsafety_state = fcx_ps.recurse(blk);
4582 replace(&mut *fcx_ps, unsafety_state)
4585 // In some cases, blocks have just one exit, but other blocks
4586 // can be targeted by multiple breaks. This can happen both
4587 // with labeled blocks as well as when we desugar
4588 // a `try { ... }` expression.
4592 // 'a: { if true { break 'a Err(()); } Ok(()) }
4594 // Here we would wind up with two coercions, one from
4595 // `Err(())` and the other from the tail expression
4596 // `Ok(())`. If the tail expression is omitted, that's a
4597 // "forced unit" -- unless the block diverges, in which
4598 // case we can ignore the tail expression (e.g., `'a: {
4599 // break 'a 22; }` would not force the type of the block
4601 let tail_expr = blk.expr.as_ref();
4602 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4603 let coerce = if blk.targeted_by_break {
4604 CoerceMany::new(coerce_to_ty)
4606 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
4607 Some(e) => slice::from_ref(e),
4610 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4613 let prev_diverges = self.diverges.get();
4614 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
4616 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4617 for s in blk.stmts {
4621 // check the tail expression **without** holding the
4622 // `enclosing_breakables` lock below.
4623 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4625 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4626 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4627 let coerce = ctxt.coerce.as_mut().unwrap();
4628 if let Some(tail_expr_ty) = tail_expr_ty {
4629 let tail_expr = tail_expr.unwrap();
4630 let span = self.get_expr_coercion_span(tail_expr);
4631 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4632 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4634 // Subtle: if there is no explicit tail expression,
4635 // that is typically equivalent to a tail expression
4636 // of `()` -- except if the block diverges. In that
4637 // case, there is no value supplied from the tail
4638 // expression (assuming there are no other breaks,
4639 // this implies that the type of the block will be
4642 // #41425 -- label the implicit `()` as being the
4643 // "found type" here, rather than the "expected type".
4644 if !self.diverges.get().is_always() {
4645 // #50009 -- Do not point at the entire fn block span, point at the return type
4646 // span, as it is the cause of the requirement, and
4647 // `consider_hint_about_removing_semicolon` will point at the last expression
4648 // if it were a relevant part of the error. This improves usability in editors
4649 // that highlight errors inline.
4650 let mut sp = blk.span;
4651 let mut fn_span = None;
4652 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4653 let ret_sp = decl.output.span();
4654 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4655 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4656 // output would otherwise be incorrect and even misleading. Make sure
4657 // the span we're aiming at correspond to a `fn` body.
4658 if block_sp == blk.span {
4660 fn_span = Some(ident.span);
4664 coerce.coerce_forced_unit(
4668 if let Some(expected_ty) = expected.only_has_type(self) {
4669 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4671 if let Some(fn_span) = fn_span {
4674 "implicitly returns `()` as its body has no tail or `return` \
4686 // If we can break from the block, then the block's exit is always reachable
4687 // (... as long as the entry is reachable) - regardless of the tail of the block.
4688 self.diverges.set(prev_diverges);
4691 let mut ty = ctxt.coerce.unwrap().complete(self);
4693 if self.has_errors.get() || ty.references_error() {
4694 ty = self.tcx.types.err
4697 self.write_ty(blk.hir_id, ty);
4699 *self.ps.borrow_mut() = prev;
4703 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4704 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4706 Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
4707 | Node::ImplItem(&hir::ImplItem {
4708 kind: hir::ImplItemKind::Method(_, body_id), ..
4710 let body = self.tcx.hir().body(body_id);
4711 if let ExprKind::Block(block, _) = &body.value.kind {
4712 return Some(block.span);
4720 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4721 fn get_parent_fn_decl(
4724 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident)> {
4725 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4726 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4729 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4730 fn get_node_fn_decl(
4733 ) -> Option<(&'tcx hir::FnDecl<'tcx>, ast::Ident, bool)> {
4735 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
4736 // This is less than ideal, it will not suggest a return type span on any
4737 // method called `main`, regardless of whether it is actually the entry point,
4738 // but it will still present it as the reason for the expected type.
4739 Some((&sig.decl, ident, ident.name != sym::main))
4741 Node::TraitItem(&hir::TraitItem {
4743 kind: hir::TraitItemKind::Method(ref sig, ..),
4745 }) => Some((&sig.decl, ident, true)),
4746 Node::ImplItem(&hir::ImplItem {
4748 kind: hir::ImplItemKind::Method(ref sig, ..),
4750 }) => Some((&sig.decl, ident, false)),
4755 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4756 /// suggestion can be made, `None` otherwise.
4757 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
4758 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4759 // `while` before reaching it, as block tail returns are not available in them.
4760 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4761 let parent = self.tcx.hir().get(blk_id);
4762 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4766 /// On implicit return expressions with mismatched types, provides the following suggestions:
4768 /// - Points out the method's return type as the reason for the expected type.
4769 /// - Possible missing semicolon.
4770 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4771 pub fn suggest_mismatched_types_on_tail(
4773 err: &mut DiagnosticBuilder<'_>,
4774 expr: &'tcx hir::Expr<'tcx>,
4780 let expr = expr.peel_drop_temps();
4781 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4782 let mut pointing_at_return_type = false;
4783 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4784 pointing_at_return_type =
4785 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4787 pointing_at_return_type
4790 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4791 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4793 /// fn foo(x: usize) -> usize { x }
4794 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4798 err: &mut DiagnosticBuilder<'_>,
4799 expr: &hir::Expr<'_>,
4803 let hir = self.tcx.hir();
4804 let (def_id, sig) = match found.kind {
4805 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4806 ty::Closure(def_id, substs) => {
4807 // We don't use `closure_sig` to account for malformed closures like
4808 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4809 let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4812 match closure_sig_ty.kind {
4813 ty::FnPtr(sig) => sig,
4821 let sig = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig).0;
4822 let sig = self.normalize_associated_types_in(expr.span, &sig);
4823 if self.can_coerce(sig.output(), expected) {
4824 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4825 (String::new(), Applicability::MachineApplicable)
4827 ("...".to_string(), Applicability::HasPlaceholders)
4829 let mut msg = "call this function";
4830 match hir.get_if_local(def_id) {
4831 Some(Node::Item(hir::Item { kind: ItemKind::Fn(.., body_id), .. }))
4832 | Some(Node::ImplItem(hir::ImplItem {
4833 kind: hir::ImplItemKind::Method(_, body_id),
4836 | Some(Node::TraitItem(hir::TraitItem {
4837 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4840 let body = hir.body(*body_id);
4844 .map(|param| match ¶m.pat.kind {
4845 hir::PatKind::Binding(_, _, ident, None)
4846 if ident.name != kw::SelfLower =>
4850 _ => "_".to_string(),
4852 .collect::<Vec<_>>()
4855 Some(Node::Expr(hir::Expr {
4856 kind: ExprKind::Closure(_, _, body_id, _, _),
4857 span: full_closure_span,
4860 if *full_closure_span == expr.span {
4863 msg = "call this closure";
4864 let body = hir.body(*body_id);
4868 .map(|param| match ¶m.pat.kind {
4869 hir::PatKind::Binding(_, _, ident, None)
4870 if ident.name != kw::SelfLower =>
4874 _ => "_".to_string(),
4876 .collect::<Vec<_>>()
4879 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4880 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4881 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4882 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4883 msg = "instantiate this tuple variant";
4885 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4886 msg = "instantiate this tuple struct";
4891 Some(Node::ForeignItem(hir::ForeignItem {
4892 kind: hir::ForeignItemKind::Fn(_, idents, _),
4898 if ident.name != kw::SelfLower {
4904 .collect::<Vec<_>>()
4907 Some(Node::TraitItem(hir::TraitItem {
4908 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4914 if ident.name != kw::SelfLower {
4920 .collect::<Vec<_>>()
4925 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4926 err.span_suggestion(
4928 &format!("use parentheses to {}", msg),
4929 format!("{}({})", code, sugg_call),
4938 pub fn suggest_ref_or_into(
4940 err: &mut DiagnosticBuilder<'_>,
4941 expr: &hir::Expr<'_>,
4945 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4946 err.span_suggestion(sp, msg, suggestion, Applicability::MachineApplicable);
4947 } else if let (ty::FnDef(def_id, ..), true) =
4948 (&found.kind, self.suggest_fn_call(err, expr, expected, found))
4950 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4951 let sp = self.sess().source_map().def_span(sp);
4952 err.span_label(sp, &format!("{} defined here", found));
4954 } else if !self.check_for_cast(err, expr, found, expected) {
4955 let is_struct_pat_shorthand_field =
4956 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
4957 let methods = self.get_conversion_methods(expr.span, expected, found);
4958 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4959 let mut suggestions = iter::repeat(&expr_text)
4960 .zip(methods.iter())
4961 .filter_map(|(receiver, method)| {
4962 let method_call = format!(".{}()", method.ident);
4963 if receiver.ends_with(&method_call) {
4964 None // do not suggest code that is already there (#53348)
4966 let method_call_list = [".to_vec()", ".to_string()"];
4967 let sugg = if receiver.ends_with(".clone()")
4968 && method_call_list.contains(&method_call.as_str())
4970 let max_len = receiver.rfind(".").unwrap();
4971 format!("{}{}", &receiver[..max_len], method_call)
4973 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
4974 format!("({}){}", receiver, method_call)
4976 format!("{}{}", receiver, method_call)
4979 Some(if is_struct_pat_shorthand_field {
4980 format!("{}: {}", receiver, sugg)
4987 if suggestions.peek().is_some() {
4988 err.span_suggestions(
4990 "try using a conversion method",
4992 Applicability::MaybeIncorrect,
4999 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
5000 /// in the heap by calling `Box::new()`.
5001 fn suggest_boxing_when_appropriate(
5003 err: &mut DiagnosticBuilder<'_>,
5004 expr: &hir::Expr<'_>,
5008 if self.tcx.hir().is_const_context(expr.hir_id) {
5009 // Do not suggest `Box::new` in const context.
5012 if !expected.is_box() || found.is_box() {
5015 let boxed_found = self.tcx.mk_box(found);
5016 if let (true, Ok(snippet)) = (
5017 self.can_coerce(boxed_found, expected),
5018 self.sess().source_map().span_to_snippet(expr.span),
5020 err.span_suggestion(
5022 "store this in the heap by calling `Box::new`",
5023 format!("Box::new({})", snippet),
5024 Applicability::MachineApplicable,
5027 "for more on the distinction between the stack and the \
5028 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
5029 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
5030 https://doc.rust-lang.org/std/boxed/index.html",
5035 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5039 /// bar_that_returns_u32()
5043 /// This routine checks if the return expression in a block would make sense on its own as a
5044 /// statement and the return type has been left as default or has been specified as `()`. If so,
5045 /// it suggests adding a semicolon.
5046 fn suggest_missing_semicolon(
5048 err: &mut DiagnosticBuilder<'_>,
5049 expression: &'tcx hir::Expr<'tcx>,
5053 if expected.is_unit() {
5054 // `BlockTailExpression` only relevant if the tail expr would be
5055 // useful on its own.
5056 match expression.kind {
5058 | ExprKind::MethodCall(..)
5059 | ExprKind::Loop(..)
5060 | ExprKind::Match(..)
5061 | ExprKind::Block(..) => {
5062 err.span_suggestion(
5063 cause_span.shrink_to_hi(),
5064 "try adding a semicolon",
5066 Applicability::MachineApplicable,
5074 /// A possible error is to forget to add a return type that is needed:
5078 /// bar_that_returns_u32()
5082 /// This routine checks if the return type is left as default, the method is not part of an
5083 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5085 fn suggest_missing_return_type(
5087 err: &mut DiagnosticBuilder<'_>,
5088 fn_decl: &hir::FnDecl<'_>,
5093 // Only suggest changing the return type for methods that
5094 // haven't set a return type at all (and aren't `fn main()` or an impl).
5095 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5096 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
5097 err.span_suggestion(
5099 "try adding a return type",
5100 format!("-> {} ", self.resolve_vars_with_obligations(found)),
5101 Applicability::MachineApplicable,
5105 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
5106 err.span_label(span, "possibly return type missing here?");
5109 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
5110 // `fn main()` must return `()`, do not suggest changing return type
5111 err.span_label(span, "expected `()` because of default return type");
5114 // expectation was caused by something else, not the default return
5115 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
5116 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
5117 // Only point to return type if the expected type is the return type, as if they
5118 // are not, the expectation must have been caused by something else.
5119 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
5121 let ty = AstConv::ast_ty_to_ty(self, ty);
5122 debug!("suggest_missing_return_type: return type {:?}", ty);
5123 debug!("suggest_missing_return_type: expected type {:?}", ty);
5124 if ty.kind == expected.kind {
5125 err.span_label(sp, format!("expected `{}` because of return type", expected));
5133 /// A possible error is to forget to add `.await` when using futures:
5136 /// async fn make_u32() -> u32 {
5140 /// fn take_u32(x: u32) {}
5142 /// async fn foo() {
5143 /// let x = make_u32();
5148 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
5149 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
5150 /// `.await` to the tail of the expression.
5151 fn suggest_missing_await(
5153 err: &mut DiagnosticBuilder<'_>,
5154 expr: &hir::Expr<'_>,
5158 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
5159 // body isn't `async`.
5160 let item_id = self.tcx().hir().get_parent_node(self.body_id);
5161 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
5162 let body = self.tcx().hir().body(body_id);
5163 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
5165 // Check for `Future` implementations by constructing a predicate to
5166 // prove: `<T as Future>::Output == U`
5167 let future_trait = self.tcx.lang_items().future_trait().unwrap();
5168 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
5170 ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
5171 // `<T as Future>::Output`
5172 projection_ty: ty::ProjectionTy {
5174 substs: self.tcx.mk_substs_trait(
5176 self.fresh_substs_for_item(sp, item_def_id),
5183 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
5184 debug!("suggest_missing_await: trying obligation {:?}", obligation);
5185 if self.infcx.predicate_may_hold(&obligation) {
5186 debug!("suggest_missing_await: obligation held: {:?}", obligation);
5187 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
5188 err.span_suggestion(
5190 "consider using `.await` here",
5191 format!("{}.await", code),
5192 Applicability::MaybeIncorrect,
5195 debug!("suggest_missing_await: no snippet for {:?}", sp);
5198 debug!("suggest_missing_await: obligation did not hold: {:?}", obligation)
5204 /// A common error is to add an extra semicolon:
5207 /// fn foo() -> usize {
5212 /// This routine checks if the final statement in a block is an
5213 /// expression with an explicit semicolon whose type is compatible
5214 /// with `expected_ty`. If so, it suggests removing the semicolon.
5215 fn consider_hint_about_removing_semicolon(
5217 blk: &'tcx hir::Block<'tcx>,
5218 expected_ty: Ty<'tcx>,
5219 err: &mut DiagnosticBuilder<'_>,
5221 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5222 err.span_suggestion(
5224 "consider removing this semicolon",
5226 Applicability::MachineApplicable,
5231 fn could_remove_semicolon(
5233 blk: &'tcx hir::Block<'tcx>,
5234 expected_ty: Ty<'tcx>,
5236 // Be helpful when the user wrote `{... expr;}` and
5237 // taking the `;` off is enough to fix the error.
5238 let last_stmt = blk.stmts.last()?;
5239 let last_expr = match last_stmt.kind {
5240 hir::StmtKind::Semi(ref e) => e,
5243 let last_expr_ty = self.node_ty(last_expr.hir_id);
5244 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5247 let original_span = original_sp(last_stmt.span, blk.span);
5248 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5251 // Instantiates the given path, which must refer to an item with the given
5252 // number of type parameters and type.
5253 pub fn instantiate_value_path(
5255 segments: &[hir::PathSegment<'_>],
5256 self_ty: Option<Ty<'tcx>>,
5260 ) -> (Ty<'tcx>, Res) {
5262 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5263 segments, self_ty, res, hir_id,
5268 let path_segs = match res {
5269 Res::Local(_) | Res::SelfCtor(_) => vec![],
5270 Res::Def(kind, def_id) => {
5271 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id)
5273 _ => bug!("instantiate_value_path on {:?}", res),
5276 let mut user_self_ty = None;
5277 let mut is_alias_variant_ctor = false;
5279 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5280 if let Some(self_ty) = self_ty {
5281 let adt_def = self_ty.ty_adt_def().unwrap();
5282 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
5283 is_alias_variant_ctor = true;
5286 Res::Def(DefKind::Method, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
5287 let container = tcx.associated_item(def_id).container;
5288 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5290 ty::TraitContainer(trait_did) => {
5291 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5293 ty::ImplContainer(impl_def_id) => {
5294 if segments.len() == 1 {
5295 // `<T>::assoc` will end up here, and so
5296 // can `T::assoc`. It this came from an
5297 // inherent impl, we need to record the
5298 // `T` for posterity (see `UserSelfTy` for
5300 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5301 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
5309 // Now that we have categorized what space the parameters for each
5310 // segment belong to, let's sort out the parameters that the user
5311 // provided (if any) into their appropriate spaces. We'll also report
5312 // errors if type parameters are provided in an inappropriate place.
5314 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5315 let generics_has_err = AstConv::prohibit_generics(
5317 segments.iter().enumerate().filter_map(|(index, seg)| {
5318 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5326 if let Res::Local(hid) = res {
5327 let ty = self.local_ty(span, hid).decl_ty;
5328 let ty = self.normalize_associated_types_in(span, &ty);
5329 self.write_ty(hir_id, ty);
5333 if generics_has_err {
5334 // Don't try to infer type parameters when prohibited generic arguments were given.
5335 user_self_ty = None;
5338 // Now we have to compare the types that the user *actually*
5339 // provided against the types that were *expected*. If the user
5340 // did not provide any types, then we want to substitute inference
5341 // variables. If the user provided some types, we may still need
5342 // to add defaults. If the user provided *too many* types, that's
5345 let mut infer_args_for_err = FxHashSet::default();
5346 for &PathSeg(def_id, index) in &path_segs {
5347 let seg = &segments[index];
5348 let generics = tcx.generics_of(def_id);
5349 // Argument-position `impl Trait` is treated as a normal generic
5350 // parameter internally, but we don't allow users to specify the
5351 // parameter's value explicitly, so we have to do some error-
5353 let suppress_errors = AstConv::check_generic_arg_count_for_call(
5354 tcx, span, &generics, &seg, false, // `is_method_call`
5356 if suppress_errors {
5357 infer_args_for_err.insert(index);
5358 self.set_tainted_by_errors(); // See issue #53251.
5362 let has_self = path_segs
5364 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
5367 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
5368 let ty = self.impl_self_ty(span, impl_def_id).ty;
5369 let adt_def = ty.ty_adt_def();
5372 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
5373 let variant = adt_def.non_enum_variant();
5374 let ctor_def_id = variant.ctor_def_id.unwrap();
5376 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
5381 let mut err = tcx.sess.struct_span_err(
5383 "the `Self` constructor can only be used with tuple or unit structs",
5385 if let Some(adt_def) = adt_def {
5386 match adt_def.adt_kind() {
5388 err.help("did you mean to use one of the enum's variants?");
5390 AdtKind::Struct | AdtKind::Union => {
5391 err.span_suggestion(
5393 "use curly brackets",
5394 String::from("Self { /* fields */ }"),
5395 Applicability::HasPlaceholders,
5402 return (tcx.types.err, res);
5408 let def_id = res.def_id();
5410 // The things we are substituting into the type should not contain
5411 // escaping late-bound regions, and nor should the base type scheme.
5412 let ty = tcx.type_of(def_id);
5414 let substs = self_ctor_substs.unwrap_or_else(|| {
5415 AstConv::create_substs_for_generic_args(
5421 // Provide the generic args, and whether types should be inferred.
5423 if let Some(&PathSeg(_, index)) =
5424 path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
5426 // If we've encountered an `impl Trait`-related error, we're just
5427 // going to infer the arguments for better error messages.
5428 if !infer_args_for_err.contains(&index) {
5429 // Check whether the user has provided generic arguments.
5430 if let Some(ref data) = segments[index].args {
5431 return (Some(data), segments[index].infer_args);
5434 return (None, segments[index].infer_args);
5439 // Provide substitutions for parameters for which (valid) arguments have been provided.
5440 |param, arg| match (¶m.kind, arg) {
5441 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5442 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5444 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5445 self.to_ty(ty).into()
5447 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5448 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
5450 _ => unreachable!(),
5452 // Provide substitutions for parameters for which arguments are inferred.
5453 |substs, param, infer_args| {
5455 GenericParamDefKind::Lifetime => {
5456 self.re_infer(Some(param), span).unwrap().into()
5458 GenericParamDefKind::Type { has_default, .. } => {
5459 if !infer_args && has_default {
5460 // If we have a default, then we it doesn't matter that we're not
5461 // inferring the type arguments: we provide the default where any
5463 let default = tcx.type_of(param.def_id);
5466 default.subst_spanned(tcx, substs.unwrap(), Some(span)),
5470 // If no type arguments were provided, we have to infer them.
5471 // This case also occurs as a result of some malformed input, e.g.
5472 // a lifetime argument being given instead of a type parameter.
5473 // Using inference instead of `Error` gives better error messages.
5474 self.var_for_def(span, param)
5477 GenericParamDefKind::Const => {
5478 // FIXME(const_generics:defaults)
5479 // No const parameters were provided, we have to infer them.
5480 self.var_for_def(span, param)
5486 assert!(!substs.has_escaping_bound_vars());
5487 assert!(!ty.has_escaping_bound_vars());
5489 // First, store the "user substs" for later.
5490 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5492 self.add_required_obligations(span, def_id, &substs);
5494 // Substitute the values for the type parameters into the type of
5495 // the referenced item.
5496 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5498 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5499 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5500 // is inherent, there is no `Self` parameter; instead, the impl needs
5501 // type parameters, which we can infer by unifying the provided `Self`
5502 // with the substituted impl type.
5503 // This also occurs for an enum variant on a type alias.
5504 let ty = tcx.type_of(impl_def_id);
5506 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5507 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5508 Ok(ok) => self.register_infer_ok_obligations(ok),
5510 self.tcx.sess.delay_span_bug(span, &format!(
5511 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5519 self.check_rustc_args_require_const(def_id, hir_id, span);
5521 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
5522 self.write_substs(hir_id, substs);
5524 (ty_substituted, res)
5527 /// Add all the obligations that are required, substituting and normalized appropriately.
5528 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
5529 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
5531 for (i, mut obligation) in traits::predicates_for_generics(
5532 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5539 // This makes the error point at the bound, but we want to point at the argument
5540 if let Some(span) = spans.get(i) {
5541 obligation.cause.code = traits::BindingObligation(def_id, *span);
5543 self.register_predicate(obligation);
5547 fn check_rustc_args_require_const(&self, def_id: DefId, hir_id: hir::HirId, span: Span) {
5548 // We're only interested in functions tagged with
5549 // #[rustc_args_required_const], so ignore anything that's not.
5550 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5554 // If our calling expression is indeed the function itself, we're good!
5555 // If not, generate an error that this can only be called directly.
5556 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)) {
5557 if let ExprKind::Call(ref callee, ..) = expr.kind {
5558 if callee.hir_id == hir_id {
5564 self.tcx.sess.span_err(
5566 "this function can only be invoked \
5567 directly, not through a function pointer",
5571 /// Resolves `typ` by a single level if `typ` is a type variable.
5572 /// If no resolution is possible, then an error is reported.
5573 /// Numeric inference variables may be left unresolved.
5574 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5575 let ty = self.resolve_vars_with_obligations(ty);
5576 if !ty.is_ty_var() {
5579 if !self.is_tainted_by_errors() {
5580 self.need_type_info_err((**self).body_id, sp, ty, E0282)
5581 .note("type must be known at this point")
5584 self.demand_suptype(sp, self.tcx.types.err, ty);
5589 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5592 ctxt: BreakableCtxt<'tcx>,
5594 ) -> (BreakableCtxt<'tcx>, R) {
5597 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5598 index = enclosing_breakables.stack.len();
5599 enclosing_breakables.by_id.insert(id, index);
5600 enclosing_breakables.stack.push(ctxt);
5604 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5605 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5606 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5607 enclosing_breakables.stack.pop().expect("missing breakable context")
5612 /// Instantiate a QueryResponse in a probe context, without a
5613 /// good ObligationCause.
5614 fn probe_instantiate_query_response(
5617 original_values: &OriginalQueryValues<'tcx>,
5618 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5619 ) -> InferResult<'tcx, Ty<'tcx>> {
5620 self.instantiate_query_response_and_region_obligations(
5621 &traits::ObligationCause::misc(span, self.body_id),
5628 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5629 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5630 let mut contained_in_place = false;
5632 while let hir::Node::Expr(parent_expr) =
5633 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5635 match &parent_expr.kind {
5636 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5637 if lhs.hir_id == expr_id {
5638 contained_in_place = true;
5644 expr_id = parent_expr.hir_id;
5651 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5652 let own_counts = generics.own_counts();
5654 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5655 own_counts.types, own_counts.consts, ty
5658 if own_counts.types == 0 {
5662 // Make a vector of booleans initially `false`; set to `true` when used.
5663 let mut types_used = vec![false; own_counts.types];
5665 for leaf_ty in ty.walk() {
5666 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.kind {
5667 debug!("found use of ty param num {}", index);
5668 types_used[index as usize - own_counts.lifetimes] = true;
5669 } else if let ty::Error = leaf_ty.kind {
5670 // If there is already another error, do not emit
5671 // an error for not using a type parameter.
5672 assert!(tcx.sess.has_errors());
5677 let types = generics.params.iter().filter(|param| match param.kind {
5678 ty::GenericParamDefKind::Type { .. } => true,
5681 for (&used, param) in types_used.iter().zip(types) {
5683 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5684 let span = tcx.hir().span(id);
5685 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5686 .span_label(span, "unused type parameter")
5692 fn fatally_break_rust(sess: &Session) {
5693 let handler = sess.diagnostic();
5694 handler.span_bug_no_panic(
5696 "It looks like you're trying to break rust; would you like some ICE?",
5698 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5699 handler.note_without_error(
5700 "we would appreciate a joke overview: \
5701 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5703 handler.note_without_error(&format!(
5704 "rustc {} running on {}",
5705 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5706 crate::session::config::host_triple(),
5710 fn potentially_plural_count(count: usize, word: &str) -> String {
5711 format!("{} {}{}", count, word, pluralize!(count))