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
86 mod generator_interior;
90 use crate::astconv::{AstConv, PathSeg};
91 use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
92 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
93 use rustc::hir::def::{CtorOf, Res, DefKind};
94 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
95 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
96 use rustc::hir::itemlikevisit::ItemLikeVisitor;
97 use rustc::hir::ptr::P;
98 use crate::middle::lang_items;
99 use crate::namespace::Namespace;
100 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
101 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
102 use rustc_index::vec::Idx;
103 use rustc_target::spec::abi::Abi;
104 use rustc::infer::opaque_types::OpaqueTypeDecl;
105 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
106 use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
107 use rustc::middle::region;
108 use rustc::mir::interpret::{ConstValue, GlobalId};
109 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
111 self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind,
112 ToPolyTraitRef, ToPredicate, RegionKind, UserType
114 use rustc::ty::adjustment::{
115 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
117 use rustc::ty::fold::TypeFoldable;
118 use rustc::ty::query::Providers;
119 use rustc::ty::subst::{
120 GenericArgKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts,
122 use rustc::ty::util::{Representability, IntTypeExt, Discr};
123 use rustc::ty::layout::VariantIdx;
124 use syntax_pos::{self, BytePos, Span, MultiSpan};
125 use syntax_pos::hygiene::DesugaringKind;
128 use syntax::feature_gate::{GateIssue, emit_feature_err};
129 use syntax::source_map::{DUMMY_SP, original_sp};
130 use syntax::symbol::{kw, sym};
131 use syntax::util::parser::ExprPrecedence;
133 use std::cell::{Cell, RefCell, Ref, RefMut};
134 use std::collections::hash_map::Entry;
137 use std::mem::replace;
138 use std::ops::{self, Deref};
141 use crate::require_c_abi_if_c_variadic;
142 use crate::session::Session;
143 use crate::session::config::EntryFnType;
144 use crate::TypeAndSubsts;
146 use crate::util::captures::Captures;
147 use crate::util::common::{ErrorReported, indenter};
148 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashSet, HirIdMap};
150 pub use self::Expectation::*;
151 use self::autoderef::Autoderef;
152 use self::callee::DeferredCallResolution;
153 use self::coercion::{CoerceMany, DynamicCoerceMany};
154 pub use self::compare_method::{compare_impl_method, compare_const_impl};
155 use self::method::{MethodCallee, SelfSource};
156 use self::TupleArgumentsFlag::*;
158 /// The type of a local binding, including the revealed type for anon types.
159 #[derive(Copy, Clone, Debug)]
160 pub struct LocalTy<'tcx> {
162 revealed_ty: Ty<'tcx>
165 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
166 #[derive(Copy, Clone)]
167 struct MaybeInProgressTables<'a, 'tcx> {
168 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
171 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
172 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
173 match self.maybe_tables {
174 Some(tables) => tables.borrow(),
176 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
181 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
182 match self.maybe_tables {
183 Some(tables) => tables.borrow_mut(),
185 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
191 /// Closures defined within the function. For example:
194 /// bar(move|| { ... })
197 /// Here, the function `foo()` and the closure passed to
198 /// `bar()` will each have their own `FnCtxt`, but they will
199 /// share the inherited fields.
200 pub struct Inherited<'a, 'tcx> {
201 infcx: InferCtxt<'a, 'tcx>,
203 tables: MaybeInProgressTables<'a, 'tcx>,
205 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
207 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
209 // Some additional `Sized` obligations badly affect type inference.
210 // These obligations are added in a later stage of typeck.
211 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
213 // When we process a call like `c()` where `c` is a closure type,
214 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
215 // `FnOnce` closure. In that case, we defer full resolution of the
216 // call until upvar inference can kick in and make the
217 // decision. We keep these deferred resolutions grouped by the
218 // def-id of the closure, so that once we decide, we can easily go
219 // back and process them.
220 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
222 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
224 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
226 // Opaque types found in explicit return types and their
227 // associated fresh inference variable. Writeback resolves these
228 // variables to get the concrete type, which can be used to
229 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
230 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
232 /// Each type parameter has an implicit region bound that
233 /// indicates it must outlive at least the function body (the user
234 /// may specify stronger requirements). This field indicates the
235 /// region of the callee. If it is `None`, then the parameter
236 /// environment is for an item or something where the "callee" is
238 implicit_region_bound: Option<ty::Region<'tcx>>,
240 body_id: Option<hir::BodyId>,
243 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
244 type Target = InferCtxt<'a, 'tcx>;
245 fn deref(&self) -> &Self::Target {
250 /// When type-checking an expression, we propagate downward
251 /// whatever type hint we are able in the form of an `Expectation`.
252 #[derive(Copy, Clone, Debug)]
253 pub enum Expectation<'tcx> {
254 /// We know nothing about what type this expression should have.
257 /// This expression should have the type given (or some subtype).
258 ExpectHasType(Ty<'tcx>),
260 /// This expression will be cast to the `Ty`.
261 ExpectCastableToType(Ty<'tcx>),
263 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
264 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
265 ExpectRvalueLikeUnsized(Ty<'tcx>),
268 impl<'a, 'tcx> Expectation<'tcx> {
269 // Disregard "castable to" expectations because they
270 // can lead us astray. Consider for example `if cond
271 // {22} else {c} as u8` -- if we propagate the
272 // "castable to u8" constraint to 22, it will pick the
273 // type 22u8, which is overly constrained (c might not
274 // be a u8). In effect, the problem is that the
275 // "castable to" expectation is not the tightest thing
276 // we can say, so we want to drop it in this case.
277 // The tightest thing we can say is "must unify with
278 // else branch". Note that in the case of a "has type"
279 // constraint, this limitation does not hold.
281 // If the expected type is just a type variable, then don't use
282 // an expected type. Otherwise, we might write parts of the type
283 // when checking the 'then' block which are incompatible with the
285 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
287 ExpectHasType(ety) => {
288 let ety = fcx.shallow_resolve(ety);
289 if !ety.is_ty_var() {
295 ExpectRvalueLikeUnsized(ety) => {
296 ExpectRvalueLikeUnsized(ety)
302 /// Provides an expectation for an rvalue expression given an *optional*
303 /// hint, which is not required for type safety (the resulting type might
304 /// be checked higher up, as is the case with `&expr` and `box expr`), but
305 /// is useful in determining the concrete type.
307 /// The primary use case is where the expected type is a fat pointer,
308 /// like `&[isize]`. For example, consider the following statement:
310 /// let x: &[isize] = &[1, 2, 3];
312 /// In this case, the expected type for the `&[1, 2, 3]` expression is
313 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
314 /// expectation `ExpectHasType([isize])`, that would be too strong --
315 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
316 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
317 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
318 /// which still is useful, because it informs integer literals and the like.
319 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
320 /// for examples of where this comes up,.
321 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
322 match fcx.tcx.struct_tail_without_normalization(ty).kind {
323 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
324 ExpectRvalueLikeUnsized(ty)
326 _ => ExpectHasType(ty)
330 // Resolves `expected` by a single level if it is a variable. If
331 // there is no expected type or resolution is not possible (e.g.,
332 // no constraints yet present), just returns `None`.
333 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
335 NoExpectation => NoExpectation,
336 ExpectCastableToType(t) => {
337 ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
339 ExpectHasType(t) => {
340 ExpectHasType(fcx.resolve_vars_if_possible(&t))
342 ExpectRvalueLikeUnsized(t) => {
343 ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
348 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
349 match self.resolve(fcx) {
350 NoExpectation => None,
351 ExpectCastableToType(ty) |
353 ExpectRvalueLikeUnsized(ty) => Some(ty),
357 /// It sometimes happens that we want to turn an expectation into
358 /// a **hard constraint** (i.e., something that must be satisfied
359 /// for the program to type-check). `only_has_type` will return
360 /// such a constraint, if it exists.
361 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
362 match self.resolve(fcx) {
363 ExpectHasType(ty) => Some(ty),
364 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
368 /// Like `only_has_type`, but instead of returning `None` if no
369 /// hard constraint exists, creates a fresh type variable.
370 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
371 self.only_has_type(fcx)
373 fcx.next_ty_var(TypeVariableOrigin {
374 kind: TypeVariableOriginKind::MiscVariable,
381 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
388 fn maybe_mut_place(m: hir::Mutability) -> Self {
390 hir::MutMutable => Needs::MutPlace,
391 hir::MutImmutable => Needs::None,
396 #[derive(Copy, Clone)]
397 pub struct UnsafetyState {
399 pub unsafety: hir::Unsafety,
400 pub unsafe_push_count: u32,
405 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
406 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
409 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
410 match self.unsafety {
411 // If this unsafe, then if the outer function was already marked as
412 // unsafe we shouldn't attribute the unsafe'ness to the block. This
413 // way the block can be warned about instead of ignoring this
414 // extraneous block (functions are never warned about).
415 hir::Unsafety::Unsafe if self.from_fn => *self,
418 let (unsafety, def, count) = match blk.rules {
419 hir::PushUnsafeBlock(..) =>
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
421 hir::PopUnsafeBlock(..) =>
422 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
423 hir::UnsafeBlock(..) =>
424 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
426 (unsafety, self.def, self.unsafe_push_count),
430 unsafe_push_count: count,
437 #[derive(Debug, Copy, Clone)]
443 /// Tracks whether executing a node may exit normally (versus
444 /// return/break/panic, which "diverge", leaving dead code in their
445 /// wake). Tracked semi-automatically (through type variables marked
446 /// as diverging), with some manual adjustments for control-flow
447 /// primitives (approximating a CFG).
448 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
450 /// Potentially unknown, some cases converge,
451 /// others require a CFG to determine them.
454 /// Definitely known to diverge and therefore
455 /// not reach the next sibling or its parent.
457 /// The `Span` points to the expression
458 /// that caused us to diverge
459 /// (e.g. `return`, `break`, etc).
461 /// In some cases (e.g. a `match` expression
462 /// where all arms diverge), we may be
463 /// able to provide a more informative
464 /// message to the user.
465 /// If this is `None`, a default messsage
466 /// will be generated, which is suitable
468 custom_note: Option<&'static str>
471 /// Same as `Always` but with a reachability
472 /// warning already emitted.
476 // Convenience impls for combining `Diverges`.
478 impl ops::BitAnd for Diverges {
480 fn bitand(self, other: Self) -> Self {
481 cmp::min(self, other)
485 impl ops::BitOr for Diverges {
487 fn bitor(self, other: Self) -> Self {
488 cmp::max(self, other)
492 impl ops::BitAndAssign for Diverges {
493 fn bitand_assign(&mut self, other: Self) {
494 *self = *self & other;
498 impl ops::BitOrAssign for Diverges {
499 fn bitor_assign(&mut self, other: Self) {
500 *self = *self | other;
505 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
506 fn always(span: Span) -> Diverges {
513 fn is_always(self) -> bool {
514 // Enum comparison ignores the
515 // contents of fields, so we just
516 // fill them in with garbage here.
517 self >= Diverges::Always {
524 pub struct BreakableCtxt<'tcx> {
527 // this is `null` for loops where break with a value is illegal,
528 // such as `while`, `for`, and `while let`
529 coerce: Option<DynamicCoerceMany<'tcx>>,
532 pub struct EnclosingBreakables<'tcx> {
533 stack: Vec<BreakableCtxt<'tcx>>,
534 by_id: HirIdMap<usize>,
537 impl<'tcx> EnclosingBreakables<'tcx> {
538 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
539 self.opt_find_breakable(target_id).unwrap_or_else(|| {
540 bug!("could not find enclosing breakable with id {}", target_id);
544 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
545 match self.by_id.get(&target_id) {
546 Some(ix) => Some(&mut self.stack[*ix]),
552 pub struct FnCtxt<'a, 'tcx> {
555 /// The parameter environment used for proving trait obligations
556 /// in this function. This can change when we descend into
557 /// closures (as they bring new things into scope), hence it is
558 /// not part of `Inherited` (as of the time of this writing,
559 /// closures do not yet change the environment, but they will
561 param_env: ty::ParamEnv<'tcx>,
563 /// Number of errors that had been reported when we started
564 /// checking this function. On exit, if we find that *more* errors
565 /// have been reported, we will skip regionck and other work that
566 /// expects the types within the function to be consistent.
567 // FIXME(matthewjasper) This should not exist, and it's not correct
568 // if type checking is run in parallel.
569 err_count_on_creation: usize,
571 /// If `Some`, this stores coercion information for returned
572 /// expressions. If `None`, this is in a context where return is
573 /// inappropriate, such as a const expression.
575 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
576 /// can track all the return expressions and then use them to
577 /// compute a useful coercion from the set, similar to a match
578 /// expression or other branching context. You can use methods
579 /// like `expected_ty` to access the declared return type (if
581 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
583 /// First span of a return site that we find. Used in error messages.
584 ret_coercion_span: RefCell<Option<Span>>,
586 yield_ty: Option<Ty<'tcx>>,
588 ps: RefCell<UnsafetyState>,
590 /// Whether the last checked node generates a divergence (e.g.,
591 /// `return` will set this to `Always`). In general, when entering
592 /// an expression or other node in the tree, the initial value
593 /// indicates whether prior parts of the containing expression may
594 /// have diverged. It is then typically set to `Maybe` (and the
595 /// old value remembered) for processing the subparts of the
596 /// current expression. As each subpart is processed, they may set
597 /// the flag to `Always`, etc. Finally, at the end, we take the
598 /// result and "union" it with the original value, so that when we
599 /// return the flag indicates if any subpart of the parent
600 /// expression (up to and including this part) has diverged. So,
601 /// if you read it after evaluating a subexpression `X`, the value
602 /// you get indicates whether any subexpression that was
603 /// evaluating up to and including `X` diverged.
605 /// We currently use this flag only for diagnostic purposes:
607 /// - To warn about unreachable code: if, after processing a
608 /// sub-expression but before we have applied the effects of the
609 /// current node, we see that the flag is set to `Always`, we
610 /// can issue a warning. This corresponds to something like
611 /// `foo(return)`; we warn on the `foo()` expression. (We then
612 /// update the flag to `WarnedAlways` to suppress duplicate
613 /// reports.) Similarly, if we traverse to a fresh statement (or
614 /// tail expression) from a `Always` setting, we will issue a
615 /// warning. This corresponds to something like `{return;
616 /// foo();}` or `{return; 22}`, where we would warn on the
619 /// An expression represents dead code if, after checking it,
620 /// the diverges flag is set to something other than `Maybe`.
621 diverges: Cell<Diverges>,
623 /// Whether any child nodes have any type errors.
624 has_errors: Cell<bool>,
626 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
628 inh: &'a Inherited<'a, 'tcx>,
631 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
632 type Target = Inherited<'a, 'tcx>;
633 fn deref(&self) -> &Self::Target {
638 /// Helper type of a temporary returned by `Inherited::build(...)`.
639 /// Necessary because we can't write the following bound:
640 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
641 pub struct InheritedBuilder<'tcx> {
642 infcx: infer::InferCtxtBuilder<'tcx>,
646 impl Inherited<'_, 'tcx> {
647 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
648 let hir_id_root = if def_id.is_local() {
649 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
650 DefId::local(hir_id.owner)
656 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
662 impl<'tcx> InheritedBuilder<'tcx> {
663 fn enter<F, R>(&mut self, f: F) -> R
665 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
667 let def_id = self.def_id;
668 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
672 impl Inherited<'a, 'tcx> {
673 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
675 let item_id = tcx.hir().as_local_hir_id(def_id);
676 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
677 let implicit_region_bound = body_id.map(|body_id| {
678 let body = tcx.hir().body(body_id);
679 tcx.mk_region(ty::ReScope(region::Scope {
680 id: body.value.hir_id.local_id,
681 data: region::ScopeData::CallSite
686 tables: MaybeInProgressTables {
687 maybe_tables: infcx.in_progress_tables,
690 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
691 locals: RefCell::new(Default::default()),
692 deferred_sized_obligations: RefCell::new(Vec::new()),
693 deferred_call_resolutions: RefCell::new(Default::default()),
694 deferred_cast_checks: RefCell::new(Vec::new()),
695 deferred_generator_interiors: RefCell::new(Vec::new()),
696 opaque_types: RefCell::new(Default::default()),
697 implicit_region_bound,
702 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
703 debug!("register_predicate({:?})", obligation);
704 if obligation.has_escaping_bound_vars() {
705 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
710 .register_predicate_obligation(self, obligation);
713 fn register_predicates<I>(&self, obligations: I)
714 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
716 for obligation in obligations {
717 self.register_predicate(obligation);
721 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
722 self.register_predicates(infer_ok.obligations);
726 fn normalize_associated_types_in<T>(&self,
729 param_env: ty::ParamEnv<'tcx>,
731 where T : TypeFoldable<'tcx>
733 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
734 self.register_infer_ok_obligations(ok)
738 struct CheckItemTypesVisitor<'tcx> {
742 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
743 fn visit_item(&mut self, i: &'tcx hir::Item) {
744 check_item_type(self.tcx, i);
746 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
747 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
750 pub fn check_wf_new(tcx: TyCtxt<'_>) {
751 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
752 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
755 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
756 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
759 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
760 debug_assert!(crate_num == LOCAL_CRATE);
761 tcx.par_body_owners(|body_owner_def_id| {
762 tcx.ensure().typeck_tables_of(body_owner_def_id);
766 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
767 wfcheck::check_item_well_formed(tcx, def_id);
770 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
771 wfcheck::check_trait_item(tcx, def_id);
774 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
775 wfcheck::check_impl_item(tcx, def_id);
778 pub fn provide(providers: &mut Providers<'_>) {
779 method::provide(providers);
780 *providers = Providers {
786 check_item_well_formed,
787 check_trait_item_well_formed,
788 check_impl_item_well_formed,
789 check_mod_item_types,
794 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
795 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
798 /// If this `DefId` is a "primary tables entry", returns
799 /// `Some((body_id, header, decl))` with information about
800 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
803 /// If this function returns `Some`, then `typeck_tables(def_id)` will
804 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
805 /// may not succeed. In some cases where this function returns `None`
806 /// (notably closures), `typeck_tables(def_id)` would wind up
807 /// redirecting to the owning function.
811 ) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
812 match tcx.hir().get(id) {
813 Node::Item(item) => {
815 hir::ItemKind::Const(ref ty, body) |
816 hir::ItemKind::Static(ref ty, _, body) =>
817 Some((body, Some(ty), None, None)),
818 hir::ItemKind::Fn(ref decl, ref header, .., body) =>
819 Some((body, None, Some(header), Some(decl))),
824 Node::TraitItem(item) => {
826 hir::TraitItemKind::Const(ref ty, Some(body)) =>
827 Some((body, Some(ty), None, None)),
828 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
829 Some((body, None, Some(&sig.header), Some(&sig.decl))),
834 Node::ImplItem(item) => {
836 hir::ImplItemKind::Const(ref ty, body) =>
837 Some((body, Some(ty), None, None)),
838 hir::ImplItemKind::Method(ref sig, body) =>
839 Some((body, None, Some(&sig.header), Some(&sig.decl))),
844 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
849 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
850 // Closures' tables come from their outermost function,
851 // as they are part of the same "inference environment".
852 let outer_def_id = tcx.closure_base_def_id(def_id);
853 if outer_def_id != def_id {
854 return tcx.has_typeck_tables(outer_def_id);
857 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
858 primary_body_of(tcx, id).is_some()
861 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
862 &*tcx.typeck_tables_of(def_id).used_trait_imports
865 fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
866 // Closures' tables come from their outermost function,
867 // as they are part of the same "inference environment".
868 let outer_def_id = tcx.closure_base_def_id(def_id);
869 if outer_def_id != def_id {
870 return tcx.typeck_tables_of(outer_def_id);
873 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
874 let span = tcx.hir().span(id);
876 // Figure out what primary body this item has.
877 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
879 span_bug!(span, "can't type-check body of {:?}", def_id);
881 let body = tcx.hir().body(body_id);
883 let tables = Inherited::build(tcx, def_id).enter(|inh| {
884 let param_env = tcx.param_env(def_id);
885 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
886 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
887 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
888 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl)
893 check_abi(tcx, span, fn_sig.abi());
895 // Compute the fty from point of view of inside the fn.
897 tcx.liberate_late_bound_regions(def_id, &fn_sig);
899 inh.normalize_associated_types_in(body.value.span,
904 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
907 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
908 let expected_type = body_ty.and_then(|ty| match ty.kind {
909 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
911 }).unwrap_or_else(|| tcx.type_of(def_id));
912 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
913 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
915 let revealed_ty = if tcx.features().impl_trait_in_bindings {
916 fcx.instantiate_opaque_types_from_value(
925 // Gather locals in statics (because of block expressions).
926 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
928 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
930 fcx.write_ty(id, revealed_ty);
935 // All type checking constraints were added, try to fallback unsolved variables.
936 fcx.select_obligations_where_possible(false, |_| {});
937 let mut fallback_has_occurred = false;
938 for ty in &fcx.unsolved_variables() {
939 fallback_has_occurred |= fcx.fallback_if_possible(ty);
941 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
943 // Even though coercion casts provide type hints, we check casts after fallback for
944 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
947 // Closure and generator analysis may run after fallback
948 // because they don't constrain other type variables.
949 fcx.closure_analyze(body);
950 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
951 fcx.resolve_generator_interiors(def_id);
953 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
954 let ty = fcx.normalize_ty(span, ty);
955 fcx.require_type_is_sized(ty, span, code);
957 fcx.select_all_obligations_or_error();
959 if fn_decl.is_some() {
960 fcx.regionck_fn(id, body);
962 fcx.regionck_expr(body);
965 fcx.resolve_type_vars_in_body(body)
968 // Consistency check our TypeckTables instance can hold all ItemLocalIds
969 // it will need to hold.
970 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
975 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
976 if !tcx.sess.target.target.is_abi_supported(abi) {
977 struct_span_err!(tcx.sess, span, E0570,
978 "The ABI `{}` is not supported for the current target", abi).emit()
982 struct GatherLocalsVisitor<'a, 'tcx> {
983 fcx: &'a FnCtxt<'a, 'tcx>,
984 parent_id: hir::HirId,
987 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
988 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
991 // infer the variable's type
992 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
993 kind: TypeVariableOriginKind::TypeInference,
996 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
1003 // take type that the user specified
1004 self.fcx.locals.borrow_mut().insert(nid, typ);
1011 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1012 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
1013 NestedVisitorMap::None
1016 // Add explicitly-declared locals.
1017 fn visit_local(&mut self, local: &'tcx hir::Local) {
1018 let local_ty = match local.ty {
1020 let o_ty = self.fcx.to_ty(&ty);
1022 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1023 self.fcx.instantiate_opaque_types_from_value(
1032 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
1033 &UserType::Ty(revealed_ty)
1035 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1036 ty.hir_id, o_ty, revealed_ty, c_ty);
1037 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1039 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1043 self.assign(local.span, local.hir_id, local_ty);
1045 debug!("local variable {:?} is assigned type {}",
1047 self.fcx.ty_to_string(
1048 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
1049 intravisit::walk_local(self, local);
1052 // Add pattern bindings.
1053 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
1054 if let PatKind::Binding(_, _, ident, _) = p.kind {
1055 let var_ty = self.assign(p.span, p.hir_id, None);
1057 if !self.fcx.tcx.features().unsized_locals {
1058 self.fcx.require_type_is_sized(var_ty, p.span,
1059 traits::VariableType(p.hir_id));
1062 debug!("pattern binding {} is assigned to {} with type {:?}",
1064 self.fcx.ty_to_string(
1065 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1068 intravisit::walk_pat(self, p);
1071 // Don't descend into the bodies of nested closures
1074 _: intravisit::FnKind<'tcx>,
1075 _: &'tcx hir::FnDecl,
1082 /// When `check_fn` is invoked on a generator (i.e., a body that
1083 /// includes yield), it returns back some information about the yield
1085 struct GeneratorTypes<'tcx> {
1086 /// Type of value that is yielded.
1089 /// Types that are captured (see `GeneratorInterior` for more).
1092 /// Indicates if the generator is movable or static (immovable).
1093 movability: hir::GeneratorMovability,
1096 /// Helper used for fns and closures. Does the grungy work of checking a function
1097 /// body and returns the function context used for that purpose, since in the case of a fn item
1098 /// there is still a bit more to do.
1101 /// * inherited: other fields inherited from the enclosing fn (if any)
1102 fn check_fn<'a, 'tcx>(
1103 inherited: &'a Inherited<'a, 'tcx>,
1104 param_env: ty::ParamEnv<'tcx>,
1105 fn_sig: ty::FnSig<'tcx>,
1106 decl: &'tcx hir::FnDecl,
1108 body: &'tcx hir::Body,
1109 can_be_generator: Option<hir::GeneratorMovability>,
1110 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1111 let mut fn_sig = fn_sig.clone();
1113 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1115 // Create the function context. This is either derived from scratch or,
1116 // in the case of closures, based on the outer context.
1117 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1118 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1120 let declared_ret_ty = fn_sig.output();
1121 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1122 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
1127 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1128 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1129 fn_sig = fcx.tcx.mk_fn_sig(
1130 fn_sig.inputs().iter().cloned(),
1137 let span = body.value.span;
1139 fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1141 if body.generator_kind.is_some() && can_be_generator.is_some() {
1142 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1143 kind: TypeVariableOriginKind::TypeInference,
1146 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1147 fcx.yield_ty = Some(yield_ty);
1150 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1151 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1152 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1154 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1155 // (as it's created inside the body itself, not passed in from outside).
1156 let maybe_va_list = if fn_sig.c_variadic {
1157 let va_list_did = fcx.tcx.require_lang_item(
1158 lang_items::VaListTypeLangItem,
1159 Some(body.params.last().unwrap().span),
1161 let region = fcx.tcx.mk_region(ty::ReScope(region::Scope {
1162 id: body.value.hir_id.local_id,
1163 data: region::ScopeData::CallSite
1166 Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()]))
1171 // Add formal parameters.
1172 for (param_ty, param) in
1173 fn_sig.inputs().iter().copied()
1174 .chain(maybe_va_list)
1177 // Check the pattern.
1178 fcx.check_pat_top(¶m.pat, param_ty, None);
1180 // Check that argument is Sized.
1181 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1182 // for simple cases like `fn foo(x: Trait)`,
1183 // where we would error once on the parameter as a whole, and once on the binding `x`.
1184 if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1185 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1188 fcx.write_ty(param.hir_id, param_ty);
1191 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1193 fcx.check_return_expr(&body.value);
1195 // We insert the deferred_generator_interiors entry after visiting the body.
1196 // This ensures that all nested generators appear before the entry of this generator.
1197 // resolve_generator_interiors relies on this property.
1198 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1199 let interior = fcx.next_ty_var(TypeVariableOrigin {
1200 kind: TypeVariableOriginKind::MiscVariable,
1203 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1204 Some(GeneratorTypes {
1205 yield_ty: fcx.yield_ty.unwrap(),
1207 movability: can_be_generator.unwrap(),
1213 // Finalize the return check by taking the LUB of the return types
1214 // we saw and assigning it to the expected return type. This isn't
1215 // really expected to fail, since the coercions would have failed
1216 // earlier when trying to find a LUB.
1218 // However, the behavior around `!` is sort of complex. In the
1219 // event that the `actual_return_ty` comes back as `!`, that
1220 // indicates that the fn either does not return or "returns" only
1221 // values of type `!`. In this case, if there is an expected
1222 // return type that is *not* `!`, that should be ok. But if the
1223 // return type is being inferred, we want to "fallback" to `!`:
1225 // let x = move || panic!();
1227 // To allow for that, I am creating a type variable with diverging
1228 // fallback. This was deemed ever so slightly better than unifying
1229 // the return value with `!` because it allows for the caller to
1230 // make more assumptions about the return type (e.g., they could do
1232 // let y: Option<u32> = Some(x());
1234 // which would then cause this return type to become `u32`, not
1236 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1237 let mut actual_return_ty = coercion.complete(&fcx);
1238 if actual_return_ty.is_never() {
1239 actual_return_ty = fcx.next_diverging_ty_var(
1240 TypeVariableOrigin {
1241 kind: TypeVariableOriginKind::DivergingFn,
1246 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1248 // Check that the main return type implements the termination trait.
1249 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1250 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1251 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1252 if main_id == fn_id {
1253 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1254 let trait_ref = ty::TraitRef::new(term_id, substs);
1255 let return_ty_span = decl.output.span();
1256 let cause = traits::ObligationCause::new(
1257 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1259 inherited.register_predicate(
1260 traits::Obligation::new(
1261 cause, param_env, trait_ref.to_predicate()));
1266 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1267 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1268 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1269 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1270 // at this point we don't care if there are duplicate handlers or if the handler has
1271 // the wrong signature as this value we'll be used when writing metadata and that
1272 // only happens if compilation succeeded
1273 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1275 if declared_ret_ty.kind != ty::Never {
1276 fcx.tcx.sess.span_err(
1278 "return type should be `!`",
1282 let inputs = fn_sig.inputs();
1283 let span = fcx.tcx.hir().span(fn_id);
1284 if inputs.len() == 1 {
1285 let arg_is_panic_info = match inputs[0].kind {
1286 ty::Ref(region, ty, mutbl) => match ty.kind {
1287 ty::Adt(ref adt, _) => {
1288 adt.did == panic_info_did &&
1289 mutbl == hir::Mutability::MutImmutable &&
1290 *region != RegionKind::ReStatic
1297 if !arg_is_panic_info {
1298 fcx.tcx.sess.span_err(
1299 decl.inputs[0].span,
1300 "argument should be `&PanicInfo`",
1304 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1305 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1306 if !generics.params.is_empty() {
1307 fcx.tcx.sess.span_err(
1309 "should have no type parameters",
1315 let span = fcx.tcx.sess.source_map().def_span(span);
1316 fcx.tcx.sess.span_err(span, "function should have one argument");
1319 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1324 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1325 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1326 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1327 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1328 if declared_ret_ty.kind != ty::Never {
1329 fcx.tcx.sess.span_err(
1331 "return type should be `!`",
1335 let inputs = fn_sig.inputs();
1336 let span = fcx.tcx.hir().span(fn_id);
1337 if inputs.len() == 1 {
1338 let arg_is_alloc_layout = match inputs[0].kind {
1339 ty::Adt(ref adt, _) => {
1340 adt.did == alloc_layout_did
1345 if !arg_is_alloc_layout {
1346 fcx.tcx.sess.span_err(
1347 decl.inputs[0].span,
1348 "argument should be `Layout`",
1352 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1353 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1354 if !generics.params.is_empty() {
1355 fcx.tcx.sess.span_err(
1357 "`#[alloc_error_handler]` function should have no type \
1364 let span = fcx.tcx.sess.source_map().def_span(span);
1365 fcx.tcx.sess.span_err(span, "function should have one argument");
1368 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1376 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1377 let def_id = tcx.hir().local_def_id(id);
1378 let def = tcx.adt_def(def_id);
1379 def.destructor(tcx); // force the destructor to be evaluated
1380 check_representable(tcx, span, def_id);
1382 if def.repr.simd() {
1383 check_simd(tcx, span, def_id);
1386 check_transparent(tcx, span, def_id);
1387 check_packed(tcx, span, def_id);
1390 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1391 let def_id = tcx.hir().local_def_id(id);
1392 let def = tcx.adt_def(def_id);
1393 def.destructor(tcx); // force the destructor to be evaluated
1394 check_representable(tcx, span, def_id);
1395 check_transparent(tcx, span, def_id);
1396 check_union_fields(tcx, span, def_id);
1397 check_packed(tcx, span, def_id);
1400 /// When the `#![feature(untagged_unions)]` gate is active,
1401 /// check that the fields of the `union` does not contain fields that need dropping.
1402 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1403 let item_type = tcx.type_of(item_def_id);
1404 if let ty::Adt(def, substs) = item_type.kind {
1405 assert!(def.is_union());
1406 let fields = &def.non_enum_variant().fields;
1407 for field in fields {
1408 let field_ty = field.ty(tcx, substs);
1409 // We are currently checking the type this field came from, so it must be local.
1410 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1411 let param_env = tcx.param_env(field.did);
1412 if field_ty.needs_drop(tcx, param_env) {
1413 struct_span_err!(tcx.sess, field_span, E0740,
1414 "unions may not contain fields that need dropping")
1415 .span_note(field_span,
1416 "`std::mem::ManuallyDrop` can be used to wrap the type")
1422 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1427 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1428 /// projections that would result in "inheriting lifetimes".
1429 fn check_opaque<'tcx>(
1432 substs: SubstsRef<'tcx>,
1434 origin: &hir::OpaqueTyOrigin,
1436 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1437 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1440 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1441 /// in "inheriting lifetimes".
1442 fn check_opaque_for_inheriting_lifetimes(
1447 let item = tcx.hir().expect_item(
1448 tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1449 debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1450 def_id, span, item);
1453 struct ProhibitOpaqueVisitor<'tcx> {
1454 opaque_identity_ty: Ty<'tcx>,
1455 generics: &'tcx ty::Generics,
1458 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1459 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1460 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1461 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1464 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1465 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1466 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1467 return *index < self.generics.parent_count as u32;
1470 r.super_visit_with(self)
1474 let prohibit_opaque = match item.kind {
1475 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
1476 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1477 let mut visitor = ProhibitOpaqueVisitor {
1478 opaque_identity_ty: tcx.mk_opaque(
1479 def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1480 generics: tcx.generics_of(def_id),
1482 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1484 tcx.predicates_of(def_id).predicates.iter().any(
1485 |(predicate, _)| predicate.visit_with(&mut visitor))
1490 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1491 if prohibit_opaque {
1492 let is_async = match item.kind {
1493 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1494 hir::OpaqueTyOrigin::AsyncFn => true,
1497 _ => unreachable!(),
1500 tcx.sess.span_err(span, &format!(
1501 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1503 if is_async { "async fn" } else { "impl Trait" },
1508 /// Checks that an opaque type does not contain cycles.
1509 fn check_opaque_for_cycles<'tcx>(
1512 substs: SubstsRef<'tcx>,
1514 origin: &hir::OpaqueTyOrigin,
1516 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1517 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1519 tcx.sess, span, E0733,
1520 "recursion in an `async fn` requires boxing",
1522 .span_label(span, "recursive `async fn`")
1523 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
1526 let mut err = struct_span_err!(
1527 tcx.sess, span, E0720,
1528 "opaque type expands to a recursive type",
1530 err.span_label(span, "expands to a recursive type");
1531 if let ty::Opaque(..) = partially_expanded_type.kind {
1532 err.note("type resolves to itself");
1534 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1541 // Forbid defining intrinsics in Rust code,
1542 // as they must always be defined by the compiler.
1543 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1544 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1545 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1549 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1551 "check_item_type(it.hir_id={}, it.name={})",
1553 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1555 let _indenter = indenter();
1557 // Consts can play a role in type-checking, so they are included here.
1558 hir::ItemKind::Static(..) => {
1559 let def_id = tcx.hir().local_def_id(it.hir_id);
1560 tcx.typeck_tables_of(def_id);
1561 maybe_check_static_with_link_section(tcx, def_id, it.span);
1563 hir::ItemKind::Const(..) => {
1564 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1566 hir::ItemKind::Enum(ref enum_definition, _) => {
1567 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1569 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1570 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1571 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1572 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1573 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1574 check_impl_items_against_trait(
1581 let trait_def_id = impl_trait_ref.def_id;
1582 check_on_unimplemented(tcx, trait_def_id, it);
1585 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1586 let def_id = tcx.hir().local_def_id(it.hir_id);
1587 check_on_unimplemented(tcx, def_id, it);
1589 for item in items.iter() {
1590 let item = tcx.hir().trait_item(item.id);
1591 if let hir::TraitItemKind::Method(sig, _) = &item.kind {
1592 let abi = sig.header.abi;
1593 fn_maybe_err(tcx, item.ident.span, abi);
1597 hir::ItemKind::Struct(..) => {
1598 check_struct(tcx, it.hir_id, it.span);
1600 hir::ItemKind::Union(..) => {
1601 check_union(tcx, it.hir_id, it.span);
1603 hir::ItemKind::OpaqueTy(hir::OpaqueTy{origin, ..}) => {
1604 let def_id = tcx.hir().local_def_id(it.hir_id);
1606 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1607 check_opaque(tcx, def_id, substs, it.span, &origin);
1609 hir::ItemKind::TyAlias(..) => {
1610 let def_id = tcx.hir().local_def_id(it.hir_id);
1611 let pty_ty = tcx.type_of(def_id);
1612 let generics = tcx.generics_of(def_id);
1613 check_bounds_are_used(tcx, &generics, pty_ty);
1615 hir::ItemKind::ForeignMod(ref m) => {
1616 check_abi(tcx, it.span, m.abi);
1618 if m.abi == Abi::RustIntrinsic {
1619 for item in &m.items {
1620 intrinsic::check_intrinsic_type(tcx, item);
1622 } else if m.abi == Abi::PlatformIntrinsic {
1623 for item in &m.items {
1624 intrinsic::check_platform_intrinsic_type(tcx, item);
1627 for item in &m.items {
1628 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1629 let own_counts = generics.own_counts();
1630 if generics.params.len() - own_counts.lifetimes != 0 {
1631 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1632 (_, 0) => ("type", "types", Some("u32")),
1633 // We don't specify an example value, because we can't generate
1634 // a valid value for any type.
1635 (0, _) => ("const", "consts", None),
1636 _ => ("type or const", "types or consts", None),
1642 "foreign items may not have {} parameters",
1646 &format!("can't have {} parameters", kinds),
1648 // FIXME: once we start storing spans for type arguments, turn this
1649 // into a suggestion.
1651 "replace the {} parameters with concrete {}{}",
1654 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1659 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1660 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1665 _ => { /* nothing to do */ }
1669 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1670 // Only restricted on wasm32 target for now
1671 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1675 // If `#[link_section]` is missing, then nothing to verify
1676 let attrs = tcx.codegen_fn_attrs(id);
1677 if attrs.link_section.is_none() {
1681 // For the wasm32 target statics with `#[link_section]` are placed into custom
1682 // sections of the final output file, but this isn't link custom sections of
1683 // other executable formats. Namely we can only embed a list of bytes,
1684 // nothing with pointers to anything else or relocations. If any relocation
1685 // show up, reject them here.
1686 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1687 // the consumer's responsibility to ensure all bytes that have been read
1688 // have defined values.
1689 let instance = ty::Instance::mono(tcx, id);
1690 let cid = GlobalId {
1694 let param_env = ty::ParamEnv::reveal_all();
1695 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1696 let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1699 bug!("Matching on non-ByRef static")
1701 if alloc.relocations().len() != 0 {
1702 let msg = "statics with a custom `#[link_section]` must be a \
1703 simple list of bytes on the wasm target with no \
1704 extra levels of indirection such as references";
1705 tcx.sess.span_err(span, msg);
1710 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
1711 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1712 // an error would be reported if this fails.
1713 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1716 fn report_forbidden_specialization(
1718 impl_item: &hir::ImplItem,
1721 let mut err = struct_span_err!(
1722 tcx.sess, impl_item.span, E0520,
1723 "`{}` specializes an item from a parent `impl`, but \
1724 that item is not marked `default`",
1726 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1729 match tcx.span_of_impl(parent_impl) {
1731 err.span_label(span, "parent `impl` is here");
1732 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1736 err.note(&format!("parent implementation is in crate `{}`", cname));
1743 fn check_specialization_validity<'tcx>(
1745 trait_def: &ty::TraitDef,
1746 trait_item: &ty::AssocItem,
1748 impl_item: &hir::ImplItem,
1750 let kind = match impl_item.kind {
1751 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1752 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1753 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1754 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1757 let mut ancestor_impls = trait_def.ancestors(tcx, impl_id)
1759 .filter_map(|parent| {
1760 if parent.is_from_trait() {
1763 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1768 if ancestor_impls.peek().is_none() {
1769 // No parent, nothing to specialize.
1773 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1775 // Parent impl exists, and contains the parent item we're trying to specialize, but
1776 // doesn't mark it `default`.
1777 Some(parent_item) if tcx.impl_item_is_final(&parent_item) => {
1778 Some(Err(parent_impl.def_id()))
1781 // Parent impl contains item and makes it specializable.
1786 // Parent impl doesn't mention the item. This means it's inherited from the
1787 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1788 // "defaultness" from the grandparent, else they are final.
1789 None => if tcx.impl_is_default(parent_impl.def_id()) {
1792 Some(Err(parent_impl.def_id()))
1797 // If `opt_result` is `None`, we have only encoutered `default impl`s that don't contain the
1798 // item. This is allowed, the item isn't actually getting specialized here.
1799 let result = opt_result.unwrap_or(Ok(()));
1801 if let Err(parent_impl) = result {
1802 report_forbidden_specialization(tcx, impl_item, parent_impl);
1806 fn check_impl_items_against_trait<'tcx>(
1810 impl_trait_ref: ty::TraitRef<'tcx>,
1811 impl_item_refs: &[hir::ImplItemRef],
1813 let impl_span = tcx.sess.source_map().def_span(impl_span);
1815 // If the trait reference itself is erroneous (so the compilation is going
1816 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1817 // isn't populated for such impls.
1818 if impl_trait_ref.references_error() { return; }
1820 // Locate trait definition and items
1821 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1822 let mut overridden_associated_type = None;
1824 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1826 // Check existing impl methods to see if they are both present in trait
1827 // and compatible with trait signature
1828 for impl_item in impl_items() {
1829 let ty_impl_item = tcx.associated_item(
1830 tcx.hir().local_def_id(impl_item.hir_id));
1831 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1832 .find(|ac| Namespace::from(&impl_item.kind) == Namespace::from(ac.kind) &&
1833 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1835 // Not compatible, but needed for the error message
1836 tcx.associated_items(impl_trait_ref.def_id)
1837 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1840 // Check that impl definition matches trait definition
1841 if let Some(ty_trait_item) = ty_trait_item {
1842 match impl_item.kind {
1843 hir::ImplItemKind::Const(..) => {
1844 // Find associated const definition.
1845 if ty_trait_item.kind == ty::AssocKind::Const {
1846 compare_const_impl(tcx,
1852 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1853 "item `{}` is an associated const, \
1854 which doesn't match its trait `{}`",
1857 err.span_label(impl_item.span, "does not match trait");
1858 // We can only get the spans from local trait definition
1859 // Same for E0324 and E0325
1860 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1861 err.span_label(trait_span, "item in trait");
1866 hir::ImplItemKind::Method(..) => {
1867 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1868 if ty_trait_item.kind == ty::AssocKind::Method {
1869 compare_impl_method(tcx,
1876 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1877 "item `{}` is an associated method, \
1878 which doesn't match its trait `{}`",
1881 err.span_label(impl_item.span, "does not match trait");
1882 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1883 err.span_label(trait_span, "item in trait");
1888 hir::ImplItemKind::OpaqueTy(..) |
1889 hir::ImplItemKind::TyAlias(_) => {
1890 if ty_trait_item.kind == ty::AssocKind::Type {
1891 if ty_trait_item.defaultness.has_value() {
1892 overridden_associated_type = Some(impl_item);
1895 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1896 "item `{}` is an associated type, \
1897 which doesn't match its trait `{}`",
1900 err.span_label(impl_item.span, "does not match trait");
1901 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1902 err.span_label(trait_span, "item in trait");
1909 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1913 // Check for missing items from trait
1914 let mut missing_items = Vec::new();
1915 let mut invalidated_items = Vec::new();
1916 let associated_type_overridden = overridden_associated_type.is_some();
1917 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1918 let is_implemented = trait_def.ancestors(tcx, impl_id)
1919 .leaf_def(tcx, trait_item.ident, trait_item.kind)
1920 .map(|node_item| !node_item.node.is_from_trait())
1923 if !is_implemented && !tcx.impl_is_default(impl_id) {
1924 if !trait_item.defaultness.has_value() {
1925 missing_items.push(trait_item);
1926 } else if associated_type_overridden {
1927 invalidated_items.push(trait_item.ident);
1932 if !missing_items.is_empty() {
1933 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1934 "not all trait items implemented, missing: `{}`",
1935 missing_items.iter()
1936 .map(|trait_item| trait_item.ident.to_string())
1937 .collect::<Vec<_>>().join("`, `"));
1938 err.span_label(impl_span, format!("missing `{}` in implementation",
1939 missing_items.iter()
1940 .map(|trait_item| trait_item.ident.to_string())
1941 .collect::<Vec<_>>().join("`, `")));
1942 for trait_item in missing_items {
1943 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1944 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1946 err.note_trait_signature(trait_item.ident.to_string(),
1947 trait_item.signature(tcx));
1953 if !invalidated_items.is_empty() {
1954 let invalidator = overridden_associated_type.unwrap();
1955 span_err!(tcx.sess, invalidator.span, E0399,
1956 "the following trait items need to be reimplemented \
1957 as `{}` was overridden: `{}`",
1959 invalidated_items.iter()
1960 .map(|name| name.to_string())
1961 .collect::<Vec<_>>().join("`, `"))
1965 /// Checks whether a type can be represented in memory. In particular, it
1966 /// identifies types that contain themselves without indirection through a
1967 /// pointer, which would mean their size is unbounded.
1968 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
1969 let rty = tcx.type_of(item_def_id);
1971 // Check that it is possible to represent this type. This call identifies
1972 // (1) types that contain themselves and (2) types that contain a different
1973 // recursive type. It is only necessary to throw an error on those that
1974 // contain themselves. For case 2, there must be an inner type that will be
1975 // caught by case 1.
1976 match rty.is_representable(tcx, sp) {
1977 Representability::SelfRecursive(spans) => {
1978 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1980 err.span_label(span, "recursive without indirection");
1985 Representability::Representable | Representability::ContainsRecursive => (),
1990 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1991 let t = tcx.type_of(def_id);
1992 if let ty::Adt(def, substs) = t.kind {
1993 if def.is_struct() {
1994 let fields = &def.non_enum_variant().fields;
1995 if fields.is_empty() {
1996 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1999 let e = fields[0].ty(tcx, substs);
2000 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2001 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2002 .span_label(sp, "SIMD elements must have the same type")
2007 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2008 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2010 span_err!(tcx.sess, sp, E0077,
2011 "SIMD vector element type should be machine type");
2019 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2020 let repr = tcx.adt_def(def_id).repr;
2022 for attr in tcx.get_attrs(def_id).iter() {
2023 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2024 if let attr::ReprPacked(pack) = r {
2025 if let Some(repr_pack) = repr.pack {
2026 if pack as u64 != repr_pack.bytes() {
2028 tcx.sess, sp, E0634,
2029 "type has conflicting packed representation hints"
2036 if repr.align.is_some() {
2037 struct_span_err!(tcx.sess, sp, E0587,
2038 "type has conflicting packed and align representation hints").emit();
2040 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
2041 struct_span_err!(tcx.sess, sp, E0588,
2042 "packed type cannot transitively contain a `[repr(align)]` type").emit();
2047 fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
2048 let t = tcx.type_of(def_id);
2049 if stack.contains(&def_id) {
2050 debug!("check_packed_inner: {:?} is recursive", t);
2053 if let ty::Adt(def, substs) = t.kind {
2054 if def.is_struct() || def.is_union() {
2055 if tcx.adt_def(def.did).repr.align.is_some() {
2058 // push struct def_id before checking fields
2060 for field in &def.non_enum_variant().fields {
2061 let f = field.ty(tcx, substs);
2062 if let ty::Adt(def, _) = f.kind {
2063 if check_packed_inner(tcx, def.did, stack) {
2068 // only need to pop if not early out
2075 /// Emit an error when encountering more or less than one variant in a transparent enum.
2076 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2077 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
2078 tcx.hir().span_if_local(variant.def_id).unwrap()
2081 "needs exactly one variant, but has {}",
2084 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2085 err.span_label(sp, &msg);
2086 if let &[ref start @ .., ref end] = &variant_spans[..] {
2087 for variant_span in start {
2088 err.span_label(*variant_span, "");
2090 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2095 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2097 fn bad_non_zero_sized_fields<'tcx>(
2099 adt: &'tcx ty::AdtDef,
2101 field_spans: impl Iterator<Item = Span>,
2104 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2105 let mut err = struct_span_err!(
2109 "{}transparent {} {}",
2110 if adt.is_enum() { "the variant of a " } else { "" },
2114 err.span_label(sp, &msg);
2115 for sp in field_spans {
2116 err.span_label(sp, "this field is non-zero-sized");
2121 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2122 let adt = tcx.adt_def(def_id);
2123 if !adt.repr.transparent() {
2126 let sp = tcx.sess.source_map().def_span(sp);
2129 if !tcx.features().transparent_enums {
2131 &tcx.sess.parse_sess,
2132 sym::transparent_enums,
2134 GateIssue::Language,
2135 "transparent enums are unstable",
2138 if adt.variants.len() != 1 {
2139 bad_variant_count(tcx, adt, sp, def_id);
2140 if adt.variants.is_empty() {
2141 // Don't bother checking the fields. No variants (and thus no fields) exist.
2147 if adt.is_union() && !tcx.features().transparent_unions {
2148 emit_feature_err(&tcx.sess.parse_sess,
2149 sym::transparent_unions,
2151 GateIssue::Language,
2152 "transparent unions are unstable");
2155 // For each field, figure out if it's known to be a ZST and align(1)
2156 let field_infos = adt.all_fields().map(|field| {
2157 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2158 let param_env = tcx.param_env(field.did);
2159 let layout = tcx.layout_of(param_env.and(ty));
2160 // We are currently checking the type this field came from, so it must be local
2161 let span = tcx.hir().span_if_local(field.did).unwrap();
2162 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2163 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2167 let non_zst_fields = field_infos.clone().filter_map(|(span, zst, _align1)| if !zst {
2172 let non_zst_count = non_zst_fields.clone().count();
2173 if non_zst_count != 1 {
2174 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2176 for (span, zst, align1) in field_infos {
2182 "zero-sized field in transparent {} has alignment larger than 1",
2184 ).span_label(span, "has alignment larger than 1").emit();
2189 #[allow(trivial_numeric_casts)]
2190 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
2191 let def_id = tcx.hir().local_def_id(id);
2192 let def = tcx.adt_def(def_id);
2193 def.destructor(tcx); // force the destructor to be evaluated
2196 let attributes = tcx.get_attrs(def_id);
2197 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2199 tcx.sess, attr.span, E0084,
2200 "unsupported representation for zero-variant enum")
2201 .span_label(sp, "zero-variant enum")
2206 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2207 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2208 if !tcx.features().repr128 {
2209 emit_feature_err(&tcx.sess.parse_sess,
2212 GateIssue::Language,
2213 "repr with 128-bit type is unstable");
2218 if let Some(ref e) = v.disr_expr {
2219 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2223 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2225 |var: &hir::Variant| match var.data {
2226 hir::VariantData::Unit(..) => true,
2230 let has_disr = |var: &hir::Variant| var.disr_expr.is_some();
2231 let has_non_units = vs.iter().any(|var| !is_unit(var));
2232 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2233 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2235 if disr_non_unit || (disr_units && has_non_units) {
2236 let mut err = struct_span_err!(tcx.sess, sp, E0732,
2237 "`#[repr(inttype)]` must be specified");
2242 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2243 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2244 // Check for duplicate discriminant values
2245 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2246 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2247 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2248 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2249 let i_span = match variant_i.disr_expr {
2250 Some(ref expr) => tcx.hir().span(expr.hir_id),
2251 None => tcx.hir().span(variant_i_hir_id)
2253 let span = match v.disr_expr {
2254 Some(ref expr) => tcx.hir().span(expr.hir_id),
2257 struct_span_err!(tcx.sess, span, E0081,
2258 "discriminant value `{}` already exists", disr_vals[i])
2259 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2260 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
2263 disr_vals.push(discr);
2266 check_representable(tcx, sp, def_id);
2267 check_transparent(tcx, sp, def_id);
2270 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
2271 span_err!(tcx.sess, span, E0533,
2272 "expected unit struct/variant or constant, found {} `{}`",
2274 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
2277 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2278 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2282 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2284 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2285 let item_id = tcx.hir().ty_param_owner(hir_id);
2286 let item_def_id = tcx.hir().local_def_id(item_id);
2287 let generics = tcx.generics_of(item_def_id);
2288 let index = generics.param_def_id_to_index[&def_id];
2289 ty::GenericPredicates {
2291 predicates: tcx.arena.alloc_from_iter(
2292 self.param_env.caller_bounds.iter().filter_map(|&predicate| match predicate {
2293 ty::Predicate::Trait(ref data)
2294 if data.skip_binder().self_ty().is_param(index) => {
2295 // HACK(eddyb) should get the original `Span`.
2296 let span = tcx.def_span(def_id);
2297 Some((predicate, span))
2307 def: Option<&ty::GenericParamDef>,
2309 ) -> Option<ty::Region<'tcx>> {
2311 Some(def) => infer::EarlyBoundRegion(span, def.name),
2312 None => infer::MiscVariable(span)
2314 Some(self.next_region_var(v))
2317 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2318 if let Some(param) = param {
2319 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2324 self.next_ty_var(TypeVariableOrigin {
2325 kind: TypeVariableOriginKind::TypeInference,
2334 param: Option<&ty::GenericParamDef>,
2336 ) -> &'tcx Const<'tcx> {
2337 if let Some(param) = param {
2338 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2343 self.next_const_var(ty, ConstVariableOrigin {
2344 kind: ConstVariableOriginKind::ConstInference,
2350 fn projected_ty_from_poly_trait_ref(&self,
2353 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2356 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2358 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2362 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2365 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2366 if ty.has_escaping_bound_vars() {
2367 ty // FIXME: normalization and escaping regions
2369 self.normalize_associated_types_in(span, &ty)
2373 fn set_tainted_by_errors(&self) {
2374 self.infcx.set_tainted_by_errors()
2377 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2378 self.write_ty(hir_id, ty)
2382 /// Controls whether the arguments are tupled. This is used for the call
2385 /// Tupling means that all call-side arguments are packed into a tuple and
2386 /// passed as a single parameter. For example, if tupling is enabled, this
2389 /// fn f(x: (isize, isize))
2391 /// Can be called as:
2398 #[derive(Clone, Eq, PartialEq)]
2399 enum TupleArgumentsFlag {
2404 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2406 inh: &'a Inherited<'a, 'tcx>,
2407 param_env: ty::ParamEnv<'tcx>,
2408 body_id: hir::HirId,
2409 ) -> FnCtxt<'a, 'tcx> {
2413 err_count_on_creation: inh.tcx.sess.err_count(),
2415 ret_coercion_span: RefCell::new(None),
2417 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2418 hir::CRATE_HIR_ID)),
2419 diverges: Cell::new(Diverges::Maybe),
2420 has_errors: Cell::new(false),
2421 enclosing_breakables: RefCell::new(EnclosingBreakables {
2423 by_id: Default::default(),
2429 pub fn sess(&self) -> &Session {
2433 pub fn errors_reported_since_creation(&self) -> bool {
2434 self.tcx.sess.err_count() > self.err_count_on_creation
2437 /// Produces warning on the given node, if the current point in the
2438 /// function is unreachable, and there hasn't been another warning.
2439 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2440 // FIXME: Combine these two 'if' expressions into one once
2441 // let chains are implemented
2442 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2443 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2444 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2445 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2446 if !span.is_desugaring(DesugaringKind::CondTemporary) &&
2447 !span.is_desugaring(DesugaringKind::Async) &&
2448 !orig_span.is_desugaring(DesugaringKind::Await)
2450 self.diverges.set(Diverges::WarnedAlways);
2452 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2454 let msg = format!("unreachable {}", kind);
2455 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
2456 .span_label(span, &msg)
2459 custom_note.unwrap_or("any code following this expression is unreachable"),
2468 code: ObligationCauseCode<'tcx>)
2469 -> ObligationCause<'tcx> {
2470 ObligationCause::new(span, self.body_id, code)
2473 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2474 self.cause(span, ObligationCauseCode::MiscObligation)
2477 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2478 /// version (resolve_vars_if_possible), this version will
2479 /// also select obligations if it seems useful, in an effort
2480 /// to get more type information.
2481 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2482 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2484 // No Infer()? Nothing needs doing.
2485 if !ty.has_infer_types() && !ty.has_infer_consts() {
2486 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2490 // If `ty` is a type variable, see whether we already know what it is.
2491 ty = self.resolve_vars_if_possible(&ty);
2492 if !ty.has_infer_types() && !ty.has_infer_consts() {
2493 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2497 // If not, try resolving pending obligations as much as
2498 // possible. This can help substantially when there are
2499 // indirect dependencies that don't seem worth tracking
2501 self.select_obligations_where_possible(false, |_| {});
2502 ty = self.resolve_vars_if_possible(&ty);
2504 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2508 fn record_deferred_call_resolution(
2510 closure_def_id: DefId,
2511 r: DeferredCallResolution<'tcx>,
2513 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2514 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2517 fn remove_deferred_call_resolutions(
2519 closure_def_id: DefId,
2520 ) -> Vec<DeferredCallResolution<'tcx>> {
2521 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2522 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2525 pub fn tag(&self) -> String {
2526 format!("{:p}", self)
2529 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2530 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2531 span_bug!(span, "no type for local variable {}",
2532 self.tcx.hir().node_to_string(nid))
2537 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2538 debug!("write_ty({:?}, {:?}) in fcx {}",
2539 id, self.resolve_vars_if_possible(&ty), self.tag());
2540 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2542 if ty.references_error() {
2543 self.has_errors.set(true);
2544 self.set_tainted_by_errors();
2548 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2549 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2552 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2553 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2556 pub fn write_method_call(&self,
2558 method: MethodCallee<'tcx>) {
2559 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2560 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2561 self.write_substs(hir_id, method.substs);
2563 // When the method is confirmed, the `method.substs` includes
2564 // parameters from not just the method, but also the impl of
2565 // the method -- in particular, the `Self` type will be fully
2566 // resolved. However, those are not something that the "user
2567 // specified" -- i.e., those types come from the inferred type
2568 // of the receiver, not something the user wrote. So when we
2569 // create the user-substs, we want to replace those earlier
2570 // types with just the types that the user actually wrote --
2571 // that is, those that appear on the *method itself*.
2573 // As an example, if the user wrote something like
2574 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2575 // type of `foo` (possibly adjusted), but we don't want to
2576 // include that. We want just the `[_, u32]` part.
2577 if !method.substs.is_noop() {
2578 let method_generics = self.tcx.generics_of(method.def_id);
2579 if !method_generics.params.is_empty() {
2580 let user_type_annotation = self.infcx.probe(|_| {
2581 let user_substs = UserSubsts {
2582 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2583 let i = param.index as usize;
2584 if i < method_generics.parent_count {
2585 self.infcx.var_for_def(DUMMY_SP, param)
2590 user_self_ty: None, // not relevant here
2593 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2599 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2600 self.write_user_type_annotation(hir_id, user_type_annotation);
2605 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2606 if !substs.is_noop() {
2607 debug!("write_substs({:?}, {:?}) in fcx {}",
2612 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2616 /// Given the substs that we just converted from the HIR, try to
2617 /// canonicalize them and store them as user-given substitutions
2618 /// (i.e., substitutions that must be respected by the NLL check).
2620 /// This should be invoked **before any unifications have
2621 /// occurred**, so that annotations like `Vec<_>` are preserved
2623 pub fn write_user_type_annotation_from_substs(
2627 substs: SubstsRef<'tcx>,
2628 user_self_ty: Option<UserSelfTy<'tcx>>,
2631 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2632 user_self_ty={:?} in fcx {}",
2633 hir_id, def_id, substs, user_self_ty, self.tag(),
2636 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2637 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2638 &UserType::TypeOf(def_id, UserSubsts {
2643 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2644 self.write_user_type_annotation(hir_id, canonicalized);
2648 pub fn write_user_type_annotation(
2651 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2654 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2655 hir_id, canonical_user_type_annotation, self.tag(),
2658 if !canonical_user_type_annotation.is_identity() {
2659 self.tables.borrow_mut().user_provided_types_mut().insert(
2660 hir_id, canonical_user_type_annotation
2663 debug!("write_user_type_annotation: skipping identity substs");
2667 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2668 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2674 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2675 Entry::Vacant(entry) => { entry.insert(adj); },
2676 Entry::Occupied(mut entry) => {
2677 debug!(" - composing on top of {:?}", entry.get());
2678 match (&entry.get()[..], &adj[..]) {
2679 // Applying any adjustment on top of a NeverToAny
2680 // is a valid NeverToAny adjustment, because it can't
2682 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2684 Adjustment { kind: Adjust::Deref(_), .. },
2685 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2687 Adjustment { kind: Adjust::Deref(_), .. },
2688 .. // Any following adjustments are allowed.
2690 // A reborrow has no effect before a dereference.
2692 // FIXME: currently we never try to compose autoderefs
2693 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2695 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2696 expr, entry.get(), adj)
2698 *entry.get_mut() = adj;
2703 /// Basically whenever we are converting from a type scheme into
2704 /// the fn body space, we always want to normalize associated
2705 /// types as well. This function combines the two.
2706 fn instantiate_type_scheme<T>(&self,
2708 substs: SubstsRef<'tcx>,
2711 where T : TypeFoldable<'tcx>
2713 let value = value.subst(self.tcx, substs);
2714 let result = self.normalize_associated_types_in(span, &value);
2715 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2722 /// As `instantiate_type_scheme`, but for the bounds found in a
2723 /// generic type scheme.
2724 fn instantiate_bounds(
2728 substs: SubstsRef<'tcx>,
2729 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
2730 let bounds = self.tcx.predicates_of(def_id);
2731 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
2732 let result = bounds.instantiate(self.tcx, substs);
2733 let result = self.normalize_associated_types_in(span, &result);
2735 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
2744 /// Replaces the opaque types from the given value with type variables,
2745 /// and records the `OpaqueTypeMap` for later use during writeback. See
2746 /// `InferCtxt::instantiate_opaque_types` for more details.
2747 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2749 parent_id: hir::HirId,
2753 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2754 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2758 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2759 self.instantiate_opaque_types(
2768 let mut opaque_types = self.opaque_types.borrow_mut();
2769 for (ty, decl) in opaque_type_map {
2770 let old_value = opaque_types.insert(ty, decl);
2771 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2777 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2778 where T : TypeFoldable<'tcx>
2780 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2783 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2785 where T : TypeFoldable<'tcx>
2787 self.inh.partially_normalize_associated_types_in(span,
2793 pub fn require_type_meets(&self,
2796 code: traits::ObligationCauseCode<'tcx>,
2799 self.register_bound(
2802 traits::ObligationCause::new(span, self.body_id, code));
2805 pub fn require_type_is_sized(
2809 code: traits::ObligationCauseCode<'tcx>,
2811 if !ty.references_error() {
2812 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2813 self.require_type_meets(ty, span, code, lang_item);
2817 pub fn require_type_is_sized_deferred(
2821 code: traits::ObligationCauseCode<'tcx>,
2823 if !ty.references_error() {
2824 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2828 pub fn register_bound(
2832 cause: traits::ObligationCause<'tcx>,
2834 if !ty.references_error() {
2835 self.fulfillment_cx.borrow_mut()
2836 .register_bound(self, self.param_env, ty, def_id, cause);
2840 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2841 let t = AstConv::ast_ty_to_ty(self, ast_t);
2842 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2846 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2847 let ty = self.to_ty(ast_ty);
2848 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2850 if Self::can_contain_user_lifetime_bounds(ty) {
2851 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2852 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2853 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2859 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2860 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2861 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2864 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2865 AstConv::ast_const_to_const(self, ast_c, ty)
2868 // If the type given by the user has free regions, save it for later, since
2869 // NLL would like to enforce those. Also pass in types that involve
2870 // projections, since those can resolve to `'static` bounds (modulo #54940,
2871 // which hopefully will be fixed by the time you see this comment, dear
2872 // reader, although I have my doubts). Also pass in types with inference
2873 // types, because they may be repeated. Other sorts of things are already
2874 // sufficiently enforced with erased regions. =)
2875 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2877 T: TypeFoldable<'tcx>
2879 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2882 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2883 match self.tables.borrow().node_types().get(id) {
2885 None if self.is_tainted_by_errors() => self.tcx.types.err,
2887 bug!("no type for node {}: {} in fcx {}",
2888 id, self.tcx.hir().node_to_string(id),
2894 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2895 /// outlive the region `r`.
2896 pub fn register_wf_obligation(
2900 code: traits::ObligationCauseCode<'tcx>,
2902 // WF obligations never themselves fail, so no real need to give a detailed cause:
2903 let cause = traits::ObligationCause::new(span, self.body_id, code);
2904 self.register_predicate(
2905 traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
2909 /// Registers obligations that all types appearing in `substs` are well-formed.
2910 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2911 for ty in substs.types() {
2912 if !ty.references_error() {
2913 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2918 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2919 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2920 /// trait/region obligations.
2922 /// For example, if there is a function:
2925 /// fn foo<'a,T:'a>(...)
2928 /// and a reference:
2934 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2935 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2936 pub fn add_obligations_for_parameters(&self,
2937 cause: traits::ObligationCause<'tcx>,
2938 predicates: &ty::InstantiatedPredicates<'tcx>)
2940 assert!(!predicates.has_escaping_bound_vars());
2942 debug!("add_obligations_for_parameters(predicates={:?})",
2945 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2946 self.register_predicate(obligation);
2950 // FIXME(arielb1): use this instead of field.ty everywhere
2951 // Only for fields! Returns <none> for methods>
2952 // Indifferent to privacy flags
2956 field: &'tcx ty::FieldDef,
2957 substs: SubstsRef<'tcx>,
2959 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2962 fn check_casts(&self) {
2963 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2964 for cast in deferred_cast_checks.drain(..) {
2969 fn resolve_generator_interiors(&self, def_id: DefId) {
2970 let mut generators = self.deferred_generator_interiors.borrow_mut();
2971 for (body_id, interior, kind) in generators.drain(..) {
2972 self.select_obligations_where_possible(false, |_| {});
2973 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
2977 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2978 // Non-numerics get replaced with ! or () (depending on whether
2979 // feature(never_type) is enabled, unconstrained ints with i32,
2980 // unconstrained floats with f64.
2981 // Fallback becomes very dubious if we have encountered type-checking errors.
2982 // In that case, fallback to Error.
2983 // The return value indicates whether fallback has occurred.
2984 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2985 use rustc::ty::error::UnconstrainedNumeric::Neither;
2986 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2988 assert!(ty.is_ty_infer());
2989 let fallback = match self.type_is_unconstrained_numeric(ty) {
2990 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2991 UnconstrainedInt => self.tcx.types.i32,
2992 UnconstrainedFloat => self.tcx.types.f64,
2993 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2994 Neither => return false,
2996 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2997 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
3001 fn select_all_obligations_or_error(&self) {
3002 debug!("select_all_obligations_or_error");
3003 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3004 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3008 /// Select as many obligations as we can at present.
3009 fn select_obligations_where_possible(
3011 fallback_has_occurred: bool,
3012 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3014 if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3015 mutate_fullfillment_errors(&mut errors);
3016 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3020 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3021 /// returns a type of `&T`, but the actual type we assign to the
3022 /// *expression* is `T`. So this function just peels off the return
3023 /// type by one layer to yield `T`.
3024 fn make_overloaded_place_return_type(&self,
3025 method: MethodCallee<'tcx>)
3026 -> ty::TypeAndMut<'tcx>
3028 // extract method return type, which will be &T;
3029 let ret_ty = method.sig.output();
3031 // method returns &T, but the type as visible to user is T, so deref
3032 ret_ty.builtin_deref(true).unwrap()
3038 base_expr: &'tcx hir::Expr,
3042 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3043 // FIXME(#18741) -- this is almost but not quite the same as the
3044 // autoderef that normal method probing does. They could likely be
3047 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3048 let mut result = None;
3049 while result.is_none() && autoderef.next().is_some() {
3050 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3052 autoderef.finalize(self);
3056 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3057 /// (and otherwise adjust) `base_expr`, looking for a type which either
3058 /// supports builtin indexing or overloaded indexing.
3059 /// This loop implements one step in that search; the autoderef loop
3060 /// is implemented by `lookup_indexing`.
3064 base_expr: &hir::Expr,
3065 autoderef: &Autoderef<'a, 'tcx>,
3068 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3069 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3070 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3077 for &unsize in &[false, true] {
3078 let mut self_ty = adjusted_ty;
3080 // We only unsize arrays here.
3081 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3082 self_ty = self.tcx.mk_slice(element_ty);
3088 // If some lookup succeeds, write callee into table and extract index/element
3089 // type from the method signature.
3090 // If some lookup succeeded, install method in table
3091 let input_ty = self.next_ty_var(TypeVariableOrigin {
3092 kind: TypeVariableOriginKind::AutoDeref,
3093 span: base_expr.span,
3095 let method = self.try_overloaded_place_op(
3096 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
3098 let result = method.map(|ok| {
3099 debug!("try_index_step: success, using overloaded indexing");
3100 let method = self.register_infer_ok_obligations(ok);
3102 let mut adjustments = autoderef.adjust_steps(self, needs);
3103 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3104 let mutbl = match r_mutbl {
3105 hir::MutImmutable => AutoBorrowMutability::Immutable,
3106 hir::MutMutable => AutoBorrowMutability::Mutable {
3107 // Indexing can be desugared to a method call,
3108 // so maybe we could use two-phase here.
3109 // See the documentation of AllowTwoPhase for why that's
3110 // not the case today.
3111 allow_two_phase_borrow: AllowTwoPhase::No,
3114 adjustments.push(Adjustment {
3115 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3116 target: self.tcx.mk_ref(region, ty::TypeAndMut {
3123 adjustments.push(Adjustment {
3124 kind: Adjust::Pointer(PointerCast::Unsize),
3125 target: method.sig.inputs()[0]
3128 self.apply_adjustments(base_expr, adjustments);
3130 self.write_method_call(expr.hir_id, method);
3131 (input_ty, self.make_overloaded_place_return_type(method).ty)
3133 if result.is_some() {
3141 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3142 let (tr, name) = match (op, is_mut) {
3143 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3144 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3145 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3146 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3148 (tr, ast::Ident::with_dummy_span(name))
3151 fn try_overloaded_place_op(&self,
3154 arg_tys: &[Ty<'tcx>],
3157 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
3159 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
3165 // Try Mut first, if needed.
3166 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3167 let method = match (needs, mut_tr) {
3168 (Needs::MutPlace, Some(trait_did)) => {
3169 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3174 // Otherwise, fall back to the immutable version.
3175 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3176 let method = match (method, imm_tr) {
3177 (None, Some(trait_did)) => {
3178 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3180 (method, _) => method,
3186 fn check_method_argument_types(
3189 expr: &'tcx hir::Expr,
3190 method: Result<MethodCallee<'tcx>, ()>,
3191 args_no_rcvr: &'tcx [hir::Expr],
3192 tuple_arguments: TupleArgumentsFlag,
3193 expected: Expectation<'tcx>,
3196 let has_error = match method {
3198 method.substs.references_error() || method.sig.references_error()
3203 let err_inputs = self.err_args(args_no_rcvr.len());
3205 let err_inputs = match tuple_arguments {
3206 DontTupleArguments => err_inputs,
3207 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3210 self.check_argument_types(
3220 return self.tcx.types.err;
3223 let method = method.unwrap();
3224 // HACK(eddyb) ignore self in the definition (see above).
3225 let expected_arg_tys = self.expected_inputs_for_expected_output(
3228 method.sig.output(),
3229 &method.sig.inputs()[1..]
3231 self.check_argument_types(
3234 &method.sig.inputs()[1..],
3235 &expected_arg_tys[..],
3237 method.sig.c_variadic,
3239 self.tcx.hir().span_if_local(method.def_id),
3244 fn self_type_matches_expected_vid(
3246 trait_ref: ty::PolyTraitRef<'tcx>,
3247 expected_vid: ty::TyVid,
3249 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3251 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3252 trait_ref, self_ty, expected_vid
3254 match self_ty.kind {
3255 ty::Infer(ty::TyVar(found_vid)) => {
3256 // FIXME: consider using `sub_root_var` here so we
3257 // can see through subtyping.
3258 let found_vid = self.root_var(found_vid);
3259 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3260 expected_vid == found_vid
3266 fn obligations_for_self_ty<'b>(
3269 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3272 // FIXME: consider using `sub_root_var` here so we
3273 // can see through subtyping.
3274 let ty_var_root = self.root_var(self_ty);
3275 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3276 self_ty, ty_var_root,
3277 self.fulfillment_cx.borrow().pending_obligations());
3281 .pending_obligations()
3283 .filter_map(move |obligation| match obligation.predicate {
3284 ty::Predicate::Projection(ref data) =>
3285 Some((data.to_poly_trait_ref(self.tcx), obligation)),
3286 ty::Predicate::Trait(ref data) =>
3287 Some((data.to_poly_trait_ref(), obligation)),
3288 ty::Predicate::Subtype(..) => None,
3289 ty::Predicate::RegionOutlives(..) => None,
3290 ty::Predicate::TypeOutlives(..) => None,
3291 ty::Predicate::WellFormed(..) => None,
3292 ty::Predicate::ObjectSafe(..) => None,
3293 ty::Predicate::ConstEvaluatable(..) => None,
3294 // N.B., this predicate is created by breaking down a
3295 // `ClosureType: FnFoo()` predicate, where
3296 // `ClosureType` represents some `Closure`. It can't
3297 // possibly be referring to the current closure,
3298 // because we haven't produced the `Closure` for
3299 // this closure yet; this is exactly why the other
3300 // code is looking for a self type of a unresolved
3301 // inference variable.
3302 ty::Predicate::ClosureKind(..) => None,
3303 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3306 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3307 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
3308 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
3312 /// Generic function that factors out common logic from function calls,
3313 /// method calls and overloaded operators.
3314 fn check_argument_types(
3317 expr: &'tcx hir::Expr,
3318 fn_inputs: &[Ty<'tcx>],
3319 expected_arg_tys: &[Ty<'tcx>],
3320 args: &'tcx [hir::Expr],
3322 tuple_arguments: TupleArgumentsFlag,
3323 def_span: Option<Span>,
3326 // Grab the argument types, supplying fresh type variables
3327 // if the wrong number of arguments were supplied
3328 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
3334 // All the input types from the fn signature must outlive the call
3335 // so as to validate implied bounds.
3336 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3337 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3340 let expected_arg_count = fn_inputs.len();
3342 let param_count_error = |expected_count: usize,
3347 let mut err = tcx.sess.struct_span_err_with_code(sp,
3348 &format!("this function takes {}{} but {} {} supplied",
3349 if c_variadic { "at least " } else { "" },
3350 potentially_plural_count(expected_count, "parameter"),
3351 potentially_plural_count(arg_count, "parameter"),
3352 if arg_count == 1 {"was"} else {"were"}),
3353 DiagnosticId::Error(error_code.to_owned()));
3355 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3356 err.span_label(def_s, "defined here");
3359 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3360 // remove closing `)` from the span
3361 let sugg_span = sugg_span.shrink_to_lo();
3362 err.span_suggestion(
3364 "expected the unit value `()`; create it with empty parentheses",
3366 Applicability::MachineApplicable);
3368 err.span_label(sp, format!("expected {}{}",
3369 if c_variadic { "at least " } else { "" },
3370 potentially_plural_count(expected_count, "parameter")));
3375 let mut expected_arg_tys = expected_arg_tys.to_vec();
3377 let formal_tys = if tuple_arguments == TupleArguments {
3378 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3379 match tuple_type.kind {
3380 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3381 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3382 expected_arg_tys = vec![];
3383 self.err_args(args.len())
3385 ty::Tuple(arg_types) => {
3386 expected_arg_tys = match expected_arg_tys.get(0) {
3387 Some(&ty) => match ty.kind {
3388 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3393 arg_types.iter().map(|k| k.expect_ty()).collect()
3396 span_err!(tcx.sess, sp, E0059,
3397 "cannot use call notation; the first type parameter \
3398 for the function trait is neither a tuple nor unit");
3399 expected_arg_tys = vec![];
3400 self.err_args(args.len())
3403 } else if expected_arg_count == supplied_arg_count {
3405 } else if c_variadic {
3406 if supplied_arg_count >= expected_arg_count {
3409 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3410 expected_arg_tys = vec![];
3411 self.err_args(supplied_arg_count)
3414 // is the missing argument of type `()`?
3415 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3416 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3417 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3418 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3422 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3424 expected_arg_tys = vec![];
3425 self.err_args(supplied_arg_count)
3428 debug!("check_argument_types: formal_tys={:?}",
3429 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3431 // If there is no expectation, expect formal_tys.
3432 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3438 let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
3440 // Check the arguments.
3441 // We do this in a pretty awful way: first we type-check any arguments
3442 // that are not closures, then we type-check the closures. This is so
3443 // that we have more information about the types of arguments when we
3444 // type-check the functions. This isn't really the right way to do this.
3445 for &check_closures in &[false, true] {
3446 debug!("check_closures={}", check_closures);
3448 // More awful hacks: before we check argument types, try to do
3449 // an "opportunistic" vtable resolution of any trait bounds on
3450 // the call. This helps coercions.
3452 self.select_obligations_where_possible(false, |errors| {
3453 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
3454 self.point_at_arg_instead_of_call_if_possible(
3456 &final_arg_types[..],
3463 // For C-variadic functions, we don't have a declared type for all of
3464 // the arguments hence we only do our usual type checking with
3465 // the arguments who's types we do know.
3466 let t = if c_variadic {
3468 } else if tuple_arguments == TupleArguments {
3473 for (i, arg) in args.iter().take(t).enumerate() {
3474 // Warn only for the first loop (the "no closures" one).
3475 // Closure arguments themselves can't be diverging, but
3476 // a previous argument can, e.g., `foo(panic!(), || {})`.
3477 if !check_closures {
3478 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3481 let is_closure = match arg.kind {
3482 ExprKind::Closure(..) => true,
3486 if is_closure != check_closures {
3490 debug!("checking the argument");
3491 let formal_ty = formal_tys[i];
3493 // The special-cased logic below has three functions:
3494 // 1. Provide as good of an expected type as possible.
3495 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3497 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3499 // 2. Coerce to the most detailed type that could be coerced
3500 // to, which is `expected_ty` if `rvalue_hint` returns an
3501 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3502 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3503 // We're processing function arguments so we definitely want to use
3504 // two-phase borrows.
3505 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3506 final_arg_types.push((i, coerce_ty));
3508 // 3. Relate the expected type and the formal one,
3509 // if the expected type was used for the coercion.
3510 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3514 // We also need to make sure we at least write the ty of the other
3515 // arguments which we skipped above.
3517 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3518 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3519 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3522 for arg in args.iter().skip(expected_arg_count) {
3523 let arg_ty = self.check_expr(&arg);
3525 // There are a few types which get autopromoted when passed via varargs
3526 // in C but we just error out instead and require explicit casts.
3527 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3529 ty::Float(ast::FloatTy::F32) => {
3530 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3532 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3533 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3535 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3536 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3539 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3540 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3541 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3549 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3550 vec![self.tcx.types.err; len]
3553 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
3554 /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
3555 /// reference a type argument. If they do, and there's only *one* argument that does, we point
3556 /// at the corresponding argument's expression span instead of the `fn` call path span.
3557 fn point_at_arg_instead_of_call_if_possible(
3559 errors: &mut Vec<traits::FulfillmentError<'_>>,
3560 final_arg_types: &[(usize, Ty<'tcx>)],
3562 args: &'tcx [hir::Expr],
3564 if !call_sp.desugaring_kind().is_some() {
3565 // We *do not* do this for desugared call spans to keep good diagnostics when involving
3566 // the `?` operator.
3567 for error in errors {
3568 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3569 // Collect the argument position for all arguments that could have caused this
3570 // `FullfillmentError`.
3571 let mut referenced_in = final_arg_types.iter()
3572 .flat_map(|(i, ty)| {
3573 let ty = self.resolve_vars_if_possible(ty);
3574 // We walk the argument type because the argument's type could have
3575 // been `Option<T>`, but the `FullfillmentError` references `T`.
3577 .filter(|&ty| ty == predicate.skip_binder().self_ty())
3580 if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3581 // We make sure that only *one* argument matches the obligation failure
3582 // and thet the obligation's span to its expression's.
3583 error.obligation.cause.span = args[ref_in].span;
3584 error.points_at_arg_span = true;
3591 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
3592 /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
3593 /// were caused by them. If they were, we point at the corresponding type argument's span
3594 /// instead of the `fn` call path span.
3595 fn point_at_type_arg_instead_of_call_if_possible(
3597 errors: &mut Vec<traits::FulfillmentError<'_>>,
3598 call_expr: &'tcx hir::Expr,
3600 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
3601 if let hir::ExprKind::Path(qpath) = &path.kind {
3602 if let hir::QPath::Resolved(_, path) = &qpath {
3603 for error in errors {
3604 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3605 // If any of the type arguments in this path segment caused the
3606 // `FullfillmentError`, point at its span (#61860).
3607 for arg in path.segments.iter()
3608 .filter_map(|seg| seg.args.as_ref())
3609 .flat_map(|a| a.args.iter())
3611 if let hir::GenericArg::Type(hir_ty) = &arg {
3612 if let hir::TyKind::Path(
3613 hir::QPath::TypeRelative(..),
3615 // Avoid ICE with associated types. As this is best
3616 // effort only, it's ok to ignore the case. It
3617 // would trigger in `is_send::<T::AssocType>();`
3618 // from `typeck-default-trait-impl-assoc-type.rs`.
3620 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
3621 let ty = self.resolve_vars_if_possible(&ty);
3622 if ty == predicate.skip_binder().self_ty() {
3623 error.obligation.cause.span = hir_ty.span;
3635 // AST fragment checking
3638 expected: Expectation<'tcx>)
3644 ast::LitKind::Str(..) => tcx.mk_static_str(),
3645 ast::LitKind::ByteStr(ref v) => {
3646 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3647 tcx.mk_array(tcx.types.u8, v.len() as u64))
3649 ast::LitKind::Byte(_) => tcx.types.u8,
3650 ast::LitKind::Char(_) => tcx.types.char,
3651 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3652 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3653 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3654 let opt_ty = expected.to_option(self).and_then(|ty| {
3656 ty::Int(_) | ty::Uint(_) => Some(ty),
3657 ty::Char => Some(tcx.types.u8),
3658 ty::RawPtr(..) => Some(tcx.types.usize),
3659 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3663 opt_ty.unwrap_or_else(|| self.next_int_var())
3665 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3666 ast::LitKind::FloatUnsuffixed(_) => {
3667 let opt_ty = expected.to_option(self).and_then(|ty| {
3669 ty::Float(_) => Some(ty),
3673 opt_ty.unwrap_or_else(|| self.next_float_var())
3675 ast::LitKind::Bool(_) => tcx.types.bool,
3676 ast::LitKind::Err(_) => tcx.types.err,
3680 // Determine the `Self` type, using fresh variables for all variables
3681 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3682 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3684 pub fn impl_self_ty(&self,
3685 span: Span, // (potential) receiver for this impl
3687 -> TypeAndSubsts<'tcx> {
3688 let ity = self.tcx.type_of(did);
3689 debug!("impl_self_ty: ity={:?}", ity);
3691 let substs = self.fresh_substs_for_item(span, did);
3692 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3694 TypeAndSubsts { substs: substs, ty: substd_ty }
3697 /// Unifies the output type with the expected type early, for more coercions
3698 /// and forward type information on the input expressions.
3699 fn expected_inputs_for_expected_output(&self,
3701 expected_ret: Expectation<'tcx>,
3702 formal_ret: Ty<'tcx>,
3703 formal_args: &[Ty<'tcx>])
3705 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
3706 let ret_ty = match expected_ret.only_has_type(self) {
3708 None => return Vec::new()
3710 let expect_args = self.fudge_inference_if_ok(|| {
3711 // Attempt to apply a subtyping relationship between the formal
3712 // return type (likely containing type variables if the function
3713 // is polymorphic) and the expected return type.
3714 // No argument expectations are produced if unification fails.
3715 let origin = self.misc(call_span);
3716 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3718 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3719 // to identity so the resulting type is not constrained.
3722 // Process any obligations locally as much as
3723 // we can. We don't care if some things turn
3724 // out unconstrained or ambiguous, as we're
3725 // just trying to get hints here.
3726 self.save_and_restore_in_snapshot_flag(|_| {
3727 let mut fulfill = TraitEngine::new(self.tcx);
3728 for obligation in ok.obligations {
3729 fulfill.register_predicate_obligation(self, obligation);
3731 fulfill.select_where_possible(self)
3732 }).map_err(|_| ())?;
3734 Err(_) => return Err(()),
3737 // Record all the argument types, with the substitutions
3738 // produced from the above subtyping unification.
3739 Ok(formal_args.iter().map(|ty| {
3740 self.resolve_vars_if_possible(ty)
3742 }).unwrap_or_default();
3743 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3744 formal_args, formal_ret,
3745 expect_args, expected_ret);
3749 pub fn check_struct_path(&self,
3752 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3753 let path_span = match *qpath {
3754 QPath::Resolved(_, ref path) => path.span,
3755 QPath::TypeRelative(ref qself, _) => qself.span
3757 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3758 let variant = match def {
3760 self.set_tainted_by_errors();
3763 Res::Def(DefKind::Variant, _) => {
3765 ty::Adt(adt, substs) => {
3766 Some((adt.variant_of_res(def), adt.did, substs))
3768 _ => bug!("unexpected type: {:?}", ty)
3771 Res::Def(DefKind::Struct, _)
3772 | Res::Def(DefKind::Union, _)
3773 | Res::Def(DefKind::TyAlias, _)
3774 | Res::Def(DefKind::AssocTy, _)
3775 | Res::SelfTy(..) => {
3777 ty::Adt(adt, substs) if !adt.is_enum() => {
3778 Some((adt.non_enum_variant(), adt.did, substs))
3783 _ => bug!("unexpected definition: {:?}", def)
3786 if let Some((variant, did, substs)) = variant {
3787 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3788 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3790 // Check bounds on type arguments used in the path.
3791 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
3792 let cause = traits::ObligationCause::new(
3795 traits::ItemObligation(did),
3797 self.add_obligations_for_parameters(cause, &bounds);
3801 struct_span_err!(self.tcx.sess, path_span, E0071,
3802 "expected struct, variant or union type, found {}",
3803 ty.sort_string(self.tcx))
3804 .span_label(path_span, "not a struct")
3810 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3811 // The newly resolved definition is written into `type_dependent_defs`.
3812 fn finish_resolving_struct_path(&self,
3819 QPath::Resolved(ref maybe_qself, ref path) => {
3820 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3821 let ty = AstConv::res_to_ty(self, self_ty, path, true);
3824 QPath::TypeRelative(ref qself, ref segment) => {
3825 let ty = self.to_ty(qself);
3827 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
3832 let result = AstConv::associated_path_to_ty(
3841 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
3842 let result = result.map(|(_, kind, def_id)| (kind, def_id));
3844 // Write back the new resolution.
3845 self.write_resolution(hir_id, result);
3847 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
3852 /// Resolves an associated value path into a base type and associated constant, or method
3853 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
3854 pub fn resolve_ty_and_res_ufcs<'b>(&self,
3858 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3860 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
3861 let (ty, qself, item_segment) = match *qpath {
3862 QPath::Resolved(ref opt_qself, ref path) => {
3864 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3865 &path.segments[..]);
3867 QPath::TypeRelative(ref qself, ref segment) => {
3868 (self.to_ty(qself), qself, segment)
3871 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
3872 // Return directly on cache hit. This is useful to avoid doubly reporting
3873 // errors with default match binding modes. See #44614.
3874 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
3875 .unwrap_or(Res::Err);
3876 return (def, Some(ty), slice::from_ref(&**item_segment));
3878 let item_name = item_segment.ident;
3879 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
3880 let result = match error {
3881 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
3882 _ => Err(ErrorReported),
3884 if item_name.name != kw::Invalid {
3885 self.report_method_error(
3889 SelfSource::QPath(qself),
3892 ).map(|mut e| e.emit());
3897 // Write back the new resolution.
3898 self.write_resolution(hir_id, result);
3900 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
3902 slice::from_ref(&**item_segment),
3906 pub fn check_decl_initializer(
3908 local: &'tcx hir::Local,
3909 init: &'tcx hir::Expr,
3911 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
3912 // for #42640 (default match binding modes).
3915 let ref_bindings = local.pat.contains_explicit_ref_binding();
3917 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
3918 if let Some(m) = ref_bindings {
3919 // Somewhat subtle: if we have a `ref` binding in the pattern,
3920 // we want to avoid introducing coercions for the RHS. This is
3921 // both because it helps preserve sanity and, in the case of
3922 // ref mut, for soundness (issue #23116). In particular, in
3923 // the latter case, we need to be clear that the type of the
3924 // referent for the reference that results is *equal to* the
3925 // type of the place it is referencing, and not some
3926 // supertype thereof.
3927 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
3928 self.demand_eqtype(init.span, local_ty, init_ty);
3931 self.check_expr_coercable_to_type(init, local_ty)
3935 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
3936 let t = self.local_ty(local.span, local.hir_id).decl_ty;
3937 self.write_ty(local.hir_id, t);
3939 if let Some(ref init) = local.init {
3940 let init_ty = self.check_decl_initializer(local, &init);
3941 self.overwrite_local_ty_if_err(local, t, init_ty);
3944 self.check_pat_top(&local.pat, t, None);
3945 let pat_ty = self.node_ty(local.pat.hir_id);
3946 self.overwrite_local_ty_if_err(local, t, pat_ty);
3949 fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
3950 if ty.references_error() {
3951 // Override the types everywhere with `types.err` to avoid knock down errors.
3952 self.write_ty(local.hir_id, ty);
3953 self.write_ty(local.pat.hir_id, ty);
3954 let local_ty = LocalTy {
3958 self.locals.borrow_mut().insert(local.hir_id, local_ty);
3959 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
3963 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
3964 err.span_suggestion_short(
3965 span.shrink_to_hi(),
3966 "consider using a semicolon here",
3968 Applicability::MachineApplicable,
3972 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
3973 // Don't do all the complex logic below for `DeclItem`.
3975 hir::StmtKind::Item(..) => return,
3976 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
3979 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
3981 // Hide the outer diverging and `has_errors` flags.
3982 let old_diverges = self.diverges.get();
3983 let old_has_errors = self.has_errors.get();
3984 self.diverges.set(Diverges::Maybe);
3985 self.has_errors.set(false);
3988 hir::StmtKind::Local(ref l) => {
3989 self.check_decl_local(&l);
3992 hir::StmtKind::Item(_) => {}
3993 hir::StmtKind::Expr(ref expr) => {
3994 // Check with expected type of `()`.
3996 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
3997 self.suggest_semicolon_at_end(expr.span, err);
4000 hir::StmtKind::Semi(ref expr) => {
4001 self.check_expr(&expr);
4005 // Combine the diverging and `has_error` flags.
4006 self.diverges.set(self.diverges.get() | old_diverges);
4007 self.has_errors.set(self.has_errors.get() | old_has_errors);
4010 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
4011 let unit = self.tcx.mk_unit();
4012 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4014 // if the block produces a `!` value, that can always be
4015 // (effectively) coerced to unit.
4017 self.demand_suptype(blk.span, unit, ty);
4021 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4022 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4023 /// when given code like the following:
4025 /// if false { return 0i32; } else { 1u32 }
4026 /// // ^^^^ point at this instead of the whole `if` expression
4028 fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
4029 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4030 let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
4031 self.in_progress_tables
4032 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4033 .and_then(|arm_ty| {
4034 if arm_ty.is_never() {
4037 Some(match &arm.body.kind {
4038 // Point at the tail expression when possible.
4039 hir::ExprKind::Block(block, _) => block.expr
4042 .unwrap_or(block.span),
4048 if arm_spans.len() == 1 {
4049 return arm_spans[0];
4055 fn check_block_with_expected(
4057 blk: &'tcx hir::Block,
4058 expected: Expectation<'tcx>,
4061 let mut fcx_ps = self.ps.borrow_mut();
4062 let unsafety_state = fcx_ps.recurse(blk);
4063 replace(&mut *fcx_ps, unsafety_state)
4066 // In some cases, blocks have just one exit, but other blocks
4067 // can be targeted by multiple breaks. This can happen both
4068 // with labeled blocks as well as when we desugar
4069 // a `try { ... }` expression.
4073 // 'a: { if true { break 'a Err(()); } Ok(()) }
4075 // Here we would wind up with two coercions, one from
4076 // `Err(())` and the other from the tail expression
4077 // `Ok(())`. If the tail expression is omitted, that's a
4078 // "forced unit" -- unless the block diverges, in which
4079 // case we can ignore the tail expression (e.g., `'a: {
4080 // break 'a 22; }` would not force the type of the block
4082 let tail_expr = blk.expr.as_ref();
4083 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4084 let coerce = if blk.targeted_by_break {
4085 CoerceMany::new(coerce_to_ty)
4087 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4088 Some(e) => slice::from_ref(e),
4091 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4094 let prev_diverges = self.diverges.get();
4095 let ctxt = BreakableCtxt {
4096 coerce: Some(coerce),
4100 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4101 for s in &blk.stmts {
4105 // check the tail expression **without** holding the
4106 // `enclosing_breakables` lock below.
4107 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4109 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4110 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4111 let coerce = ctxt.coerce.as_mut().unwrap();
4112 if let Some(tail_expr_ty) = tail_expr_ty {
4113 let tail_expr = tail_expr.unwrap();
4114 let span = self.get_expr_coercion_span(tail_expr);
4115 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4116 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4118 // Subtle: if there is no explicit tail expression,
4119 // that is typically equivalent to a tail expression
4120 // of `()` -- except if the block diverges. In that
4121 // case, there is no value supplied from the tail
4122 // expression (assuming there are no other breaks,
4123 // this implies that the type of the block will be
4126 // #41425 -- label the implicit `()` as being the
4127 // "found type" here, rather than the "expected type".
4128 if !self.diverges.get().is_always() {
4129 // #50009 -- Do not point at the entire fn block span, point at the return type
4130 // span, as it is the cause of the requirement, and
4131 // `consider_hint_about_removing_semicolon` will point at the last expression
4132 // if it were a relevant part of the error. This improves usability in editors
4133 // that highlight errors inline.
4134 let mut sp = blk.span;
4135 let mut fn_span = None;
4136 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4137 let ret_sp = decl.output.span();
4138 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4139 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4140 // output would otherwise be incorrect and even misleading. Make sure
4141 // the span we're aiming at correspond to a `fn` body.
4142 if block_sp == blk.span {
4144 fn_span = Some(ident.span);
4148 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
4149 if let Some(expected_ty) = expected.only_has_type(self) {
4150 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4152 if let Some(fn_span) = fn_span {
4155 "implicitly returns `()` as its body has no tail or `return` \
4165 // If we can break from the block, then the block's exit is always reachable
4166 // (... as long as the entry is reachable) - regardless of the tail of the block.
4167 self.diverges.set(prev_diverges);
4170 let mut ty = ctxt.coerce.unwrap().complete(self);
4172 if self.has_errors.get() || ty.references_error() {
4173 ty = self.tcx.types.err
4176 self.write_ty(blk.hir_id, ty);
4178 *self.ps.borrow_mut() = prev;
4182 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4183 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4185 Node::Item(&hir::Item {
4186 kind: hir::ItemKind::Fn(_, _, _, body_id), ..
4188 Node::ImplItem(&hir::ImplItem {
4189 kind: hir::ImplItemKind::Method(_, body_id), ..
4191 let body = self.tcx.hir().body(body_id);
4192 if let ExprKind::Block(block, _) = &body.value.kind {
4193 return Some(block.span);
4201 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4202 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
4203 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4204 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4207 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4208 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
4210 Node::Item(&hir::Item {
4211 ident, kind: hir::ItemKind::Fn(ref decl, ..), ..
4213 // This is less than ideal, it will not suggest a return type span on any
4214 // method called `main`, regardless of whether it is actually the entry point,
4215 // but it will still present it as the reason for the expected type.
4216 Some((decl, ident, ident.name != sym::main))
4218 Node::TraitItem(&hir::TraitItem {
4219 ident, kind: hir::TraitItemKind::Method(hir::MethodSig {
4222 }) => Some((decl, ident, true)),
4223 Node::ImplItem(&hir::ImplItem {
4224 ident, kind: hir::ImplItemKind::Method(hir::MethodSig {
4227 }) => Some((decl, ident, false)),
4232 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4233 /// suggestion can be made, `None` otherwise.
4234 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
4235 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4236 // `while` before reaching it, as block tail returns are not available in them.
4237 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4238 let parent = self.tcx.hir().get(blk_id);
4239 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4243 /// On implicit return expressions with mismatched types, provides the following suggestions:
4245 /// - Points out the method's return type as the reason for the expected type.
4246 /// - Possible missing semicolon.
4247 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4248 pub fn suggest_mismatched_types_on_tail(
4250 err: &mut DiagnosticBuilder<'tcx>,
4251 expr: &'tcx hir::Expr,
4257 let expr = expr.peel_drop_temps();
4258 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4259 let mut pointing_at_return_type = false;
4260 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4261 pointing_at_return_type = self.suggest_missing_return_type(
4262 err, &fn_decl, expected, found, can_suggest);
4264 self.suggest_ref_or_into(err, expr, expected, found);
4265 self.suggest_boxing_when_appropriate(err, expr, expected, found);
4266 pointing_at_return_type
4269 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4270 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4272 /// fn foo(x: usize) -> usize { x }
4273 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4277 err: &mut DiagnosticBuilder<'tcx>,
4282 let hir = self.tcx.hir();
4283 let (def_id, sig) = match found.kind {
4284 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4285 ty::Closure(def_id, substs) => {
4286 // We don't use `closure_sig` to account for malformed closures like
4287 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4288 let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4289 (def_id, match closure_sig_ty.kind {
4290 ty::FnPtr(sig) => sig,
4298 .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
4300 let sig = self.normalize_associated_types_in(expr.span, &sig);
4301 if self.can_coerce(sig.output(), expected) {
4302 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4303 (String::new(), Applicability::MachineApplicable)
4305 ("...".to_string(), Applicability::HasPlaceholders)
4307 let mut msg = "call this function";
4308 match hir.get_if_local(def_id) {
4309 Some(Node::Item(hir::Item {
4310 kind: ItemKind::Fn(.., body_id),
4313 Some(Node::ImplItem(hir::ImplItem {
4314 kind: hir::ImplItemKind::Method(_, body_id),
4317 Some(Node::TraitItem(hir::TraitItem {
4318 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4321 let body = hir.body(*body_id);
4322 sugg_call = body.params.iter()
4323 .map(|param| match ¶m.pat.kind {
4324 hir::PatKind::Binding(_, _, ident, None)
4325 if ident.name != kw::SelfLower => ident.to_string(),
4326 _ => "_".to_string(),
4327 }).collect::<Vec<_>>().join(", ");
4329 Some(Node::Expr(hir::Expr {
4330 kind: ExprKind::Closure(_, _, body_id, closure_span, _),
4331 span: full_closure_span,
4334 if *full_closure_span == expr.span {
4337 err.span_label(*closure_span, "closure defined here");
4338 msg = "call this closure";
4339 let body = hir.body(*body_id);
4340 sugg_call = body.params.iter()
4341 .map(|param| match ¶m.pat.kind {
4342 hir::PatKind::Binding(_, _, ident, None)
4343 if ident.name != kw::SelfLower => ident.to_string(),
4344 _ => "_".to_string(),
4345 }).collect::<Vec<_>>().join(", ");
4347 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4348 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4349 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4350 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4351 msg = "instantiate this tuple variant";
4353 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4354 msg = "instantiate this tuple struct";
4359 Some(Node::ForeignItem(hir::ForeignItem {
4360 kind: hir::ForeignItemKind::Fn(_, idents, _),
4363 Some(Node::TraitItem(hir::TraitItem {
4364 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4366 })) => sugg_call = idents.iter()
4367 .map(|ident| if ident.name != kw::SelfLower {
4371 }).collect::<Vec<_>>()
4375 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4376 err.span_suggestion(
4378 &format!("use parentheses to {}", msg),
4379 format!("{}({})", code, sugg_call),
4388 pub fn suggest_ref_or_into(
4390 err: &mut DiagnosticBuilder<'tcx>,
4395 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4396 err.span_suggestion(
4400 Applicability::MachineApplicable,
4402 } else if let (ty::FnDef(def_id, ..), true) = (
4404 self.suggest_fn_call(err, expr, expected, found),
4406 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4407 let sp = self.sess().source_map().def_span(sp);
4408 err.span_label(sp, &format!("{} defined here", found));
4410 } else if !self.check_for_cast(err, expr, found, expected) {
4411 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4415 let methods = self.get_conversion_methods(expr.span, expected, found);
4416 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4417 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4418 .filter_map(|(receiver, method)| {
4419 let method_call = format!(".{}()", method.ident);
4420 if receiver.ends_with(&method_call) {
4421 None // do not suggest code that is already there (#53348)
4423 let method_call_list = [".to_vec()", ".to_string()"];
4424 let sugg = if receiver.ends_with(".clone()")
4425 && method_call_list.contains(&method_call.as_str()) {
4426 let max_len = receiver.rfind(".").unwrap();
4427 format!("{}{}", &receiver[..max_len], method_call)
4429 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
4430 format!("({}){}", receiver, method_call)
4432 format!("{}{}", receiver, method_call)
4435 Some(if is_struct_pat_shorthand_field {
4436 format!("{}: {}", receiver, sugg)
4442 if suggestions.peek().is_some() {
4443 err.span_suggestions(
4445 "try using a conversion method",
4447 Applicability::MaybeIncorrect,
4454 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
4455 /// in the heap by calling `Box::new()`.
4456 fn suggest_boxing_when_appropriate(
4458 err: &mut DiagnosticBuilder<'tcx>,
4463 if self.tcx.hir().is_const_context(expr.hir_id) {
4464 // Do not suggest `Box::new` in const context.
4467 if !expected.is_box() || found.is_box() {
4470 let boxed_found = self.tcx.mk_box(found);
4471 if let (true, Ok(snippet)) = (
4472 self.can_coerce(boxed_found, expected),
4473 self.sess().source_map().span_to_snippet(expr.span),
4475 err.span_suggestion(
4477 "store this in the heap by calling `Box::new`",
4478 format!("Box::new({})", snippet),
4479 Applicability::MachineApplicable,
4481 err.note("for more on the distinction between the stack and the \
4482 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
4483 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
4484 https://doc.rust-lang.org/std/boxed/index.html");
4489 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4493 /// bar_that_returns_u32()
4497 /// This routine checks if the return expression in a block would make sense on its own as a
4498 /// statement and the return type has been left as default or has been specified as `()`. If so,
4499 /// it suggests adding a semicolon.
4500 fn suggest_missing_semicolon(
4502 err: &mut DiagnosticBuilder<'tcx>,
4503 expression: &'tcx hir::Expr,
4507 if expected.is_unit() {
4508 // `BlockTailExpression` only relevant if the tail expr would be
4509 // useful on its own.
4510 match expression.kind {
4511 ExprKind::Call(..) |
4512 ExprKind::MethodCall(..) |
4513 ExprKind::Loop(..) |
4514 ExprKind::Match(..) |
4515 ExprKind::Block(..) => {
4516 let sp = self.tcx.sess.source_map().next_point(cause_span);
4517 err.span_suggestion(
4519 "try adding a semicolon",
4521 Applicability::MachineApplicable);
4528 /// A possible error is to forget to add a return type that is needed:
4532 /// bar_that_returns_u32()
4536 /// This routine checks if the return type is left as default, the method is not part of an
4537 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4539 fn suggest_missing_return_type(
4541 err: &mut DiagnosticBuilder<'tcx>,
4542 fn_decl: &hir::FnDecl,
4547 // Only suggest changing the return type for methods that
4548 // haven't set a return type at all (and aren't `fn main()` or an impl).
4549 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4550 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4551 err.span_suggestion(
4553 "try adding a return type",
4554 format!("-> {} ", self.resolve_vars_with_obligations(found)),
4555 Applicability::MachineApplicable);
4558 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4559 err.span_label(span, "possibly return type missing here?");
4562 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4563 // `fn main()` must return `()`, do not suggest changing return type
4564 err.span_label(span, "expected `()` because of default return type");
4567 // expectation was caused by something else, not the default return
4568 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4569 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4570 // Only point to return type if the expected type is the return type, as if they
4571 // are not, the expectation must have been caused by something else.
4572 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
4574 let ty = AstConv::ast_ty_to_ty(self, ty);
4575 debug!("suggest_missing_return_type: return type {:?}", ty);
4576 debug!("suggest_missing_return_type: expected type {:?}", ty);
4577 if ty.kind == expected.kind {
4578 err.span_label(sp, format!("expected `{}` because of return type",
4587 /// A possible error is to forget to add `.await` when using futures:
4590 /// async fn make_u32() -> u32 {
4594 /// fn take_u32(x: u32) {}
4596 /// async fn foo() {
4597 /// let x = make_u32();
4602 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
4603 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
4604 /// `.await` to the tail of the expression.
4605 fn suggest_missing_await(
4607 err: &mut DiagnosticBuilder<'tcx>,
4612 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
4613 // body isn't `async`.
4614 let item_id = self.tcx().hir().get_parent_node(self.body_id);
4615 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
4616 let body = self.tcx().hir().body(body_id);
4617 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
4619 // Check for `Future` implementations by constructing a predicate to
4620 // prove: `<T as Future>::Output == U`
4621 let future_trait = self.tcx.lang_items().future_trait().unwrap();
4622 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
4623 let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
4624 // `<T as Future>::Output`
4625 projection_ty: ty::ProjectionTy {
4627 substs: self.tcx.mk_substs_trait(
4629 self.fresh_substs_for_item(sp, item_def_id)
4636 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
4637 if self.infcx.predicate_may_hold(&obligation) {
4638 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
4639 err.span_suggestion(
4641 "consider using `.await` here",
4642 format!("{}.await", code),
4643 Applicability::MaybeIncorrect,
4651 /// A common error is to add an extra semicolon:
4654 /// fn foo() -> usize {
4659 /// This routine checks if the final statement in a block is an
4660 /// expression with an explicit semicolon whose type is compatible
4661 /// with `expected_ty`. If so, it suggests removing the semicolon.
4662 fn consider_hint_about_removing_semicolon(
4664 blk: &'tcx hir::Block,
4665 expected_ty: Ty<'tcx>,
4666 err: &mut DiagnosticBuilder<'_>,
4668 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4669 err.span_suggestion(
4671 "consider removing this semicolon",
4673 Applicability::MachineApplicable,
4678 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4679 // Be helpful when the user wrote `{... expr;}` and
4680 // taking the `;` off is enough to fix the error.
4681 let last_stmt = blk.stmts.last()?;
4682 let last_expr = match last_stmt.kind {
4683 hir::StmtKind::Semi(ref e) => e,
4686 let last_expr_ty = self.node_ty(last_expr.hir_id);
4687 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4690 let original_span = original_sp(last_stmt.span, blk.span);
4691 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4694 // Instantiates the given path, which must refer to an item with the given
4695 // number of type parameters and type.
4696 pub fn instantiate_value_path(&self,
4697 segments: &[hir::PathSegment],
4698 self_ty: Option<Ty<'tcx>>,
4702 -> (Ty<'tcx>, Res) {
4704 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4713 let path_segs = match res {
4714 Res::Local(_) | Res::SelfCtor(_) => vec![],
4715 Res::Def(kind, def_id) =>
4716 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4717 _ => bug!("instantiate_value_path on {:?}", res),
4720 let mut user_self_ty = None;
4721 let mut is_alias_variant_ctor = false;
4723 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4724 if let Some(self_ty) = self_ty {
4725 let adt_def = self_ty.ty_adt_def().unwrap();
4726 user_self_ty = Some(UserSelfTy {
4727 impl_def_id: adt_def.did,
4730 is_alias_variant_ctor = true;
4733 Res::Def(DefKind::Method, def_id)
4734 | Res::Def(DefKind::AssocConst, def_id) => {
4735 let container = tcx.associated_item(def_id).container;
4736 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4738 ty::TraitContainer(trait_did) => {
4739 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4741 ty::ImplContainer(impl_def_id) => {
4742 if segments.len() == 1 {
4743 // `<T>::assoc` will end up here, and so
4744 // can `T::assoc`. It this came from an
4745 // inherent impl, we need to record the
4746 // `T` for posterity (see `UserSelfTy` for
4748 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4749 user_self_ty = Some(UserSelfTy {
4760 // Now that we have categorized what space the parameters for each
4761 // segment belong to, let's sort out the parameters that the user
4762 // provided (if any) into their appropriate spaces. We'll also report
4763 // errors if type parameters are provided in an inappropriate place.
4765 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4766 let generics_has_err = AstConv::prohibit_generics(
4767 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4768 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4775 if let Res::Local(hid) = res {
4776 let ty = self.local_ty(span, hid).decl_ty;
4777 let ty = self.normalize_associated_types_in(span, &ty);
4778 self.write_ty(hir_id, ty);
4782 if generics_has_err {
4783 // Don't try to infer type parameters when prohibited generic arguments were given.
4784 user_self_ty = None;
4787 // Now we have to compare the types that the user *actually*
4788 // provided against the types that were *expected*. If the user
4789 // did not provide any types, then we want to substitute inference
4790 // variables. If the user provided some types, we may still need
4791 // to add defaults. If the user provided *too many* types, that's
4794 let mut infer_args_for_err = FxHashSet::default();
4795 for &PathSeg(def_id, index) in &path_segs {
4796 let seg = &segments[index];
4797 let generics = tcx.generics_of(def_id);
4798 // Argument-position `impl Trait` is treated as a normal generic
4799 // parameter internally, but we don't allow users to specify the
4800 // parameter's value explicitly, so we have to do some error-
4802 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4807 false, // `is_method_call`
4809 if suppress_errors {
4810 infer_args_for_err.insert(index);
4811 self.set_tainted_by_errors(); // See issue #53251.
4815 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4816 tcx.generics_of(*def_id).has_self
4817 }).unwrap_or(false);
4819 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
4820 let ty = self.impl_self_ty(span, impl_def_id).ty;
4821 let adt_def = ty.ty_adt_def();
4824 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
4825 let variant = adt_def.non_enum_variant();
4826 let ctor_def_id = variant.ctor_def_id.unwrap();
4828 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
4833 let mut err = tcx.sess.struct_span_err(span,
4834 "the `Self` constructor can only be used with tuple or unit structs");
4835 if let Some(adt_def) = adt_def {
4836 match adt_def.adt_kind() {
4838 err.help("did you mean to use one of the enum's variants?");
4842 err.span_suggestion(
4844 "use curly brackets",
4845 String::from("Self { /* fields */ }"),
4846 Applicability::HasPlaceholders,
4853 return (tcx.types.err, res)
4859 let def_id = res.def_id();
4861 // The things we are substituting into the type should not contain
4862 // escaping late-bound regions, and nor should the base type scheme.
4863 let ty = tcx.type_of(def_id);
4865 let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
4871 // Provide the generic args, and whether types should be inferred.
4873 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4876 // If we've encountered an `impl Trait`-related error, we're just
4877 // going to infer the arguments for better error messages.
4878 if !infer_args_for_err.contains(&index) {
4879 // Check whether the user has provided generic arguments.
4880 if let Some(ref data) = segments[index].args {
4881 return (Some(data), segments[index].infer_args);
4884 return (None, segments[index].infer_args);
4889 // Provide substitutions for parameters for which (valid) arguments have been provided.
4891 match (¶m.kind, arg) {
4892 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4893 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4895 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4896 self.to_ty(ty).into()
4898 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4899 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4901 _ => unreachable!(),
4904 // Provide substitutions for parameters for which arguments are inferred.
4905 |substs, param, infer_args| {
4907 GenericParamDefKind::Lifetime => {
4908 self.re_infer(Some(param), span).unwrap().into()
4910 GenericParamDefKind::Type { has_default, .. } => {
4911 if !infer_args && has_default {
4912 // If we have a default, then we it doesn't matter that we're not
4913 // inferring the type arguments: we provide the default where any
4915 let default = tcx.type_of(param.def_id);
4918 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4921 // If no type arguments were provided, we have to infer them.
4922 // This case also occurs as a result of some malformed input, e.g.
4923 // a lifetime argument being given instead of a type parameter.
4924 // Using inference instead of `Error` gives better error messages.
4925 self.var_for_def(span, param)
4928 GenericParamDefKind::Const => {
4929 // FIXME(const_generics:defaults)
4930 // No const parameters were provided, we have to infer them.
4931 self.var_for_def(span, param)
4936 assert!(!substs.has_escaping_bound_vars());
4937 assert!(!ty.has_escaping_bound_vars());
4939 // First, store the "user substs" for later.
4940 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4942 self.add_required_obligations(span, def_id, &substs);
4944 // Substitute the values for the type parameters into the type of
4945 // the referenced item.
4946 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4948 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4949 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4950 // is inherent, there is no `Self` parameter; instead, the impl needs
4951 // type parameters, which we can infer by unifying the provided `Self`
4952 // with the substituted impl type.
4953 // This also occurs for an enum variant on a type alias.
4954 let ty = tcx.type_of(impl_def_id);
4956 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4957 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4958 Ok(ok) => self.register_infer_ok_obligations(ok),
4960 self.tcx.sess.delay_span_bug(span, &format!(
4961 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4969 self.check_rustc_args_require_const(def_id, hir_id, span);
4971 debug!("instantiate_value_path: type of {:?} is {:?}",
4974 self.write_substs(hir_id, substs);
4976 (ty_substituted, res)
4979 /// Add all the obligations that are required, substituting and normalized appropriately.
4980 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
4981 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
4983 for (i, mut obligation) in traits::predicates_for_generics(
4984 traits::ObligationCause::new(
4987 traits::ItemObligation(def_id),
4991 ).into_iter().enumerate() {
4992 // This makes the error point at the bound, but we want to point at the argument
4993 if let Some(span) = spans.get(i) {
4994 obligation.cause.code = traits::BindingObligation(def_id, *span);
4996 self.register_predicate(obligation);
5000 fn check_rustc_args_require_const(&self,
5004 // We're only interested in functions tagged with
5005 // #[rustc_args_required_const], so ignore anything that's not.
5006 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5010 // If our calling expression is indeed the function itself, we're good!
5011 // If not, generate an error that this can only be called directly.
5012 if let Node::Expr(expr) = self.tcx.hir().get(
5013 self.tcx.hir().get_parent_node(hir_id))
5015 if let ExprKind::Call(ref callee, ..) = expr.kind {
5016 if callee.hir_id == hir_id {
5022 self.tcx.sess.span_err(span, "this function can only be invoked \
5023 directly, not through a function pointer");
5026 // Resolves `typ` by a single level if `typ` is a type variable.
5027 // If no resolution is possible, then an error is reported.
5028 // Numeric inference variables may be left unresolved.
5029 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5030 let ty = self.resolve_vars_with_obligations(ty);
5031 if !ty.is_ty_var() {
5034 if !self.is_tainted_by_errors() {
5035 self.need_type_info_err((**self).body_id, sp, ty)
5036 .note("type must be known at this point")
5039 self.demand_suptype(sp, self.tcx.types.err, ty);
5044 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5047 ctxt: BreakableCtxt<'tcx>,
5049 ) -> (BreakableCtxt<'tcx>, R) {
5052 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5053 index = enclosing_breakables.stack.len();
5054 enclosing_breakables.by_id.insert(id, index);
5055 enclosing_breakables.stack.push(ctxt);
5059 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5060 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5061 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5062 enclosing_breakables.stack.pop().expect("missing breakable context")
5067 /// Instantiate a QueryResponse in a probe context, without a
5068 /// good ObligationCause.
5069 fn probe_instantiate_query_response(
5072 original_values: &OriginalQueryValues<'tcx>,
5073 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5074 ) -> InferResult<'tcx, Ty<'tcx>>
5076 self.instantiate_query_response_and_region_obligations(
5077 &traits::ObligationCause::misc(span, self.body_id),
5083 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5084 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5085 let mut contained_in_place = false;
5087 while let hir::Node::Expr(parent_expr) =
5088 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5090 match &parent_expr.kind {
5091 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5092 if lhs.hir_id == expr_id {
5093 contained_in_place = true;
5099 expr_id = parent_expr.hir_id;
5106 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5107 let own_counts = generics.own_counts();
5109 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5115 if own_counts.types == 0 {
5119 // Make a vector of booleans initially `false`; set to `true` when used.
5120 let mut types_used = vec![false; own_counts.types];
5122 for leaf_ty in ty.walk() {
5123 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.kind {
5124 debug!("found use of ty param num {}", index);
5125 types_used[index as usize - own_counts.lifetimes] = true;
5126 } else if let ty::Error = leaf_ty.kind {
5127 // If there is already another error, do not emit
5128 // an error for not using a type parameter.
5129 assert!(tcx.sess.has_errors());
5134 let types = generics.params.iter().filter(|param| match param.kind {
5135 ty::GenericParamDefKind::Type { .. } => true,
5138 for (&used, param) in types_used.iter().zip(types) {
5140 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5141 let span = tcx.hir().span(id);
5142 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5143 .span_label(span, "unused type parameter")
5149 fn fatally_break_rust(sess: &Session) {
5150 let handler = sess.diagnostic();
5151 handler.span_bug_no_panic(
5153 "It looks like you're trying to break rust; would you like some ICE?",
5155 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5156 handler.note_without_error(
5157 "we would appreciate a joke overview: \
5158 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5160 handler.note_without_error(&format!("rustc {} running on {}",
5161 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5162 crate::session::config::host_triple(),
5166 fn potentially_plural_count(count: usize, word: &str) -> String {
5167 format!("{} {}{}", count, word, pluralise!(count))