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
84 mod generator_interior;
88 use crate::astconv::{AstConv, PathSeg};
89 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
90 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
91 use rustc::hir::def::{CtorOf, CtorKind, Res, DefKind};
92 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
93 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
94 use rustc::hir::itemlikevisit::ItemLikeVisitor;
95 use crate::middle::lang_items;
96 use crate::namespace::Namespace;
97 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
98 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
99 use rustc_data_structures::indexed_vec::Idx;
100 use rustc_target::spec::abi::Abi;
101 use rustc::infer::opaque_types::OpaqueTypeDecl;
102 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
103 use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
104 use rustc::middle::region;
105 use rustc::mir::interpret::{ConstValue, GlobalId};
106 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
108 self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
109 ToPolyTraitRef, ToPredicate, RegionKind, UserType
111 use rustc::ty::adjustment::{
112 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
114 use rustc::ty::fold::TypeFoldable;
115 use rustc::ty::query::Providers;
116 use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
117 use rustc::ty::util::{Representability, IntTypeExt, Discr};
118 use rustc::ty::layout::VariantIdx;
119 use syntax_pos::{self, BytePos, Span, MultiSpan};
120 use syntax_pos::hygiene::CompilerDesugaringKind;
123 use syntax::feature_gate::{GateIssue, emit_feature_err};
125 use syntax::source_map::{DUMMY_SP, original_sp};
126 use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
127 use syntax::util::lev_distance::find_best_match_for_name;
129 use std::cell::{Cell, RefCell, Ref, RefMut};
130 use std::collections::hash_map::Entry;
132 use std::fmt::Display;
134 use std::mem::replace;
135 use std::ops::{self, Deref};
138 use crate::require_c_abi_if_c_variadic;
139 use crate::session::Session;
140 use crate::session::config::EntryFnType;
141 use crate::TypeAndSubsts;
143 use crate::util::captures::Captures;
144 use crate::util::common::{ErrorReported, indenter};
145 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, HirIdMap};
147 pub use self::Expectation::*;
148 use self::autoderef::Autoderef;
149 use self::callee::DeferredCallResolution;
150 use self::coercion::{CoerceMany, DynamicCoerceMany};
151 pub use self::compare_method::{compare_impl_method, compare_const_impl};
152 use self::method::{MethodCallee, SelfSource};
153 use self::TupleArgumentsFlag::*;
155 /// The type of a local binding, including the revealed type for anon types.
156 #[derive(Copy, Clone)]
157 pub struct LocalTy<'tcx> {
159 revealed_ty: Ty<'tcx>
162 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
163 #[derive(Copy, Clone)]
164 struct MaybeInProgressTables<'a, 'tcx: 'a> {
165 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
168 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
169 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
170 match self.maybe_tables {
171 Some(tables) => tables.borrow(),
173 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
178 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
179 match self.maybe_tables {
180 Some(tables) => tables.borrow_mut(),
182 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
188 /// Closures defined within the function. For example:
191 /// bar(move|| { ... })
194 /// Here, the function `foo()` and the closure passed to
195 /// `bar()` will each have their own `FnCtxt`, but they will
196 /// share the inherited fields.
197 pub struct Inherited<'a, 'tcx: 'a> {
198 infcx: InferCtxt<'a, 'tcx>,
200 tables: MaybeInProgressTables<'a, 'tcx>,
202 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
204 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
206 // Some additional `Sized` obligations badly affect type inference.
207 // These obligations are added in a later stage of typeck.
208 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
210 // When we process a call like `c()` where `c` is a closure type,
211 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
212 // `FnOnce` closure. In that case, we defer full resolution of the
213 // call until upvar inference can kick in and make the
214 // decision. We keep these deferred resolutions grouped by the
215 // def-id of the closure, so that once we decide, we can easily go
216 // back and process them.
217 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
219 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
221 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
223 // Opaque types found in explicit return types and their
224 // associated fresh inference variable. Writeback resolves these
225 // variables to get the concrete type, which can be used to
226 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
227 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
229 /// Each type parameter has an implicit region bound that
230 /// indicates it must outlive at least the function body (the user
231 /// may specify stronger requirements). This field indicates the
232 /// region of the callee. If it is `None`, then the parameter
233 /// environment is for an item or something where the "callee" is
235 implicit_region_bound: Option<ty::Region<'tcx>>,
237 body_id: Option<hir::BodyId>,
240 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
241 type Target = InferCtxt<'a, 'tcx>;
242 fn deref(&self) -> &Self::Target {
247 /// When type-checking an expression, we propagate downward
248 /// whatever type hint we are able in the form of an `Expectation`.
249 #[derive(Copy, Clone, Debug)]
250 pub enum Expectation<'tcx> {
251 /// We know nothing about what type this expression should have.
254 /// This expression should have the type given (or some subtype).
255 ExpectHasType(Ty<'tcx>),
257 /// This expression will be cast to the `Ty`.
258 ExpectCastableToType(Ty<'tcx>),
260 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
261 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
262 ExpectRvalueLikeUnsized(Ty<'tcx>),
265 impl<'a, 'tcx> Expectation<'tcx> {
266 // Disregard "castable to" expectations because they
267 // can lead us astray. Consider for example `if cond
268 // {22} else {c} as u8` -- if we propagate the
269 // "castable to u8" constraint to 22, it will pick the
270 // type 22u8, which is overly constrained (c might not
271 // be a u8). In effect, the problem is that the
272 // "castable to" expectation is not the tightest thing
273 // we can say, so we want to drop it in this case.
274 // The tightest thing we can say is "must unify with
275 // else branch". Note that in the case of a "has type"
276 // constraint, this limitation does not hold.
278 // If the expected type is just a type variable, then don't use
279 // an expected type. Otherwise, we might write parts of the type
280 // when checking the 'then' block which are incompatible with the
282 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
284 ExpectHasType(ety) => {
285 let ety = fcx.shallow_resolve(ety);
286 if !ety.is_ty_var() {
292 ExpectRvalueLikeUnsized(ety) => {
293 ExpectRvalueLikeUnsized(ety)
299 /// Provides an expectation for an rvalue expression given an *optional*
300 /// hint, which is not required for type safety (the resulting type might
301 /// be checked higher up, as is the case with `&expr` and `box expr`), but
302 /// is useful in determining the concrete type.
304 /// The primary use case is where the expected type is a fat pointer,
305 /// like `&[isize]`. For example, consider the following statement:
307 /// let x: &[isize] = &[1, 2, 3];
309 /// In this case, the expected type for the `&[1, 2, 3]` expression is
310 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
311 /// expectation `ExpectHasType([isize])`, that would be too strong --
312 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
313 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
314 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
315 /// which still is useful, because it informs integer literals and the like.
316 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
317 /// for examples of where this comes up,.
318 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
319 match fcx.tcx.struct_tail(ty).sty {
320 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
321 ExpectRvalueLikeUnsized(ty)
323 _ => ExpectHasType(ty)
327 // Resolves `expected` by a single level if it is a variable. If
328 // there is no expected type or resolution is not possible (e.g.,
329 // no constraints yet present), just returns `None`.
330 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
332 NoExpectation => NoExpectation,
333 ExpectCastableToType(t) => {
334 ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
336 ExpectHasType(t) => {
337 ExpectHasType(fcx.resolve_vars_if_possible(&t))
339 ExpectRvalueLikeUnsized(t) => {
340 ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
345 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
346 match self.resolve(fcx) {
347 NoExpectation => None,
348 ExpectCastableToType(ty) |
350 ExpectRvalueLikeUnsized(ty) => Some(ty),
354 /// It sometimes happens that we want to turn an expectation into
355 /// a **hard constraint** (i.e., something that must be satisfied
356 /// for the program to type-check). `only_has_type` will return
357 /// such a constraint, if it exists.
358 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
359 match self.resolve(fcx) {
360 ExpectHasType(ty) => Some(ty),
361 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
365 /// Like `only_has_type`, but instead of returning `None` if no
366 /// hard constraint exists, creates a fresh type variable.
367 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
368 self.only_has_type(fcx)
370 fcx.next_ty_var(TypeVariableOrigin {
371 kind: TypeVariableOriginKind::MiscVariable,
378 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
385 fn maybe_mut_place(m: hir::Mutability) -> Self {
387 hir::MutMutable => Needs::MutPlace,
388 hir::MutImmutable => Needs::None,
393 #[derive(Copy, Clone)]
394 pub struct UnsafetyState {
396 pub unsafety: hir::Unsafety,
397 pub unsafe_push_count: u32,
402 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
403 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
406 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
407 match self.unsafety {
408 // If this unsafe, then if the outer function was already marked as
409 // unsafe we shouldn't attribute the unsafe'ness to the block. This
410 // way the block can be warned about instead of ignoring this
411 // extraneous block (functions are never warned about).
412 hir::Unsafety::Unsafe if self.from_fn => *self,
415 let (unsafety, def, count) = match blk.rules {
416 hir::PushUnsafeBlock(..) =>
417 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
418 hir::PopUnsafeBlock(..) =>
419 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
420 hir::UnsafeBlock(..) =>
421 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
423 (unsafety, self.def, self.unsafe_push_count),
427 unsafe_push_count: count,
434 #[derive(Debug, Copy, Clone)]
440 /// Tracks whether executing a node may exit normally (versus
441 /// return/break/panic, which "diverge", leaving dead code in their
442 /// wake). Tracked semi-automatically (through type variables marked
443 /// as diverging), with some manual adjustments for control-flow
444 /// primitives (approximating a CFG).
445 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
447 /// Potentially unknown, some cases converge,
448 /// others require a CFG to determine them.
451 /// Definitely known to diverge and therefore
452 /// not reach the next sibling or its parent.
455 /// Same as `Always` but with a reachability
456 /// warning already emitted.
460 // Convenience impls for combinig `Diverges`.
462 impl ops::BitAnd for Diverges {
464 fn bitand(self, other: Self) -> Self {
465 cmp::min(self, other)
469 impl ops::BitOr for Diverges {
471 fn bitor(self, other: Self) -> Self {
472 cmp::max(self, other)
476 impl ops::BitAndAssign for Diverges {
477 fn bitand_assign(&mut self, other: Self) {
478 *self = *self & other;
482 impl ops::BitOrAssign for Diverges {
483 fn bitor_assign(&mut self, other: Self) {
484 *self = *self | other;
489 fn always(self) -> bool {
490 self >= Diverges::Always
494 pub struct BreakableCtxt<'tcx> {
497 // this is `null` for loops where break with a value is illegal,
498 // such as `while`, `for`, and `while let`
499 coerce: Option<DynamicCoerceMany<'tcx>>,
502 pub struct EnclosingBreakables<'tcx> {
503 stack: Vec<BreakableCtxt<'tcx>>,
504 by_id: HirIdMap<usize>,
507 impl<'tcx> EnclosingBreakables<'tcx> {
508 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
509 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
510 bug!("could not find enclosing breakable with id {}", target_id);
516 pub struct FnCtxt<'a, 'tcx: 'a> {
519 /// The parameter environment used for proving trait obligations
520 /// in this function. This can change when we descend into
521 /// closures (as they bring new things into scope), hence it is
522 /// not part of `Inherited` (as of the time of this writing,
523 /// closures do not yet change the environment, but they will
525 param_env: ty::ParamEnv<'tcx>,
527 /// Number of errors that had been reported when we started
528 /// checking this function. On exit, if we find that *more* errors
529 /// have been reported, we will skip regionck and other work that
530 /// expects the types within the function to be consistent.
531 err_count_on_creation: usize,
533 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
534 ret_coercion_span: RefCell<Option<Span>>,
536 yield_ty: Option<Ty<'tcx>>,
538 ps: RefCell<UnsafetyState>,
540 /// Whether the last checked node generates a divergence (e.g.,
541 /// `return` will set this to `Always`). In general, when entering
542 /// an expression or other node in the tree, the initial value
543 /// indicates whether prior parts of the containing expression may
544 /// have diverged. It is then typically set to `Maybe` (and the
545 /// old value remembered) for processing the subparts of the
546 /// current expression. As each subpart is processed, they may set
547 /// the flag to `Always`, etc. Finally, at the end, we take the
548 /// result and "union" it with the original value, so that when we
549 /// return the flag indicates if any subpart of the parent
550 /// expression (up to and including this part) has diverged. So,
551 /// if you read it after evaluating a subexpression `X`, the value
552 /// you get indicates whether any subexpression that was
553 /// evaluating up to and including `X` diverged.
555 /// We currently use this flag only for diagnostic purposes:
557 /// - To warn about unreachable code: if, after processing a
558 /// sub-expression but before we have applied the effects of the
559 /// current node, we see that the flag is set to `Always`, we
560 /// can issue a warning. This corresponds to something like
561 /// `foo(return)`; we warn on the `foo()` expression. (We then
562 /// update the flag to `WarnedAlways` to suppress duplicate
563 /// reports.) Similarly, if we traverse to a fresh statement (or
564 /// tail expression) from a `Always` setting, we will issue a
565 /// warning. This corresponds to something like `{return;
566 /// foo();}` or `{return; 22}`, where we would warn on the
569 /// An expression represents dead code if, after checking it,
570 /// the diverges flag is set to something other than `Maybe`.
571 diverges: Cell<Diverges>,
573 /// Whether any child nodes have any type errors.
574 has_errors: Cell<bool>,
576 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
578 inh: &'a Inherited<'a, 'tcx>,
581 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
582 type Target = Inherited<'a, 'tcx>;
583 fn deref(&self) -> &Self::Target {
588 /// Helper type of a temporary returned by `Inherited::build(...)`.
589 /// Necessary because we can't write the following bound:
590 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
591 pub struct InheritedBuilder<'tcx> {
592 infcx: infer::InferCtxtBuilder<'tcx>,
596 impl Inherited<'_, 'tcx> {
597 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
598 let hir_id_root = if def_id.is_local() {
599 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
600 DefId::local(hir_id.owner)
606 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
612 impl<'tcx> InheritedBuilder<'tcx> {
613 fn enter<F, R>(&mut self, f: F) -> R
615 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
617 let def_id = self.def_id;
618 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
622 impl Inherited<'a, 'tcx> {
623 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
625 let item_id = tcx.hir().as_local_hir_id(def_id);
626 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by_by_hir_id(id));
627 let implicit_region_bound = body_id.map(|body_id| {
628 let body = tcx.hir().body(body_id);
629 tcx.mk_region(ty::ReScope(region::Scope {
630 id: body.value.hir_id.local_id,
631 data: region::ScopeData::CallSite
636 tables: MaybeInProgressTables {
637 maybe_tables: infcx.in_progress_tables,
640 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
641 locals: RefCell::new(Default::default()),
642 deferred_sized_obligations: RefCell::new(Vec::new()),
643 deferred_call_resolutions: RefCell::new(Default::default()),
644 deferred_cast_checks: RefCell::new(Vec::new()),
645 deferred_generator_interiors: RefCell::new(Vec::new()),
646 opaque_types: RefCell::new(Default::default()),
647 implicit_region_bound,
652 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
653 debug!("register_predicate({:?})", obligation);
654 if obligation.has_escaping_bound_vars() {
655 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
660 .register_predicate_obligation(self, obligation);
663 fn register_predicates<I>(&self, obligations: I)
664 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
666 for obligation in obligations {
667 self.register_predicate(obligation);
671 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
672 self.register_predicates(infer_ok.obligations);
676 fn normalize_associated_types_in<T>(&self,
679 param_env: ty::ParamEnv<'tcx>,
681 where T : TypeFoldable<'tcx>
683 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
684 self.register_infer_ok_obligations(ok)
688 struct CheckItemTypesVisitor<'tcx> {
692 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
693 fn visit_item(&mut self, i: &'tcx hir::Item) {
694 check_item_type(self.tcx, i);
696 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
697 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
700 pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
701 tcx.sess.track_errors(|| {
702 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
703 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
707 fn check_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
708 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
711 fn typeck_item_bodies<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) {
712 debug_assert!(crate_num == LOCAL_CRATE);
713 tcx.par_body_owners(|body_owner_def_id| {
714 tcx.ensure().typeck_tables_of(body_owner_def_id);
718 fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
719 wfcheck::check_item_well_formed(tcx, def_id);
722 fn check_trait_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
723 wfcheck::check_trait_item(tcx, def_id);
726 fn check_impl_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
727 wfcheck::check_impl_item(tcx, def_id);
730 pub fn provide(providers: &mut Providers<'_>) {
731 method::provide(providers);
732 *providers = Providers {
738 check_item_well_formed,
739 check_trait_item_well_formed,
740 check_impl_item_well_formed,
741 check_mod_item_types,
746 fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::Destructor> {
747 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
750 /// If this `DefId` is a "primary tables entry", returns `Some((body_id, decl))`
751 /// with information about it's body-id and fn-decl (if any). Otherwise,
754 /// If this function returns "some", then `typeck_tables(def_id)` will
755 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
756 /// may not succeed. In some cases where this function returns `None`
757 /// (notably closures), `typeck_tables(def_id)` would wind up
758 /// redirecting to the owning function.
759 fn primary_body_of<'tcx>(
762 ) -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)> {
763 match tcx.hir().get_by_hir_id(id) {
764 Node::Item(item) => {
766 hir::ItemKind::Const(_, body) |
767 hir::ItemKind::Static(_, _, body) =>
769 hir::ItemKind::Fn(ref decl, .., body) =>
770 Some((body, Some(decl))),
775 Node::TraitItem(item) => {
777 hir::TraitItemKind::Const(_, Some(body)) =>
779 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
780 Some((body, Some(&sig.decl))),
785 Node::ImplItem(item) => {
787 hir::ImplItemKind::Const(_, body) =>
789 hir::ImplItemKind::Method(ref sig, body) =>
790 Some((body, Some(&sig.decl))),
795 Node::AnonConst(constant) => Some((constant.body, None)),
800 fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
801 // Closures' tables come from their outermost function,
802 // as they are part of the same "inference environment".
803 let outer_def_id = tcx.closure_base_def_id(def_id);
804 if outer_def_id != def_id {
805 return tcx.has_typeck_tables(outer_def_id);
808 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
809 primary_body_of(tcx, id).is_some()
812 fn used_trait_imports<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx DefIdSet {
813 &*tcx.typeck_tables_of(def_id).used_trait_imports
816 fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckTables<'tcx> {
817 // Closures' tables come from their outermost function,
818 // as they are part of the same "inference environment".
819 let outer_def_id = tcx.closure_base_def_id(def_id);
820 if outer_def_id != def_id {
821 return tcx.typeck_tables_of(outer_def_id);
824 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
825 let span = tcx.hir().span_by_hir_id(id);
827 // Figure out what primary body this item has.
828 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
829 span_bug!(span, "can't type-check body of {:?}", def_id);
831 let body = tcx.hir().body(body_id);
833 let tables = Inherited::build(tcx, def_id).enter(|inh| {
834 let param_env = tcx.param_env(def_id);
835 let fcx = if let Some(decl) = fn_decl {
836 let fn_sig = tcx.fn_sig(def_id);
838 check_abi(tcx, span, fn_sig.abi());
840 // Compute the fty from point of view of inside the fn.
842 tcx.liberate_late_bound_regions(def_id, &fn_sig);
844 inh.normalize_associated_types_in(body.value.span,
849 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
852 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
853 let expected_type = tcx.type_of(def_id);
854 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
855 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
857 let revealed_ty = if tcx.features().impl_trait_in_bindings {
858 fcx.instantiate_opaque_types_from_value(
866 // Gather locals in statics (because of block expressions).
867 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
869 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
871 fcx.write_ty(id, revealed_ty);
876 // All type checking constraints were added, try to fallback unsolved variables.
877 fcx.select_obligations_where_possible(false);
878 let mut fallback_has_occurred = false;
879 for ty in &fcx.unsolved_variables() {
880 fallback_has_occurred |= fcx.fallback_if_possible(ty);
882 fcx.select_obligations_where_possible(fallback_has_occurred);
884 // Even though coercion casts provide type hints, we check casts after fallback for
885 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
888 // Closure and generator analysis may run after fallback
889 // because they don't constrain other type variables.
890 fcx.closure_analyze(body);
891 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
892 fcx.resolve_generator_interiors(def_id);
894 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
895 let ty = fcx.normalize_ty(span, ty);
896 fcx.require_type_is_sized(ty, span, code);
898 fcx.select_all_obligations_or_error();
900 if fn_decl.is_some() {
901 fcx.regionck_fn(id, body);
903 fcx.regionck_expr(body);
906 fcx.resolve_type_vars_in_body(body)
909 // Consistency check our TypeckTables instance can hold all ItemLocalIds
910 // it will need to hold.
911 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
916 fn check_abi<'tcx>(tcx: TyCtxt<'tcx>, span: Span, abi: Abi) {
917 if !tcx.sess.target.target.is_abi_supported(abi) {
918 struct_span_err!(tcx.sess, span, E0570,
919 "The ABI `{}` is not supported for the current target", abi).emit()
923 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
924 fcx: &'a FnCtxt<'a, 'tcx>,
925 parent_id: hir::HirId,
928 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
929 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
932 // infer the variable's type
933 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
934 kind: TypeVariableOriginKind::TypeInference,
937 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
944 // take type that the user specified
945 self.fcx.locals.borrow_mut().insert(nid, typ);
952 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
953 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
954 NestedVisitorMap::None
957 // Add explicitly-declared locals.
958 fn visit_local(&mut self, local: &'tcx hir::Local) {
959 let local_ty = match local.ty {
961 let o_ty = self.fcx.to_ty(&ty);
963 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
964 self.fcx.instantiate_opaque_types_from_value(
972 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
973 &UserType::Ty(revealed_ty)
975 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
976 ty.hir_id, o_ty, revealed_ty, c_ty);
977 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
979 Some(LocalTy { decl_ty: o_ty, revealed_ty })
983 self.assign(local.span, local.hir_id, local_ty);
985 debug!("Local variable {:?} is assigned type {}",
987 self.fcx.ty_to_string(
988 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
989 intravisit::walk_local(self, local);
992 // Add pattern bindings.
993 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
994 if let PatKind::Binding(_, _, ident, _) = p.node {
995 let var_ty = self.assign(p.span, p.hir_id, None);
997 let node_id = self.fcx.tcx.hir().hir_to_node_id(p.hir_id);
998 if !self.fcx.tcx.features().unsized_locals {
999 self.fcx.require_type_is_sized(var_ty, p.span,
1000 traits::VariableType(node_id));
1003 debug!("Pattern binding {} is assigned to {} with type {:?}",
1005 self.fcx.ty_to_string(
1006 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1009 intravisit::walk_pat(self, p);
1012 // Don't descend into the bodies of nested closures
1015 _: intravisit::FnKind<'tcx>,
1016 _: &'tcx hir::FnDecl,
1023 /// When `check_fn` is invoked on a generator (i.e., a body that
1024 /// includes yield), it returns back some information about the yield
1026 struct GeneratorTypes<'tcx> {
1027 /// Type of value that is yielded.
1030 /// Types that are captured (see `GeneratorInterior` for more).
1033 /// Indicates if the generator is movable or static (immovable).
1034 movability: hir::GeneratorMovability,
1037 /// Helper used for fns and closures. Does the grungy work of checking a function
1038 /// body and returns the function context used for that purpose, since in the case of a fn item
1039 /// there is still a bit more to do.
1042 /// * inherited: other fields inherited from the enclosing fn (if any)
1043 fn check_fn<'a, 'tcx>(
1044 inherited: &'a Inherited<'a, 'tcx>,
1045 param_env: ty::ParamEnv<'tcx>,
1046 fn_sig: ty::FnSig<'tcx>,
1047 decl: &'tcx hir::FnDecl,
1049 body: &'tcx hir::Body,
1050 can_be_generator: Option<hir::GeneratorMovability>,
1051 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1052 let mut fn_sig = fn_sig.clone();
1054 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1056 // Create the function context. This is either derived from scratch or,
1057 // in the case of closures, based on the outer context.
1058 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1059 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1061 let declared_ret_ty = fn_sig.output();
1062 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1063 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty);
1064 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1065 fn_sig = fcx.tcx.mk_fn_sig(
1066 fn_sig.inputs().iter().cloned(),
1073 let span = body.value.span;
1075 if body.is_generator && can_be_generator.is_some() {
1076 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1077 kind: TypeVariableOriginKind::TypeInference,
1080 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1081 fcx.yield_ty = Some(yield_ty);
1084 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id_from_hir_id(fn_id));
1085 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1086 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1088 // Add formal parameters.
1089 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1090 // Check the pattern.
1091 let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
1092 fcx.check_pat_walk(&arg.pat, arg_ty, binding_mode, None);
1094 // Check that argument is Sized.
1095 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1096 // for simple cases like `fn foo(x: Trait)`,
1097 // where we would error once on the parameter as a whole, and once on the binding `x`.
1098 if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1099 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
1102 fcx.write_ty(arg.hir_id, arg_ty);
1105 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1107 fcx.check_return_expr(&body.value);
1109 // We insert the deferred_generator_interiors entry after visiting the body.
1110 // This ensures that all nested generators appear before the entry of this generator.
1111 // resolve_generator_interiors relies on this property.
1112 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1113 let interior = fcx.next_ty_var(TypeVariableOrigin {
1114 kind: TypeVariableOriginKind::MiscVariable,
1117 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1118 Some(GeneratorTypes {
1119 yield_ty: fcx.yield_ty.unwrap(),
1121 movability: can_be_generator.unwrap(),
1127 // Finalize the return check by taking the LUB of the return types
1128 // we saw and assigning it to the expected return type. This isn't
1129 // really expected to fail, since the coercions would have failed
1130 // earlier when trying to find a LUB.
1132 // However, the behavior around `!` is sort of complex. In the
1133 // event that the `actual_return_ty` comes back as `!`, that
1134 // indicates that the fn either does not return or "returns" only
1135 // values of type `!`. In this case, if there is an expected
1136 // return type that is *not* `!`, that should be ok. But if the
1137 // return type is being inferred, we want to "fallback" to `!`:
1139 // let x = move || panic!();
1141 // To allow for that, I am creating a type variable with diverging
1142 // fallback. This was deemed ever so slightly better than unifying
1143 // the return value with `!` because it allows for the caller to
1144 // make more assumptions about the return type (e.g., they could do
1146 // let y: Option<u32> = Some(x());
1148 // which would then cause this return type to become `u32`, not
1150 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1151 let mut actual_return_ty = coercion.complete(&fcx);
1152 if actual_return_ty.is_never() {
1153 actual_return_ty = fcx.next_diverging_ty_var(
1154 TypeVariableOrigin {
1155 kind: TypeVariableOriginKind::DivergingFn,
1160 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1162 // Check that the main return type implements the termination trait.
1163 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1164 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1165 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1166 if main_id == fn_id {
1167 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1168 let trait_ref = ty::TraitRef::new(term_id, substs);
1169 let return_ty_span = decl.output.span();
1170 let cause = traits::ObligationCause::new(
1171 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1173 inherited.register_predicate(
1174 traits::Obligation::new(
1175 cause, param_env, trait_ref.to_predicate()));
1180 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1181 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1182 if panic_impl_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1183 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1184 // at this point we don't care if there are duplicate handlers or if the handler has
1185 // the wrong signature as this value we'll be used when writing metadata and that
1186 // only happens if compilation succeeded
1187 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1189 if declared_ret_ty.sty != ty::Never {
1190 fcx.tcx.sess.span_err(
1192 "return type should be `!`",
1196 let inputs = fn_sig.inputs();
1197 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1198 if inputs.len() == 1 {
1199 let arg_is_panic_info = match inputs[0].sty {
1200 ty::Ref(region, ty, mutbl) => match ty.sty {
1201 ty::Adt(ref adt, _) => {
1202 adt.did == panic_info_did &&
1203 mutbl == hir::Mutability::MutImmutable &&
1204 *region != RegionKind::ReStatic
1211 if !arg_is_panic_info {
1212 fcx.tcx.sess.span_err(
1213 decl.inputs[0].span,
1214 "argument should be `&PanicInfo`",
1218 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1219 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1220 if !generics.params.is_empty() {
1221 fcx.tcx.sess.span_err(
1223 "should have no type parameters",
1229 let span = fcx.tcx.sess.source_map().def_span(span);
1230 fcx.tcx.sess.span_err(span, "function should have one argument");
1233 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1238 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1239 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1240 if alloc_error_handler_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
1241 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1242 if declared_ret_ty.sty != ty::Never {
1243 fcx.tcx.sess.span_err(
1245 "return type should be `!`",
1249 let inputs = fn_sig.inputs();
1250 let span = fcx.tcx.hir().span_by_hir_id(fn_id);
1251 if inputs.len() == 1 {
1252 let arg_is_alloc_layout = match inputs[0].sty {
1253 ty::Adt(ref adt, _) => {
1254 adt.did == alloc_layout_did
1259 if !arg_is_alloc_layout {
1260 fcx.tcx.sess.span_err(
1261 decl.inputs[0].span,
1262 "argument should be `Layout`",
1266 if let Node::Item(item) = fcx.tcx.hir().get_by_hir_id(fn_id) {
1267 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1268 if !generics.params.is_empty() {
1269 fcx.tcx.sess.span_err(
1271 "`#[alloc_error_handler]` function should have no type \
1278 let span = fcx.tcx.sess.source_map().def_span(span);
1279 fcx.tcx.sess.span_err(span, "function should have one argument");
1282 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1290 fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
1291 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1292 let def = tcx.adt_def(def_id);
1293 def.destructor(tcx); // force the destructor to be evaluated
1294 check_representable(tcx, span, def_id);
1296 if def.repr.simd() {
1297 check_simd(tcx, span, def_id);
1300 check_transparent(tcx, span, def_id);
1301 check_packed(tcx, span, def_id);
1304 fn check_union<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
1305 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1306 let def = tcx.adt_def(def_id);
1307 def.destructor(tcx); // force the destructor to be evaluated
1308 check_representable(tcx, span, def_id);
1309 check_transparent(tcx, span, def_id);
1310 check_packed(tcx, span, def_id);
1313 fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, span: Span) {
1314 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1315 let mut err = struct_span_err!(
1316 tcx.sess, span, E0720,
1317 "opaque type expands to a recursive type",
1319 err.span_label(span, "expands to self-referential type");
1320 if let ty::Opaque(..) = partially_expanded_type.sty {
1321 err.note("type resolves to itself");
1323 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1329 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1331 "check_item_type(it.hir_id={}, it.name={})",
1333 tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
1335 let _indenter = indenter();
1337 // Consts can play a role in type-checking, so they are included here.
1338 hir::ItemKind::Static(..) => {
1339 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1340 tcx.typeck_tables_of(def_id);
1341 maybe_check_static_with_link_section(tcx, def_id, it.span);
1343 hir::ItemKind::Const(..) => {
1344 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(it.hir_id));
1346 hir::ItemKind::Enum(ref enum_definition, _) => {
1347 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1349 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1350 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1351 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1352 let impl_def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1353 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1354 check_impl_items_against_trait(
1361 let trait_def_id = impl_trait_ref.def_id;
1362 check_on_unimplemented(tcx, trait_def_id, it);
1365 hir::ItemKind::Trait(..) => {
1366 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1367 check_on_unimplemented(tcx, def_id, it);
1369 hir::ItemKind::Struct(..) => {
1370 check_struct(tcx, it.hir_id, it.span);
1372 hir::ItemKind::Union(..) => {
1373 check_union(tcx, it.hir_id, it.span);
1375 hir::ItemKind::Existential(..) => {
1376 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1378 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1379 check_opaque(tcx, def_id, substs, it.span);
1381 hir::ItemKind::Ty(..) => {
1382 let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
1383 let pty_ty = tcx.type_of(def_id);
1384 let generics = tcx.generics_of(def_id);
1385 check_bounds_are_used(tcx, &generics, pty_ty);
1387 hir::ItemKind::ForeignMod(ref m) => {
1388 check_abi(tcx, it.span, m.abi);
1390 if m.abi == Abi::RustIntrinsic {
1391 for item in &m.items {
1392 intrinsic::check_intrinsic_type(tcx, item);
1394 } else if m.abi == Abi::PlatformIntrinsic {
1395 for item in &m.items {
1396 intrinsic::check_platform_intrinsic_type(tcx, item);
1399 for item in &m.items {
1400 let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
1401 if generics.params.len() - generics.own_counts().lifetimes != 0 {
1402 let mut err = struct_span_err!(
1406 "foreign items may not have type parameters"
1408 err.span_label(item.span, "can't have type parameters");
1409 // FIXME: once we start storing spans for type arguments, turn this into a
1412 "use specialization instead of type parameters by replacing them \
1413 with concrete types like `u32`",
1418 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1419 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1424 _ => { /* nothing to do */ }
1428 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1429 // Only restricted on wasm32 target for now
1430 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1434 // If `#[link_section]` is missing, then nothing to verify
1435 let attrs = tcx.codegen_fn_attrs(id);
1436 if attrs.link_section.is_none() {
1440 // For the wasm32 target statics with #[link_section] are placed into custom
1441 // sections of the final output file, but this isn't link custom sections of
1442 // other executable formats. Namely we can only embed a list of bytes,
1443 // nothing with pointers to anything else or relocations. If any relocation
1444 // show up, reject them here.
1445 let instance = ty::Instance::mono(tcx, id);
1446 let cid = GlobalId {
1450 let param_env = ty::ParamEnv::reveal_all();
1451 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1452 let alloc = if let ConstValue::ByRef(_, allocation) = static_.val {
1455 bug!("Matching on non-ByRef static")
1457 if alloc.relocations.len() != 0 {
1458 let msg = "statics with a custom `#[link_section]` must be a \
1459 simple list of bytes on the wasm target with no \
1460 extra levels of indirection such as references";
1461 tcx.sess.span_err(span, msg);
1466 fn check_on_unimplemented<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, item: &hir::Item) {
1467 let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
1468 // an error would be reported if this fails.
1469 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1472 fn report_forbidden_specialization<'tcx>(
1474 impl_item: &hir::ImplItem,
1477 let mut err = struct_span_err!(
1478 tcx.sess, impl_item.span, E0520,
1479 "`{}` specializes an item from a parent `impl`, but \
1480 that item is not marked `default`",
1482 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1485 match tcx.span_of_impl(parent_impl) {
1487 err.span_label(span, "parent `impl` is here");
1488 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1492 err.note(&format!("parent implementation is in crate `{}`", cname));
1499 fn check_specialization_validity<'tcx>(
1501 trait_def: &ty::TraitDef,
1502 trait_item: &ty::AssocItem,
1504 impl_item: &hir::ImplItem,
1506 let ancestors = trait_def.ancestors(tcx, impl_id);
1508 let kind = match impl_item.node {
1509 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1510 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1511 hir::ImplItemKind::Existential(..) => ty::AssocKind::Existential,
1512 hir::ImplItemKind::Type(_) => ty::AssocKind::Type
1515 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1516 .map(|node_item| node_item.map(|parent| parent.defaultness));
1518 if let Some(parent) = parent {
1519 if tcx.impl_item_is_final(&parent) {
1520 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1526 fn check_impl_items_against_trait<'tcx>(
1530 impl_trait_ref: ty::TraitRef<'tcx>,
1531 impl_item_refs: &[hir::ImplItemRef],
1533 let impl_span = tcx.sess.source_map().def_span(impl_span);
1535 // If the trait reference itself is erroneous (so the compilation is going
1536 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1537 // isn't populated for such impls.
1538 if impl_trait_ref.references_error() { return; }
1540 // Locate trait definition and items
1541 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1542 let mut overridden_associated_type = None;
1544 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1546 // Check existing impl methods to see if they are both present in trait
1547 // and compatible with trait signature
1548 for impl_item in impl_items() {
1549 let ty_impl_item = tcx.associated_item(
1550 tcx.hir().local_def_id_from_hir_id(impl_item.hir_id));
1551 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1552 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1553 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1555 // Not compatible, but needed for the error message
1556 tcx.associated_items(impl_trait_ref.def_id)
1557 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1560 // Check that impl definition matches trait definition
1561 if let Some(ty_trait_item) = ty_trait_item {
1562 match impl_item.node {
1563 hir::ImplItemKind::Const(..) => {
1564 // Find associated const definition.
1565 if ty_trait_item.kind == ty::AssocKind::Const {
1566 compare_const_impl(tcx,
1572 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1573 "item `{}` is an associated const, \
1574 which doesn't match its trait `{}`",
1577 err.span_label(impl_item.span, "does not match trait");
1578 // We can only get the spans from local trait definition
1579 // Same for E0324 and E0325
1580 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1581 err.span_label(trait_span, "item in trait");
1586 hir::ImplItemKind::Method(..) => {
1587 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1588 if ty_trait_item.kind == ty::AssocKind::Method {
1589 compare_impl_method(tcx,
1596 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1597 "item `{}` is an associated method, \
1598 which doesn't match its trait `{}`",
1601 err.span_label(impl_item.span, "does not match trait");
1602 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1603 err.span_label(trait_span, "item in trait");
1608 hir::ImplItemKind::Existential(..) |
1609 hir::ImplItemKind::Type(_) => {
1610 if ty_trait_item.kind == ty::AssocKind::Type {
1611 if ty_trait_item.defaultness.has_value() {
1612 overridden_associated_type = Some(impl_item);
1615 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1616 "item `{}` is an associated type, \
1617 which doesn't match its trait `{}`",
1620 err.span_label(impl_item.span, "does not match trait");
1621 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1622 err.span_label(trait_span, "item in trait");
1629 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1633 // Check for missing items from trait
1634 let mut missing_items = Vec::new();
1635 let mut invalidated_items = Vec::new();
1636 let associated_type_overridden = overridden_associated_type.is_some();
1637 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1638 let is_implemented = trait_def.ancestors(tcx, impl_id)
1639 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1641 .map(|node_item| !node_item.node.is_from_trait())
1644 if !is_implemented && !tcx.impl_is_default(impl_id) {
1645 if !trait_item.defaultness.has_value() {
1646 missing_items.push(trait_item);
1647 } else if associated_type_overridden {
1648 invalidated_items.push(trait_item.ident);
1653 if !missing_items.is_empty() {
1654 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1655 "not all trait items implemented, missing: `{}`",
1656 missing_items.iter()
1657 .map(|trait_item| trait_item.ident.to_string())
1658 .collect::<Vec<_>>().join("`, `"));
1659 err.span_label(impl_span, format!("missing `{}` in implementation",
1660 missing_items.iter()
1661 .map(|trait_item| trait_item.ident.to_string())
1662 .collect::<Vec<_>>().join("`, `")));
1663 for trait_item in missing_items {
1664 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1665 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1667 err.note_trait_signature(trait_item.ident.to_string(),
1668 trait_item.signature(tcx));
1674 if !invalidated_items.is_empty() {
1675 let invalidator = overridden_associated_type.unwrap();
1676 span_err!(tcx.sess, invalidator.span, E0399,
1677 "the following trait items need to be reimplemented \
1678 as `{}` was overridden: `{}`",
1680 invalidated_items.iter()
1681 .map(|name| name.to_string())
1682 .collect::<Vec<_>>().join("`, `"))
1686 /// Checks whether a type can be represented in memory. In particular, it
1687 /// identifies types that contain themselves without indirection through a
1688 /// pointer, which would mean their size is unbounded.
1689 fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) -> bool {
1690 let rty = tcx.type_of(item_def_id);
1692 // Check that it is possible to represent this type. This call identifies
1693 // (1) types that contain themselves and (2) types that contain a different
1694 // recursive type. It is only necessary to throw an error on those that
1695 // contain themselves. For case 2, there must be an inner type that will be
1696 // caught by case 1.
1697 match rty.is_representable(tcx, sp) {
1698 Representability::SelfRecursive(spans) => {
1699 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1701 err.span_label(span, "recursive without indirection");
1706 Representability::Representable | Representability::ContainsRecursive => (),
1711 pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1712 let t = tcx.type_of(def_id);
1713 if let ty::Adt(def, substs) = t.sty {
1714 if def.is_struct() {
1715 let fields = &def.non_enum_variant().fields;
1716 if fields.is_empty() {
1717 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1720 let e = fields[0].ty(tcx, substs);
1721 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1722 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1723 .span_label(sp, "SIMD elements must have the same type")
1728 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1729 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1731 span_err!(tcx.sess, sp, E0077,
1732 "SIMD vector element type should be machine type");
1740 fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1741 let repr = tcx.adt_def(def_id).repr;
1743 for attr in tcx.get_attrs(def_id).iter() {
1744 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1745 if let attr::ReprPacked(pack) = r {
1746 if pack != repr.pack {
1747 struct_span_err!(tcx.sess, sp, E0634,
1748 "type has conflicting packed representation hints").emit();
1754 struct_span_err!(tcx.sess, sp, E0587,
1755 "type has conflicting packed and align representation hints").emit();
1757 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1758 struct_span_err!(tcx.sess, sp, E0588,
1759 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1764 fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
1765 let t = tcx.type_of(def_id);
1766 if stack.contains(&def_id) {
1767 debug!("check_packed_inner: {:?} is recursive", t);
1770 if let ty::Adt(def, substs) = t.sty {
1771 if def.is_struct() || def.is_union() {
1772 if tcx.adt_def(def.did).repr.align > 0 {
1775 // push struct def_id before checking fields
1777 for field in &def.non_enum_variant().fields {
1778 let f = field.ty(tcx, substs);
1779 if let ty::Adt(def, _) = f.sty {
1780 if check_packed_inner(tcx, def.did, stack) {
1785 // only need to pop if not early out
1792 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
1793 let adt = tcx.adt_def(def_id);
1794 if !adt.repr.transparent() {
1797 let sp = tcx.sess.source_map().def_span(sp);
1800 if !tcx.features().transparent_enums {
1802 &tcx.sess.parse_sess,
1803 sym::transparent_enums,
1805 GateIssue::Language,
1806 "transparent enums are unstable",
1809 if adt.variants.len() != 1 {
1810 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
1811 tcx.hir().span_if_local(variant.def_id).unwrap()
1814 "needs exactly one variant, but has {}",
1817 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
1818 err.span_label(sp, &msg);
1819 match &variant_spans[..] {
1821 &[ref start.., ref end] => {
1822 for variant_span in start {
1823 err.span_label(*variant_span, "");
1825 err.span_label(*end, &format!(
1826 "too many variants in `{}`",
1827 tcx.def_path_str(def_id),
1832 if adt.variants.is_empty() {
1833 // Don't bother checking the fields. No variants (and thus no fields) exist.
1839 if adt.is_union() && !tcx.features().transparent_unions {
1840 emit_feature_err(&tcx.sess.parse_sess,
1841 sym::transparent_unions,
1843 GateIssue::Language,
1844 "transparent unions are unstable");
1847 // For each field, figure out if it's known to be a ZST and align(1)
1848 let field_infos = adt.all_fields().map(|field| {
1849 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
1850 let param_env = tcx.param_env(field.did);
1851 let layout = tcx.layout_of(param_env.and(ty));
1852 // We are currently checking the type this field came from, so it must be local
1853 let span = tcx.hir().span_if_local(field.did).unwrap();
1854 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1855 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
1859 let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
1860 let non_zst_count = non_zst_fields.clone().count();
1861 if non_zst_count != 1 {
1862 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
1864 let msg = format!("needs exactly one non-zero-sized field, but has {}", non_zst_count);
1865 let mut err = struct_span_err!(
1869 "{}transparent {} {}",
1870 if adt.is_enum() { "the variant of a " } else { "" },
1874 err.span_label(sp, &msg);
1875 for sp in &field_spans {
1876 err.span_label(*sp, "this field is non-zero-sized");
1880 for (span, zst, align1) in field_infos {
1886 "zero-sized field in transparent {} has alignment larger than 1",
1888 ).span_label(span, "has alignment larger than 1").emit();
1893 #[allow(trivial_numeric_casts)]
1894 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
1895 let def_id = tcx.hir().local_def_id_from_hir_id(id);
1896 let def = tcx.adt_def(def_id);
1897 def.destructor(tcx); // force the destructor to be evaluated
1900 let attributes = tcx.get_attrs(def_id);
1901 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
1903 tcx.sess, attr.span, E0084,
1904 "unsupported representation for zero-variant enum")
1905 .span_label(sp, "zero-variant enum")
1910 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1911 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1912 if !tcx.features().repr128 {
1913 emit_feature_err(&tcx.sess.parse_sess,
1916 GateIssue::Language,
1917 "repr with 128-bit type is unstable");
1922 if let Some(ref e) = v.node.disr_expr {
1923 tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(e.hir_id));
1927 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
1928 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
1929 // Check for duplicate discriminant values
1930 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1931 let variant_did = def.variants[VariantIdx::new(i)].def_id;
1932 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
1933 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
1934 let i_span = match variant_i.node.disr_expr {
1935 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1936 None => tcx.hir().span_by_hir_id(variant_i_hir_id)
1938 let span = match v.node.disr_expr {
1939 Some(ref expr) => tcx.hir().span_by_hir_id(expr.hir_id),
1942 struct_span_err!(tcx.sess, span, E0081,
1943 "discriminant value `{}` already exists", disr_vals[i])
1944 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1945 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1948 disr_vals.push(discr);
1951 check_representable(tcx, sp, def_id);
1952 check_transparent(tcx, sp, def_id);
1955 fn report_unexpected_variant_res<'tcx>(tcx: TyCtxt<'tcx>, res: Res, span: Span, qpath: &QPath) {
1956 span_err!(tcx.sess, span, E0533,
1957 "expected unit struct/variant or constant, found {} `{}`",
1959 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1962 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1963 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
1967 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1968 -> &'tcx ty::GenericPredicates<'tcx>
1971 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
1972 let item_id = tcx.hir().ty_param_owner(hir_id);
1973 let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
1974 let generics = tcx.generics_of(item_def_id);
1975 let index = generics.param_def_id_to_index[&def_id];
1976 tcx.arena.alloc(ty::GenericPredicates {
1978 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
1980 ty::Predicate::Trait(ref data)
1981 if data.skip_binder().self_ty().is_param(index) => {
1982 // HACK(eddyb) should get the original `Span`.
1983 let span = tcx.def_span(def_id);
1984 Some((predicate, span))
1994 def: Option<&ty::GenericParamDef>,
1996 ) -> Option<ty::Region<'tcx>> {
1998 Some(def) => infer::EarlyBoundRegion(span, def.name),
1999 None => infer::MiscVariable(span)
2001 Some(self.next_region_var(v))
2004 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2005 if let Some(param) = param {
2006 if let UnpackedKind::Type(ty) = self.var_for_def(span, param).unpack() {
2011 self.next_ty_var(TypeVariableOrigin {
2012 kind: TypeVariableOriginKind::TypeInference,
2021 param: Option<&ty::GenericParamDef>,
2023 ) -> &'tcx Const<'tcx> {
2024 if let Some(param) = param {
2025 if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
2030 self.next_const_var(ty, ConstVariableOrigin {
2031 kind: ConstVariableOriginKind::ConstInference,
2037 fn projected_ty_from_poly_trait_ref(&self,
2040 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2043 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2045 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2049 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2052 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2053 if ty.has_escaping_bound_vars() {
2054 ty // FIXME: normalization and escaping regions
2056 self.normalize_associated_types_in(span, &ty)
2060 fn set_tainted_by_errors(&self) {
2061 self.infcx.set_tainted_by_errors()
2064 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2065 self.write_ty(hir_id, ty)
2069 /// Controls whether the arguments are tupled. This is used for the call
2072 /// Tupling means that all call-side arguments are packed into a tuple and
2073 /// passed as a single parameter. For example, if tupling is enabled, this
2076 /// fn f(x: (isize, isize))
2078 /// Can be called as:
2085 #[derive(Clone, Eq, PartialEq)]
2086 enum TupleArgumentsFlag {
2091 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2093 inh: &'a Inherited<'a, 'tcx>,
2094 param_env: ty::ParamEnv<'tcx>,
2095 body_id: hir::HirId,
2096 ) -> FnCtxt<'a, 'tcx> {
2100 err_count_on_creation: inh.tcx.sess.err_count(),
2102 ret_coercion_span: RefCell::new(None),
2104 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2105 hir::CRATE_HIR_ID)),
2106 diverges: Cell::new(Diverges::Maybe),
2107 has_errors: Cell::new(false),
2108 enclosing_breakables: RefCell::new(EnclosingBreakables {
2110 by_id: Default::default(),
2116 pub fn sess(&self) -> &Session {
2120 pub fn err_count_since_creation(&self) -> usize {
2121 self.tcx.sess.err_count() - self.err_count_on_creation
2124 /// Produces warning on the given node, if the current point in the
2125 /// function is unreachable, and there hasn't been another warning.
2126 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2127 if self.diverges.get() == Diverges::Always &&
2128 // If span arose from a desugaring of `if` then it is the condition itself,
2129 // which diverges, that we are about to lint on. This gives suboptimal diagnostics
2130 // and so we stop here and allow the block of the `if`-expression to be linted instead.
2131 !span.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary) {
2132 self.diverges.set(Diverges::WarnedAlways);
2134 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2136 let msg = format!("unreachable {}", kind);
2137 self.tcx().lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg);
2143 code: ObligationCauseCode<'tcx>)
2144 -> ObligationCause<'tcx> {
2145 ObligationCause::new(span, self.body_id, code)
2148 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2149 self.cause(span, ObligationCauseCode::MiscObligation)
2152 /// Resolves type variables in `ty` if possible. Unlike the infcx
2153 /// version (resolve_vars_if_possible), this version will
2154 /// also select obligations if it seems useful, in an effort
2155 /// to get more type information.
2156 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2157 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2159 // No Infer()? Nothing needs doing.
2160 if !ty.has_infer_types() {
2161 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2165 // If `ty` is a type variable, see whether we already know what it is.
2166 ty = self.resolve_vars_if_possible(&ty);
2167 if !ty.has_infer_types() {
2168 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2172 // If not, try resolving pending obligations as much as
2173 // possible. This can help substantially when there are
2174 // indirect dependencies that don't seem worth tracking
2176 self.select_obligations_where_possible(false);
2177 ty = self.resolve_vars_if_possible(&ty);
2179 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2183 fn record_deferred_call_resolution(
2185 closure_def_id: DefId,
2186 r: DeferredCallResolution<'tcx>,
2188 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2189 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2192 fn remove_deferred_call_resolutions(
2194 closure_def_id: DefId,
2195 ) -> Vec<DeferredCallResolution<'tcx>> {
2196 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2197 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2200 pub fn tag(&self) -> String {
2201 format!("{:p}", self)
2204 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2205 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2206 span_bug!(span, "no type for local variable {}",
2207 self.tcx.hir().hir_to_string(nid))
2212 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2213 debug!("write_ty({:?}, {:?}) in fcx {}",
2214 id, self.resolve_vars_if_possible(&ty), self.tag());
2215 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2217 if ty.references_error() {
2218 self.has_errors.set(true);
2219 self.set_tainted_by_errors();
2223 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2224 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2227 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2228 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2231 pub fn write_method_call(&self,
2233 method: MethodCallee<'tcx>) {
2234 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2235 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2236 self.write_substs(hir_id, method.substs);
2238 // When the method is confirmed, the `method.substs` includes
2239 // parameters from not just the method, but also the impl of
2240 // the method -- in particular, the `Self` type will be fully
2241 // resolved. However, those are not something that the "user
2242 // specified" -- i.e., those types come from the inferred type
2243 // of the receiver, not something the user wrote. So when we
2244 // create the user-substs, we want to replace those earlier
2245 // types with just the types that the user actually wrote --
2246 // that is, those that appear on the *method itself*.
2248 // As an example, if the user wrote something like
2249 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2250 // type of `foo` (possibly adjusted), but we don't want to
2251 // include that. We want just the `[_, u32]` part.
2252 if !method.substs.is_noop() {
2253 let method_generics = self.tcx.generics_of(method.def_id);
2254 if !method_generics.params.is_empty() {
2255 let user_type_annotation = self.infcx.probe(|_| {
2256 let user_substs = UserSubsts {
2257 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2258 let i = param.index as usize;
2259 if i < method_generics.parent_count {
2260 self.infcx.var_for_def(DUMMY_SP, param)
2265 user_self_ty: None, // not relevant here
2268 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2274 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2275 self.write_user_type_annotation(hir_id, user_type_annotation);
2280 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2281 if !substs.is_noop() {
2282 debug!("write_substs({:?}, {:?}) in fcx {}",
2287 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2291 /// Given the substs that we just converted from the HIR, try to
2292 /// canonicalize them and store them as user-given substitutions
2293 /// (i.e., substitutions that must be respected by the NLL check).
2295 /// This should be invoked **before any unifications have
2296 /// occurred**, so that annotations like `Vec<_>` are preserved
2298 pub fn write_user_type_annotation_from_substs(
2302 substs: SubstsRef<'tcx>,
2303 user_self_ty: Option<UserSelfTy<'tcx>>,
2306 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2307 user_self_ty={:?} in fcx {}",
2308 hir_id, def_id, substs, user_self_ty, self.tag(),
2311 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2312 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2313 &UserType::TypeOf(def_id, UserSubsts {
2318 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2319 self.write_user_type_annotation(hir_id, canonicalized);
2323 pub fn write_user_type_annotation(
2326 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2329 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2330 hir_id, canonical_user_type_annotation, self.tag(),
2333 if !canonical_user_type_annotation.is_identity() {
2334 self.tables.borrow_mut().user_provided_types_mut().insert(
2335 hir_id, canonical_user_type_annotation
2338 debug!("write_user_type_annotation: skipping identity substs");
2342 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2343 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2349 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2350 Entry::Vacant(entry) => { entry.insert(adj); },
2351 Entry::Occupied(mut entry) => {
2352 debug!(" - composing on top of {:?}", entry.get());
2353 match (&entry.get()[..], &adj[..]) {
2354 // Applying any adjustment on top of a NeverToAny
2355 // is a valid NeverToAny adjustment, because it can't
2357 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2359 Adjustment { kind: Adjust::Deref(_), .. },
2360 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2362 Adjustment { kind: Adjust::Deref(_), .. },
2363 .. // Any following adjustments are allowed.
2365 // A reborrow has no effect before a dereference.
2367 // FIXME: currently we never try to compose autoderefs
2368 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2370 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2371 expr, entry.get(), adj)
2373 *entry.get_mut() = adj;
2378 /// Basically whenever we are converting from a type scheme into
2379 /// the fn body space, we always want to normalize associated
2380 /// types as well. This function combines the two.
2381 fn instantiate_type_scheme<T>(&self,
2383 substs: SubstsRef<'tcx>,
2386 where T : TypeFoldable<'tcx>
2388 let value = value.subst(self.tcx, substs);
2389 let result = self.normalize_associated_types_in(span, &value);
2390 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2397 /// As `instantiate_type_scheme`, but for the bounds found in a
2398 /// generic type scheme.
2399 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: SubstsRef<'tcx>)
2400 -> ty::InstantiatedPredicates<'tcx> {
2401 let bounds = self.tcx.predicates_of(def_id);
2402 let result = bounds.instantiate(self.tcx, substs);
2403 let result = self.normalize_associated_types_in(span, &result);
2404 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2411 /// Replaces the opaque types from the given value with type variables,
2412 /// and records the `OpaqueTypeMap` for later use during writeback. See
2413 /// `InferCtxt::instantiate_opaque_types` for more details.
2414 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2416 parent_id: hir::HirId,
2419 let parent_def_id = self.tcx.hir().local_def_id_from_hir_id(parent_id);
2420 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2424 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2425 self.instantiate_opaque_types(
2433 let mut opaque_types = self.opaque_types.borrow_mut();
2434 for (ty, decl) in opaque_type_map {
2435 let old_value = opaque_types.insert(ty, decl);
2436 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2442 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2443 where T : TypeFoldable<'tcx>
2445 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2448 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2450 where T : TypeFoldable<'tcx>
2452 self.inh.partially_normalize_associated_types_in(span,
2458 pub fn require_type_meets(&self,
2461 code: traits::ObligationCauseCode<'tcx>,
2464 self.register_bound(
2467 traits::ObligationCause::new(span, self.body_id, code));
2470 pub fn require_type_is_sized(&self,
2473 code: traits::ObligationCauseCode<'tcx>)
2475 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2476 self.require_type_meets(ty, span, code, lang_item);
2479 pub fn require_type_is_sized_deferred(&self,
2482 code: traits::ObligationCauseCode<'tcx>)
2484 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2487 pub fn register_bound(&self,
2490 cause: traits::ObligationCause<'tcx>)
2492 self.fulfillment_cx.borrow_mut()
2493 .register_bound(self, self.param_env, ty, def_id, cause);
2496 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2497 let t = AstConv::ast_ty_to_ty(self, ast_t);
2498 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2502 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2503 let ty = self.to_ty(ast_ty);
2504 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2506 if Self::can_contain_user_lifetime_bounds(ty) {
2507 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2508 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2509 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2515 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2516 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2517 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2520 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2521 AstConv::ast_const_to_const(self, ast_c, ty)
2524 // If the type given by the user has free regions, save it for later, since
2525 // NLL would like to enforce those. Also pass in types that involve
2526 // projections, since those can resolve to `'static` bounds (modulo #54940,
2527 // which hopefully will be fixed by the time you see this comment, dear
2528 // reader, although I have my doubts). Also pass in types with inference
2529 // types, because they may be repeated. Other sorts of things are already
2530 // sufficiently enforced with erased regions. =)
2531 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2533 T: TypeFoldable<'tcx>
2535 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2538 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2539 match self.tables.borrow().node_types().get(id) {
2541 None if self.is_tainted_by_errors() => self.tcx.types.err,
2543 let node_id = self.tcx.hir().hir_to_node_id(id);
2544 bug!("no type for node {}: {} in fcx {}",
2545 node_id, self.tcx.hir().node_to_string(node_id),
2551 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2552 /// outlive the region `r`.
2553 pub fn register_wf_obligation(&self,
2556 code: traits::ObligationCauseCode<'tcx>)
2558 // WF obligations never themselves fail, so no real need to give a detailed cause:
2559 let cause = traits::ObligationCause::new(span, self.body_id, code);
2560 self.register_predicate(traits::Obligation::new(cause,
2562 ty::Predicate::WellFormed(ty)));
2565 /// Registers obligations that all types appearing in `substs` are well-formed.
2566 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2567 for ty in substs.types() {
2568 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2572 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2573 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2574 /// trait/region obligations.
2576 /// For example, if there is a function:
2579 /// fn foo<'a,T:'a>(...)
2582 /// and a reference:
2588 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2589 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2590 pub fn add_obligations_for_parameters(&self,
2591 cause: traits::ObligationCause<'tcx>,
2592 predicates: &ty::InstantiatedPredicates<'tcx>)
2594 assert!(!predicates.has_escaping_bound_vars());
2596 debug!("add_obligations_for_parameters(predicates={:?})",
2599 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2600 self.register_predicate(obligation);
2604 // FIXME(arielb1): use this instead of field.ty everywhere
2605 // Only for fields! Returns <none> for methods>
2606 // Indifferent to privacy flags
2607 pub fn field_ty(&self,
2609 field: &'tcx ty::FieldDef,
2610 substs: SubstsRef<'tcx>)
2613 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2616 fn check_casts(&self) {
2617 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2618 for cast in deferred_cast_checks.drain(..) {
2623 fn resolve_generator_interiors(&self, def_id: DefId) {
2624 let mut generators = self.deferred_generator_interiors.borrow_mut();
2625 for (body_id, interior) in generators.drain(..) {
2626 self.select_obligations_where_possible(false);
2627 generator_interior::resolve_interior(self, def_id, body_id, interior);
2631 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2632 // Non-numerics get replaced with ! or () (depending on whether
2633 // feature(never_type) is enabled, unconstrained ints with i32,
2634 // unconstrained floats with f64.
2635 // Fallback becomes very dubious if we have encountered type-checking errors.
2636 // In that case, fallback to Error.
2637 // The return value indicates whether fallback has occurred.
2638 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2639 use rustc::ty::error::UnconstrainedNumeric::Neither;
2640 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2642 assert!(ty.is_ty_infer());
2643 let fallback = match self.type_is_unconstrained_numeric(ty) {
2644 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2645 UnconstrainedInt => self.tcx.types.i32,
2646 UnconstrainedFloat => self.tcx.types.f64,
2647 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2648 Neither => return false,
2650 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2651 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2655 fn select_all_obligations_or_error(&self) {
2656 debug!("select_all_obligations_or_error");
2657 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2658 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2662 /// Select as many obligations as we can at present.
2663 fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2664 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2665 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2669 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2670 /// returns a type of `&T`, but the actual type we assign to the
2671 /// *expression* is `T`. So this function just peels off the return
2672 /// type by one layer to yield `T`.
2673 fn make_overloaded_place_return_type(&self,
2674 method: MethodCallee<'tcx>)
2675 -> ty::TypeAndMut<'tcx>
2677 // extract method return type, which will be &T;
2678 let ret_ty = method.sig.output();
2680 // method returns &T, but the type as visible to user is T, so deref
2681 ret_ty.builtin_deref(true).unwrap()
2687 base_expr: &'tcx hir::Expr,
2691 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2692 // FIXME(#18741) -- this is almost but not quite the same as the
2693 // autoderef that normal method probing does. They could likely be
2696 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2697 let mut result = None;
2698 while result.is_none() && autoderef.next().is_some() {
2699 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2701 autoderef.finalize(self);
2705 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2706 /// (and otherwise adjust) `base_expr`, looking for a type which either
2707 /// supports builtin indexing or overloaded indexing.
2708 /// This loop implements one step in that search; the autoderef loop
2709 /// is implemented by `lookup_indexing`.
2713 base_expr: &hir::Expr,
2714 autoderef: &Autoderef<'a, 'tcx>,
2717 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2718 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2719 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2726 for &unsize in &[false, true] {
2727 let mut self_ty = adjusted_ty;
2729 // We only unsize arrays here.
2730 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2731 self_ty = self.tcx.mk_slice(element_ty);
2737 // If some lookup succeeds, write callee into table and extract index/element
2738 // type from the method signature.
2739 // If some lookup succeeded, install method in table
2740 let input_ty = self.next_ty_var(TypeVariableOrigin {
2741 kind: TypeVariableOriginKind::AutoDeref,
2742 span: base_expr.span,
2744 let method = self.try_overloaded_place_op(
2745 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2747 let result = method.map(|ok| {
2748 debug!("try_index_step: success, using overloaded indexing");
2749 let method = self.register_infer_ok_obligations(ok);
2751 let mut adjustments = autoderef.adjust_steps(self, needs);
2752 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2753 let mutbl = match r_mutbl {
2754 hir::MutImmutable => AutoBorrowMutability::Immutable,
2755 hir::MutMutable => AutoBorrowMutability::Mutable {
2756 // Indexing can be desugared to a method call,
2757 // so maybe we could use two-phase here.
2758 // See the documentation of AllowTwoPhase for why that's
2759 // not the case today.
2760 allow_two_phase_borrow: AllowTwoPhase::No,
2763 adjustments.push(Adjustment {
2764 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2765 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2772 adjustments.push(Adjustment {
2773 kind: Adjust::Pointer(PointerCast::Unsize),
2774 target: method.sig.inputs()[0]
2777 self.apply_adjustments(base_expr, adjustments);
2779 self.write_method_call(expr.hir_id, method);
2780 (input_ty, self.make_overloaded_place_return_type(method).ty)
2782 if result.is_some() {
2790 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
2791 let (tr, name) = match (op, is_mut) {
2792 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
2793 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
2794 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
2795 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
2797 (tr, ast::Ident::with_empty_ctxt(name))
2800 fn try_overloaded_place_op(&self,
2803 arg_tys: &[Ty<'tcx>],
2806 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2808 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2814 // Try Mut first, if needed.
2815 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2816 let method = match (needs, mut_tr) {
2817 (Needs::MutPlace, Some(trait_did)) => {
2818 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2823 // Otherwise, fall back to the immutable version.
2824 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2825 let method = match (method, imm_tr) {
2826 (None, Some(trait_did)) => {
2827 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2829 (method, _) => method,
2835 fn check_method_argument_types(
2839 method: Result<MethodCallee<'tcx>, ()>,
2840 args_no_rcvr: &'tcx [hir::Expr],
2841 tuple_arguments: TupleArgumentsFlag,
2842 expected: Expectation<'tcx>,
2844 let has_error = match method {
2846 method.substs.references_error() || method.sig.references_error()
2851 let err_inputs = self.err_args(args_no_rcvr.len());
2853 let err_inputs = match tuple_arguments {
2854 DontTupleArguments => err_inputs,
2855 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
2858 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2859 false, tuple_arguments, None);
2860 return self.tcx.types.err;
2863 let method = method.unwrap();
2864 // HACK(eddyb) ignore self in the definition (see above).
2865 let expected_arg_tys = self.expected_inputs_for_expected_output(
2868 method.sig.output(),
2869 &method.sig.inputs()[1..]
2871 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2872 args_no_rcvr, method.sig.c_variadic, tuple_arguments,
2873 self.tcx.hir().span_if_local(method.def_id));
2877 fn self_type_matches_expected_vid(
2879 trait_ref: ty::PolyTraitRef<'tcx>,
2880 expected_vid: ty::TyVid,
2882 let self_ty = self.shallow_resolve(trait_ref.self_ty());
2884 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
2885 trait_ref, self_ty, expected_vid
2888 ty::Infer(ty::TyVar(found_vid)) => {
2889 // FIXME: consider using `sub_root_var` here so we
2890 // can see through subtyping.
2891 let found_vid = self.root_var(found_vid);
2892 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
2893 expected_vid == found_vid
2899 fn obligations_for_self_ty<'b>(
2902 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
2905 // FIXME: consider using `sub_root_var` here so we
2906 // can see through subtyping.
2907 let ty_var_root = self.root_var(self_ty);
2908 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
2909 self_ty, ty_var_root,
2910 self.fulfillment_cx.borrow().pending_obligations());
2914 .pending_obligations()
2916 .filter_map(move |obligation| match obligation.predicate {
2917 ty::Predicate::Projection(ref data) =>
2918 Some((data.to_poly_trait_ref(self.tcx), obligation)),
2919 ty::Predicate::Trait(ref data) =>
2920 Some((data.to_poly_trait_ref(), obligation)),
2921 ty::Predicate::Subtype(..) => None,
2922 ty::Predicate::RegionOutlives(..) => None,
2923 ty::Predicate::TypeOutlives(..) => None,
2924 ty::Predicate::WellFormed(..) => None,
2925 ty::Predicate::ObjectSafe(..) => None,
2926 ty::Predicate::ConstEvaluatable(..) => None,
2927 // N.B., this predicate is created by breaking down a
2928 // `ClosureType: FnFoo()` predicate, where
2929 // `ClosureType` represents some `Closure`. It can't
2930 // possibly be referring to the current closure,
2931 // because we haven't produced the `Closure` for
2932 // this closure yet; this is exactly why the other
2933 // code is looking for a self type of a unresolved
2934 // inference variable.
2935 ty::Predicate::ClosureKind(..) => None,
2936 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
2939 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
2940 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
2941 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
2945 /// Generic function that factors out common logic from function calls,
2946 /// method calls and overloaded operators.
2947 fn check_argument_types(
2951 fn_inputs: &[Ty<'tcx>],
2952 expected_arg_tys: &[Ty<'tcx>],
2953 args: &'tcx [hir::Expr],
2955 tuple_arguments: TupleArgumentsFlag,
2956 def_span: Option<Span>,
2960 // Grab the argument types, supplying fresh type variables
2961 // if the wrong number of arguments were supplied
2962 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2968 // All the input types from the fn signature must outlive the call
2969 // so as to validate implied bounds.
2970 for &fn_input_ty in fn_inputs {
2971 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2974 let expected_arg_count = fn_inputs.len();
2976 let param_count_error = |expected_count: usize,
2981 let mut err = tcx.sess.struct_span_err_with_code(sp,
2982 &format!("this function takes {}{} but {} {} supplied",
2983 if c_variadic { "at least " } else { "" },
2984 potentially_plural_count(expected_count, "parameter"),
2985 potentially_plural_count(arg_count, "parameter"),
2986 if arg_count == 1 {"was"} else {"were"}),
2987 DiagnosticId::Error(error_code.to_owned()));
2989 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
2990 err.span_label(def_s, "defined here");
2993 let sugg_span = tcx.sess.source_map().end_point(expr_sp);
2994 // remove closing `)` from the span
2995 let sugg_span = sugg_span.shrink_to_lo();
2996 err.span_suggestion(
2998 "expected the unit value `()`; create it with empty parentheses",
3000 Applicability::MachineApplicable);
3002 err.span_label(sp, format!("expected {}{}",
3003 if c_variadic { "at least " } else { "" },
3004 potentially_plural_count(expected_count, "parameter")));
3009 let mut expected_arg_tys = expected_arg_tys.to_vec();
3011 let formal_tys = if tuple_arguments == TupleArguments {
3012 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3013 match tuple_type.sty {
3014 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3015 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3016 expected_arg_tys = vec![];
3017 self.err_args(args.len())
3019 ty::Tuple(arg_types) => {
3020 expected_arg_tys = match expected_arg_tys.get(0) {
3021 Some(&ty) => match ty.sty {
3022 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3027 arg_types.iter().map(|k| k.expect_ty()).collect()
3030 span_err!(tcx.sess, sp, E0059,
3031 "cannot use call notation; the first type parameter \
3032 for the function trait is neither a tuple nor unit");
3033 expected_arg_tys = vec![];
3034 self.err_args(args.len())
3037 } else if expected_arg_count == supplied_arg_count {
3039 } else if c_variadic {
3040 if supplied_arg_count >= expected_arg_count {
3043 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3044 expected_arg_tys = vec![];
3045 self.err_args(supplied_arg_count)
3048 // is the missing argument of type `()`?
3049 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3050 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3051 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3052 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3056 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3058 expected_arg_tys = vec![];
3059 self.err_args(supplied_arg_count)
3062 debug!("check_argument_types: formal_tys={:?}",
3063 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3065 // If there is no expectation, expect formal_tys.
3066 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3072 // Check the arguments.
3073 // We do this in a pretty awful way: first we type-check any arguments
3074 // that are not closures, then we type-check the closures. This is so
3075 // that we have more information about the types of arguments when we
3076 // type-check the functions. This isn't really the right way to do this.
3077 for &check_closures in &[false, true] {
3078 debug!("check_closures={}", check_closures);
3080 // More awful hacks: before we check argument types, try to do
3081 // an "opportunistic" vtable resolution of any trait bounds on
3082 // the call. This helps coercions.
3084 self.select_obligations_where_possible(false);
3087 // For C-variadic functions, we don't have a declared type for all of
3088 // the arguments hence we only do our usual type checking with
3089 // the arguments who's types we do know.
3090 let t = if c_variadic {
3092 } else if tuple_arguments == TupleArguments {
3097 for (i, arg) in args.iter().take(t).enumerate() {
3098 // Warn only for the first loop (the "no closures" one).
3099 // Closure arguments themselves can't be diverging, but
3100 // a previous argument can, e.g., `foo(panic!(), || {})`.
3101 if !check_closures {
3102 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3105 let is_closure = match arg.node {
3106 ExprKind::Closure(..) => true,
3110 if is_closure != check_closures {
3114 debug!("checking the argument");
3115 let formal_ty = formal_tys[i];
3117 // The special-cased logic below has three functions:
3118 // 1. Provide as good of an expected type as possible.
3119 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3121 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3123 // 2. Coerce to the most detailed type that could be coerced
3124 // to, which is `expected_ty` if `rvalue_hint` returns an
3125 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3126 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3127 // We're processing function arguments so we definitely want to use
3128 // two-phase borrows.
3129 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3131 // 3. Relate the expected type and the formal one,
3132 // if the expected type was used for the coercion.
3133 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3137 // We also need to make sure we at least write the ty of the other
3138 // arguments which we skipped above.
3140 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3141 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3142 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3145 for arg in args.iter().skip(expected_arg_count) {
3146 let arg_ty = self.check_expr(&arg);
3148 // There are a few types which get autopromoted when passed via varargs
3149 // in C but we just error out instead and require explicit casts.
3150 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3152 ty::Float(ast::FloatTy::F32) => {
3153 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3155 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3156 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3158 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3159 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3162 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3163 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3164 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3172 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3173 vec![self.tcx.types.err; len]
3176 // AST fragment checking
3179 expected: Expectation<'tcx>)
3185 ast::LitKind::Str(..) => tcx.mk_static_str(),
3186 ast::LitKind::ByteStr(ref v) => {
3187 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3188 tcx.mk_array(tcx.types.u8, v.len() as u64))
3190 ast::LitKind::Byte(_) => tcx.types.u8,
3191 ast::LitKind::Char(_) => tcx.types.char,
3192 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3193 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3194 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3195 let opt_ty = expected.to_option(self).and_then(|ty| {
3197 ty::Int(_) | ty::Uint(_) => Some(ty),
3198 ty::Char => Some(tcx.types.u8),
3199 ty::RawPtr(..) => Some(tcx.types.usize),
3200 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3204 opt_ty.unwrap_or_else(|| self.next_int_var())
3206 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3207 ast::LitKind::FloatUnsuffixed(_) => {
3208 let opt_ty = expected.to_option(self).and_then(|ty| {
3210 ty::Float(_) => Some(ty),
3214 opt_ty.unwrap_or_else(|| self.next_float_var())
3216 ast::LitKind::Bool(_) => tcx.types.bool,
3217 ast::LitKind::Err(_) => tcx.types.err,
3221 fn check_expr_eq_type(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) {
3222 let ty = self.check_expr_with_hint(expr, expected);
3223 self.demand_eqtype(expr.span, expected, ty);
3226 pub fn check_expr_has_type_or_error(
3228 expr: &'tcx hir::Expr,
3231 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
3234 fn check_expr_meets_expectation_or_error(
3236 expr: &'tcx hir::Expr,
3237 expected: Expectation<'tcx>,
3239 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
3240 let mut ty = self.check_expr_with_expectation(expr, expected);
3242 // While we don't allow *arbitrary* coercions here, we *do* allow
3243 // coercions from ! to `expected`.
3245 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
3246 "expression with never type wound up being adjusted");
3247 let adj_ty = self.next_diverging_ty_var(
3248 TypeVariableOrigin {
3249 kind: TypeVariableOriginKind::AdjustmentType,
3253 self.apply_adjustments(expr, vec![Adjustment {
3254 kind: Adjust::NeverToAny,
3260 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
3261 let expr = match &expr.node {
3262 ExprKind::DropTemps(expr) => expr,
3265 // Error possibly reported in `check_assign` so avoid emitting error again.
3266 err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
3271 fn check_expr_coercable_to_type(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) -> Ty<'tcx> {
3272 let ty = self.check_expr_with_hint(expr, expected);
3273 // checks don't need two phase
3274 self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
3277 fn check_expr_with_hint(&self, expr: &'tcx hir::Expr, expected: Ty<'tcx>) -> Ty<'tcx> {
3278 self.check_expr_with_expectation(expr, ExpectHasType(expected))
3281 fn check_expr_with_expectation(
3283 expr: &'tcx hir::Expr,
3284 expected: Expectation<'tcx>,
3286 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
3289 fn check_expr(&self, expr: &'tcx hir::Expr) -> Ty<'tcx> {
3290 self.check_expr_with_expectation(expr, NoExpectation)
3293 fn check_expr_with_needs(&self, expr: &'tcx hir::Expr, needs: Needs) -> Ty<'tcx> {
3294 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
3297 // Determine the `Self` type, using fresh variables for all variables
3298 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3299 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3301 pub fn impl_self_ty(&self,
3302 span: Span, // (potential) receiver for this impl
3304 -> TypeAndSubsts<'tcx> {
3305 let ity = self.tcx.type_of(did);
3306 debug!("impl_self_ty: ity={:?}", ity);
3308 let substs = self.fresh_substs_for_item(span, did);
3309 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3311 TypeAndSubsts { substs: substs, ty: substd_ty }
3314 /// Unifies the output type with the expected type early, for more coercions
3315 /// and forward type information on the input expressions.
3316 fn expected_inputs_for_expected_output(&self,
3318 expected_ret: Expectation<'tcx>,
3319 formal_ret: Ty<'tcx>,
3320 formal_args: &[Ty<'tcx>])
3322 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3323 let ret_ty = match expected_ret.only_has_type(self) {
3325 None => return Vec::new()
3327 let expect_args = self.fudge_inference_if_ok(|| {
3328 // Attempt to apply a subtyping relationship between the formal
3329 // return type (likely containing type variables if the function
3330 // is polymorphic) and the expected return type.
3331 // No argument expectations are produced if unification fails.
3332 let origin = self.misc(call_span);
3333 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3335 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3336 // to identity so the resulting type is not constrained.
3339 // Process any obligations locally as much as
3340 // we can. We don't care if some things turn
3341 // out unconstrained or ambiguous, as we're
3342 // just trying to get hints here.
3343 self.save_and_restore_in_snapshot_flag(|_| {
3344 let mut fulfill = TraitEngine::new(self.tcx);
3345 for obligation in ok.obligations {
3346 fulfill.register_predicate_obligation(self, obligation);
3348 fulfill.select_where_possible(self)
3349 }).map_err(|_| ())?;
3351 Err(_) => return Err(()),
3354 // Record all the argument types, with the substitutions
3355 // produced from the above subtyping unification.
3356 Ok(formal_args.iter().map(|ty| {
3357 self.resolve_vars_if_possible(ty)
3359 }).unwrap_or_default();
3360 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3361 formal_args, formal_ret,
3362 expect_args, expected_ret);
3366 // Checks a method call.
3367 fn check_method_call(
3369 expr: &'tcx hir::Expr,
3370 segment: &hir::PathSegment,
3372 args: &'tcx [hir::Expr],
3373 expected: Expectation<'tcx>,
3376 let rcvr = &args[0];
3377 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
3378 // no need to check for bot/err -- callee does that
3379 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
3381 let method = match self.lookup_method(rcvr_t,
3387 self.write_method_call(expr.hir_id, method);
3391 if segment.ident.name != kw::Invalid {
3392 self.report_method_error(span,
3395 SelfSource::MethodCall(rcvr),
3403 // Call the generic checker.
3404 self.check_method_argument_types(span,
3412 fn check_return_expr(&self, return_expr: &'tcx hir::Expr) {
3416 .unwrap_or_else(|| span_bug!(return_expr.span,
3417 "check_return_expr called outside fn body"));
3419 let ret_ty = ret_coercion.borrow().expected_ty();
3420 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
3421 ret_coercion.borrow_mut()
3423 &self.cause(return_expr.span,
3424 ObligationCauseCode::ReturnType(return_expr.hir_id)),
3429 // Check field access expressions
3432 expr: &'tcx hir::Expr,
3434 base: &'tcx hir::Expr,
3437 let expr_t = self.check_expr_with_needs(base, needs);
3438 let expr_t = self.structurally_resolved_type(base.span,
3440 let mut private_candidate = None;
3441 let mut autoderef = self.autoderef(expr.span, expr_t);
3442 while let Some((base_t, _)) = autoderef.next() {
3444 ty::Adt(base_def, substs) if !base_def.is_enum() => {
3445 debug!("struct named {:?}", base_t);
3446 let (ident, def_scope) =
3447 self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
3448 let fields = &base_def.non_enum_variant().fields;
3449 if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
3450 let field = &fields[index];
3451 let field_ty = self.field_ty(expr.span, field, substs);
3452 // Save the index of all fields regardless of their visibility in case
3453 // of error recovery.
3454 self.write_field_index(expr.hir_id, index);
3455 if field.vis.is_accessible_from(def_scope, self.tcx) {
3456 let adjustments = autoderef.adjust_steps(self, needs);
3457 self.apply_adjustments(base, adjustments);
3458 autoderef.finalize(self);
3460 self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
3463 private_candidate = Some((base_def.did, field_ty));
3466 ty::Tuple(ref tys) => {
3467 let fstr = field.as_str();
3468 if let Ok(index) = fstr.parse::<usize>() {
3469 if fstr == index.to_string() {
3470 if let Some(field_ty) = tys.get(index) {
3471 let adjustments = autoderef.adjust_steps(self, needs);
3472 self.apply_adjustments(base, adjustments);
3473 autoderef.finalize(self);
3475 self.write_field_index(expr.hir_id, index);
3476 return field_ty.expect_ty();
3484 autoderef.unambiguous_final_ty(self);
3486 if let Some((did, field_ty)) = private_candidate {
3487 let struct_path = self.tcx().def_path_str(did);
3488 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3489 "field `{}` of struct `{}` is private",
3490 field, struct_path);
3491 // Also check if an accessible method exists, which is often what is meant.
3492 if self.method_exists(field, expr_t, expr.hir_id, false)
3493 && !self.expr_in_place(expr.hir_id)
3495 self.suggest_method_call(
3497 &format!("a method `{}` also exists, call it with parentheses", field),
3505 } else if field.name == kw::Invalid {
3506 self.tcx().types.err
3507 } else if self.method_exists(field, expr_t, expr.hir_id, true) {
3508 let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3509 "attempted to take value of method `{}` on type `{}`",
3512 if !self.expr_in_place(expr.hir_id) {
3513 self.suggest_method_call(
3515 "use parentheses to call the method",
3521 err.help("methods are immutable and cannot be assigned to");
3525 self.tcx().types.err
3527 if !expr_t.is_primitive_ty() {
3528 let mut err = self.no_such_field_err(field.span, field, expr_t);
3531 ty::Adt(def, _) if !def.is_enum() => {
3532 if let Some(suggested_field_name) =
3533 Self::suggest_field_name(def.non_enum_variant(),
3534 &field.as_str(), vec![]) {
3535 err.span_suggestion(
3537 "a field with a similar name exists",
3538 suggested_field_name.to_string(),
3539 Applicability::MaybeIncorrect,
3542 err.span_label(field.span, "unknown field");
3543 let struct_variant_def = def.non_enum_variant();
3544 let field_names = self.available_field_names(struct_variant_def);
3545 if !field_names.is_empty() {
3546 err.note(&format!("available fields are: {}",
3547 self.name_series_display(field_names)));
3551 ty::Array(_, len) => {
3552 if let (Some(len), Ok(user_index)) = (
3553 len.assert_usize(self.tcx),
3554 field.as_str().parse::<u64>()
3556 let base = self.tcx.sess.source_map()
3557 .span_to_snippet(base.span)
3559 self.tcx.hir().hir_to_pretty_string(base.hir_id));
3560 let help = "instead of using tuple indexing, use array indexing";
3561 let suggestion = format!("{}[{}]", base, field);
3562 let applicability = if len < user_index {
3563 Applicability::MachineApplicable
3565 Applicability::MaybeIncorrect
3567 err.span_suggestion(
3568 expr.span, help, suggestion, applicability
3573 let base = self.tcx.sess.source_map()
3574 .span_to_snippet(base.span)
3575 .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
3576 let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
3577 let suggestion = format!("(*{}).{}", base, field);
3578 err.span_suggestion(
3582 Applicability::MaybeIncorrect,
3589 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3590 "`{}` is a primitive type and therefore doesn't have fields",
3593 self.tcx().types.err
3597 // Return an hint about the closest match in field names
3598 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3600 skip: Vec<LocalInternedString>)
3602 let names = variant.fields.iter().filter_map(|field| {
3603 // ignore already set fields and private fields from non-local crates
3604 if skip.iter().any(|x| *x == field.ident.as_str()) ||
3605 (!variant.def_id.is_local() && field.vis != Visibility::Public)
3609 Some(&field.ident.name)
3613 find_best_match_for_name(names, field, None)
3616 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3617 variant.fields.iter().filter(|field| {
3619 self.tcx.adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id).1;
3620 field.vis.is_accessible_from(def_scope, self.tcx)
3622 .map(|field| field.ident.name)
3626 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3627 // dynamic limit, to never omit just one field
3628 let limit = if names.len() == 6 { 6 } else { 5 };
3629 let mut display = names.iter().take(limit)
3630 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3631 if names.len() > limit {
3632 display = format!("{} ... and {} others", display, names.len() - limit);
3637 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
3638 -> DiagnosticBuilder<'_> {
3639 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3640 "no field `{}` on type `{}`",
3644 fn report_unknown_field(
3647 variant: &'tcx ty::VariantDef,
3649 skip_fields: &[hir::Field],
3652 if variant.recovered {
3655 let mut err = self.type_error_struct_with_diag(
3657 |actual| match ty.sty {
3658 ty::Adt(adt, ..) if adt.is_enum() => {
3659 struct_span_err!(self.tcx.sess, field.ident.span, E0559,
3660 "{} `{}::{}` has no field named `{}`",
3661 kind_name, actual, variant.ident, field.ident)
3664 struct_span_err!(self.tcx.sess, field.ident.span, E0560,
3665 "{} `{}` has no field named `{}`",
3666 kind_name, actual, field.ident)
3670 // prevent all specified fields from being suggested
3671 let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
3672 if let Some(field_name) = Self::suggest_field_name(variant,
3673 &field.ident.as_str(),
3674 skip_fields.collect()) {
3675 err.span_suggestion(
3677 "a field with a similar name exists",
3678 field_name.to_string(),
3679 Applicability::MaybeIncorrect,
3683 ty::Adt(adt, ..) => {
3685 err.span_label(field.ident.span,
3686 format!("`{}::{}` does not have this field",
3687 ty, variant.ident));
3689 err.span_label(field.ident.span,
3690 format!("`{}` does not have this field", ty));
3692 let available_field_names = self.available_field_names(variant);
3693 if !available_field_names.is_empty() {
3694 err.note(&format!("available fields are: {}",
3695 self.name_series_display(available_field_names)));
3698 _ => bug!("non-ADT passed to report_unknown_field")
3704 fn check_expr_struct_fields(
3707 expected: Expectation<'tcx>,
3708 expr_id: hir::HirId,
3710 variant: &'tcx ty::VariantDef,
3711 ast_fields: &'tcx [hir::Field],
3712 check_completeness: bool,
3717 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3718 .get(0).cloned().unwrap_or(adt_ty);
3719 // re-link the regions that EIfEO can erase.
3720 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3722 let (substs, adt_kind, kind_name) = match &adt_ty.sty {
3723 &ty::Adt(adt, substs) => {
3724 (substs, adt.adt_kind(), adt.variant_descr())
3726 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3729 let mut remaining_fields = variant.fields.iter().enumerate().map(|(i, field)|
3730 (field.ident.modern(), (i, field))
3731 ).collect::<FxHashMap<_, _>>();
3733 let mut seen_fields = FxHashMap::default();
3735 let mut error_happened = false;
3737 // Type-check each field.
3738 for field in ast_fields {
3739 let ident = tcx.adjust_ident(field.ident, variant.def_id);
3740 let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
3741 seen_fields.insert(ident, field.span);
3742 self.write_field_index(field.hir_id, i);
3744 // We don't look at stability attributes on
3745 // struct-like enums (yet...), but it's definitely not
3746 // a bug to have constructed one.
3747 if adt_kind != AdtKind::Enum {
3748 tcx.check_stability(v_field.did, Some(expr_id), field.span);
3751 self.field_ty(field.span, v_field, substs)
3753 error_happened = true;
3754 if let Some(prev_span) = seen_fields.get(&ident) {
3755 let mut err = struct_span_err!(self.tcx.sess,
3758 "field `{}` specified more than once",
3761 err.span_label(field.ident.span, "used more than once");
3762 err.span_label(*prev_span, format!("first use of `{}`", ident));
3766 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3772 // Make sure to give a type to the field even if there's
3773 // an error, so we can continue type-checking.
3774 self.check_expr_coercable_to_type(&field.expr, field_type);
3777 // Make sure the programmer specified correct number of fields.
3778 if kind_name == "union" {
3779 if ast_fields.len() != 1 {
3780 tcx.sess.span_err(span, "union expressions should have exactly one field");
3782 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3783 let len = remaining_fields.len();
3785 let mut displayable_field_names = remaining_fields
3787 .map(|ident| ident.as_str())
3788 .collect::<Vec<_>>();
3790 displayable_field_names.sort();
3792 let truncated_fields_error = if len <= 3 {
3795 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3798 let remaining_fields_names = displayable_field_names.iter().take(3)
3799 .map(|n| format!("`{}`", n))
3800 .collect::<Vec<_>>()
3803 struct_span_err!(tcx.sess, span, E0063,
3804 "missing field{} {}{} in initializer of `{}`",
3805 if remaining_fields.len() == 1 { "" } else { "s" },
3806 remaining_fields_names,
3807 truncated_fields_error,
3809 .span_label(span, format!("missing {}{}",
3810 remaining_fields_names,
3811 truncated_fields_error))
3817 fn check_struct_fields_on_error(
3819 fields: &'tcx [hir::Field],
3820 base_expr: &'tcx Option<P<hir::Expr>>,
3822 for field in fields {
3823 self.check_expr(&field.expr);
3825 if let Some(ref base) = *base_expr {
3826 self.check_expr(&base);
3830 pub fn check_struct_path(&self,
3833 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3834 let path_span = match *qpath {
3835 QPath::Resolved(_, ref path) => path.span,
3836 QPath::TypeRelative(ref qself, _) => qself.span
3838 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3839 let variant = match def {
3841 self.set_tainted_by_errors();
3844 Res::Def(DefKind::Variant, _) => {
3846 ty::Adt(adt, substs) => {
3847 Some((adt.variant_of_res(def), adt.did, substs))
3849 _ => bug!("unexpected type: {:?}", ty)
3852 Res::Def(DefKind::Struct, _)
3853 | Res::Def(DefKind::Union, _)
3854 | Res::Def(DefKind::TyAlias, _)
3855 | Res::Def(DefKind::AssocTy, _)
3856 | Res::SelfTy(..) => {
3858 ty::Adt(adt, substs) if !adt.is_enum() => {
3859 Some((adt.non_enum_variant(), adt.did, substs))
3864 _ => bug!("unexpected definition: {:?}", def)
3867 if let Some((variant, did, substs)) = variant {
3868 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3869 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3871 // Check bounds on type arguments used in the path.
3872 let bounds = self.instantiate_bounds(path_span, did, substs);
3873 let cause = traits::ObligationCause::new(path_span, self.body_id,
3874 traits::ItemObligation(did));
3875 self.add_obligations_for_parameters(cause, &bounds);
3879 struct_span_err!(self.tcx.sess, path_span, E0071,
3880 "expected struct, variant or union type, found {}",
3881 ty.sort_string(self.tcx))
3882 .span_label(path_span, "not a struct")
3888 fn check_expr_struct(
3891 expected: Expectation<'tcx>,
3893 fields: &'tcx [hir::Field],
3894 base_expr: &'tcx Option<P<hir::Expr>>,
3896 // Find the relevant variant
3897 let (variant, adt_ty) =
3898 if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id) {
3901 self.check_struct_fields_on_error(fields, base_expr);
3902 return self.tcx.types.err;
3905 let path_span = match *qpath {
3906 QPath::Resolved(_, ref path) => path.span,
3907 QPath::TypeRelative(ref qself, _) => qself.span
3910 // Prohibit struct expressions when non-exhaustive flag is set.
3911 let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
3912 if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
3913 span_err!(self.tcx.sess, expr.span, E0639,
3914 "cannot create non-exhaustive {} using struct expression",
3915 adt.variant_descr());
3918 let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.hir_id, path_span,
3919 variant, fields, base_expr.is_none());
3920 if let &Some(ref base_expr) = base_expr {
3921 // If check_expr_struct_fields hit an error, do not attempt to populate
3922 // the fields with the base_expr. This could cause us to hit errors later
3923 // when certain fields are assumed to exist that in fact do not.
3924 if !error_happened {
3925 self.check_expr_has_type_or_error(base_expr, adt_ty);
3927 ty::Adt(adt, substs) if adt.is_struct() => {
3928 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3929 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3934 .fru_field_types_mut()
3935 .insert(expr.hir_id, fru_field_types);
3938 span_err!(self.tcx.sess, base_expr.span, E0436,
3939 "functional record update syntax requires a struct");
3944 self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
3950 /// If an expression has any sub-expressions that result in a type error,
3951 /// inspecting that expression's type with `ty.references_error()` will return
3952 /// true. Likewise, if an expression is known to diverge, inspecting its
3953 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3954 /// strict, _|_ can appear in the type of an expression that does not,
3955 /// itself, diverge: for example, fn() -> _|_.)
3956 /// Note that inspecting a type's structure *directly* may expose the fact
3957 /// that there are actually multiple representations for `Error`, so avoid
3958 /// that when err needs to be handled differently.
3959 fn check_expr_with_expectation_and_needs(
3961 expr: &'tcx hir::Expr,
3962 expected: Expectation<'tcx>,
3965 debug!(">> type-checking: expr={:?} expected={:?}",
3968 // Warn for expressions after diverging siblings.
3969 self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
3971 // Hide the outer diverging and has_errors flags.
3972 let old_diverges = self.diverges.get();
3973 let old_has_errors = self.has_errors.get();
3974 self.diverges.set(Diverges::Maybe);
3975 self.has_errors.set(false);
3977 let ty = self.check_expr_kind(expr, expected, needs);
3979 // Warn for non-block expressions with diverging children.
3981 ExprKind::Block(..) |
3982 ExprKind::Loop(..) | ExprKind::While(..) |
3983 ExprKind::Match(..) => {}
3985 _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression")
3988 // Any expression that produces a value of type `!` must have diverged
3990 self.diverges.set(self.diverges.get() | Diverges::Always);
3993 // Record the type, which applies it effects.
3994 // We need to do this after the warning above, so that
3995 // we don't warn for the diverging expression itself.
3996 self.write_ty(expr.hir_id, ty);
3998 // Combine the diverging and has_error flags.
3999 self.diverges.set(self.diverges.get() | old_diverges);
4000 self.has_errors.set(self.has_errors.get() | old_has_errors);
4002 debug!("type of {} is...", self.tcx.hir().hir_to_string(expr.hir_id));
4003 debug!("... {:?}, expected is {:?}", ty, expected);
4010 expr: &'tcx hir::Expr,
4011 expected: Expectation<'tcx>,
4015 "check_expr_kind(expr={:?}, expected={:?}, needs={:?})",
4022 let id = expr.hir_id;
4024 ExprKind::Box(ref subexpr) => {
4025 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
4027 ty::Adt(def, _) if def.is_box()
4028 => Expectation::rvalue_hint(self, ty.boxed_ty()),
4032 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
4033 tcx.mk_box(referent_ty)
4036 ExprKind::Lit(ref lit) => {
4037 self.check_lit(&lit, expected)
4039 ExprKind::Binary(op, ref lhs, ref rhs) => {
4040 self.check_binop(expr, op, lhs, rhs)
4042 ExprKind::AssignOp(op, ref lhs, ref rhs) => {
4043 self.check_binop_assign(expr, op, lhs, rhs)
4045 ExprKind::Unary(unop, ref oprnd) => {
4046 let expected_inner = match unop {
4047 hir::UnNot | hir::UnNeg => {
4054 let needs = match unop {
4055 hir::UnDeref => needs,
4058 let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
4062 if !oprnd_t.references_error() {
4063 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
4066 if let Some(mt) = oprnd_t.builtin_deref(true) {
4068 } else if let Some(ok) = self.try_overloaded_deref(
4069 expr.span, oprnd_t, needs) {
4070 let method = self.register_infer_ok_obligations(ok);
4071 if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
4072 let mutbl = match mutbl {
4073 hir::MutImmutable => AutoBorrowMutability::Immutable,
4074 hir::MutMutable => AutoBorrowMutability::Mutable {
4075 // (It shouldn't actually matter for unary ops whether
4076 // we enable two-phase borrows or not, since a unary
4077 // op has no additional operands.)
4078 allow_two_phase_borrow: AllowTwoPhase::No,
4081 self.apply_adjustments(oprnd, vec![Adjustment {
4082 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
4083 target: method.sig.inputs()[0]
4086 oprnd_t = self.make_overloaded_place_return_type(method).ty;
4087 self.write_method_call(expr.hir_id, method);
4089 let mut err = type_error_struct!(
4094 "type `{}` cannot be dereferenced",
4097 let sp = tcx.sess.source_map().start_point(expr.span);
4098 if let Some(sp) = tcx.sess.parse_sess.ambiguous_block_expr_parse
4101 tcx.sess.parse_sess.expr_parentheses_needed(
4108 oprnd_t = tcx.types.err;
4112 let result = self.check_user_unop(expr, oprnd_t, unop);
4113 // If it's builtin, we can reuse the type, this helps inference.
4114 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::Bool) {
4119 let result = self.check_user_unop(expr, oprnd_t, unop);
4120 // If it's builtin, we can reuse the type, this helps inference.
4121 if !oprnd_t.is_numeric() {
4129 ExprKind::AddrOf(mutbl, ref oprnd) => {
4130 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
4132 ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
4133 if oprnd.is_place_expr() {
4134 // Places may legitimately have unsized types.
4135 // For example, dereferences of a fat pointer and
4136 // the last field of a struct can be unsized.
4139 Expectation::rvalue_hint(self, ty)
4145 let needs = Needs::maybe_mut_place(mutbl);
4146 let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
4148 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
4149 if tm.ty.references_error() {
4152 // Note: at this point, we cannot say what the best lifetime
4153 // is to use for resulting pointer. We want to use the
4154 // shortest lifetime possible so as to avoid spurious borrowck
4155 // errors. Moreover, the longest lifetime will depend on the
4156 // precise details of the value whose address is being taken
4157 // (and how long it is valid), which we don't know yet until type
4158 // inference is complete.
4160 // Therefore, here we simply generate a region variable. The
4161 // region inferencer will then select the ultimate value.
4162 // Finally, borrowck is charged with guaranteeing that the
4163 // value whose address was taken can actually be made to live
4164 // as long as it needs to live.
4165 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
4166 tcx.mk_ref(region, tm)
4169 ExprKind::Path(ref qpath) => {
4170 let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id,
4172 let ty = match res {
4174 self.set_tainted_by_errors();
4177 Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
4178 report_unexpected_variant_res(tcx, res, expr.span, qpath);
4181 _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, id).0,
4184 if let ty::FnDef(..) = ty.sty {
4185 let fn_sig = ty.fn_sig(tcx);
4186 if !tcx.features().unsized_locals {
4187 // We want to remove some Sized bounds from std functions,
4188 // but don't want to expose the removal to stable Rust.
4189 // i.e., we don't want to allow
4195 // to work in stable even if the Sized bound on `drop` is relaxed.
4196 for i in 0..fn_sig.inputs().skip_binder().len() {
4197 // We just want to check sizedness, so instead of introducing
4198 // placeholder lifetimes with probing, we just replace higher lifetimes
4200 let input = self.replace_bound_vars_with_fresh_vars(
4202 infer::LateBoundRegionConversionTime::FnCall,
4203 &fn_sig.input(i)).0;
4204 self.require_type_is_sized_deferred(input, expr.span,
4205 traits::SizedArgumentType);
4208 // Here we want to prevent struct constructors from returning unsized types.
4209 // There were two cases this happened: fn pointer coercion in stable
4210 // and usual function call in presense of unsized_locals.
4211 // Also, as we just want to check sizedness, instead of introducing
4212 // placeholder lifetimes with probing, we just replace higher lifetimes
4214 let output = self.replace_bound_vars_with_fresh_vars(
4216 infer::LateBoundRegionConversionTime::FnCall,
4217 &fn_sig.output()).0;
4218 self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
4221 // We always require that the type provided as the value for
4222 // a type parameter outlives the moment of instantiation.
4223 let substs = self.tables.borrow().node_substs(expr.hir_id);
4224 self.add_wf_bounds(substs, expr);
4228 ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
4229 for expr in outputs.iter().chain(inputs.iter()) {
4230 self.check_expr(expr);
4234 ExprKind::Break(destination, ref expr_opt) => {
4235 if let Ok(target_id) = destination.target_id {
4237 if let Some(ref e) = *expr_opt {
4238 // If this is a break with a value, we need to type-check
4239 // the expression. Get an expected type from the loop context.
4240 let opt_coerce_to = {
4241 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4242 enclosing_breakables.find_breakable(target_id)
4245 .map(|coerce| coerce.expected_ty())
4248 // If the loop context is not a `loop { }`, then break with
4249 // a value is illegal, and `opt_coerce_to` will be `None`.
4250 // Just set expectation to error in that case.
4251 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
4253 // Recurse without `enclosing_breakables` borrowed.
4254 e_ty = self.check_expr_with_hint(e, coerce_to);
4255 cause = self.misc(e.span);
4257 // Otherwise, this is a break *without* a value. That's
4258 // always legal, and is equivalent to `break ()`.
4259 e_ty = tcx.mk_unit();
4260 cause = self.misc(expr.span);
4263 // Now that we have type-checked `expr_opt`, borrow
4264 // the `enclosing_loops` field and let's coerce the
4265 // type of `expr_opt` into what is expected.
4266 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4267 let ctxt = enclosing_breakables.find_breakable(target_id);
4268 if let Some(ref mut coerce) = ctxt.coerce {
4269 if let Some(ref e) = *expr_opt {
4270 coerce.coerce(self, &cause, e, e_ty);
4272 assert!(e_ty.is_unit());
4273 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
4276 // If `ctxt.coerce` is `None`, we can just ignore
4277 // the type of the expresison. This is because
4278 // either this was a break *without* a value, in
4279 // which case it is always a legal type (`()`), or
4280 // else an error would have been flagged by the
4281 // `loops` pass for using break with an expression
4282 // where you are not supposed to.
4283 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
4286 ctxt.may_break = true;
4288 // the type of a `break` is always `!`, since it diverges
4291 // Otherwise, we failed to find the enclosing loop;
4292 // this can only happen if the `break` was not
4293 // inside a loop at all, which is caught by the
4294 // loop-checking pass.
4295 if self.tcx.sess.err_count() == 0 {
4296 self.tcx.sess.delay_span_bug(expr.span,
4297 "break was outside loop, but no error was emitted");
4300 // We still need to assign a type to the inner expression to
4301 // prevent the ICE in #43162.
4302 if let Some(ref e) = *expr_opt {
4303 self.check_expr_with_hint(e, tcx.types.err);
4305 // ... except when we try to 'break rust;'.
4306 // ICE this expression in particular (see #43162).
4307 if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
4308 if path.segments.len() == 1 &&
4309 path.segments[0].ident.name == sym::rust {
4310 fatally_break_rust(self.tcx.sess);
4314 // There was an error; make type-check fail.
4319 ExprKind::Continue(destination) => {
4320 if destination.target_id.is_ok() {
4323 // There was an error; make type-check fail.
4327 ExprKind::Ret(ref expr_opt) => {
4328 if self.ret_coercion.is_none() {
4329 struct_span_err!(self.tcx.sess, expr.span, E0572,
4330 "return statement outside of function body").emit();
4331 } else if let Some(ref e) = *expr_opt {
4332 if self.ret_coercion_span.borrow().is_none() {
4333 *self.ret_coercion_span.borrow_mut() = Some(e.span);
4335 self.check_return_expr(e);
4337 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
4338 if self.ret_coercion_span.borrow().is_none() {
4339 *self.ret_coercion_span.borrow_mut() = Some(expr.span);
4341 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
4342 if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
4343 coercion.coerce_forced_unit(
4348 fn_decl.output.span(),
4350 "expected `{}` because of this return type",
4358 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
4363 ExprKind::Assign(ref lhs, ref rhs) => {
4364 self.check_assign(expr, expected, lhs, rhs)
4366 ExprKind::While(ref cond, ref body, _) => {
4367 let ctxt = BreakableCtxt {
4368 // cannot use break with a value from a while loop
4370 may_break: false, // Will get updated if/when we find a `break`.
4373 let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
4374 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
4375 let cond_diverging = self.diverges.get();
4376 self.check_block_no_value(&body);
4378 // We may never reach the body so it diverging means nothing.
4379 self.diverges.set(cond_diverging);
4383 // No way to know whether it's diverging because
4384 // of a `break` or an outer `break` or `return`.
4385 self.diverges.set(Diverges::Maybe);
4390 ExprKind::Loop(ref body, _, source) => {
4391 let coerce = match source {
4392 // you can only use break with a value from a normal `loop { }`
4393 hir::LoopSource::Loop => {
4394 let coerce_to = expected.coercion_target_type(self, body.span);
4395 Some(CoerceMany::new(coerce_to))
4398 hir::LoopSource::WhileLet |
4399 hir::LoopSource::ForLoop => {
4404 let ctxt = BreakableCtxt {
4406 may_break: false, // Will get updated if/when we find a `break`.
4409 let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
4410 self.check_block_no_value(&body);
4414 // No way to know whether it's diverging because
4415 // of a `break` or an outer `break` or `return`.
4416 self.diverges.set(Diverges::Maybe);
4419 // If we permit break with a value, then result type is
4420 // the LUB of the breaks (possibly ! if none); else, it
4421 // is nil. This makes sense because infinite loops
4422 // (which would have type !) are only possible iff we
4423 // permit break with a value [1].
4424 if ctxt.coerce.is_none() && !ctxt.may_break {
4426 self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
4428 ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
4430 ExprKind::Match(ref discrim, ref arms, match_src) => {
4431 self.check_match(expr, &discrim, arms, expected, match_src)
4433 ExprKind::Closure(capture, ref decl, body_id, _, gen) => {
4434 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
4436 ExprKind::Block(ref body, _) => {
4437 self.check_block_with_expected(&body, expected)
4439 ExprKind::Call(ref callee, ref args) => {
4440 self.check_call(expr, &callee, args, expected)
4442 ExprKind::MethodCall(ref segment, span, ref args) => {
4443 self.check_method_call(expr, segment, span, args, expected, needs)
4445 ExprKind::Cast(ref e, ref t) => {
4446 // Find the type of `e`. Supply hints based on the type we are casting to,
4448 let t_cast = self.to_ty_saving_user_provided_ty(t);
4449 let t_cast = self.resolve_vars_if_possible(&t_cast);
4450 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
4451 let t_cast = self.resolve_vars_if_possible(&t_cast);
4453 // Eagerly check for some obvious errors.
4454 if t_expr.references_error() || t_cast.references_error() {
4457 // Defer other checks until we're done type checking.
4458 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
4459 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
4461 deferred_cast_checks.push(cast_check);
4464 Err(ErrorReported) => {
4470 ExprKind::Type(ref e, ref t) => {
4471 let ty = self.to_ty_saving_user_provided_ty(&t);
4472 self.check_expr_eq_type(&e, ty);
4475 ExprKind::DropTemps(ref e) => {
4476 self.check_expr_with_expectation(e, expected)
4478 ExprKind::Array(ref args) => {
4479 let uty = expected.to_option(self).and_then(|uty| {
4481 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4486 let element_ty = if !args.is_empty() {
4487 let coerce_to = uty.unwrap_or_else(|| {
4488 self.next_ty_var(TypeVariableOrigin {
4489 kind: TypeVariableOriginKind::TypeInference,
4493 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
4494 assert_eq!(self.diverges.get(), Diverges::Maybe);
4496 let e_ty = self.check_expr_with_hint(e, coerce_to);
4497 let cause = self.misc(e.span);
4498 coerce.coerce(self, &cause, e, e_ty);
4500 coerce.complete(self)
4502 self.next_ty_var(TypeVariableOrigin {
4503 kind: TypeVariableOriginKind::TypeInference,
4507 tcx.mk_array(element_ty, args.len() as u64)
4509 ExprKind::Repeat(ref element, ref count) => {
4510 let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
4511 let count = if self.const_param_def_id(count).is_some() {
4512 Ok(self.to_const(count, self.tcx.type_of(count_def_id)))
4514 let param_env = ty::ParamEnv::empty();
4515 let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
4516 let instance = ty::Instance::resolve(
4522 let global_id = GlobalId {
4527 tcx.const_eval(param_env.and(global_id))
4530 let uty = match expected {
4531 ExpectHasType(uty) => {
4533 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4540 let (element_ty, t) = match uty {
4542 self.check_expr_coercable_to_type(&element, uty);
4546 let ty = self.next_ty_var(TypeVariableOrigin {
4547 kind: TypeVariableOriginKind::MiscVariable,
4550 let element_ty = self.check_expr_has_type_or_error(&element, ty);
4555 if let Ok(count) = count {
4556 let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
4558 // For [foo, ..n] where n > 1, `foo` must have
4560 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4561 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4565 if element_ty.references_error() {
4567 } else if let Ok(count) = count {
4568 tcx.mk_ty(ty::Array(t, count))
4573 ExprKind::Tup(ref elts) => {
4574 let flds = expected.only_has_type(self).and_then(|ty| {
4575 let ty = self.resolve_type_vars_with_obligations(ty);
4577 ty::Tuple(ref flds) => Some(&flds[..]),
4582 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4583 let t = match flds {
4584 Some(ref fs) if i < fs.len() => {
4585 let ety = fs[i].expect_ty();
4586 self.check_expr_coercable_to_type(&e, ety);
4590 self.check_expr_with_expectation(&e, NoExpectation)
4595 let tuple = tcx.mk_tup(elt_ts_iter);
4596 if tuple.references_error() {
4599 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4603 ExprKind::Struct(ref qpath, ref fields, ref base_expr) => {
4604 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4606 ExprKind::Field(ref base, field) => {
4607 self.check_field(expr, needs, &base, field)
4609 ExprKind::Index(ref base, ref idx) => {
4610 let base_t = self.check_expr_with_needs(&base, needs);
4611 let idx_t = self.check_expr(&idx);
4613 if base_t.references_error() {
4615 } else if idx_t.references_error() {
4618 let base_t = self.structurally_resolved_type(base.span, base_t);
4619 match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
4620 Some((index_ty, element_ty)) => {
4621 // two-phase not needed because index_ty is never mutable
4622 self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
4627 type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4628 "cannot index into a value of type `{}`",
4630 // Try to give some advice about indexing tuples.
4631 if let ty::Tuple(..) = base_t.sty {
4632 let mut needs_note = true;
4633 // If the index is an integer, we can show the actual
4634 // fixed expression:
4635 if let ExprKind::Lit(ref lit) = idx.node {
4636 if let ast::LitKind::Int(i,
4637 ast::LitIntType::Unsuffixed) = lit.node {
4638 let snip = tcx.sess.source_map().span_to_snippet(base.span);
4639 if let Ok(snip) = snip {
4640 err.span_suggestion(
4642 "to access tuple elements, use",
4643 format!("{}.{}", snip, i),
4644 Applicability::MachineApplicable,
4651 err.help("to access tuple elements, use tuple indexing \
4652 syntax (e.g., `tuple.0`)");
4661 ExprKind::Yield(ref value) => {
4662 match self.yield_ty {
4664 self.check_expr_coercable_to_type(&value, ty);
4667 struct_span_err!(self.tcx.sess, expr.span, E0627,
4668 "yield statement outside of generator literal").emit();
4673 hir::ExprKind::Err => {
4679 /// Type check assignment expression `expr` of form `lhs = rhs`.
4680 /// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
4683 expr: &'tcx hir::Expr,
4684 expected: Expectation<'tcx>,
4685 lhs: &'tcx hir::Expr,
4686 rhs: &'tcx hir::Expr,
4688 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
4689 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
4691 let expected_ty = expected.coercion_target_type(self, expr.span);
4692 if expected_ty == self.tcx.types.bool {
4693 // The expected type is `bool` but this will result in `()` so we can reasonably
4694 // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
4695 // The likely cause of this is `if foo = bar { .. }`.
4696 let actual_ty = self.tcx.mk_unit();
4697 let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
4698 let msg = "try comparing for equality";
4699 let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
4700 let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
4701 if let (Ok(left), Ok(right)) = (left, right) {
4702 let help = format!("{} == {}", left, right);
4703 err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
4708 } else if !lhs.is_place_expr() {
4709 struct_span_err!(self.tcx.sess, expr.span, E0070,
4710 "invalid left-hand side expression")
4711 .span_label(expr.span, "left-hand of expression not valid")
4715 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
4717 if lhs_ty.references_error() || rhs_ty.references_error() {
4724 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4725 // The newly resolved definition is written into `type_dependent_defs`.
4726 fn finish_resolving_struct_path(&self,
4733 QPath::Resolved(ref maybe_qself, ref path) => {
4734 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4735 let ty = AstConv::res_to_ty(self, self_ty, path, true);
4738 QPath::TypeRelative(ref qself, ref segment) => {
4739 let ty = self.to_ty(qself);
4741 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
4746 let result = AstConv::associated_path_to_ty(
4755 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
4756 let result = result.map(|(_, kind, def_id)| (kind, def_id));
4758 // Write back the new resolution.
4759 self.write_resolution(hir_id, result);
4761 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
4766 /// Resolves associated value path into a base type and associated constant or method
4767 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
4768 pub fn resolve_ty_and_res_ufcs<'b>(&self,
4772 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4774 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
4775 let (ty, qself, item_segment) = match *qpath {
4776 QPath::Resolved(ref opt_qself, ref path) => {
4778 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4779 &path.segments[..]);
4781 QPath::TypeRelative(ref qself, ref segment) => {
4782 (self.to_ty(qself), qself, segment)
4785 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4786 // Return directly on cache hit. This is useful to avoid doubly reporting
4787 // errors with default match binding modes. See #44614.
4788 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
4789 .unwrap_or(Res::Err);
4790 return (def, Some(ty), slice::from_ref(&**item_segment));
4792 let item_name = item_segment.ident;
4793 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
4794 let result = match error {
4795 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
4796 _ => Err(ErrorReported),
4798 if item_name.name != kw::Invalid {
4799 self.report_method_error(
4803 SelfSource::QPath(qself),
4811 // Write back the new resolution.
4812 self.write_resolution(hir_id, result);
4814 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
4816 slice::from_ref(&**item_segment),
4820 pub fn check_decl_initializer(
4822 local: &'tcx hir::Local,
4823 init: &'tcx hir::Expr,
4825 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4826 // for #42640 (default match binding modes).
4829 let ref_bindings = local.pat.contains_explicit_ref_binding();
4831 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
4832 if let Some(m) = ref_bindings {
4833 // Somewhat subtle: if we have a `ref` binding in the pattern,
4834 // we want to avoid introducing coercions for the RHS. This is
4835 // both because it helps preserve sanity and, in the case of
4836 // ref mut, for soundness (issue #23116). In particular, in
4837 // the latter case, we need to be clear that the type of the
4838 // referent for the reference that results is *equal to* the
4839 // type of the place it is referencing, and not some
4840 // supertype thereof.
4841 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4842 self.demand_eqtype(init.span, local_ty, init_ty);
4845 self.check_expr_coercable_to_type(init, local_ty)
4849 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
4850 let t = self.local_ty(local.span, local.hir_id).decl_ty;
4851 self.write_ty(local.hir_id, t);
4853 if let Some(ref init) = local.init {
4854 let init_ty = self.check_decl_initializer(local, &init);
4855 if init_ty.references_error() {
4856 self.write_ty(local.hir_id, init_ty);
4860 self.check_pat_walk(
4863 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4866 let pat_ty = self.node_ty(local.pat.hir_id);
4867 if pat_ty.references_error() {
4868 self.write_ty(local.hir_id, pat_ty);
4872 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
4873 // Don't do all the complex logic below for `DeclItem`.
4875 hir::StmtKind::Item(..) => return,
4876 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4879 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
4881 // Hide the outer diverging and `has_errors` flags.
4882 let old_diverges = self.diverges.get();
4883 let old_has_errors = self.has_errors.get();
4884 self.diverges.set(Diverges::Maybe);
4885 self.has_errors.set(false);
4888 hir::StmtKind::Local(ref l) => {
4889 self.check_decl_local(&l);
4892 hir::StmtKind::Item(_) => {}
4893 hir::StmtKind::Expr(ref expr) => {
4894 // Check with expected type of `()`.
4895 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
4897 hir::StmtKind::Semi(ref expr) => {
4898 self.check_expr(&expr);
4902 // Combine the diverging and `has_error` flags.
4903 self.diverges.set(self.diverges.get() | old_diverges);
4904 self.has_errors.set(self.has_errors.get() | old_has_errors);
4907 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
4908 let unit = self.tcx.mk_unit();
4909 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4911 // if the block produces a `!` value, that can always be
4912 // (effectively) coerced to unit.
4914 self.demand_suptype(blk.span, unit, ty);
4918 fn check_block_with_expected(
4920 blk: &'tcx hir::Block,
4921 expected: Expectation<'tcx>,
4924 let mut fcx_ps = self.ps.borrow_mut();
4925 let unsafety_state = fcx_ps.recurse(blk);
4926 replace(&mut *fcx_ps, unsafety_state)
4929 // In some cases, blocks have just one exit, but other blocks
4930 // can be targeted by multiple breaks. This can happen both
4931 // with labeled blocks as well as when we desugar
4932 // a `try { ... }` expression.
4936 // 'a: { if true { break 'a Err(()); } Ok(()) }
4938 // Here we would wind up with two coercions, one from
4939 // `Err(())` and the other from the tail expression
4940 // `Ok(())`. If the tail expression is omitted, that's a
4941 // "forced unit" -- unless the block diverges, in which
4942 // case we can ignore the tail expression (e.g., `'a: {
4943 // break 'a 22; }` would not force the type of the block
4945 let tail_expr = blk.expr.as_ref();
4946 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4947 let coerce = if blk.targeted_by_break {
4948 CoerceMany::new(coerce_to_ty)
4950 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4951 Some(e) => slice::from_ref(e),
4954 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4957 let prev_diverges = self.diverges.get();
4958 let ctxt = BreakableCtxt {
4959 coerce: Some(coerce),
4963 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4964 for s in &blk.stmts {
4968 // check the tail expression **without** holding the
4969 // `enclosing_breakables` lock below.
4970 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4972 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4973 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4974 let coerce = ctxt.coerce.as_mut().unwrap();
4975 if let Some(tail_expr_ty) = tail_expr_ty {
4976 let tail_expr = tail_expr.unwrap();
4977 let cause = self.cause(tail_expr.span,
4978 ObligationCauseCode::BlockTailExpression(blk.hir_id));
4984 // Subtle: if there is no explicit tail expression,
4985 // that is typically equivalent to a tail expression
4986 // of `()` -- except if the block diverges. In that
4987 // case, there is no value supplied from the tail
4988 // expression (assuming there are no other breaks,
4989 // this implies that the type of the block will be
4992 // #41425 -- label the implicit `()` as being the
4993 // "found type" here, rather than the "expected type".
4994 if !self.diverges.get().always() {
4995 // #50009 -- Do not point at the entire fn block span, point at the return type
4996 // span, as it is the cause of the requirement, and
4997 // `consider_hint_about_removing_semicolon` will point at the last expression
4998 // if it were a relevant part of the error. This improves usability in editors
4999 // that highlight errors inline.
5000 let mut sp = blk.span;
5001 let mut fn_span = None;
5002 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
5003 let ret_sp = decl.output.span();
5004 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
5005 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
5006 // output would otherwise be incorrect and even misleading. Make sure
5007 // the span we're aiming at correspond to a `fn` body.
5008 if block_sp == blk.span {
5010 fn_span = Some(ident.span);
5014 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
5015 if let Some(expected_ty) = expected.only_has_type(self) {
5016 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
5018 if let Some(fn_span) = fn_span {
5019 err.span_label(fn_span, "this function's body doesn't return");
5027 // If we can break from the block, then the block's exit is always reachable
5028 // (... as long as the entry is reachable) - regardless of the tail of the block.
5029 self.diverges.set(prev_diverges);
5032 let mut ty = ctxt.coerce.unwrap().complete(self);
5034 if self.has_errors.get() || ty.references_error() {
5035 ty = self.tcx.types.err
5038 self.write_ty(blk.hir_id, ty);
5040 *self.ps.borrow_mut() = prev;
5044 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
5045 let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(id));
5047 Node::Item(&hir::Item {
5048 node: hir::ItemKind::Fn(_, _, _, body_id), ..
5050 Node::ImplItem(&hir::ImplItem {
5051 node: hir::ImplItemKind::Method(_, body_id), ..
5053 let body = self.tcx.hir().body(body_id);
5054 if let ExprKind::Block(block, _) = &body.value.node {
5055 return Some(block.span);
5063 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
5064 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> {
5065 let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id));
5066 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
5069 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
5070 fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> {
5072 Node::Item(&hir::Item {
5073 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
5074 }) => decl.clone().and_then(|decl| {
5075 // This is less than ideal, it will not suggest a return type span on any
5076 // method called `main`, regardless of whether it is actually the entry point,
5077 // but it will still present it as the reason for the expected type.
5078 Some((decl, ident, ident.name != sym::main))
5080 Node::TraitItem(&hir::TraitItem {
5081 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
5084 }) => decl.clone().and_then(|decl| Some((decl, ident, true))),
5085 Node::ImplItem(&hir::ImplItem {
5086 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
5089 }) => decl.clone().and_then(|decl| Some((decl, ident, false))),
5094 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
5095 /// suggestion can be made, `None` otherwise.
5096 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> {
5097 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
5098 // `while` before reaching it, as block tail returns are not available in them.
5099 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
5100 let parent = self.tcx.hir().get_by_hir_id(blk_id);
5101 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
5105 /// On implicit return expressions with mismatched types, provides the following suggestions:
5107 /// - Points out the method's return type as the reason for the expected type.
5108 /// - Possible missing semicolon.
5109 /// - Possible missing return type if the return type is the default, and not `fn main()`.
5110 pub fn suggest_mismatched_types_on_tail(
5112 err: &mut DiagnosticBuilder<'tcx>,
5113 expression: &'tcx hir::Expr,
5119 self.suggest_missing_semicolon(err, expression, expected, cause_span);
5120 let mut pointing_at_return_type = false;
5121 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
5122 pointing_at_return_type = self.suggest_missing_return_type(
5123 err, &fn_decl, expected, found, can_suggest);
5125 self.suggest_ref_or_into(err, expression, expected, found);
5126 pointing_at_return_type
5129 pub fn suggest_ref_or_into(
5131 err: &mut DiagnosticBuilder<'tcx>,
5136 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
5137 err.span_suggestion(
5141 Applicability::MachineApplicable,
5143 } else if !self.check_for_cast(err, expr, found, expected) {
5144 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
5148 let methods = self.get_conversion_methods(expr.span, expected, found);
5149 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
5150 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
5151 .filter_map(|(receiver, method)| {
5152 let method_call = format!(".{}()", method.ident);
5153 if receiver.ends_with(&method_call) {
5154 None // do not suggest code that is already there (#53348)
5156 let method_call_list = [".to_vec()", ".to_string()"];
5157 let sugg = if receiver.ends_with(".clone()")
5158 && method_call_list.contains(&method_call.as_str()) {
5159 let max_len = receiver.rfind(".").unwrap();
5160 format!("{}{}", &receiver[..max_len], method_call)
5162 format!("{}{}", receiver, method_call)
5164 Some(if is_struct_pat_shorthand_field {
5165 format!("{}: {}", receiver, sugg)
5171 if suggestions.peek().is_some() {
5172 err.span_suggestions(
5174 "try using a conversion method",
5176 Applicability::MaybeIncorrect,
5183 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
5187 /// bar_that_returns_u32()
5191 /// This routine checks if the return expression in a block would make sense on its own as a
5192 /// statement and the return type has been left as default or has been specified as `()`. If so,
5193 /// it suggests adding a semicolon.
5194 fn suggest_missing_semicolon(
5196 err: &mut DiagnosticBuilder<'tcx>,
5197 expression: &'tcx hir::Expr,
5201 if expected.is_unit() {
5202 // `BlockTailExpression` only relevant if the tail expr would be
5203 // useful on its own.
5204 match expression.node {
5205 ExprKind::Call(..) |
5206 ExprKind::MethodCall(..) |
5207 ExprKind::While(..) |
5208 ExprKind::Loop(..) |
5209 ExprKind::Match(..) |
5210 ExprKind::Block(..) => {
5211 let sp = self.tcx.sess.source_map().next_point(cause_span);
5212 err.span_suggestion(
5214 "try adding a semicolon",
5216 Applicability::MachineApplicable);
5223 /// A possible error is to forget to add a return type that is needed:
5227 /// bar_that_returns_u32()
5231 /// This routine checks if the return type is left as default, the method is not part of an
5232 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
5234 fn suggest_missing_return_type(
5236 err: &mut DiagnosticBuilder<'tcx>,
5237 fn_decl: &hir::FnDecl,
5242 // Only suggest changing the return type for methods that
5243 // haven't set a return type at all (and aren't `fn main()` or an impl).
5244 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
5245 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
5246 err.span_suggestion(
5248 "try adding a return type",
5249 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
5250 Applicability::MachineApplicable);
5253 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
5254 err.span_label(span, "possibly return type missing here?");
5257 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
5258 // `fn main()` must return `()`, do not suggest changing return type
5259 err.span_label(span, "expected `()` because of default return type");
5262 // expectation was caused by something else, not the default return
5263 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
5264 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
5265 // Only point to return type if the expected type is the return type, as if they
5266 // are not, the expectation must have been caused by something else.
5267 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
5269 let ty = AstConv::ast_ty_to_ty(self, ty);
5270 debug!("suggest_missing_return_type: return type {:?}", ty);
5271 debug!("suggest_missing_return_type: expected type {:?}", ty);
5272 if ty.sty == expected.sty {
5273 err.span_label(sp, format!("expected `{}` because of return type",
5282 /// A common error is to add an extra semicolon:
5285 /// fn foo() -> usize {
5290 /// This routine checks if the final statement in a block is an
5291 /// expression with an explicit semicolon whose type is compatible
5292 /// with `expected_ty`. If so, it suggests removing the semicolon.
5293 fn consider_hint_about_removing_semicolon(
5295 blk: &'tcx hir::Block,
5296 expected_ty: Ty<'tcx>,
5297 err: &mut DiagnosticBuilder<'_>,
5299 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
5300 err.span_suggestion(
5302 "consider removing this semicolon",
5304 Applicability::MachineApplicable,
5309 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
5310 // Be helpful when the user wrote `{... expr;}` and
5311 // taking the `;` off is enough to fix the error.
5312 let last_stmt = blk.stmts.last()?;
5313 let last_expr = match last_stmt.node {
5314 hir::StmtKind::Semi(ref e) => e,
5317 let last_expr_ty = self.node_ty(last_expr.hir_id);
5318 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5321 let original_span = original_sp(last_stmt.span, blk.span);
5322 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
5325 // Rewrite `SelfCtor` to `Ctor`
5326 pub fn rewrite_self_ctor(
5330 ) -> Result<Res, ErrorReported> {
5332 if let Res::SelfCtor(impl_def_id) = res {
5333 let ty = self.impl_self_ty(span, impl_def_id).ty;
5334 let adt_def = ty.ty_adt_def();
5337 Some(adt_def) if adt_def.has_ctor() => {
5338 let variant = adt_def.non_enum_variant();
5339 let ctor_def_id = variant.ctor_def_id.unwrap();
5340 Ok(Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id))
5343 let mut err = tcx.sess.struct_span_err(span,
5344 "the `Self` constructor can only be used with tuple or unit structs");
5345 if let Some(adt_def) = adt_def {
5346 match adt_def.adt_kind() {
5348 err.help("did you mean to use one of the enum's variants?");
5352 err.span_suggestion(
5354 "use curly brackets",
5355 String::from("Self { /* fields */ }"),
5356 Applicability::HasPlaceholders,
5371 // Instantiates the given path, which must refer to an item with the given
5372 // number of type parameters and type.
5373 pub fn instantiate_value_path(&self,
5374 segments: &[hir::PathSegment],
5375 self_ty: Option<Ty<'tcx>>,
5379 -> (Ty<'tcx>, Res) {
5381 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
5390 let res = match self.rewrite_self_ctor(res, span) {
5392 Err(ErrorReported) => return (tcx.types.err, res),
5394 let path_segs = match res {
5395 Res::Local(_) => vec![],
5396 Res::Def(kind, def_id) =>
5397 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
5398 _ => bug!("instantiate_value_path on {:?}", res),
5401 let mut user_self_ty = None;
5402 let mut is_alias_variant_ctor = false;
5404 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
5405 if let Some(self_ty) = self_ty {
5406 let adt_def = self_ty.ty_adt_def().unwrap();
5407 user_self_ty = Some(UserSelfTy {
5408 impl_def_id: adt_def.did,
5411 is_alias_variant_ctor = true;
5414 Res::Def(DefKind::Method, def_id)
5415 | Res::Def(DefKind::AssocConst, def_id) => {
5416 let container = tcx.associated_item(def_id).container;
5417 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
5419 ty::TraitContainer(trait_did) => {
5420 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5422 ty::ImplContainer(impl_def_id) => {
5423 if segments.len() == 1 {
5424 // `<T>::assoc` will end up here, and so
5425 // can `T::assoc`. It this came from an
5426 // inherent impl, we need to record the
5427 // `T` for posterity (see `UserSelfTy` for
5429 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5430 user_self_ty = Some(UserSelfTy {
5441 // Now that we have categorized what space the parameters for each
5442 // segment belong to, let's sort out the parameters that the user
5443 // provided (if any) into their appropriate spaces. We'll also report
5444 // errors if type parameters are provided in an inappropriate place.
5446 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5447 let generics_has_err = AstConv::prohibit_generics(
5448 self, segments.iter().enumerate().filter_map(|(index, seg)| {
5449 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5456 if let Res::Local(hid) = res {
5457 let ty = self.local_ty(span, hid).decl_ty;
5458 let ty = self.normalize_associated_types_in(span, &ty);
5459 self.write_ty(hir_id, ty);
5463 if generics_has_err {
5464 // Don't try to infer type parameters when prohibited generic arguments were given.
5465 user_self_ty = None;
5468 // Now we have to compare the types that the user *actually*
5469 // provided against the types that were *expected*. If the user
5470 // did not provide any types, then we want to substitute inference
5471 // variables. If the user provided some types, we may still need
5472 // to add defaults. If the user provided *too many* types, that's
5475 let mut infer_args_for_err = FxHashSet::default();
5476 for &PathSeg(def_id, index) in &path_segs {
5477 let seg = &segments[index];
5478 let generics = tcx.generics_of(def_id);
5479 // Argument-position `impl Trait` is treated as a normal generic
5480 // parameter internally, but we don't allow users to specify the
5481 // parameter's value explicitly, so we have to do some error-
5483 let suppress_errors = AstConv::check_generic_arg_count_for_call(
5488 false, // `is_method_call`
5490 if suppress_errors {
5491 infer_args_for_err.insert(index);
5492 self.set_tainted_by_errors(); // See issue #53251.
5496 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
5497 tcx.generics_of(*def_id).has_self
5498 }).unwrap_or(false);
5500 let def_id = res.def_id();
5502 // The things we are substituting into the type should not contain
5503 // escaping late-bound regions, and nor should the base type scheme.
5504 let ty = tcx.type_of(def_id);
5506 let substs = AstConv::create_substs_for_generic_args(
5512 // Provide the generic args, and whether types should be inferred.
5514 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
5517 // If we've encountered an `impl Trait`-related error, we're just
5518 // going to infer the arguments for better error messages.
5519 if !infer_args_for_err.contains(&index) {
5520 // Check whether the user has provided generic arguments.
5521 if let Some(ref data) = segments[index].args {
5522 return (Some(data), segments[index].infer_args);
5525 return (None, segments[index].infer_args);
5530 // Provide substitutions for parameters for which (valid) arguments have been provided.
5532 match (¶m.kind, arg) {
5533 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5534 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5536 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5537 self.to_ty(ty).into()
5539 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
5540 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
5542 _ => unreachable!(),
5545 // Provide substitutions for parameters for which arguments are inferred.
5546 |substs, param, infer_args| {
5548 GenericParamDefKind::Lifetime => {
5549 self.re_infer(Some(param), span).unwrap().into()
5551 GenericParamDefKind::Type { has_default, .. } => {
5552 if !infer_args && has_default {
5553 // If we have a default, then we it doesn't matter that we're not
5554 // inferring the type arguments: we provide the default where any
5556 let default = tcx.type_of(param.def_id);
5559 default.subst_spanned(tcx, substs.unwrap(), Some(span))
5562 // If no type arguments were provided, we have to infer them.
5563 // This case also occurs as a result of some malformed input, e.g.
5564 // a lifetime argument being given instead of a type parameter.
5565 // Using inference instead of `Error` gives better error messages.
5566 self.var_for_def(span, param)
5569 GenericParamDefKind::Const => {
5570 // FIXME(const_generics:defaults)
5571 // No const parameters were provided, we have to infer them.
5572 self.var_for_def(span, param)
5577 assert!(!substs.has_escaping_bound_vars());
5578 assert!(!ty.has_escaping_bound_vars());
5580 // First, store the "user substs" for later.
5581 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
5583 // Add all the obligations that are required, substituting and
5584 // normalized appropriately.
5585 let bounds = self.instantiate_bounds(span, def_id, &substs);
5586 self.add_obligations_for_parameters(
5587 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5590 // Substitute the values for the type parameters into the type of
5591 // the referenced item.
5592 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5594 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5595 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5596 // is inherent, there is no `Self` parameter; instead, the impl needs
5597 // type parameters, which we can infer by unifying the provided `Self`
5598 // with the substituted impl type.
5599 // This also occurs for an enum variant on a type alias.
5600 let ty = tcx.type_of(impl_def_id);
5602 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5603 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5604 Ok(ok) => self.register_infer_ok_obligations(ok),
5606 self.tcx.sess.delay_span_bug(span, &format!(
5607 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5615 self.check_rustc_args_require_const(def_id, hir_id, span);
5617 debug!("instantiate_value_path: type of {:?} is {:?}",
5620 self.write_substs(hir_id, substs);
5622 (ty_substituted, res)
5625 fn check_rustc_args_require_const(&self,
5629 // We're only interested in functions tagged with
5630 // #[rustc_args_required_const], so ignore anything that's not.
5631 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5635 // If our calling expression is indeed the function itself, we're good!
5636 // If not, generate an error that this can only be called directly.
5637 if let Node::Expr(expr) = self.tcx.hir().get_by_hir_id(
5638 self.tcx.hir().get_parent_node_by_hir_id(hir_id))
5640 if let ExprKind::Call(ref callee, ..) = expr.node {
5641 if callee.hir_id == hir_id {
5647 self.tcx.sess.span_err(span, "this function can only be invoked \
5648 directly, not through a function pointer");
5651 // Resolves `typ` by a single level if `typ` is a type variable.
5652 // If no resolution is possible, then an error is reported.
5653 // Numeric inference variables may be left unresolved.
5654 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5655 let ty = self.resolve_type_vars_with_obligations(ty);
5656 if !ty.is_ty_var() {
5659 if !self.is_tainted_by_errors() {
5660 self.need_type_info_err((**self).body_id, sp, ty)
5661 .note("type must be known at this point")
5664 self.demand_suptype(sp, self.tcx.types.err, ty);
5669 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5672 ctxt: BreakableCtxt<'tcx>,
5674 ) -> (BreakableCtxt<'tcx>, R) {
5677 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5678 index = enclosing_breakables.stack.len();
5679 enclosing_breakables.by_id.insert(id, index);
5680 enclosing_breakables.stack.push(ctxt);
5684 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5685 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5686 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5687 enclosing_breakables.stack.pop().expect("missing breakable context")
5692 /// Instantiate a QueryResponse in a probe context, without a
5693 /// good ObligationCause.
5694 fn probe_instantiate_query_response(
5697 original_values: &OriginalQueryValues<'tcx>,
5698 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5699 ) -> InferResult<'tcx, Ty<'tcx>>
5701 self.instantiate_query_response_and_region_obligations(
5702 &traits::ObligationCause::misc(span, self.body_id),
5708 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5709 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5710 let mut contained_in_place = false;
5712 while let hir::Node::Expr(parent_expr) =
5713 self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(expr_id))
5715 match &parent_expr.node {
5716 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5717 if lhs.hir_id == expr_id {
5718 contained_in_place = true;
5724 expr_id = parent_expr.hir_id;
5731 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5732 let own_counts = generics.own_counts();
5734 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5740 if own_counts.types == 0 {
5744 // Make a vector of booleans initially false, set to true when used.
5745 let mut types_used = vec![false; own_counts.types];
5747 for leaf_ty in ty.walk() {
5748 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.sty {
5749 debug!("Found use of ty param num {}", index);
5750 types_used[index as usize - own_counts.lifetimes] = true;
5751 } else if let ty::Error = leaf_ty.sty {
5752 // If there is already another error, do not emit
5753 // an error for not using a type Parameter.
5754 assert!(tcx.sess.err_count() > 0);
5759 let types = generics.params.iter().filter(|param| match param.kind {
5760 ty::GenericParamDefKind::Type { .. } => true,
5763 for (&used, param) in types_used.iter().zip(types) {
5765 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5766 let span = tcx.hir().span_by_hir_id(id);
5767 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5768 .span_label(span, "unused type parameter")
5774 fn fatally_break_rust(sess: &Session) {
5775 let handler = sess.diagnostic();
5776 handler.span_bug_no_panic(
5778 "It looks like you're trying to break rust; would you like some ICE?",
5780 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5781 handler.note_without_error(
5782 "we would appreciate a joke overview: \
5783 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5785 handler.note_without_error(&format!("rustc {} running on {}",
5786 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5787 crate::session::config::host_triple(),
5791 fn potentially_plural_count(count: usize, word: &str) -> String {
5792 format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })