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
85 mod generator_interior;
89 use crate::astconv::{AstConv, PathSeg};
90 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
91 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
92 use rustc::hir::def::{CtorOf, Res, DefKind};
93 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
94 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
95 use rustc::hir::itemlikevisit::ItemLikeVisitor;
96 use crate::middle::lang_items;
97 use crate::namespace::Namespace;
98 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
99 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
100 use rustc_data_structures::indexed_vec::Idx;
101 use rustc_target::spec::abi::Abi;
102 use rustc::infer::opaque_types::OpaqueTypeDecl;
103 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
104 use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
105 use rustc::middle::region;
106 use rustc::mir::interpret::{ConstValue, GlobalId};
107 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
109 self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
110 ToPolyTraitRef, ToPredicate, RegionKind, UserType
112 use rustc::ty::adjustment::{
113 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
115 use rustc::ty::fold::TypeFoldable;
116 use rustc::ty::query::Providers;
117 use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
118 use rustc::ty::util::{Representability, IntTypeExt, Discr};
119 use rustc::ty::layout::VariantIdx;
120 use syntax_pos::{self, BytePos, Span, MultiSpan};
121 use syntax_pos::hygiene::CompilerDesugaringKind;
124 use syntax::feature_gate::{GateIssue, emit_feature_err};
126 use syntax::source_map::{DUMMY_SP, original_sp};
127 use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
128 use syntax::util::lev_distance::find_best_match_for_name;
130 use std::cell::{Cell, RefCell, Ref, RefMut};
131 use std::collections::hash_map::Entry;
133 use std::fmt::Display;
135 use std::mem::replace;
136 use std::ops::{self, Deref};
139 use crate::require_c_abi_if_c_variadic;
140 use crate::session::Session;
141 use crate::session::config::EntryFnType;
142 use crate::TypeAndSubsts;
144 use crate::util::captures::Captures;
145 use crate::util::common::{ErrorReported, indenter};
146 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, HirIdMap};
148 pub use self::Expectation::*;
149 use self::autoderef::Autoderef;
150 use self::callee::DeferredCallResolution;
151 use self::coercion::{CoerceMany, DynamicCoerceMany};
152 pub use self::compare_method::{compare_impl_method, compare_const_impl};
153 use self::method::{MethodCallee, SelfSource};
154 use self::TupleArgumentsFlag::*;
156 /// The type of a local binding, including the revealed type for anon types.
157 #[derive(Copy, Clone)]
158 pub struct LocalTy<'tcx> {
160 revealed_ty: Ty<'tcx>
163 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
164 #[derive(Copy, Clone)]
165 struct MaybeInProgressTables<'a, 'tcx: 'a> {
166 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
169 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
170 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
171 match self.maybe_tables {
172 Some(tables) => tables.borrow(),
174 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
179 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
180 match self.maybe_tables {
181 Some(tables) => tables.borrow_mut(),
183 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
189 /// Closures defined within the function. For example:
192 /// bar(move|| { ... })
195 /// Here, the function `foo()` and the closure passed to
196 /// `bar()` will each have their own `FnCtxt`, but they will
197 /// share the inherited fields.
198 pub struct Inherited<'a, 'tcx: 'a> {
199 infcx: InferCtxt<'a, 'tcx>,
201 tables: MaybeInProgressTables<'a, 'tcx>,
203 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
205 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
207 // Some additional `Sized` obligations badly affect type inference.
208 // These obligations are added in a later stage of typeck.
209 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
211 // When we process a call like `c()` where `c` is a closure type,
212 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
213 // `FnOnce` closure. In that case, we defer full resolution of the
214 // call until upvar inference can kick in and make the
215 // decision. We keep these deferred resolutions grouped by the
216 // def-id of the closure, so that once we decide, we can easily go
217 // back and process them.
218 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
220 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
222 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
224 // Opaque types found in explicit return types and their
225 // associated fresh inference variable. Writeback resolves these
226 // variables to get the concrete type, which can be used to
227 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
228 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
230 /// Each type parameter has an implicit region bound that
231 /// indicates it must outlive at least the function body (the user
232 /// may specify stronger requirements). This field indicates the
233 /// region of the callee. If it is `None`, then the parameter
234 /// environment is for an item or something where the "callee" is
236 implicit_region_bound: Option<ty::Region<'tcx>>,
238 body_id: Option<hir::BodyId>,
241 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
242 type Target = InferCtxt<'a, 'tcx>;
243 fn deref(&self) -> &Self::Target {
248 /// When type-checking an expression, we propagate downward
249 /// whatever type hint we are able in the form of an `Expectation`.
250 #[derive(Copy, Clone, Debug)]
251 pub enum Expectation<'tcx> {
252 /// We know nothing about what type this expression should have.
255 /// This expression should have the type given (or some subtype).
256 ExpectHasType(Ty<'tcx>),
258 /// This expression will be cast to the `Ty`.
259 ExpectCastableToType(Ty<'tcx>),
261 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
262 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
263 ExpectRvalueLikeUnsized(Ty<'tcx>),
266 impl<'a, 'tcx> Expectation<'tcx> {
267 // Disregard "castable to" expectations because they
268 // can lead us astray. Consider for example `if cond
269 // {22} else {c} as u8` -- if we propagate the
270 // "castable to u8" constraint to 22, it will pick the
271 // type 22u8, which is overly constrained (c might not
272 // be a u8). In effect, the problem is that the
273 // "castable to" expectation is not the tightest thing
274 // we can say, so we want to drop it in this case.
275 // The tightest thing we can say is "must unify with
276 // else branch". Note that in the case of a "has type"
277 // constraint, this limitation does not hold.
279 // If the expected type is just a type variable, then don't use
280 // an expected type. Otherwise, we might write parts of the type
281 // when checking the 'then' block which are incompatible with the
283 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
285 ExpectHasType(ety) => {
286 let ety = fcx.shallow_resolve(ety);
287 if !ety.is_ty_var() {
293 ExpectRvalueLikeUnsized(ety) => {
294 ExpectRvalueLikeUnsized(ety)
300 /// Provides an expectation for an rvalue expression given an *optional*
301 /// hint, which is not required for type safety (the resulting type might
302 /// be checked higher up, as is the case with `&expr` and `box expr`), but
303 /// is useful in determining the concrete type.
305 /// The primary use case is where the expected type is a fat pointer,
306 /// like `&[isize]`. For example, consider the following statement:
308 /// let x: &[isize] = &[1, 2, 3];
310 /// In this case, the expected type for the `&[1, 2, 3]` expression is
311 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
312 /// expectation `ExpectHasType([isize])`, that would be too strong --
313 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
314 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
315 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
316 /// which still is useful, because it informs integer literals and the like.
317 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
318 /// for examples of where this comes up,.
319 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
320 match fcx.tcx.struct_tail(ty).sty {
321 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
322 ExpectRvalueLikeUnsized(ty)
324 _ => ExpectHasType(ty)
328 // Resolves `expected` by a single level if it is a variable. If
329 // there is no expected type or resolution is not possible (e.g.,
330 // no constraints yet present), just returns `None`.
331 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
333 NoExpectation => NoExpectation,
334 ExpectCastableToType(t) => {
335 ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
337 ExpectHasType(t) => {
338 ExpectHasType(fcx.resolve_vars_if_possible(&t))
340 ExpectRvalueLikeUnsized(t) => {
341 ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
346 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
347 match self.resolve(fcx) {
348 NoExpectation => None,
349 ExpectCastableToType(ty) |
351 ExpectRvalueLikeUnsized(ty) => Some(ty),
355 /// It sometimes happens that we want to turn an expectation into
356 /// a **hard constraint** (i.e., something that must be satisfied
357 /// for the program to type-check). `only_has_type` will return
358 /// such a constraint, if it exists.
359 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
360 match self.resolve(fcx) {
361 ExpectHasType(ty) => Some(ty),
362 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
366 /// Like `only_has_type`, but instead of returning `None` if no
367 /// hard constraint exists, creates a fresh type variable.
368 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
369 self.only_has_type(fcx)
371 fcx.next_ty_var(TypeVariableOrigin {
372 kind: TypeVariableOriginKind::MiscVariable,
379 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
386 fn maybe_mut_place(m: hir::Mutability) -> Self {
388 hir::MutMutable => Needs::MutPlace,
389 hir::MutImmutable => Needs::None,
394 #[derive(Copy, Clone)]
395 pub struct UnsafetyState {
397 pub unsafety: hir::Unsafety,
398 pub unsafe_push_count: u32,
403 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
404 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
407 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
408 match self.unsafety {
409 // If this unsafe, then if the outer function was already marked as
410 // unsafe we shouldn't attribute the unsafe'ness to the block. This
411 // way the block can be warned about instead of ignoring this
412 // extraneous block (functions are never warned about).
413 hir::Unsafety::Unsafe if self.from_fn => *self,
416 let (unsafety, def, count) = match blk.rules {
417 hir::PushUnsafeBlock(..) =>
418 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
419 hir::PopUnsafeBlock(..) =>
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
421 hir::UnsafeBlock(..) =>
422 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
424 (unsafety, self.def, self.unsafe_push_count),
428 unsafe_push_count: count,
435 #[derive(Debug, Copy, Clone)]
441 /// Tracks whether executing a node may exit normally (versus
442 /// return/break/panic, which "diverge", leaving dead code in their
443 /// wake). Tracked semi-automatically (through type variables marked
444 /// as diverging), with some manual adjustments for control-flow
445 /// primitives (approximating a CFG).
446 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
448 /// Potentially unknown, some cases converge,
449 /// others require a CFG to determine them.
452 /// Definitely known to diverge and therefore
453 /// not reach the next sibling or its parent.
456 /// Same as `Always` but with a reachability
457 /// warning already emitted.
461 // Convenience impls for combinig `Diverges`.
463 impl ops::BitAnd for Diverges {
465 fn bitand(self, other: Self) -> Self {
466 cmp::min(self, other)
470 impl ops::BitOr for Diverges {
472 fn bitor(self, other: Self) -> Self {
473 cmp::max(self, other)
477 impl ops::BitAndAssign for Diverges {
478 fn bitand_assign(&mut self, other: Self) {
479 *self = *self & other;
483 impl ops::BitOrAssign for Diverges {
484 fn bitor_assign(&mut self, other: Self) {
485 *self = *self | other;
490 fn always(self) -> bool {
491 self >= Diverges::Always
495 pub struct BreakableCtxt<'tcx> {
498 // this is `null` for loops where break with a value is illegal,
499 // such as `while`, `for`, and `while let`
500 coerce: Option<DynamicCoerceMany<'tcx>>,
503 pub struct EnclosingBreakables<'tcx> {
504 stack: Vec<BreakableCtxt<'tcx>>,
505 by_id: HirIdMap<usize>,
508 impl<'tcx> EnclosingBreakables<'tcx> {
509 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
510 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
511 bug!("could not find enclosing breakable with id {}", target_id);
517 pub struct FnCtxt<'a, 'tcx: 'a> {
520 /// The parameter environment used for proving trait obligations
521 /// in this function. This can change when we descend into
522 /// closures (as they bring new things into scope), hence it is
523 /// not part of `Inherited` (as of the time of this writing,
524 /// closures do not yet change the environment, but they will
526 param_env: ty::ParamEnv<'tcx>,
528 /// Number of errors that had been reported when we started
529 /// checking this function. On exit, if we find that *more* errors
530 /// have been reported, we will skip regionck and other work that
531 /// expects the types within the function to be consistent.
532 err_count_on_creation: usize,
534 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
535 ret_coercion_span: RefCell<Option<Span>>,
537 yield_ty: Option<Ty<'tcx>>,
539 ps: RefCell<UnsafetyState>,
541 /// Whether the last checked node generates a divergence (e.g.,
542 /// `return` will set this to `Always`). In general, when entering
543 /// an expression or other node in the tree, the initial value
544 /// indicates whether prior parts of the containing expression may
545 /// have diverged. It is then typically set to `Maybe` (and the
546 /// old value remembered) for processing the subparts of the
547 /// current expression. As each subpart is processed, they may set
548 /// the flag to `Always`, etc. Finally, at the end, we take the
549 /// result and "union" it with the original value, so that when we
550 /// return the flag indicates if any subpart of the parent
551 /// expression (up to and including this part) has diverged. So,
552 /// if you read it after evaluating a subexpression `X`, the value
553 /// you get indicates whether any subexpression that was
554 /// evaluating up to and including `X` diverged.
556 /// We currently use this flag only for diagnostic purposes:
558 /// - To warn about unreachable code: if, after processing a
559 /// sub-expression but before we have applied the effects of the
560 /// current node, we see that the flag is set to `Always`, we
561 /// can issue a warning. This corresponds to something like
562 /// `foo(return)`; we warn on the `foo()` expression. (We then
563 /// update the flag to `WarnedAlways` to suppress duplicate
564 /// reports.) Similarly, if we traverse to a fresh statement (or
565 /// tail expression) from a `Always` setting, we will issue a
566 /// warning. This corresponds to something like `{return;
567 /// foo();}` or `{return; 22}`, where we would warn on the
570 /// An expression represents dead code if, after checking it,
571 /// the diverges flag is set to something other than `Maybe`.
572 diverges: Cell<Diverges>,
574 /// Whether any child nodes have any type errors.
575 has_errors: Cell<bool>,
577 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
579 inh: &'a Inherited<'a, 'tcx>,
582 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
583 type Target = Inherited<'a, 'tcx>;
584 fn deref(&self) -> &Self::Target {
589 /// Helper type of a temporary returned by `Inherited::build(...)`.
590 /// Necessary because we can't write the following bound:
591 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
592 pub struct InheritedBuilder<'tcx> {
593 infcx: infer::InferCtxtBuilder<'tcx>,
597 impl Inherited<'_, 'tcx> {
598 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
599 let hir_id_root = if def_id.is_local() {
600 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
601 DefId::local(hir_id.owner)
607 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
613 impl<'tcx> InheritedBuilder<'tcx> {
614 fn enter<F, R>(&mut self, f: F) -> R
616 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
618 let def_id = self.def_id;
619 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
623 impl Inherited<'a, 'tcx> {
624 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
626 let item_id = tcx.hir().as_local_hir_id(def_id);
627 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by_by_hir_id(id));
628 let implicit_region_bound = body_id.map(|body_id| {
629 let body = tcx.hir().body(body_id);
630 tcx.mk_region(ty::ReScope(region::Scope {
631 id: body.value.hir_id.local_id,
632 data: region::ScopeData::CallSite
637 tables: MaybeInProgressTables {
638 maybe_tables: infcx.in_progress_tables,
641 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
642 locals: RefCell::new(Default::default()),
643 deferred_sized_obligations: RefCell::new(Vec::new()),
644 deferred_call_resolutions: RefCell::new(Default::default()),
645 deferred_cast_checks: RefCell::new(Vec::new()),
646 deferred_generator_interiors: RefCell::new(Vec::new()),
647 opaque_types: RefCell::new(Default::default()),
648 implicit_region_bound,
653 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
654 debug!("register_predicate({:?})", obligation);
655 if obligation.has_escaping_bound_vars() {
656 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
661 .register_predicate_obligation(self, obligation);
664 fn register_predicates<I>(&self, obligations: I)
665 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
667 for obligation in obligations {
668 self.register_predicate(obligation);
672 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
673 self.register_predicates(infer_ok.obligations);
677 fn normalize_associated_types_in<T>(&self,
680 param_env: ty::ParamEnv<'tcx>,
682 where T : TypeFoldable<'tcx>
684 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
685 self.register_infer_ok_obligations(ok)
689 struct CheckItemTypesVisitor<'tcx> {
693 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
694 fn visit_item(&mut self, i: &'tcx hir::Item) {
695 check_item_type(self.tcx, i);
697 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
698 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
701 pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
702 tcx.sess.track_errors(|| {
703 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
704 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
708 fn check_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
709 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
712 fn typeck_item_bodies<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) {
713 debug_assert!(crate_num == LOCAL_CRATE);
714 tcx.par_body_owners(|body_owner_def_id| {
715 tcx.ensure().typeck_tables_of(body_owner_def_id);
719 fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
720 wfcheck::check_item_well_formed(tcx, def_id);
723 fn check_trait_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
724 wfcheck::check_trait_item(tcx, def_id);
727 fn check_impl_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
728 wfcheck::check_impl_item(tcx, def_id);
731 pub fn provide(providers: &mut Providers<'_>) {
732 method::provide(providers);
733 *providers = Providers {
739 check_item_well_formed,
740 check_trait_item_well_formed,
741 check_impl_item_well_formed,
742 check_mod_item_types,
747 fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::Destructor> {
748 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
751 /// If this `DefId` is a "primary tables entry", returns `Some((body_id, decl))`
752 /// with information about it's body-id and fn-decl (if any). Otherwise,
755 /// If this function returns "some", then `typeck_tables(def_id)` will
756 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
757 /// may not succeed. In some cases where this function returns `None`
758 /// (notably closures), `typeck_tables(def_id)` would wind up
759 /// redirecting to the owning function.
760 fn primary_body_of<'tcx>(
763 ) -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)> {
764 match tcx.hir().get_by_hir_id(id) {
765 Node::Item(item) => {
767 hir::ItemKind::Const(_, body) |
768 hir::ItemKind::Static(_, _, body) =>
770 hir::ItemKind::Fn(ref decl, .., body) =>
771 Some((body, Some(decl))),
776 Node::TraitItem(item) => {
778 hir::TraitItemKind::Const(_, Some(body)) =>
780 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
781 Some((body, Some(&sig.decl))),
786 Node::ImplItem(item) => {
788 hir::ImplItemKind::Const(_, body) =>
790 hir::ImplItemKind::Method(ref sig, body) =>
791 Some((body, Some(&sig.decl))),
796 Node::AnonConst(constant) => Some((constant.body, None)),
801 fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
802 // Closures' tables come from their outermost function,
803 // as they are part of the same "inference environment".
804 let outer_def_id = tcx.closure_base_def_id(def_id);
805 if outer_def_id != def_id {
806 return tcx.has_typeck_tables(outer_def_id);
809 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
810 primary_body_of(tcx, id).is_some()
813 fn used_trait_imports<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx DefIdSet {
814 &*tcx.typeck_tables_of(def_id).used_trait_imports
817 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckTables<'tcx> {
818 // Closures' tables come from their outermost function,
819 // as they are part of the same "inference environment".
820 let outer_def_id = tcx.closure_base_def_id(def_id);
821 if outer_def_id != def_id {
822 return tcx.typeck_tables_of(outer_def_id);
825 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
826 let span = tcx.hir().span_by_hir_id(id);
828 // Figure out what primary body this item has.
829 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
830 span_bug!(span, "can't type-check body of {:?}", def_id);
832 let body = tcx.hir().body(body_id);
834 let tables = Inherited::build(tcx, def_id).enter(|inh| {
835 let param_env = tcx.param_env(def_id);
836 let fcx = if let Some(decl) = fn_decl {
837 let fn_sig = tcx.fn_sig(def_id);
839 check_abi(tcx, span, fn_sig.abi());
841 // Compute the fty from point of view of inside the fn.
843 tcx.liberate_late_bound_regions(def_id, &fn_sig);
845 inh.normalize_associated_types_in(body.value.span,
850 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
853 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
854 let expected_type = tcx.type_of(def_id);
855 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
856 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
858 let revealed_ty = if tcx.features().impl_trait_in_bindings {
859 fcx.instantiate_opaque_types_from_value(
867 // Gather locals in statics (because of block expressions).
868 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
870 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
872 fcx.write_ty(id, revealed_ty);
877 // All type checking constraints were added, try to fallback unsolved variables.
878 fcx.select_obligations_where_possible(false);
879 let mut fallback_has_occurred = false;
880 for ty in &fcx.unsolved_variables() {
881 fallback_has_occurred |= fcx.fallback_if_possible(ty);
883 fcx.select_obligations_where_possible(fallback_has_occurred);
885 // Even though coercion casts provide type hints, we check casts after fallback for
886 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
889 // Closure and generator analysis may run after fallback
890 // because they don't constrain other type variables.
891 fcx.closure_analyze(body);
892 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
893 fcx.resolve_generator_interiors(def_id);
895 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
896 let ty = fcx.normalize_ty(span, ty);
897 fcx.require_type_is_sized(ty, span, code);
899 fcx.select_all_obligations_or_error();
901 if fn_decl.is_some() {
902 fcx.regionck_fn(id, body);
904 fcx.regionck_expr(body);
907 fcx.resolve_type_vars_in_body(body)
910 // Consistency check our TypeckTables instance can hold all ItemLocalIds
911 // it will need to hold.
912 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
917 fn check_abi<'tcx>(tcx: TyCtxt<'tcx>, span: Span, abi: Abi) {
918 if !tcx.sess.target.target.is_abi_supported(abi) {
919 struct_span_err!(tcx.sess, span, E0570,
920 "The ABI `{}` is not supported for the current target", abi).emit()
924 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
925 fcx: &'a FnCtxt<'a, 'tcx>,
926 parent_id: hir::HirId,
929 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
930 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
933 // infer the variable's type
934 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
935 kind: TypeVariableOriginKind::TypeInference,
938 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
945 // take type that the user specified
946 self.fcx.locals.borrow_mut().insert(nid, typ);
953 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
954 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
955 NestedVisitorMap::None
958 // Add explicitly-declared locals.
959 fn visit_local(&mut self, local: &'tcx hir::Local) {
960 let local_ty = match local.ty {
962 let o_ty = self.fcx.to_ty(&ty);
964 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
965 self.fcx.instantiate_opaque_types_from_value(
973 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
974 &UserType::Ty(revealed_ty)
976 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
977 ty.hir_id, o_ty, revealed_ty, c_ty);
978 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
980 Some(LocalTy { decl_ty: o_ty, revealed_ty })
984 self.assign(local.span, local.hir_id, local_ty);
986 debug!("Local variable {:?} is assigned type {}",
988 self.fcx.ty_to_string(
989 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
990 intravisit::walk_local(self, local);
993 // Add pattern bindings.
994 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
995 if let PatKind::Binding(_, _, ident, _) = p.node {
996 let var_ty = self.assign(p.span, p.hir_id, None);
998 let node_id = self.fcx.tcx.hir().hir_to_node_id(p.hir_id);
999 if !self.fcx.tcx.features().unsized_locals {
1000 self.fcx.require_type_is_sized(var_ty, p.span,
1001 traits::VariableType(node_id));
1004 debug!("Pattern binding {} is assigned to {} with type {:?}",
1006 self.fcx.ty_to_string(
1007 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1010 intravisit::walk_pat(self, p);
1013 // Don't descend into the bodies of nested closures
1016 _: intravisit::FnKind<'tcx>,
1017 _: &'tcx hir::FnDecl,
1024 /// When `check_fn` is invoked on a generator (i.e., a body that
1025 /// includes yield), it returns back some information about the yield
1027 struct GeneratorTypes<'tcx> {
1028 /// Type of value that is yielded.
1031 /// Types that are captured (see `GeneratorInterior` for more).
1034 /// Indicates if the generator is movable or static (immovable).
1035 movability: hir::GeneratorMovability,
1038 /// Helper used for fns and closures. Does the grungy work of checking a function
1039 /// body and returns the function context used for that purpose, since in the case of a fn item
1040 /// there is still a bit more to do.
1043 /// * inherited: other fields inherited from the enclosing fn (if any)
1044 fn check_fn<'a, 'tcx>(
1045 inherited: &'a Inherited<'a, 'tcx>,
1046 param_env: ty::ParamEnv<'tcx>,
1047 fn_sig: ty::FnSig<'tcx>,
1048 decl: &'tcx hir::FnDecl,
1050 body: &'tcx hir::Body,
1051 can_be_generator: Option<hir::GeneratorMovability>,
1052 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1053 let mut fn_sig = fn_sig.clone();
1055 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1057 // Create the function context. This is either derived from scratch or,
1058 // in the case of closures, based on the outer context.
1059 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1060 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1062 let declared_ret_ty = fn_sig.output();
1063 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1064 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty);
1065 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1066 fn_sig = fcx.tcx.mk_fn_sig(
1067 fn_sig.inputs().iter().cloned(),
1074 let span = body.value.span;
1076 if body.is_generator && can_be_generator.is_some() {
1077 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1078 kind: TypeVariableOriginKind::TypeInference,
1081 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1082 fcx.yield_ty = Some(yield_ty);
1085 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id_from_hir_id(fn_id));
1086 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1087 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1089 // Add formal parameters.
1090 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1091 // Check the pattern.
1092 let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
1093 fcx.check_pat_walk(&arg.pat, arg_ty, binding_mode, None);
1095 // Check that argument is Sized.
1096 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1097 // for simple cases like `fn foo(x: Trait)`,
1098 // where we would error once on the parameter as a whole, and once on the binding `x`.
1099 if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1100 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
1103 fcx.write_ty(arg.hir_id, arg_ty);
1106 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1108 fcx.check_return_expr(&body.value);
1110 // We insert the deferred_generator_interiors entry after visiting the body.
1111 // This ensures that all nested generators appear before the entry of this generator.
1112 // resolve_generator_interiors relies on this property.
1113 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1114 let interior = fcx.next_ty_var(TypeVariableOrigin {
1115 kind: TypeVariableOriginKind::MiscVariable,
1118 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1119 Some(GeneratorTypes {
1120 yield_ty: fcx.yield_ty.unwrap(),
1122 movability: can_be_generator.unwrap(),
1128 // Finalize the return check by taking the LUB of the return types
1129 // we saw and assigning it to the expected return type. This isn't
1130 // really expected to fail, since the coercions would have failed
1131 // earlier when trying to find a LUB.
1133 // However, the behavior around `!` is sort of complex. In the
1134 // event that the `actual_return_ty` comes back as `!`, that
1135 // indicates that the fn either does not return or "returns" only
1136 // values of type `!`. In this case, if there is an expected
1137 // return type that is *not* `!`, that should be ok. But if the
1138 // return type is being inferred, we want to "fallback" to `!`:
1140 // let x = move || panic!();
1142 // To allow for that, I am creating a type variable with diverging
1143 // fallback. This was deemed ever so slightly better than unifying
1144 // the return value with `!` because it allows for the caller to
1145 // make more assumptions about the return type (e.g., they could do
1147 // let y: Option<u32> = Some(x());
1149 // which would then cause this return type to become `u32`, not
1151 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1152 let mut actual_return_ty = coercion.complete(&fcx);
1153 if actual_return_ty.is_never() {
1154 actual_return_ty = fcx.next_diverging_ty_var(
1155 TypeVariableOrigin {
1156 kind: TypeVariableOriginKind::DivergingFn,
1161 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1163 // Check that the main return type implements the termination trait.
1164 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1165 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1166 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1167 if main_id == fn_id {
1168 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1169 let trait_ref = ty::TraitRef::new(term_id, substs);
1170 let return_ty_span = decl.output.span();
1171 let cause = traits::ObligationCause::new(
1172 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1174 inherited.register_predicate(
1175 traits::Obligation::new(
1176 cause, param_env, trait_ref.to_predicate()));
1181 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1182 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1183 if panic_impl_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1184 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1185 // at this point we don't care if there are duplicate handlers or if the handler has
1186 // the wrong signature as this value we'll be used when writing metadata and that
1187 // only happens if compilation succeeded
1188 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1190 if declared_ret_ty.sty != ty::Never {
1191 fcx.tcx.sess.span_err(
1193 "return type should be `!`",
1197 let inputs = fn_sig.inputs();
1198 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1199 if inputs.len() == 1 {
1200 let arg_is_panic_info = match inputs[0].sty {
1201 ty::Ref(region, ty, mutbl) => match ty.sty {
1202 ty::Adt(ref adt, _) => {
1203 adt.did == panic_info_did &&
1204 mutbl == hir::Mutability::MutImmutable &&
1205 *region != RegionKind::ReStatic
1212 if !arg_is_panic_info {
1213 fcx.tcx.sess.span_err(
1214 decl.inputs[0].span,
1215 "argument should be `&PanicInfo`",
1219 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1220 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1221 if !generics.params.is_empty() {
1222 fcx.tcx.sess.span_err(
1224 "should have no type parameters",
1230 let span = fcx.tcx.sess.source_map().def_span(span);
1231 fcx.tcx.sess.span_err(span, "function should have one argument");
1234 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1239 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1240 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1241 if alloc_error_handler_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1242 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1243 if declared_ret_ty.sty != ty::Never {
1244 fcx.tcx.sess.span_err(
1246 "return type should be `!`",
1250 let inputs = fn_sig.inputs();
1251 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1252 if inputs.len() == 1 {
1253 let arg_is_alloc_layout = match inputs[0].sty {
1254 ty::Adt(ref adt, _) => {
1255 adt.did == alloc_layout_did
1260 if !arg_is_alloc_layout {
1261 fcx.tcx.sess.span_err(
1262 decl.inputs[0].span,
1263 "argument should be `Layout`",
1267 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1268 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1269 if !generics.params.is_empty() {
1270 fcx.tcx.sess.span_err(
1272 "`#[alloc_error_handler]` function should have no type \
1279 let span = fcx.tcx.sess.source_map().def_span(span);
1280 fcx.tcx.sess.span_err(span, "function should have one argument");
1283 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1291 fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
1292 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1293 let def = tcx.adt_def(def_id);
1294 def.destructor(tcx); // force the destructor to be evaluated
1295 check_representable(tcx, span, def_id);
1297 if def.repr.simd() {
1298 check_simd(tcx, span, def_id);
1301 check_transparent(tcx, span, def_id);
1302 check_packed(tcx, span, def_id);
1305 fn check_union<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
1306 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1307 let def = tcx.adt_def(def_id);
1308 def.destructor(tcx); // force the destructor to be evaluated
1309 check_representable(tcx, span, def_id);
1310 check_transparent(tcx, span, def_id);
1311 check_packed(tcx, span, def_id);
1314 fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, span: Span) {
1315 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1316 let mut err = struct_span_err!(
1317 tcx.sess, span, E0720,
1318 "opaque type expands to a recursive type",
1320 err.span_label(span, "expands to self-referential type");
1321 if let ty::Opaque(..) = partially_expanded_type.sty {
1322 err.note("type resolves to itself");
1324 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1330 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1332 "check_item_type(it.hir_id={}, it.name={})",
1334 tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
1336 let _indenter = indenter();
1338 // Consts can play a role in type-checking, so they are included here.
1339 hir::ItemKind::Static(..) => {
1340 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1341 tcx.typeck_tables_of(def_id);
1342 maybe_check_static_with_link_section(tcx, def_id, it.span);
1344 hir::ItemKind::Const(..) => {
1345 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(it.hir_id));
1347 hir::ItemKind::Enum(ref enum_definition, _) => {
1348 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1350 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1351 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1352 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1353 let impl_def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1354 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1355 check_impl_items_against_trait(
1362 let trait_def_id = impl_trait_ref.def_id;
1363 check_on_unimplemented(tcx, trait_def_id, it);
1366 hir::ItemKind::Trait(..) => {
1367 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1368 check_on_unimplemented(tcx, def_id, it);
1370 hir::ItemKind::Struct(..) => {
1371 check_struct(tcx, it.hir_id, it.span);
1373 hir::ItemKind::Union(..) => {
1374 check_union(tcx, it.hir_id, it.span);
1376 hir::ItemKind::Existential(..) => {
1377 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1379 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1380 check_opaque(tcx, def_id, substs, it.span);
1382 hir::ItemKind::Ty(..) => {
1383 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1384 let pty_ty = tcx.type_of(def_id);
1385 let generics = tcx.generics_of(def_id);
1386 check_bounds_are_used(tcx, &generics, pty_ty);
1388 hir::ItemKind::ForeignMod(ref m) => {
1389 check_abi(tcx, it.span, m.abi);
1391 if m.abi == Abi::RustIntrinsic {
1392 for item in &m.items {
1393 intrinsic::check_intrinsic_type(tcx, item);
1395 } else if m.abi == Abi::PlatformIntrinsic {
1396 for item in &m.items {
1397 intrinsic::check_platform_intrinsic_type(tcx, item);
1400 for item in &m.items {
1401 let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
1402 if generics.params.len() - generics.own_counts().lifetimes != 0 {
1403 let mut err = struct_span_err!(
1407 "foreign items may not have type parameters"
1409 err.span_label(item.span, "can't have type parameters");
1410 // FIXME: once we start storing spans for type arguments, turn this into a
1413 "use specialization instead of type parameters by replacing them \
1414 with concrete types like `u32`",
1419 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1420 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1425 _ => { /* nothing to do */ }
1429 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1430 // Only restricted on wasm32 target for now
1431 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1435 // If `#[link_section]` is missing, then nothing to verify
1436 let attrs = tcx.codegen_fn_attrs(id);
1437 if attrs.link_section.is_none() {
1441 // For the wasm32 target statics with #[link_section] are placed into custom
1442 // sections of the final output file, but this isn't link custom sections of
1443 // other executable formats. Namely we can only embed a list of bytes,
1444 // nothing with pointers to anything else or relocations. If any relocation
1445 // show up, reject them here.
1446 let instance = ty::Instance::mono(tcx, id);
1447 let cid = GlobalId {
1451 let param_env = ty::ParamEnv::reveal_all();
1452 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1453 let alloc = if let ConstValue::ByRef(_, allocation) = static_.val {
1456 bug!("Matching on non-ByRef static")
1458 if alloc.relocations.len() != 0 {
1459 let msg = "statics with a custom `#[link_section]` must be a \
1460 simple list of bytes on the wasm target with no \
1461 extra levels of indirection such as references";
1462 tcx.sess.span_err(span, msg);
1467 fn check_on_unimplemented<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, item: &hir::Item) {
1468 let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
1469 // an error would be reported if this fails.
1470 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1473 fn report_forbidden_specialization<'tcx>(
1475 impl_item: &hir::ImplItem,
1478 let mut err = struct_span_err!(
1479 tcx.sess, impl_item.span, E0520,
1480 "`{}` specializes an item from a parent `impl`, but \
1481 that item is not marked `default`",
1483 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1486 match tcx.span_of_impl(parent_impl) {
1488 err.span_label(span, "parent `impl` is here");
1489 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1493 err.note(&format!("parent implementation is in crate `{}`", cname));
1500 fn check_specialization_validity<'tcx>(
1502 trait_def: &ty::TraitDef,
1503 trait_item: &ty::AssocItem,
1505 impl_item: &hir::ImplItem,
1507 let ancestors = trait_def.ancestors(tcx, impl_id);
1509 let kind = match impl_item.node {
1510 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1511 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1512 hir::ImplItemKind::Existential(..) => ty::AssocKind::Existential,
1513 hir::ImplItemKind::Type(_) => ty::AssocKind::Type
1516 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1517 .map(|node_item| node_item.map(|parent| parent.defaultness));
1519 if let Some(parent) = parent {
1520 if tcx.impl_item_is_final(&parent) {
1521 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1527 fn check_impl_items_against_trait<'tcx>(
1531 impl_trait_ref: ty::TraitRef<'tcx>,
1532 impl_item_refs: &[hir::ImplItemRef],
1534 let impl_span = tcx.sess.source_map().def_span(impl_span);
1536 // If the trait reference itself is erroneous (so the compilation is going
1537 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1538 // isn't populated for such impls.
1539 if impl_trait_ref.references_error() { return; }
1541 // Locate trait definition and items
1542 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1543 let mut overridden_associated_type = None;
1545 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1547 // Check existing impl methods to see if they are both present in trait
1548 // and compatible with trait signature
1549 for impl_item in impl_items() {
1550 let ty_impl_item = tcx.associated_item(
1551 tcx.hir().local_def_id_from_hir_id(impl_item.hir_id));
1552 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1553 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1554 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1556 // Not compatible, but needed for the error message
1557 tcx.associated_items(impl_trait_ref.def_id)
1558 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1561 // Check that impl definition matches trait definition
1562 if let Some(ty_trait_item) = ty_trait_item {
1563 match impl_item.node {
1564 hir::ImplItemKind::Const(..) => {
1565 // Find associated const definition.
1566 if ty_trait_item.kind == ty::AssocKind::Const {
1567 compare_const_impl(tcx,
1573 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1574 "item `{}` is an associated const, \
1575 which doesn't match its trait `{}`",
1578 err.span_label(impl_item.span, "does not match trait");
1579 // We can only get the spans from local trait definition
1580 // Same for E0324 and E0325
1581 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1582 err.span_label(trait_span, "item in trait");
1587 hir::ImplItemKind::Method(..) => {
1588 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1589 if ty_trait_item.kind == ty::AssocKind::Method {
1590 compare_impl_method(tcx,
1597 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1598 "item `{}` is an associated method, \
1599 which doesn't match its trait `{}`",
1602 err.span_label(impl_item.span, "does not match trait");
1603 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1604 err.span_label(trait_span, "item in trait");
1609 hir::ImplItemKind::Existential(..) |
1610 hir::ImplItemKind::Type(_) => {
1611 if ty_trait_item.kind == ty::AssocKind::Type {
1612 if ty_trait_item.defaultness.has_value() {
1613 overridden_associated_type = Some(impl_item);
1616 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1617 "item `{}` is an associated type, \
1618 which doesn't match its trait `{}`",
1621 err.span_label(impl_item.span, "does not match trait");
1622 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1623 err.span_label(trait_span, "item in trait");
1630 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1634 // Check for missing items from trait
1635 let mut missing_items = Vec::new();
1636 let mut invalidated_items = Vec::new();
1637 let associated_type_overridden = overridden_associated_type.is_some();
1638 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1639 let is_implemented = trait_def.ancestors(tcx, impl_id)
1640 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1642 .map(|node_item| !node_item.node.is_from_trait())
1645 if !is_implemented && !tcx.impl_is_default(impl_id) {
1646 if !trait_item.defaultness.has_value() {
1647 missing_items.push(trait_item);
1648 } else if associated_type_overridden {
1649 invalidated_items.push(trait_item.ident);
1654 if !missing_items.is_empty() {
1655 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1656 "not all trait items implemented, missing: `{}`",
1657 missing_items.iter()
1658 .map(|trait_item| trait_item.ident.to_string())
1659 .collect::<Vec<_>>().join("`, `"));
1660 err.span_label(impl_span, format!("missing `{}` in implementation",
1661 missing_items.iter()
1662 .map(|trait_item| trait_item.ident.to_string())
1663 .collect::<Vec<_>>().join("`, `")));
1664 for trait_item in missing_items {
1665 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1666 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1668 err.note_trait_signature(trait_item.ident.to_string(),
1669 trait_item.signature(tcx));
1675 if !invalidated_items.is_empty() {
1676 let invalidator = overridden_associated_type.unwrap();
1677 span_err!(tcx.sess, invalidator.span, E0399,
1678 "the following trait items need to be reimplemented \
1679 as `{}` was overridden: `{}`",
1681 invalidated_items.iter()
1682 .map(|name| name.to_string())
1683 .collect::<Vec<_>>().join("`, `"))
1687 /// Checks whether a type can be represented in memory. In particular, it
1688 /// identifies types that contain themselves without indirection through a
1689 /// pointer, which would mean their size is unbounded.
1690 fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) -> bool {
1691 let rty = tcx.type_of(item_def_id);
1693 // Check that it is possible to represent this type. This call identifies
1694 // (1) types that contain themselves and (2) types that contain a different
1695 // recursive type. It is only necessary to throw an error on those that
1696 // contain themselves. For case 2, there must be an inner type that will be
1697 // caught by case 1.
1698 match rty.is_representable(tcx, sp) {
1699 Representability::SelfRecursive(spans) => {
1700 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1702 err.span_label(span, "recursive without indirection");
1707 Representability::Representable | Representability::ContainsRecursive => (),
1712 pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1713 let t = tcx.type_of(def_id);
1714 if let ty::Adt(def, substs) = t.sty {
1715 if def.is_struct() {
1716 let fields = &def.non_enum_variant().fields;
1717 if fields.is_empty() {
1718 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1721 let e = fields[0].ty(tcx, substs);
1722 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1723 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1724 .span_label(sp, "SIMD elements must have the same type")
1729 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1730 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1732 span_err!(tcx.sess, sp, E0077,
1733 "SIMD vector element type should be machine type");
1741 fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1742 let repr = tcx.adt_def(def_id).repr;
1744 for attr in tcx.get_attrs(def_id).iter() {
1745 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1746 if let attr::ReprPacked(pack) = r {
1747 if pack != repr.pack {
1748 struct_span_err!(tcx.sess, sp, E0634,
1749 "type has conflicting packed representation hints").emit();
1755 struct_span_err!(tcx.sess, sp, E0587,
1756 "type has conflicting packed and align representation hints").emit();
1758 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1759 struct_span_err!(tcx.sess, sp, E0588,
1760 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1765 fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
1766 let t = tcx.type_of(def_id);
1767 if stack.contains(&def_id) {
1768 debug!("check_packed_inner: {:?} is recursive", t);
1771 if let ty::Adt(def, substs) = t.sty {
1772 if def.is_struct() || def.is_union() {
1773 if tcx.adt_def(def.did).repr.align > 0 {
1776 // push struct def_id before checking fields
1778 for field in &def.non_enum_variant().fields {
1779 let f = field.ty(tcx, substs);
1780 if let ty::Adt(def, _) = f.sty {
1781 if check_packed_inner(tcx, def.did, stack) {
1786 // only need to pop if not early out
1793 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1794 let adt = tcx.adt_def(def_id);
1795 if !adt.repr.transparent() {
1800 if !tcx.features().transparent_enums {
1801 emit_feature_err(&tcx.sess.parse_sess,
1802 sym::transparent_enums,
1804 GateIssue::Language,
1805 "transparent enums are unstable");
1807 if adt.variants.len() != 1 {
1808 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
1809 tcx.hir().span_if_local(variant.def_id).unwrap()
1811 let mut err = struct_span_err!(tcx.sess, sp, E0731,
1812 "transparent enum needs exactly one variant, but has {}",
1813 adt.variants.len());
1814 if !variant_spans.is_empty() {
1815 err.span_note(variant_spans, &format!("the following variants exist on `{}`",
1816 tcx.def_path_str(def_id)));
1819 if adt.variants.is_empty() {
1820 // Don't bother checking the fields. No variants (and thus no fields) exist.
1826 if adt.is_union() && !tcx.features().transparent_unions {
1827 emit_feature_err(&tcx.sess.parse_sess,
1828 sym::transparent_unions,
1830 GateIssue::Language,
1831 "transparent unions are unstable");
1834 // For each field, figure out if it's known to be a ZST and align(1)
1835 let field_infos = adt.all_fields().map(|field| {
1836 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
1837 let param_env = tcx.param_env(field.did);
1838 let layout = tcx.layout_of(param_env.and(ty));
1839 // We are currently checking the type this field came from, so it must be local
1840 let span = tcx.hir().span_if_local(field.did).unwrap();
1841 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1842 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
1846 let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
1847 let non_zst_count = non_zst_fields.clone().count();
1848 if non_zst_count != 1 {
1849 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
1851 let mut err = struct_span_err!(tcx.sess, sp, E0690,
1852 "{}transparent {} needs exactly one non-zero-sized field, but has {}",
1853 if adt.is_enum() { "the variant of a " } else { "" },
1856 if !field_spans.is_empty() {
1857 err.span_note(field_spans,
1858 &format!("the following non-zero-sized fields exist on `{}`:",
1859 tcx.def_path_str(def_id)));
1863 for (span, zst, align1) in field_infos {
1865 span_err!(tcx.sess, span, E0691,
1866 "zero-sized field in transparent {} has alignment larger than 1",
1872 #[allow(trivial_numeric_casts)]
1873 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
1874 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1875 let def = tcx.adt_def(def_id);
1876 def.destructor(tcx); // force the destructor to be evaluated
1879 let attributes = tcx.get_attrs(def_id);
1880 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
1882 tcx.sess, attr.span, E0084,
1883 "unsupported representation for zero-variant enum")
1884 .span_label(sp, "zero-variant enum")
1889 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1890 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1891 if !tcx.features().repr128 {
1892 emit_feature_err(&tcx.sess.parse_sess,
1895 GateIssue::Language,
1896 "repr with 128-bit type is unstable");
1901 if let Some(ref e) = v.node.disr_expr {
1902 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(e.hir_id));
1906 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
1907 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
1908 // Check for duplicate discriminant values
1909 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1910 let variant_did = def.variants[VariantIdx::new(i)].def_id;
1911 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
1912 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
1913 let i_span = match variant_i.node.disr_expr {
1914 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1915 None => tcx.hir().span_by_hir_id(variant_i_hir_id)
1917 let span = match v.node.disr_expr {
1918 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1921 struct_span_err!(tcx.sess, span, E0081,
1922 "discriminant value `{}` already exists", disr_vals[i])
1923 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1924 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1927 disr_vals.push(discr);
1930 check_representable(tcx, sp, def_id);
1931 check_transparent(tcx, sp, def_id);
1934 fn report_unexpected_variant_res<'tcx>(tcx: TyCtxt<'tcx>, res: Res, span: Span, qpath: &QPath) {
1935 span_err!(tcx.sess, span, E0533,
1936 "expected unit struct/variant or constant, found {} `{}`",
1938 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1941 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1942 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
1946 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1947 -> &'tcx ty::GenericPredicates<'tcx>
1950 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
1951 let item_id = tcx.hir().ty_param_owner(hir_id);
1952 let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
1953 let generics = tcx.generics_of(item_def_id);
1954 let index = generics.param_def_id_to_index[&def_id];
1955 tcx.arena.alloc(ty::GenericPredicates {
1957 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
1959 ty::Predicate::Trait(ref data)
1960 if data.skip_binder().self_ty().is_param(index) => {
1961 // HACK(eddyb) should get the original `Span`.
1962 let span = tcx.def_span(def_id);
1963 Some((predicate, span))
1973 def: Option<&ty::GenericParamDef>,
1975 ) -> Option<ty::Region<'tcx>> {
1977 Some(def) => infer::EarlyBoundRegion(span, def.name),
1978 None => infer::MiscVariable(span)
1980 Some(self.next_region_var(v))
1983 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
1984 if let Some(param) = param {
1985 if let UnpackedKind::Type(ty) = self.var_for_def(span, param).unpack() {
1990 self.next_ty_var(TypeVariableOrigin {
1991 kind: TypeVariableOriginKind::TypeInference,
2000 param: Option<&ty::GenericParamDef>,
2002 ) -> &'tcx Const<'tcx> {
2003 if let Some(param) = param {
2004 if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
2009 self.next_const_var(ty, ConstVariableOrigin {
2010 kind: ConstVariableOriginKind::ConstInference,
2016 fn projected_ty_from_poly_trait_ref(&self,
2019 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2022 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2024 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2028 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2031 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2032 if ty.has_escaping_bound_vars() {
2033 ty // FIXME: normalization and escaping regions
2035 self.normalize_associated_types_in(span, &ty)
2039 fn set_tainted_by_errors(&self) {
2040 self.infcx.set_tainted_by_errors()
2043 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2044 self.write_ty(hir_id, ty)
2048 /// Controls whether the arguments are tupled. This is used for the call
2051 /// Tupling means that all call-side arguments are packed into a tuple and
2052 /// passed as a single parameter. For example, if tupling is enabled, this
2055 /// fn f(x: (isize, isize))
2057 /// Can be called as:
2064 #[derive(Clone, Eq, PartialEq)]
2065 enum TupleArgumentsFlag {
2070 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2072 inh: &'a Inherited<'a, 'tcx>,
2073 param_env: ty::ParamEnv<'tcx>,
2074 body_id: hir::HirId,
2075 ) -> FnCtxt<'a, 'tcx> {
2079 err_count_on_creation: inh.tcx.sess.err_count(),
2081 ret_coercion_span: RefCell::new(None),
2083 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2084 hir::CRATE_HIR_ID)),
2085 diverges: Cell::new(Diverges::Maybe),
2086 has_errors: Cell::new(false),
2087 enclosing_breakables: RefCell::new(EnclosingBreakables {
2089 by_id: Default::default(),
2095 pub fn sess(&self) -> &Session {
2099 pub fn err_count_since_creation(&self) -> usize {
2100 self.tcx.sess.err_count() - self.err_count_on_creation
2103 /// Produces warning on the given node, if the current point in the
2104 /// function is unreachable, and there hasn't been another warning.
2105 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2106 if self.diverges.get() == Diverges::Always &&
2107 // If span arose from a desugaring of `if` then it is the condition itself,
2108 // which diverges, that we are about to lint on. This gives suboptimal diagnostics
2109 // and so we stop here and allow the block of the `if`-expression to be linted instead.
2110 !span.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary) {
2111 self.diverges.set(Diverges::WarnedAlways);
2113 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2115 let msg = format!("unreachable {}", kind);
2116 self.tcx().lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg);
2122 code: ObligationCauseCode<'tcx>)
2123 -> ObligationCause<'tcx> {
2124 ObligationCause::new(span, self.body_id, code)
2127 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2128 self.cause(span, ObligationCauseCode::MiscObligation)
2131 /// Resolves type variables in `ty` if possible. Unlike the infcx
2132 /// version (resolve_vars_if_possible), this version will
2133 /// also select obligations if it seems useful, in an effort
2134 /// to get more type information.
2135 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2136 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2138 // No Infer()? Nothing needs doing.
2139 if !ty.has_infer_types() {
2140 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2144 // If `ty` is a type variable, see whether we already know what it is.
2145 ty = self.resolve_vars_if_possible(&ty);
2146 if !ty.has_infer_types() {
2147 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2151 // If not, try resolving pending obligations as much as
2152 // possible. This can help substantially when there are
2153 // indirect dependencies that don't seem worth tracking
2155 self.select_obligations_where_possible(false);
2156 ty = self.resolve_vars_if_possible(&ty);
2158 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2162 fn record_deferred_call_resolution(
2164 closure_def_id: DefId,
2165 r: DeferredCallResolution<'tcx>,
2167 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2168 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2171 fn remove_deferred_call_resolutions(
2173 closure_def_id: DefId,
2174 ) -> Vec<DeferredCallResolution<'tcx>> {
2175 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2176 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2179 pub fn tag(&self) -> String {
2180 format!("{:p}", self)
2183 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2184 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2185 span_bug!(span, "no type for local variable {}",
2186 self.tcx.hir().hir_to_string(nid))
2191 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2192 debug!("write_ty({:?}, {:?}) in fcx {}",
2193 id, self.resolve_vars_if_possible(&ty), self.tag());
2194 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2196 if ty.references_error() {
2197 self.has_errors.set(true);
2198 self.set_tainted_by_errors();
2202 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2203 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2206 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2207 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2210 pub fn write_method_call(&self,
2212 method: MethodCallee<'tcx>) {
2213 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2214 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2215 self.write_substs(hir_id, method.substs);
2217 // When the method is confirmed, the `method.substs` includes
2218 // parameters from not just the method, but also the impl of
2219 // the method -- in particular, the `Self` type will be fully
2220 // resolved. However, those are not something that the "user
2221 // specified" -- i.e., those types come from the inferred type
2222 // of the receiver, not something the user wrote. So when we
2223 // create the user-substs, we want to replace those earlier
2224 // types with just the types that the user actually wrote --
2225 // that is, those that appear on the *method itself*.
2227 // As an example, if the user wrote something like
2228 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2229 // type of `foo` (possibly adjusted), but we don't want to
2230 // include that. We want just the `[_, u32]` part.
2231 if !method.substs.is_noop() {
2232 let method_generics = self.tcx.generics_of(method.def_id);
2233 if !method_generics.params.is_empty() {
2234 let user_type_annotation = self.infcx.probe(|_| {
2235 let user_substs = UserSubsts {
2236 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2237 let i = param.index as usize;
2238 if i < method_generics.parent_count {
2239 self.infcx.var_for_def(DUMMY_SP, param)
2244 user_self_ty: None, // not relevant here
2247 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2253 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2254 self.write_user_type_annotation(hir_id, user_type_annotation);
2259 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2260 if !substs.is_noop() {
2261 debug!("write_substs({:?}, {:?}) in fcx {}",
2266 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2270 /// Given the substs that we just converted from the HIR, try to
2271 /// canonicalize them and store them as user-given substitutions
2272 /// (i.e., substitutions that must be respected by the NLL check).
2274 /// This should be invoked **before any unifications have
2275 /// occurred**, so that annotations like `Vec<_>` are preserved
2277 pub fn write_user_type_annotation_from_substs(
2281 substs: SubstsRef<'tcx>,
2282 user_self_ty: Option<UserSelfTy<'tcx>>,
2285 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2286 user_self_ty={:?} in fcx {}",
2287 hir_id, def_id, substs, user_self_ty, self.tag(),
2290 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2291 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2292 &UserType::TypeOf(def_id, UserSubsts {
2297 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2298 self.write_user_type_annotation(hir_id, canonicalized);
2302 pub fn write_user_type_annotation(
2305 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2308 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2309 hir_id, canonical_user_type_annotation, self.tag(),
2312 if !canonical_user_type_annotation.is_identity() {
2313 self.tables.borrow_mut().user_provided_types_mut().insert(
2314 hir_id, canonical_user_type_annotation
2317 debug!("write_user_type_annotation: skipping identity substs");
2321 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2322 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2328 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2329 Entry::Vacant(entry) => { entry.insert(adj); },
2330 Entry::Occupied(mut entry) => {
2331 debug!(" - composing on top of {:?}", entry.get());
2332 match (&entry.get()[..], &adj[..]) {
2333 // Applying any adjustment on top of a NeverToAny
2334 // is a valid NeverToAny adjustment, because it can't
2336 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2338 Adjustment { kind: Adjust::Deref(_), .. },
2339 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2341 Adjustment { kind: Adjust::Deref(_), .. },
2342 .. // Any following adjustments are allowed.
2344 // A reborrow has no effect before a dereference.
2346 // FIXME: currently we never try to compose autoderefs
2347 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2349 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2350 expr, entry.get(), adj)
2352 *entry.get_mut() = adj;
2357 /// Basically whenever we are converting from a type scheme into
2358 /// the fn body space, we always want to normalize associated
2359 /// types as well. This function combines the two.
2360 fn instantiate_type_scheme<T>(&self,
2362 substs: SubstsRef<'tcx>,
2365 where T : TypeFoldable<'tcx>
2367 let value = value.subst(self.tcx, substs);
2368 let result = self.normalize_associated_types_in(span, &value);
2369 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2376 /// As `instantiate_type_scheme`, but for the bounds found in a
2377 /// generic type scheme.
2378 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: SubstsRef<'tcx>)
2379 -> ty::InstantiatedPredicates<'tcx> {
2380 let bounds = self.tcx.predicates_of(def_id);
2381 let result = bounds.instantiate(self.tcx, substs);
2382 let result = self.normalize_associated_types_in(span, &result);
2383 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2390 /// Replaces the opaque types from the given value with type variables,
2391 /// and records the `OpaqueTypeMap` for later use during writeback. See
2392 /// `InferCtxt::instantiate_opaque_types` for more details.
2393 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2395 parent_id: hir::HirId,
2398 let parent_def_id = self.tcx.hir().local_def_id_from_hir_id(parent_id);
2399 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2403 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2404 self.instantiate_opaque_types(
2412 let mut opaque_types = self.opaque_types.borrow_mut();
2413 for (ty, decl) in opaque_type_map {
2414 let old_value = opaque_types.insert(ty, decl);
2415 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2421 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2422 where T : TypeFoldable<'tcx>
2424 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2427 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2429 where T : TypeFoldable<'tcx>
2431 self.inh.partially_normalize_associated_types_in(span,
2437 pub fn require_type_meets(&self,
2440 code: traits::ObligationCauseCode<'tcx>,
2443 self.register_bound(
2446 traits::ObligationCause::new(span, self.body_id, code));
2449 pub fn require_type_is_sized(&self,
2452 code: traits::ObligationCauseCode<'tcx>)
2454 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2455 self.require_type_meets(ty, span, code, lang_item);
2458 pub fn require_type_is_sized_deferred(&self,
2461 code: traits::ObligationCauseCode<'tcx>)
2463 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2466 pub fn register_bound(&self,
2469 cause: traits::ObligationCause<'tcx>)
2471 self.fulfillment_cx.borrow_mut()
2472 .register_bound(self, self.param_env, ty, def_id, cause);
2475 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2476 let t = AstConv::ast_ty_to_ty(self, ast_t);
2477 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2481 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2482 let ty = self.to_ty(ast_ty);
2483 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2485 if Self::can_contain_user_lifetime_bounds(ty) {
2486 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2487 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2488 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2494 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2495 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2496 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2499 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2500 AstConv::ast_const_to_const(self, ast_c, ty)
2503 // If the type given by the user has free regions, save it for later, since
2504 // NLL would like to enforce those. Also pass in types that involve
2505 // projections, since those can resolve to `'static` bounds (modulo #54940,
2506 // which hopefully will be fixed by the time you see this comment, dear
2507 // reader, although I have my doubts). Also pass in types with inference
2508 // types, because they may be repeated. Other sorts of things are already
2509 // sufficiently enforced with erased regions. =)
2510 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2512 T: TypeFoldable<'tcx>
2514 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2517 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2518 match self.tables.borrow().node_types().get(id) {
2520 None if self.is_tainted_by_errors() => self.tcx.types.err,
2522 let node_id = self.tcx.hir().hir_to_node_id(id);
2523 bug!("no type for node {}: {} in fcx {}",
2524 node_id, self.tcx.hir().node_to_string(node_id),
2530 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2531 /// outlive the region `r`.
2532 pub fn register_wf_obligation(&self,
2535 code: traits::ObligationCauseCode<'tcx>)
2537 // WF obligations never themselves fail, so no real need to give a detailed cause:
2538 let cause = traits::ObligationCause::new(span, self.body_id, code);
2539 self.register_predicate(traits::Obligation::new(cause,
2541 ty::Predicate::WellFormed(ty)));
2544 /// Registers obligations that all types appearing in `substs` are well-formed.
2545 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2546 for ty in substs.types() {
2547 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2551 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2552 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2553 /// trait/region obligations.
2555 /// For example, if there is a function:
2558 /// fn foo<'a,T:'a>(...)
2561 /// and a reference:
2567 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2568 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2569 pub fn add_obligations_for_parameters(&self,
2570 cause: traits::ObligationCause<'tcx>,
2571 predicates: &ty::InstantiatedPredicates<'tcx>)
2573 assert!(!predicates.has_escaping_bound_vars());
2575 debug!("add_obligations_for_parameters(predicates={:?})",
2578 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2579 self.register_predicate(obligation);
2583 // FIXME(arielb1): use this instead of field.ty everywhere
2584 // Only for fields! Returns <none> for methods>
2585 // Indifferent to privacy flags
2586 pub fn field_ty(&self,
2588 field: &'tcx ty::FieldDef,
2589 substs: SubstsRef<'tcx>)
2592 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2595 fn check_casts(&self) {
2596 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2597 for cast in deferred_cast_checks.drain(..) {
2602 fn resolve_generator_interiors(&self, def_id: DefId) {
2603 let mut generators = self.deferred_generator_interiors.borrow_mut();
2604 for (body_id, interior) in generators.drain(..) {
2605 self.select_obligations_where_possible(false);
2606 generator_interior::resolve_interior(self, def_id, body_id, interior);
2610 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2611 // Non-numerics get replaced with ! or () (depending on whether
2612 // feature(never_type) is enabled, unconstrained ints with i32,
2613 // unconstrained floats with f64.
2614 // Fallback becomes very dubious if we have encountered type-checking errors.
2615 // In that case, fallback to Error.
2616 // The return value indicates whether fallback has occurred.
2617 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2618 use rustc::ty::error::UnconstrainedNumeric::Neither;
2619 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2621 assert!(ty.is_ty_infer());
2622 let fallback = match self.type_is_unconstrained_numeric(ty) {
2623 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2624 UnconstrainedInt => self.tcx.types.i32,
2625 UnconstrainedFloat => self.tcx.types.f64,
2626 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2627 Neither => return false,
2629 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2630 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2634 fn select_all_obligations_or_error(&self) {
2635 debug!("select_all_obligations_or_error");
2636 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2637 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2641 /// Select as many obligations as we can at present.
2642 fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2643 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2644 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2648 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2649 /// returns a type of `&T`, but the actual type we assign to the
2650 /// *expression* is `T`. So this function just peels off the return
2651 /// type by one layer to yield `T`.
2652 fn make_overloaded_place_return_type(&self,
2653 method: MethodCallee<'tcx>)
2654 -> ty::TypeAndMut<'tcx>
2656 // extract method return type, which will be &T;
2657 let ret_ty = method.sig.output();
2659 // method returns &T, but the type as visible to user is T, so deref
2660 ret_ty.builtin_deref(true).unwrap()
2666 base_expr: &'tcx hir::Expr,
2670 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2671 // FIXME(#18741) -- this is almost but not quite the same as the
2672 // autoderef that normal method probing does. They could likely be
2675 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2676 let mut result = None;
2677 while result.is_none() && autoderef.next().is_some() {
2678 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2680 autoderef.finalize(self);
2684 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2685 /// (and otherwise adjust) `base_expr`, looking for a type which either
2686 /// supports builtin indexing or overloaded indexing.
2687 /// This loop implements one step in that search; the autoderef loop
2688 /// is implemented by `lookup_indexing`.
2692 base_expr: &hir::Expr,
2693 autoderef: &Autoderef<'a, 'tcx>,
2696 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2697 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2698 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2705 for &unsize in &[false, true] {
2706 let mut self_ty = adjusted_ty;
2708 // We only unsize arrays here.
2709 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2710 self_ty = self.tcx.mk_slice(element_ty);
2716 // If some lookup succeeds, write callee into table and extract index/element
2717 // type from the method signature.
2718 // If some lookup succeeded, install method in table
2719 let input_ty = self.next_ty_var(TypeVariableOrigin {
2720 kind: TypeVariableOriginKind::AutoDeref,
2721 span: base_expr.span,
2723 let method = self.try_overloaded_place_op(
2724 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2726 let result = method.map(|ok| {
2727 debug!("try_index_step: success, using overloaded indexing");
2728 let method = self.register_infer_ok_obligations(ok);
2730 let mut adjustments = autoderef.adjust_steps(self, needs);
2731 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2732 let mutbl = match r_mutbl {
2733 hir::MutImmutable => AutoBorrowMutability::Immutable,
2734 hir::MutMutable => AutoBorrowMutability::Mutable {
2735 // Indexing can be desugared to a method call,
2736 // so maybe we could use two-phase here.
2737 // See the documentation of AllowTwoPhase for why that's
2738 // not the case today.
2739 allow_two_phase_borrow: AllowTwoPhase::No,
2742 adjustments.push(Adjustment {
2743 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2744 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2751 adjustments.push(Adjustment {
2752 kind: Adjust::Pointer(PointerCast::Unsize),
2753 target: method.sig.inputs()[0]
2756 self.apply_adjustments(base_expr, adjustments);
2758 self.write_method_call(expr.hir_id, method);
2759 (input_ty, self.make_overloaded_place_return_type(method).ty)
2761 if result.is_some() {
2769 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
2770 let (tr, name) = match (op, is_mut) {
2771 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
2772 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
2773 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
2774 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
2776 (tr, ast::Ident::with_empty_ctxt(name))
2779 fn try_overloaded_place_op(&self,
2782 arg_tys: &[Ty<'tcx>],
2785 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2787 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2793 // Try Mut first, if needed.
2794 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2795 let method = match (needs, mut_tr) {
2796 (Needs::MutPlace, Some(trait_did)) => {
2797 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2802 // Otherwise, fall back to the immutable version.
2803 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2804 let method = match (method, imm_tr) {
2805 (None, Some(trait_did)) => {
2806 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2808 (method, _) => method,
2814 fn check_method_argument_types(
2818 method: Result<MethodCallee<'tcx>, ()>,
2819 args_no_rcvr: &'tcx [hir::Expr],
2820 tuple_arguments: TupleArgumentsFlag,
2821 expected: Expectation<'tcx>,
2823 let has_error = match method {
2825 method.substs.references_error() || method.sig.references_error()
2830 let err_inputs = self.err_args(args_no_rcvr.len());
2832 let err_inputs = match tuple_arguments {
2833 DontTupleArguments => err_inputs,
2834 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
2837 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2838 false, tuple_arguments, None);
2839 return self.tcx.types.err;
2842 let method = method.unwrap();
2843 // HACK(eddyb) ignore self in the definition (see above).
2844 let expected_arg_tys = self.expected_inputs_for_expected_output(
2847 method.sig.output(),
2848 &method.sig.inputs()[1..]
2850 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2851 args_no_rcvr, method.sig.c_variadic, tuple_arguments,
2852 self.tcx.hir().span_if_local(method.def_id));
2856 fn self_type_matches_expected_vid(
2858 trait_ref: ty::PolyTraitRef<'tcx>,
2859 expected_vid: ty::TyVid,
2861 let self_ty = self.shallow_resolve(trait_ref.self_ty());
2863 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
2864 trait_ref, self_ty, expected_vid
2867 ty::Infer(ty::TyVar(found_vid)) => {
2868 // FIXME: consider using `sub_root_var` here so we
2869 // can see through subtyping.
2870 let found_vid = self.root_var(found_vid);
2871 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
2872 expected_vid == found_vid
2878 fn obligations_for_self_ty<'b>(
2881 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
2884 // FIXME: consider using `sub_root_var` here so we
2885 // can see through subtyping.
2886 let ty_var_root = self.root_var(self_ty);
2887 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
2888 self_ty, ty_var_root,
2889 self.fulfillment_cx.borrow().pending_obligations());
2893 .pending_obligations()
2895 .filter_map(move |obligation| match obligation.predicate {
2896 ty::Predicate::Projection(ref data) =>
2897 Some((data.to_poly_trait_ref(self.tcx), obligation)),
2898 ty::Predicate::Trait(ref data) =>
2899 Some((data.to_poly_trait_ref(), obligation)),
2900 ty::Predicate::Subtype(..) => None,
2901 ty::Predicate::RegionOutlives(..) => None,
2902 ty::Predicate::TypeOutlives(..) => None,
2903 ty::Predicate::WellFormed(..) => None,
2904 ty::Predicate::ObjectSafe(..) => None,
2905 ty::Predicate::ConstEvaluatable(..) => None,
2906 // N.B., this predicate is created by breaking down a
2907 // `ClosureType: FnFoo()` predicate, where
2908 // `ClosureType` represents some `Closure`. It can't
2909 // possibly be referring to the current closure,
2910 // because we haven't produced the `Closure` for
2911 // this closure yet; this is exactly why the other
2912 // code is looking for a self type of a unresolved
2913 // inference variable.
2914 ty::Predicate::ClosureKind(..) => None,
2915 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
2918 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
2919 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
2920 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
2924 /// Generic function that factors out common logic from function calls,
2925 /// method calls and overloaded operators.
2926 fn check_argument_types(
2930 fn_inputs: &[Ty<'tcx>],
2931 expected_arg_tys: &[Ty<'tcx>],
2932 args: &'tcx [hir::Expr],
2934 tuple_arguments: TupleArgumentsFlag,
2935 def_span: Option<Span>,
2939 // Grab the argument types, supplying fresh type variables
2940 // if the wrong number of arguments were supplied
2941 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2947 // All the input types from the fn signature must outlive the call
2948 // so as to validate implied bounds.
2949 for &fn_input_ty in fn_inputs {
2950 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2953 let expected_arg_count = fn_inputs.len();
2955 let param_count_error = |expected_count: usize,
2960 let mut err = tcx.sess.struct_span_err_with_code(sp,
2961 &format!("this function takes {}{} but {} {} supplied",
2962 if c_variadic { "at least " } else { "" },
2963 potentially_plural_count(expected_count, "parameter"),
2964 potentially_plural_count(arg_count, "parameter"),
2965 if arg_count == 1 {"was"} else {"were"}),
2966 DiagnosticId::Error(error_code.to_owned()));
2968 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
2969 err.span_label(def_s, "defined here");
2972 let sugg_span = tcx.sess.source_map().end_point(expr_sp);
2973 // remove closing `)` from the span
2974 let sugg_span = sugg_span.shrink_to_lo();
2975 err.span_suggestion(
2977 "expected the unit value `()`; create it with empty parentheses",
2979 Applicability::MachineApplicable);
2981 err.span_label(sp, format!("expected {}{}",
2982 if c_variadic { "at least " } else { "" },
2983 potentially_plural_count(expected_count, "parameter")));
2988 let mut expected_arg_tys = expected_arg_tys.to_vec();
2990 let formal_tys = if tuple_arguments == TupleArguments {
2991 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2992 match tuple_type.sty {
2993 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
2994 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
2995 expected_arg_tys = vec![];
2996 self.err_args(args.len())
2998 ty::Tuple(arg_types) => {
2999 expected_arg_tys = match expected_arg_tys.get(0) {
3000 Some(&ty) => match ty.sty {
3001 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3006 arg_types.iter().map(|k| k.expect_ty()).collect()
3009 span_err!(tcx.sess, sp, E0059,
3010 "cannot use call notation; the first type parameter \
3011 for the function trait is neither a tuple nor unit");
3012 expected_arg_tys = vec![];
3013 self.err_args(args.len())
3016 } else if expected_arg_count == supplied_arg_count {
3018 } else if c_variadic {
3019 if supplied_arg_count >= expected_arg_count {
3022 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3023 expected_arg_tys = vec![];
3024 self.err_args(supplied_arg_count)
3027 // is the missing argument of type `()`?
3028 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3029 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3030 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3031 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3035 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3037 expected_arg_tys = vec![];
3038 self.err_args(supplied_arg_count)
3041 debug!("check_argument_types: formal_tys={:?}",
3042 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3044 // If there is no expectation, expect formal_tys.
3045 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3051 // Check the arguments.
3052 // We do this in a pretty awful way: first we type-check any arguments
3053 // that are not closures, then we type-check the closures. This is so
3054 // that we have more information about the types of arguments when we
3055 // type-check the functions. This isn't really the right way to do this.
3056 for &check_closures in &[false, true] {
3057 debug!("check_closures={}", check_closures);
3059 // More awful hacks: before we check argument types, try to do
3060 // an "opportunistic" vtable resolution of any trait bounds on
3061 // the call. This helps coercions.
3063 self.select_obligations_where_possible(false);
3066 // For C-variadic functions, we don't have a declared type for all of
3067 // the arguments hence we only do our usual type checking with
3068 // the arguments who's types we do know.
3069 let t = if c_variadic {
3071 } else if tuple_arguments == TupleArguments {
3076 for (i, arg) in args.iter().take(t).enumerate() {
3077 // Warn only for the first loop (the "no closures" one).
3078 // Closure arguments themselves can't be diverging, but
3079 // a previous argument can, e.g., `foo(panic!(), || {})`.
3080 if !check_closures {
3081 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3084 let is_closure = match arg.node {
3085 ExprKind::Closure(..) => true,
3089 if is_closure != check_closures {
3093 debug!("checking the argument");
3094 let formal_ty = formal_tys[i];
3096 // The special-cased logic below has three functions:
3097 // 1. Provide as good of an expected type as possible.
3098 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3100 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3102 // 2. Coerce to the most detailed type that could be coerced
3103 // to, which is `expected_ty` if `rvalue_hint` returns an
3104 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3105 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3106 // We're processing function arguments so we definitely want to use
3107 // two-phase borrows.
3108 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3110 // 3. Relate the expected type and the formal one,
3111 // if the expected type was used for the coercion.
3112 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3116 // We also need to make sure we at least write the ty of the other
3117 // arguments which we skipped above.
3119 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3120 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3121 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3124 for arg in args.iter().skip(expected_arg_count) {
3125 let arg_ty = self.check_expr(&arg);
3127 // There are a few types which get autopromoted when passed via varargs
3128 // in C but we just error out instead and require explicit casts.
3129 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3131 ty::Float(ast::FloatTy::F32) => {
3132 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3134 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3135 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3137 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3138 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3141 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3142 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3143 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3151 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3152 vec![self.tcx.types.err; len]
3155 // AST fragment checking
3158 expected: Expectation<'tcx>)
3164 ast::LitKind::Str(..) => tcx.mk_static_str(),
3165 ast::LitKind::ByteStr(ref v) => {
3166 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3167 tcx.mk_array(tcx.types.u8, v.len() as u64))
3169 ast::LitKind::Byte(_) => tcx.types.u8,
3170 ast::LitKind::Char(_) => tcx.types.char,
3171 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3172 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3173 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3174 let opt_ty = expected.to_option(self).and_then(|ty| {
3176 ty::Int(_) | ty::Uint(_) => Some(ty),
3177 ty::Char => Some(tcx.types.u8),
3178 ty::RawPtr(..) => Some(tcx.types.usize),
3179 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3183 opt_ty.unwrap_or_else(|| self.next_int_var())
3185 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3186 ast::LitKind::FloatUnsuffixed(_) => {
3187 let opt_ty = expected.to_option(self).and_then(|ty| {
3189 ty::Float(_) => Some(ty),
3193 opt_ty.unwrap_or_else(|| self.next_float_var())
3195 ast::LitKind::Bool(_) => tcx.types.bool,
3196 ast::LitKind::Err(_) => tcx.types.err,
3200 fn check_expr_eq_type(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) {
3201 let ty = self.check_expr_with_hint(expr, expected);
3202 self.demand_eqtype(expr.span, expected, ty);
3205 pub fn check_expr_has_type_or_error(
3207 expr: &'tcx hir::Expr,
3210 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
3213 fn check_expr_meets_expectation_or_error(
3215 expr: &'tcx hir::Expr,
3216 expected: Expectation<'tcx>,
3218 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
3219 let mut ty = self.check_expr_with_expectation(expr, expected);
3221 // While we don't allow *arbitrary* coercions here, we *do* allow
3222 // coercions from ! to `expected`.
3224 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
3225 "expression with never type wound up being adjusted");
3226 let adj_ty = self.next_diverging_ty_var(
3227 TypeVariableOrigin {
3228 kind: TypeVariableOriginKind::AdjustmentType,
3232 self.apply_adjustments(expr, vec![Adjustment {
3233 kind: Adjust::NeverToAny,
3239 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
3240 let expr = match &expr.node {
3241 ExprKind::DropTemps(expr) => expr,
3244 // Error possibly reported in `check_assign` so avoid emitting error again.
3245 err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
3250 fn check_expr_coercable_to_type(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) -> Ty<'tcx> {
3251 let ty = self.check_expr_with_hint(expr, expected);
3252 // checks don't need two phase
3253 self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
3256 fn check_expr_with_hint(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) -> Ty<'tcx> {
3257 self.check_expr_with_expectation(expr, ExpectHasType(expected))
3260 fn check_expr_with_expectation(
3262 expr: &'tcx hir::Expr,
3263 expected: Expectation<'tcx>,
3265 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
3268 fn check_expr(&self, expr: &'tcx hir::Expr) -> Ty<'tcx> {
3269 self.check_expr_with_expectation(expr, NoExpectation)
3272 fn check_expr_with_needs(&self, expr: &'tcx hir::Expr, needs: Needs) -> Ty<'tcx> {
3273 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
3276 // Determine the `Self` type, using fresh variables for all variables
3277 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3278 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3280 pub fn impl_self_ty(&self,
3281 span: Span, // (potential) receiver for this impl
3283 -> TypeAndSubsts<'tcx> {
3284 let ity = self.tcx.type_of(did);
3285 debug!("impl_self_ty: ity={:?}", ity);
3287 let substs = self.fresh_substs_for_item(span, did);
3288 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3290 TypeAndSubsts { substs: substs, ty: substd_ty }
3293 /// Unifies the output type with the expected type early, for more coercions
3294 /// and forward type information on the input expressions.
3295 fn expected_inputs_for_expected_output(&self,
3297 expected_ret: Expectation<'tcx>,
3298 formal_ret: Ty<'tcx>,
3299 formal_args: &[Ty<'tcx>])
3301 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3302 let ret_ty = match expected_ret.only_has_type(self) {
3304 None => return Vec::new()
3306 let expect_args = self.fudge_inference_if_ok(|| {
3307 // Attempt to apply a subtyping relationship between the formal
3308 // return type (likely containing type variables if the function
3309 // is polymorphic) and the expected return type.
3310 // No argument expectations are produced if unification fails.
3311 let origin = self.misc(call_span);
3312 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3314 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3315 // to identity so the resulting type is not constrained.
3318 // Process any obligations locally as much as
3319 // we can. We don't care if some things turn
3320 // out unconstrained or ambiguous, as we're
3321 // just trying to get hints here.
3322 self.save_and_restore_in_snapshot_flag(|_| {
3323 let mut fulfill = TraitEngine::new(self.tcx);
3324 for obligation in ok.obligations {
3325 fulfill.register_predicate_obligation(self, obligation);
3327 fulfill.select_where_possible(self)
3328 }).map_err(|_| ())?;
3330 Err(_) => return Err(()),
3333 // Record all the argument types, with the substitutions
3334 // produced from the above subtyping unification.
3335 Ok(formal_args.iter().map(|ty| {
3336 self.resolve_vars_if_possible(ty)
3338 }).unwrap_or_default();
3339 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3340 formal_args, formal_ret,
3341 expect_args, expected_ret);
3345 // Checks a method call.
3346 fn check_method_call(
3348 expr: &'tcx hir::Expr,
3349 segment: &hir::PathSegment,
3351 args: &'tcx [hir::Expr],
3352 expected: Expectation<'tcx>,
3355 let rcvr = &args[0];
3356 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
3357 // no need to check for bot/err -- callee does that
3358 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
3360 let method = match self.lookup_method(rcvr_t,
3366 self.write_method_call(expr.hir_id, method);
3370 if segment.ident.name != kw::Invalid {
3371 self.report_method_error(span,
3374 SelfSource::MethodCall(rcvr),
3382 // Call the generic checker.
3383 self.check_method_argument_types(span,
3391 fn check_return_expr(&self, return_expr: &'tcx hir::Expr) {
3395 .unwrap_or_else(|| span_bug!(return_expr.span,
3396 "check_return_expr called outside fn body"));
3398 let ret_ty = ret_coercion.borrow().expected_ty();
3399 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
3400 ret_coercion.borrow_mut()
3402 &self.cause(return_expr.span,
3403 ObligationCauseCode::ReturnType(return_expr.hir_id)),
3408 // Check field access expressions
3411 expr: &'tcx hir::Expr,
3413 base: &'tcx hir::Expr,
3416 let expr_t = self.check_expr_with_needs(base, needs);
3417 let expr_t = self.structurally_resolved_type(base.span,
3419 let mut private_candidate = None;
3420 let mut autoderef = self.autoderef(expr.span, expr_t);
3421 while let Some((base_t, _)) = autoderef.next() {
3423 ty::Adt(base_def, substs) if !base_def.is_enum() => {
3424 debug!("struct named {:?}", base_t);
3425 let (ident, def_scope) =
3426 self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
3427 let fields = &base_def.non_enum_variant().fields;
3428 if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
3429 let field = &fields[index];
3430 let field_ty = self.field_ty(expr.span, field, substs);
3431 // Save the index of all fields regardless of their visibility in case
3432 // of error recovery.
3433 self.write_field_index(expr.hir_id, index);
3434 if field.vis.is_accessible_from(def_scope, self.tcx) {
3435 let adjustments = autoderef.adjust_steps(self, needs);
3436 self.apply_adjustments(base, adjustments);
3437 autoderef.finalize(self);
3439 self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
3442 private_candidate = Some((base_def.did, field_ty));
3445 ty::Tuple(ref tys) => {
3446 let fstr = field.as_str();
3447 if let Ok(index) = fstr.parse::<usize>() {
3448 if fstr == index.to_string() {
3449 if let Some(field_ty) = tys.get(index) {
3450 let adjustments = autoderef.adjust_steps(self, needs);
3451 self.apply_adjustments(base, adjustments);
3452 autoderef.finalize(self);
3454 self.write_field_index(expr.hir_id, index);
3455 return field_ty.expect_ty();
3463 autoderef.unambiguous_final_ty(self);
3465 if let Some((did, field_ty)) = private_candidate {
3466 let struct_path = self.tcx().def_path_str(did);
3467 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3468 "field `{}` of struct `{}` is private",
3469 field, struct_path);
3470 // Also check if an accessible method exists, which is often what is meant.
3471 if self.method_exists(field, expr_t, expr.hir_id, false)
3472 && !self.expr_in_place(expr.hir_id)
3474 self.suggest_method_call(
3476 &format!("a method `{}` also exists, call it with parentheses", field),
3484 } else if field.name == kw::Invalid {
3485 self.tcx().types.err
3486 } else if self.method_exists(field, expr_t, expr.hir_id, true) {
3487 let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3488 "attempted to take value of method `{}` on type `{}`",
3491 if !self.expr_in_place(expr.hir_id) {
3492 self.suggest_method_call(
3494 "use parentheses to call the method",
3500 err.help("methods are immutable and cannot be assigned to");
3504 self.tcx().types.err
3506 if !expr_t.is_primitive_ty() {
3507 let mut err = self.no_such_field_err(field.span, field, expr_t);
3510 ty::Adt(def, _) if !def.is_enum() => {
3511 if let Some(suggested_field_name) =
3512 Self::suggest_field_name(def.non_enum_variant(),
3513 &field.as_str(), vec![]) {
3514 err.span_suggestion(
3516 "a field with a similar name exists",
3517 suggested_field_name.to_string(),
3518 Applicability::MaybeIncorrect,
3521 err.span_label(field.span, "unknown field");
3522 let struct_variant_def = def.non_enum_variant();
3523 let field_names = self.available_field_names(struct_variant_def);
3524 if !field_names.is_empty() {
3525 err.note(&format!("available fields are: {}",
3526 self.name_series_display(field_names)));
3530 ty::Array(_, len) => {
3531 if let (Some(len), Ok(user_index)) = (
3532 len.assert_usize(self.tcx),
3533 field.as_str().parse::<u64>()
3535 let base = self.tcx.sess.source_map()
3536 .span_to_snippet(base.span)
3538 self.tcx.hir().hir_to_pretty_string(base.hir_id));
3539 let help = "instead of using tuple indexing, use array indexing";
3540 let suggestion = format!("{}[{}]", base, field);
3541 let applicability = if len < user_index {
3542 Applicability::MachineApplicable
3544 Applicability::MaybeIncorrect
3546 err.span_suggestion(
3547 expr.span, help, suggestion, applicability
3552 let base = self.tcx.sess.source_map()
3553 .span_to_snippet(base.span)
3554 .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
3555 let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
3556 let suggestion = format!("(*{}).{}", base, field);
3557 err.span_suggestion(
3561 Applicability::MaybeIncorrect,
3568 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3569 "`{}` is a primitive type and therefore doesn't have fields",
3572 self.tcx().types.err
3576 // Return an hint about the closest match in field names
3577 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3579 skip: Vec<LocalInternedString>)
3581 let names = variant.fields.iter().filter_map(|field| {
3582 // ignore already set fields and private fields from non-local crates
3583 if skip.iter().any(|x| *x == field.ident.as_str()) ||
3584 (!variant.def_id.is_local() && field.vis != Visibility::Public)
3588 Some(&field.ident.name)
3592 find_best_match_for_name(names, field, None)
3595 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3596 variant.fields.iter().filter(|field| {
3598 self.tcx.adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id).1;
3599 field.vis.is_accessible_from(def_scope, self.tcx)
3601 .map(|field| field.ident.name)
3605 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3606 // dynamic limit, to never omit just one field
3607 let limit = if names.len() == 6 { 6 } else { 5 };
3608 let mut display = names.iter().take(limit)
3609 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3610 if names.len() > limit {
3611 display = format!("{} ... and {} others", display, names.len() - limit);
3616 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
3617 -> DiagnosticBuilder<'_> {
3618 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3619 "no field `{}` on type `{}`",
3623 fn report_unknown_field(
3626 variant: &'tcx ty::VariantDef,
3628 skip_fields: &[hir::Field],
3631 if variant.recovered {
3634 let mut err = self.type_error_struct_with_diag(
3636 |actual| match ty.sty {
3637 ty::Adt(adt, ..) if adt.is_enum() => {
3638 struct_span_err!(self.tcx.sess, field.ident.span, E0559,
3639 "{} `{}::{}` has no field named `{}`",
3640 kind_name, actual, variant.ident, field.ident)
3643 struct_span_err!(self.tcx.sess, field.ident.span, E0560,
3644 "{} `{}` has no field named `{}`",
3645 kind_name, actual, field.ident)
3649 // prevent all specified fields from being suggested
3650 let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
3651 if let Some(field_name) = Self::suggest_field_name(variant,
3652 &field.ident.as_str(),
3653 skip_fields.collect()) {
3654 err.span_suggestion(
3656 "a field with a similar name exists",
3657 field_name.to_string(),
3658 Applicability::MaybeIncorrect,
3662 ty::Adt(adt, ..) => {
3664 err.span_label(field.ident.span,
3665 format!("`{}::{}` does not have this field",
3666 ty, variant.ident));
3668 err.span_label(field.ident.span,
3669 format!("`{}` does not have this field", ty));
3671 let available_field_names = self.available_field_names(variant);
3672 if !available_field_names.is_empty() {
3673 err.note(&format!("available fields are: {}",
3674 self.name_series_display(available_field_names)));
3677 _ => bug!("non-ADT passed to report_unknown_field")
3683 fn check_expr_struct_fields(
3686 expected: Expectation<'tcx>,
3687 expr_id: hir::HirId,
3689 variant: &'tcx ty::VariantDef,
3690 ast_fields: &'tcx [hir::Field],
3691 check_completeness: bool,
3696 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3697 .get(0).cloned().unwrap_or(adt_ty);
3698 // re-link the regions that EIfEO can erase.
3699 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3701 let (substs, adt_kind, kind_name) = match &adt_ty.sty {
3702 &ty::Adt(adt, substs) => {
3703 (substs, adt.adt_kind(), adt.variant_descr())
3705 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3708 let mut remaining_fields = variant.fields.iter().enumerate().map(|(i, field)|
3709 (field.ident.modern(), (i, field))
3710 ).collect::<FxHashMap<_, _>>();
3712 let mut seen_fields = FxHashMap::default();
3714 let mut error_happened = false;
3716 // Type-check each field.
3717 for field in ast_fields {
3718 let ident = tcx.adjust_ident(field.ident, variant.def_id);
3719 let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
3720 seen_fields.insert(ident, field.span);
3721 self.write_field_index(field.hir_id, i);
3723 // We don't look at stability attributes on
3724 // struct-like enums (yet...), but it's definitely not
3725 // a bug to have constructed one.
3726 if adt_kind != AdtKind::Enum {
3727 tcx.check_stability(v_field.did, Some(expr_id), field.span);
3730 self.field_ty(field.span, v_field, substs)
3732 error_happened = true;
3733 if let Some(prev_span) = seen_fields.get(&ident) {
3734 let mut err = struct_span_err!(self.tcx.sess,
3737 "field `{}` specified more than once",
3740 err.span_label(field.ident.span, "used more than once");
3741 err.span_label(*prev_span, format!("first use of `{}`", ident));
3745 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3751 // Make sure to give a type to the field even if there's
3752 // an error, so we can continue type-checking.
3753 self.check_expr_coercable_to_type(&field.expr, field_type);
3756 // Make sure the programmer specified correct number of fields.
3757 if kind_name == "union" {
3758 if ast_fields.len() != 1 {
3759 tcx.sess.span_err(span, "union expressions should have exactly one field");
3761 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3762 let len = remaining_fields.len();
3764 let mut displayable_field_names = remaining_fields
3766 .map(|ident| ident.as_str())
3767 .collect::<Vec<_>>();
3769 displayable_field_names.sort();
3771 let truncated_fields_error = if len <= 3 {
3774 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3777 let remaining_fields_names = displayable_field_names.iter().take(3)
3778 .map(|n| format!("`{}`", n))
3779 .collect::<Vec<_>>()
3782 struct_span_err!(tcx.sess, span, E0063,
3783 "missing field{} {}{} in initializer of `{}`",
3784 if remaining_fields.len() == 1 { "" } else { "s" },
3785 remaining_fields_names,
3786 truncated_fields_error,
3788 .span_label(span, format!("missing {}{}",
3789 remaining_fields_names,
3790 truncated_fields_error))
3796 fn check_struct_fields_on_error(
3798 fields: &'tcx [hir::Field],
3799 base_expr: &'tcx Option<P<hir::Expr>>,
3801 for field in fields {
3802 self.check_expr(&field.expr);
3804 if let Some(ref base) = *base_expr {
3805 self.check_expr(&base);
3809 pub fn check_struct_path(&self,
3812 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3813 let path_span = match *qpath {
3814 QPath::Resolved(_, ref path) => path.span,
3815 QPath::TypeRelative(ref qself, _) => qself.span
3817 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3818 let variant = match def {
3820 self.set_tainted_by_errors();
3823 Res::Def(DefKind::Variant, _) => {
3825 ty::Adt(adt, substs) => {
3826 Some((adt.variant_of_res(def), adt.did, substs))
3828 _ => bug!("unexpected type: {:?}", ty)
3831 Res::Def(DefKind::Struct, _)
3832 | Res::Def(DefKind::Union, _)
3833 | Res::Def(DefKind::TyAlias, _)
3834 | Res::Def(DefKind::AssocTy, _)
3835 | Res::SelfTy(..) => {
3837 ty::Adt(adt, substs) if !adt.is_enum() => {
3838 Some((adt.non_enum_variant(), adt.did, substs))
3843 _ => bug!("unexpected definition: {:?}", def)
3846 if let Some((variant, did, substs)) = variant {
3847 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3848 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3850 // Check bounds on type arguments used in the path.
3851 let bounds = self.instantiate_bounds(path_span, did, substs);
3852 let cause = traits::ObligationCause::new(path_span, self.body_id,
3853 traits::ItemObligation(did));
3854 self.add_obligations_for_parameters(cause, &bounds);
3858 struct_span_err!(self.tcx.sess, path_span, E0071,
3859 "expected struct, variant or union type, found {}",
3860 ty.sort_string(self.tcx))
3861 .span_label(path_span, "not a struct")
3867 fn check_expr_struct(
3870 expected: Expectation<'tcx>,
3872 fields: &'tcx [hir::Field],
3873 base_expr: &'tcx Option<P<hir::Expr>>,
3875 // Find the relevant variant
3876 let (variant, adt_ty) =
3877 if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id) {
3880 self.check_struct_fields_on_error(fields, base_expr);
3881 return self.tcx.types.err;
3884 let path_span = match *qpath {
3885 QPath::Resolved(_, ref path) => path.span,
3886 QPath::TypeRelative(ref qself, _) => qself.span
3889 // Prohibit struct expressions when non-exhaustive flag is set.
3890 let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
3891 if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
3892 span_err!(self.tcx.sess, expr.span, E0639,
3893 "cannot create non-exhaustive {} using struct expression",
3894 adt.variant_descr());
3897 let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.hir_id, path_span,
3898 variant, fields, base_expr.is_none());
3899 if let &Some(ref base_expr) = base_expr {
3900 // If check_expr_struct_fields hit an error, do not attempt to populate
3901 // the fields with the base_expr. This could cause us to hit errors later
3902 // when certain fields are assumed to exist that in fact do not.
3903 if !error_happened {
3904 self.check_expr_has_type_or_error(base_expr, adt_ty);
3906 ty::Adt(adt, substs) if adt.is_struct() => {
3907 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3908 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3913 .fru_field_types_mut()
3914 .insert(expr.hir_id, fru_field_types);
3917 span_err!(self.tcx.sess, base_expr.span, E0436,
3918 "functional record update syntax requires a struct");
3923 self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
3928 /// If an expression has any sub-expressions that result in a type error,
3929 /// inspecting that expression's type with `ty.references_error()` will return
3930 /// true. Likewise, if an expression is known to diverge, inspecting its
3931 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3932 /// strict, _|_ can appear in the type of an expression that does not,
3933 /// itself, diverge: for example, fn() -> _|_.)
3934 /// Note that inspecting a type's structure *directly* may expose the fact
3935 /// that there are actually multiple representations for `Error`, so avoid
3936 /// that when err needs to be handled differently.
3937 fn check_expr_with_expectation_and_needs(
3939 expr: &'tcx hir::Expr,
3940 expected: Expectation<'tcx>,
3943 debug!(">> type-checking: expr={:?} expected={:?}",
3946 // Warn for expressions after diverging siblings.
3947 self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
3949 // Hide the outer diverging and has_errors flags.
3950 let old_diverges = self.diverges.get();
3951 let old_has_errors = self.has_errors.get();
3952 self.diverges.set(Diverges::Maybe);
3953 self.has_errors.set(false);
3955 let ty = self.check_expr_kind(expr, expected, needs);
3957 // Warn for non-block expressions with diverging children.
3959 ExprKind::Block(..) |
3960 ExprKind::Loop(..) | ExprKind::While(..) |
3961 ExprKind::Match(..) => {}
3963 _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression")
3966 // Any expression that produces a value of type `!` must have diverged
3968 self.diverges.set(self.diverges.get() | Diverges::Always);
3971 // Record the type, which applies it effects.
3972 // We need to do this after the warning above, so that
3973 // we don't warn for the diverging expression itself.
3974 self.write_ty(expr.hir_id, ty);
3976 // Combine the diverging and has_error flags.
3977 self.diverges.set(self.diverges.get() | old_diverges);
3978 self.has_errors.set(self.has_errors.get() | old_has_errors);
3980 debug!("type of {} is...", self.tcx.hir().hir_to_string(expr.hir_id));
3981 debug!("... {:?}, expected is {:?}", ty, expected);
3986 /// Type check assignment expression `expr` of form `lhs = rhs`.
3987 /// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
3990 expr: &'tcx hir::Expr,
3991 expected: Expectation<'tcx>,
3992 lhs: &'tcx hir::Expr,
3993 rhs: &'tcx hir::Expr,
3995 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
3996 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3998 let expected_ty = expected.coercion_target_type(self, expr.span);
3999 if expected_ty == self.tcx.types.bool {
4000 // The expected type is `bool` but this will result in `()` so we can reasonably
4001 // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
4002 // The likely cause of this is `if foo = bar { .. }`.
4003 let actual_ty = self.tcx.mk_unit();
4004 let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
4005 let msg = "try comparing for equality";
4006 let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
4007 let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
4008 if let (Ok(left), Ok(right)) = (left, right) {
4009 let help = format!("{} == {}", left, right);
4010 err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
4015 } else if !lhs.is_place_expr() {
4016 struct_span_err!(self.tcx.sess, expr.span, E0070,
4017 "invalid left-hand side expression")
4018 .span_label(expr.span, "left-hand of expression not valid")
4022 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
4024 if lhs_ty.references_error() || rhs_ty.references_error() {
4031 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4032 // The newly resolved definition is written into `type_dependent_defs`.
4033 fn finish_resolving_struct_path(&self,
4040 QPath::Resolved(ref maybe_qself, ref path) => {
4041 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4042 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4045 QPath::TypeRelative(ref qself, ref segment) => {
4046 let ty = self.to_ty(qself);
4048 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
4053 let result = AstConv::associated_path_to_ty(
4062 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4063 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4065 // Write back the new resolution.
4066 self.write_resolution(hir_id, result);
4068 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4073 /// Resolves associated value path into a base type and associated constant or method
4074 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4075 pub fn resolve_ty_and_res_ufcs<'b>(&self,
4079 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4081 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4082 let (ty, qself, item_segment) = match *qpath {
4083 QPath::Resolved(ref opt_qself, ref path) => {
4085 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4086 &path.segments[..]);
4088 QPath::TypeRelative(ref qself, ref segment) => {
4089 (self.to_ty(qself), qself, segment)
4092 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4093 // Return directly on cache hit. This is useful to avoid doubly reporting
4094 // errors with default match binding modes. See #44614.
4095 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
4096 .unwrap_or(Res::Err);
4097 return (def, Some(ty), slice::from_ref(&**item_segment));
4099 let item_name = item_segment.ident;
4100 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4101 let result = match error {
4102 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4103 _ => Err(ErrorReported),
4105 if item_name.name != kw::Invalid {
4106 self.report_method_error(
4110 SelfSource::QPath(qself),
4118 // Write back the new resolution.
4119 self.write_resolution(hir_id, result);
4121 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4123 slice::from_ref(&**item_segment),
4127 pub fn check_decl_initializer(
4129 local: &'tcx hir::Local,
4130 init: &'tcx hir::Expr,
4132 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4133 // for #42640 (default match binding modes).
4136 let ref_bindings = local.pat.contains_explicit_ref_binding();
4138 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4139 if let Some(m) = ref_bindings {
4140 // Somewhat subtle: if we have a `ref` binding in the pattern,
4141 // we want to avoid introducing coercions for the RHS. This is
4142 // both because it helps preserve sanity and, in the case of
4143 // ref mut, for soundness (issue #23116). In particular, in
4144 // the latter case, we need to be clear that the type of the
4145 // referent for the reference that results is *equal to* the
4146 // type of the place it is referencing, and not some
4147 // supertype thereof.
4148 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4149 self.demand_eqtype(init.span, local_ty, init_ty);
4152 self.check_expr_coercable_to_type(init, local_ty)
4156 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
4157 let t = self.local_ty(local.span, local.hir_id).decl_ty;
4158 self.write_ty(local.hir_id, t);
4160 if let Some(ref init) = local.init {
4161 let init_ty = self.check_decl_initializer(local, &init);
4162 if init_ty.references_error() {
4163 self.write_ty(local.hir_id, init_ty);
4167 self.check_pat_walk(
4170 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4173 let pat_ty = self.node_ty(local.pat.hir_id);
4174 if pat_ty.references_error() {
4175 self.write_ty(local.hir_id, pat_ty);
4179 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
4180 // Don't do all the complex logic below for `DeclItem`.
4182 hir::StmtKind::Item(..) => return,
4183 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4186 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4188 // Hide the outer diverging and `has_errors` flags.
4189 let old_diverges = self.diverges.get();
4190 let old_has_errors = self.has_errors.get();
4191 self.diverges.set(Diverges::Maybe);
4192 self.has_errors.set(false);
4195 hir::StmtKind::Local(ref l) => {
4196 self.check_decl_local(&l);
4199 hir::StmtKind::Item(_) => {}
4200 hir::StmtKind::Expr(ref expr) => {
4201 // Check with expected type of `()`.
4202 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
4204 hir::StmtKind::Semi(ref expr) => {
4205 self.check_expr(&expr);
4209 // Combine the diverging and `has_error` flags.
4210 self.diverges.set(self.diverges.get() | old_diverges);
4211 self.has_errors.set(self.has_errors.get() | old_has_errors);
4214 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
4215 let unit = self.tcx.mk_unit();
4216 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4218 // if the block produces a `!` value, that can always be
4219 // (effectively) coerced to unit.
4221 self.demand_suptype(blk.span, unit, ty);
4225 fn check_block_with_expected(
4227 blk: &'tcx hir::Block,
4228 expected: Expectation<'tcx>,
4231 let mut fcx_ps = self.ps.borrow_mut();
4232 let unsafety_state = fcx_ps.recurse(blk);
4233 replace(&mut *fcx_ps, unsafety_state)
4236 // In some cases, blocks have just one exit, but other blocks
4237 // can be targeted by multiple breaks. This can happen both
4238 // with labeled blocks as well as when we desugar
4239 // a `try { ... }` expression.
4243 // 'a: { if true { break 'a Err(()); } Ok(()) }
4245 // Here we would wind up with two coercions, one from
4246 // `Err(())` and the other from the tail expression
4247 // `Ok(())`. If the tail expression is omitted, that's a
4248 // "forced unit" -- unless the block diverges, in which
4249 // case we can ignore the tail expression (e.g., `'a: {
4250 // break 'a 22; }` would not force the type of the block
4252 let tail_expr = blk.expr.as_ref();
4253 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4254 let coerce = if blk.targeted_by_break {
4255 CoerceMany::new(coerce_to_ty)
4257 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4258 Some(e) => slice::from_ref(e),
4261 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4264 let prev_diverges = self.diverges.get();
4265 let ctxt = BreakableCtxt {
4266 coerce: Some(coerce),
4270 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4271 for s in &blk.stmts {
4275 // check the tail expression **without** holding the
4276 // `enclosing_breakables` lock below.
4277 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4279 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4280 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4281 let coerce = ctxt.coerce.as_mut().unwrap();
4282 if let Some(tail_expr_ty) = tail_expr_ty {
4283 let tail_expr = tail_expr.unwrap();
4284 let cause = self.cause(tail_expr.span,
4285 ObligationCauseCode::BlockTailExpression(blk.hir_id));
4291 // Subtle: if there is no explicit tail expression,
4292 // that is typically equivalent to a tail expression
4293 // of `()` -- except if the block diverges. In that
4294 // case, there is no value supplied from the tail
4295 // expression (assuming there are no other breaks,
4296 // this implies that the type of the block will be
4299 // #41425 -- label the implicit `()` as being the
4300 // "found type" here, rather than the "expected type".
4301 if !self.diverges.get().always() {
4302 // #50009 -- Do not point at the entire fn block span, point at the return type
4303 // span, as it is the cause of the requirement, and
4304 // `consider_hint_about_removing_semicolon` will point at the last expression
4305 // if it were a relevant part of the error. This improves usability in editors
4306 // that highlight errors inline.
4307 let mut sp = blk.span;
4308 let mut fn_span = None;
4309 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4310 let ret_sp = decl.output.span();
4311 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4312 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4313 // output would otherwise be incorrect and even misleading. Make sure
4314 // the span we're aiming at correspond to a `fn` body.
4315 if block_sp == blk.span {
4317 fn_span = Some(ident.span);
4321 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
4322 if let Some(expected_ty) = expected.only_has_type(self) {
4323 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4325 if let Some(fn_span) = fn_span {
4326 err.span_label(fn_span, "this function's body doesn't return");
4334 // If we can break from the block, then the block's exit is always reachable
4335 // (... as long as the entry is reachable) - regardless of the tail of the block.
4336 self.diverges.set(prev_diverges);
4339 let mut ty = ctxt.coerce.unwrap().complete(self);
4341 if self.has_errors.get() || ty.references_error() {
4342 ty = self.tcx.types.err
4345 self.write_ty(blk.hir_id, ty);
4347 *self.ps.borrow_mut() = prev;
4351 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4352 let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(id));
4354 Node::Item(&hir::Item {
4355 node: hir::ItemKind::Fn(_, _, _, body_id), ..
4357 Node::ImplItem(&hir::ImplItem {
4358 node: hir::ImplItemKind::Method(_, body_id), ..
4360 let body = self.tcx.hir().body(body_id);
4361 if let ExprKind::Block(block, _) = &body.value.node {
4362 return Some(block.span);
4370 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4371 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> {
4372 let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id));
4373 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4376 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4377 fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> {
4379 Node::Item(&hir::Item {
4380 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4381 }) => decl.clone().and_then(|decl| {
4382 // This is less than ideal, it will not suggest a return type span on any
4383 // method called `main`, regardless of whether it is actually the entry point,
4384 // but it will still present it as the reason for the expected type.
4385 Some((decl, ident, ident.name != sym::main))
4387 Node::TraitItem(&hir::TraitItem {
4388 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
4391 }) => decl.clone().and_then(|decl| Some((decl, ident, true))),
4392 Node::ImplItem(&hir::ImplItem {
4393 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
4396 }) => decl.clone().and_then(|decl| Some((decl, ident, false))),
4401 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4402 /// suggestion can be made, `None` otherwise.
4403 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> {
4404 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4405 // `while` before reaching it, as block tail returns are not available in them.
4406 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4407 let parent = self.tcx.hir().get_by_hir_id(blk_id);
4408 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4412 /// On implicit return expressions with mismatched types, provides the following suggestions:
4414 /// - Points out the method's return type as the reason for the expected type.
4415 /// - Possible missing semicolon.
4416 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4417 pub fn suggest_mismatched_types_on_tail(
4419 err: &mut DiagnosticBuilder<'tcx>,
4420 expression: &'tcx hir::Expr,
4426 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4427 let mut pointing_at_return_type = false;
4428 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4429 pointing_at_return_type = self.suggest_missing_return_type(
4430 err, &fn_decl, expected, found, can_suggest);
4432 self.suggest_ref_or_into(err, expression, expected, found);
4433 pointing_at_return_type
4436 pub fn suggest_ref_or_into(
4438 err: &mut DiagnosticBuilder<'tcx>,
4443 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4444 err.span_suggestion(
4448 Applicability::MachineApplicable,
4450 } else if !self.check_for_cast(err, expr, found, expected) {
4451 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4455 let methods = self.get_conversion_methods(expr.span, expected, found);
4456 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4457 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4458 .filter_map(|(receiver, method)| {
4459 let method_call = format!(".{}()", method.ident);
4460 if receiver.ends_with(&method_call) {
4461 None // do not suggest code that is already there (#53348)
4463 let method_call_list = [".to_vec()", ".to_string()"];
4464 let sugg = if receiver.ends_with(".clone()")
4465 && method_call_list.contains(&method_call.as_str()) {
4466 let max_len = receiver.rfind(".").unwrap();
4467 format!("{}{}", &receiver[..max_len], method_call)
4469 format!("{}{}", receiver, method_call)
4471 Some(if is_struct_pat_shorthand_field {
4472 format!("{}: {}", receiver, sugg)
4478 if suggestions.peek().is_some() {
4479 err.span_suggestions(
4481 "try using a conversion method",
4483 Applicability::MaybeIncorrect,
4490 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4494 /// bar_that_returns_u32()
4498 /// This routine checks if the return expression in a block would make sense on its own as a
4499 /// statement and the return type has been left as default or has been specified as `()`. If so,
4500 /// it suggests adding a semicolon.
4501 fn suggest_missing_semicolon(
4503 err: &mut DiagnosticBuilder<'tcx>,
4504 expression: &'tcx hir::Expr,
4508 if expected.is_unit() {
4509 // `BlockTailExpression` only relevant if the tail expr would be
4510 // useful on its own.
4511 match expression.node {
4512 ExprKind::Call(..) |
4513 ExprKind::MethodCall(..) |
4514 ExprKind::While(..) |
4515 ExprKind::Loop(..) |
4516 ExprKind::Match(..) |
4517 ExprKind::Block(..) => {
4518 let sp = self.tcx.sess.source_map().next_point(cause_span);
4519 err.span_suggestion(
4521 "try adding a semicolon",
4523 Applicability::MachineApplicable);
4530 /// A possible error is to forget to add a return type that is needed:
4534 /// bar_that_returns_u32()
4538 /// This routine checks if the return type is left as default, the method is not part of an
4539 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4541 fn suggest_missing_return_type(
4543 err: &mut DiagnosticBuilder<'tcx>,
4544 fn_decl: &hir::FnDecl,
4549 // Only suggest changing the return type for methods that
4550 // haven't set a return type at all (and aren't `fn main()` or an impl).
4551 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4552 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4553 err.span_suggestion(
4555 "try adding a return type",
4556 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
4557 Applicability::MachineApplicable);
4560 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4561 err.span_label(span, "possibly return type missing here?");
4564 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4565 // `fn main()` must return `()`, do not suggest changing return type
4566 err.span_label(span, "expected `()` because of default return type");
4569 // expectation was caused by something else, not the default return
4570 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4571 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4572 // Only point to return type if the expected type is the return type, as if they
4573 // are not, the expectation must have been caused by something else.
4574 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4576 let ty = AstConv::ast_ty_to_ty(self, ty);
4577 debug!("suggest_missing_return_type: return type {:?}", ty);
4578 debug!("suggest_missing_return_type: expected type {:?}", ty);
4579 if ty.sty == expected.sty {
4580 err.span_label(sp, format!("expected `{}` because of return type",
4589 /// A common error is to add an extra semicolon:
4592 /// fn foo() -> usize {
4597 /// This routine checks if the final statement in a block is an
4598 /// expression with an explicit semicolon whose type is compatible
4599 /// with `expected_ty`. If so, it suggests removing the semicolon.
4600 fn consider_hint_about_removing_semicolon(
4602 blk: &'tcx hir::Block,
4603 expected_ty: Ty<'tcx>,
4604 err: &mut DiagnosticBuilder<'_>,
4606 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4607 err.span_suggestion(
4609 "consider removing this semicolon",
4611 Applicability::MachineApplicable,
4616 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4617 // Be helpful when the user wrote `{... expr;}` and
4618 // taking the `;` off is enough to fix the error.
4619 let last_stmt = blk.stmts.last()?;
4620 let last_expr = match last_stmt.node {
4621 hir::StmtKind::Semi(ref e) => e,
4624 let last_expr_ty = self.node_ty(last_expr.hir_id);
4625 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4628 let original_span = original_sp(last_stmt.span, blk.span);
4629 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4632 // Rewrite `SelfCtor` to `Ctor`
4633 pub fn rewrite_self_ctor(
4637 ) -> Result<Res, ErrorReported> {
4639 if let Res::SelfCtor(impl_def_id) = res {
4640 let ty = self.impl_self_ty(span, impl_def_id).ty;
4641 let adt_def = ty.ty_adt_def();
4644 Some(adt_def) if adt_def.has_ctor() => {
4645 let variant = adt_def.non_enum_variant();
4646 let ctor_def_id = variant.ctor_def_id.unwrap();
4647 Ok(Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id))
4650 let mut err = tcx.sess.struct_span_err(span,
4651 "the `Self` constructor can only be used with tuple or unit structs");
4652 if let Some(adt_def) = adt_def {
4653 match adt_def.adt_kind() {
4655 err.help("did you mean to use one of the enum's variants?");
4659 err.span_suggestion(
4661 "use curly brackets",
4662 String::from("Self { /* fields */ }"),
4663 Applicability::HasPlaceholders,
4678 // Instantiates the given path, which must refer to an item with the given
4679 // number of type parameters and type.
4680 pub fn instantiate_value_path(&self,
4681 segments: &[hir::PathSegment],
4682 self_ty: Option<Ty<'tcx>>,
4686 -> (Ty<'tcx>, Res) {
4688 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4697 let res = match self.rewrite_self_ctor(res, span) {
4699 Err(ErrorReported) => return (tcx.types.err, res),
4701 let path_segs = match res {
4702 Res::Local(_) => vec![],
4703 Res::Def(kind, def_id) =>
4704 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4705 _ => bug!("instantiate_value_path on {:?}", res),
4708 let mut user_self_ty = None;
4709 let mut is_alias_variant_ctor = false;
4711 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4712 if let Some(self_ty) = self_ty {
4713 let adt_def = self_ty.ty_adt_def().unwrap();
4714 user_self_ty = Some(UserSelfTy {
4715 impl_def_id: adt_def.did,
4718 is_alias_variant_ctor = true;
4721 Res::Def(DefKind::Method, def_id)
4722 | Res::Def(DefKind::AssocConst, def_id) => {
4723 let container = tcx.associated_item(def_id).container;
4724 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4726 ty::TraitContainer(trait_did) => {
4727 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4729 ty::ImplContainer(impl_def_id) => {
4730 if segments.len() == 1 {
4731 // `<T>::assoc` will end up here, and so
4732 // can `T::assoc`. It this came from an
4733 // inherent impl, we need to record the
4734 // `T` for posterity (see `UserSelfTy` for
4736 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4737 user_self_ty = Some(UserSelfTy {
4748 // Now that we have categorized what space the parameters for each
4749 // segment belong to, let's sort out the parameters that the user
4750 // provided (if any) into their appropriate spaces. We'll also report
4751 // errors if type parameters are provided in an inappropriate place.
4753 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4754 let generics_has_err = AstConv::prohibit_generics(
4755 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4756 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4763 if let Res::Local(hid) = res {
4764 let ty = self.local_ty(span, hid).decl_ty;
4765 let ty = self.normalize_associated_types_in(span, &ty);
4766 self.write_ty(hir_id, ty);
4770 if generics_has_err {
4771 // Don't try to infer type parameters when prohibited generic arguments were given.
4772 user_self_ty = None;
4775 // Now we have to compare the types that the user *actually*
4776 // provided against the types that were *expected*. If the user
4777 // did not provide any types, then we want to substitute inference
4778 // variables. If the user provided some types, we may still need
4779 // to add defaults. If the user provided *too many* types, that's
4782 let mut infer_args_for_err = FxHashSet::default();
4783 for &PathSeg(def_id, index) in &path_segs {
4784 let seg = &segments[index];
4785 let generics = tcx.generics_of(def_id);
4786 // Argument-position `impl Trait` is treated as a normal generic
4787 // parameter internally, but we don't allow users to specify the
4788 // parameter's value explicitly, so we have to do some error-
4790 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4795 false, // `is_method_call`
4797 if suppress_errors {
4798 infer_args_for_err.insert(index);
4799 self.set_tainted_by_errors(); // See issue #53251.
4803 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4804 tcx.generics_of(*def_id).has_self
4805 }).unwrap_or(false);
4807 let def_id = res.def_id();
4809 // The things we are substituting into the type should not contain
4810 // escaping late-bound regions, and nor should the base type scheme.
4811 let ty = tcx.type_of(def_id);
4813 let substs = AstConv::create_substs_for_generic_args(
4819 // Provide the generic args, and whether types should be inferred.
4821 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4824 // If we've encountered an `impl Trait`-related error, we're just
4825 // going to infer the arguments for better error messages.
4826 if !infer_args_for_err.contains(&index) {
4827 // Check whether the user has provided generic arguments.
4828 if let Some(ref data) = segments[index].args {
4829 return (Some(data), segments[index].infer_args);
4832 return (None, segments[index].infer_args);
4837 // Provide substitutions for parameters for which (valid) arguments have been provided.
4839 match (¶m.kind, arg) {
4840 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4841 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4843 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4844 self.to_ty(ty).into()
4846 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4847 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4849 _ => unreachable!(),
4852 // Provide substitutions for parameters for which arguments are inferred.
4853 |substs, param, infer_args| {
4855 GenericParamDefKind::Lifetime => {
4856 self.re_infer(Some(param), span).unwrap().into()
4858 GenericParamDefKind::Type { has_default, .. } => {
4859 if !infer_args && has_default {
4860 // If we have a default, then we it doesn't matter that we're not
4861 // inferring the type arguments: we provide the default where any
4863 let default = tcx.type_of(param.def_id);
4866 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4869 // If no type arguments were provided, we have to infer them.
4870 // This case also occurs as a result of some malformed input, e.g.
4871 // a lifetime argument being given instead of a type parameter.
4872 // Using inference instead of `Error` gives better error messages.
4873 self.var_for_def(span, param)
4876 GenericParamDefKind::Const => {
4877 // FIXME(const_generics:defaults)
4878 // No const parameters were provided, we have to infer them.
4879 self.var_for_def(span, param)
4884 assert!(!substs.has_escaping_bound_vars());
4885 assert!(!ty.has_escaping_bound_vars());
4887 // First, store the "user substs" for later.
4888 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4890 // Add all the obligations that are required, substituting and
4891 // normalized appropriately.
4892 let bounds = self.instantiate_bounds(span, def_id, &substs);
4893 self.add_obligations_for_parameters(
4894 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
4897 // Substitute the values for the type parameters into the type of
4898 // the referenced item.
4899 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4901 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4902 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4903 // is inherent, there is no `Self` parameter; instead, the impl needs
4904 // type parameters, which we can infer by unifying the provided `Self`
4905 // with the substituted impl type.
4906 // This also occurs for an enum variant on a type alias.
4907 let ty = tcx.type_of(impl_def_id);
4909 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4910 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4911 Ok(ok) => self.register_infer_ok_obligations(ok),
4913 self.tcx.sess.delay_span_bug(span, &format!(
4914 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4922 self.check_rustc_args_require_const(def_id, hir_id, span);
4924 debug!("instantiate_value_path: type of {:?} is {:?}",
4927 self.write_substs(hir_id, substs);
4929 (ty_substituted, res)
4932 fn check_rustc_args_require_const(&self,
4936 // We're only interested in functions tagged with
4937 // #[rustc_args_required_const], so ignore anything that's not.
4938 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
4942 // If our calling expression is indeed the function itself, we're good!
4943 // If not, generate an error that this can only be called directly.
4944 if let Node::Expr(expr) = self.tcx.hir().get_by_hir_id(
4945 self.tcx.hir().get_parent_node_by_hir_id(hir_id))
4947 if let ExprKind::Call(ref callee, ..) = expr.node {
4948 if callee.hir_id == hir_id {
4954 self.tcx.sess.span_err(span, "this function can only be invoked \
4955 directly, not through a function pointer");
4958 // Resolves `typ` by a single level if `typ` is a type variable.
4959 // If no resolution is possible, then an error is reported.
4960 // Numeric inference variables may be left unresolved.
4961 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4962 let ty = self.resolve_type_vars_with_obligations(ty);
4963 if !ty.is_ty_var() {
4966 if !self.is_tainted_by_errors() {
4967 self.need_type_info_err((**self).body_id, sp, ty)
4968 .note("type must be known at this point")
4971 self.demand_suptype(sp, self.tcx.types.err, ty);
4976 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
4979 ctxt: BreakableCtxt<'tcx>,
4981 ) -> (BreakableCtxt<'tcx>, R) {
4984 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4985 index = enclosing_breakables.stack.len();
4986 enclosing_breakables.by_id.insert(id, index);
4987 enclosing_breakables.stack.push(ctxt);
4991 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4992 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4993 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4994 enclosing_breakables.stack.pop().expect("missing breakable context")
4999 /// Instantiate a QueryResponse in a probe context, without a
5000 /// good ObligationCause.
5001 fn probe_instantiate_query_response(
5004 original_values: &OriginalQueryValues<'tcx>,
5005 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5006 ) -> InferResult<'tcx, Ty<'tcx>>
5008 self.instantiate_query_response_and_region_obligations(
5009 &traits::ObligationCause::misc(span, self.body_id),
5015 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5016 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5017 let mut contained_in_place = false;
5019 while let hir::Node::Expr(parent_expr) =
5020 self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(expr_id))
5022 match &parent_expr.node {
5023 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5024 if lhs.hir_id == expr_id {
5025 contained_in_place = true;
5031 expr_id = parent_expr.hir_id;
5038 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5039 let own_counts = generics.own_counts();
5041 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5047 if own_counts.types == 0 {
5051 // Make a vector of booleans initially false, set to true when used.
5052 let mut types_used = vec![false; own_counts.types];
5054 for leaf_ty in ty.walk() {
5055 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.sty {
5056 debug!("Found use of ty param num {}", index);
5057 types_used[index as usize - own_counts.lifetimes] = true;
5058 } else if let ty::Error = leaf_ty.sty {
5059 // If there is already another error, do not emit
5060 // an error for not using a type Parameter.
5061 assert!(tcx.sess.err_count() > 0);
5066 let types = generics.params.iter().filter(|param| match param.kind {
5067 ty::GenericParamDefKind::Type { .. } => true,
5070 for (&used, param) in types_used.iter().zip(types) {
5072 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5073 let span = tcx.hir().span_by_hir_id(id);
5074 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5075 .span_label(span, "unused type parameter")
5081 fn fatally_break_rust(sess: &Session) {
5082 let handler = sess.diagnostic();
5083 handler.span_bug_no_panic(
5085 "It looks like you're trying to break rust; would you like some ICE?",
5087 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5088 handler.note_without_error(
5089 "we would appreciate a joke overview: \
5090 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5092 handler.note_without_error(&format!("rustc {} running on {}",
5093 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5094 crate::session::config::host_triple(),
5098 fn potentially_plural_count(count: usize, word: &str) -> String {
5099 format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })