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 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
540 bug!("could not find enclosing breakable with id {}", target_id);
546 pub struct FnCtxt<'a, 'tcx> {
549 /// The parameter environment used for proving trait obligations
550 /// in this function. This can change when we descend into
551 /// closures (as they bring new things into scope), hence it is
552 /// not part of `Inherited` (as of the time of this writing,
553 /// closures do not yet change the environment, but they will
555 param_env: ty::ParamEnv<'tcx>,
557 /// Number of errors that had been reported when we started
558 /// checking this function. On exit, if we find that *more* errors
559 /// have been reported, we will skip regionck and other work that
560 /// expects the types within the function to be consistent.
561 // FIXME(matthewjasper) This should not exist, and it's not correct
562 // if type checking is run in parallel.
563 err_count_on_creation: usize,
565 /// If `Some`, this stores coercion information for returned
566 /// expressions. If `None`, this is in a context where return is
567 /// inappropriate, such as a const expression.
569 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
570 /// can track all the return expressions and then use them to
571 /// compute a useful coercion from the set, similar to a match
572 /// expression or other branching context. You can use methods
573 /// like `expected_ty` to access the declared return type (if
575 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
577 /// First span of a return site that we find. Used in error messages.
578 ret_coercion_span: RefCell<Option<Span>>,
580 yield_ty: Option<Ty<'tcx>>,
582 ps: RefCell<UnsafetyState>,
584 /// Whether the last checked node generates a divergence (e.g.,
585 /// `return` will set this to `Always`). In general, when entering
586 /// an expression or other node in the tree, the initial value
587 /// indicates whether prior parts of the containing expression may
588 /// have diverged. It is then typically set to `Maybe` (and the
589 /// old value remembered) for processing the subparts of the
590 /// current expression. As each subpart is processed, they may set
591 /// the flag to `Always`, etc. Finally, at the end, we take the
592 /// result and "union" it with the original value, so that when we
593 /// return the flag indicates if any subpart of the parent
594 /// expression (up to and including this part) has diverged. So,
595 /// if you read it after evaluating a subexpression `X`, the value
596 /// you get indicates whether any subexpression that was
597 /// evaluating up to and including `X` diverged.
599 /// We currently use this flag only for diagnostic purposes:
601 /// - To warn about unreachable code: if, after processing a
602 /// sub-expression but before we have applied the effects of the
603 /// current node, we see that the flag is set to `Always`, we
604 /// can issue a warning. This corresponds to something like
605 /// `foo(return)`; we warn on the `foo()` expression. (We then
606 /// update the flag to `WarnedAlways` to suppress duplicate
607 /// reports.) Similarly, if we traverse to a fresh statement (or
608 /// tail expression) from a `Always` setting, we will issue a
609 /// warning. This corresponds to something like `{return;
610 /// foo();}` or `{return; 22}`, where we would warn on the
613 /// An expression represents dead code if, after checking it,
614 /// the diverges flag is set to something other than `Maybe`.
615 diverges: Cell<Diverges>,
617 /// Whether any child nodes have any type errors.
618 has_errors: Cell<bool>,
620 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
622 inh: &'a Inherited<'a, 'tcx>,
625 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
626 type Target = Inherited<'a, 'tcx>;
627 fn deref(&self) -> &Self::Target {
632 /// Helper type of a temporary returned by `Inherited::build(...)`.
633 /// Necessary because we can't write the following bound:
634 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
635 pub struct InheritedBuilder<'tcx> {
636 infcx: infer::InferCtxtBuilder<'tcx>,
640 impl Inherited<'_, 'tcx> {
641 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
642 let hir_id_root = if def_id.is_local() {
643 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
644 DefId::local(hir_id.owner)
650 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
656 impl<'tcx> InheritedBuilder<'tcx> {
657 fn enter<F, R>(&mut self, f: F) -> R
659 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
661 let def_id = self.def_id;
662 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
666 impl Inherited<'a, 'tcx> {
667 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
669 let item_id = tcx.hir().as_local_hir_id(def_id);
670 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
671 let implicit_region_bound = body_id.map(|body_id| {
672 let body = tcx.hir().body(body_id);
673 tcx.mk_region(ty::ReScope(region::Scope {
674 id: body.value.hir_id.local_id,
675 data: region::ScopeData::CallSite
680 tables: MaybeInProgressTables {
681 maybe_tables: infcx.in_progress_tables,
684 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
685 locals: RefCell::new(Default::default()),
686 deferred_sized_obligations: RefCell::new(Vec::new()),
687 deferred_call_resolutions: RefCell::new(Default::default()),
688 deferred_cast_checks: RefCell::new(Vec::new()),
689 deferred_generator_interiors: RefCell::new(Vec::new()),
690 opaque_types: RefCell::new(Default::default()),
691 implicit_region_bound,
696 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
697 debug!("register_predicate({:?})", obligation);
698 if obligation.has_escaping_bound_vars() {
699 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
704 .register_predicate_obligation(self, obligation);
707 fn register_predicates<I>(&self, obligations: I)
708 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
710 for obligation in obligations {
711 self.register_predicate(obligation);
715 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
716 self.register_predicates(infer_ok.obligations);
720 fn normalize_associated_types_in<T>(&self,
723 param_env: ty::ParamEnv<'tcx>,
725 where T : TypeFoldable<'tcx>
727 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
728 self.register_infer_ok_obligations(ok)
732 struct CheckItemTypesVisitor<'tcx> {
736 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
737 fn visit_item(&mut self, i: &'tcx hir::Item) {
738 check_item_type(self.tcx, i);
740 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
741 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
744 pub fn check_wf_new(tcx: TyCtxt<'_>) {
745 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
746 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
749 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
750 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
753 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
754 debug_assert!(crate_num == LOCAL_CRATE);
755 tcx.par_body_owners(|body_owner_def_id| {
756 tcx.ensure().typeck_tables_of(body_owner_def_id);
760 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
761 wfcheck::check_item_well_formed(tcx, def_id);
764 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
765 wfcheck::check_trait_item(tcx, def_id);
768 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
769 wfcheck::check_impl_item(tcx, def_id);
772 pub fn provide(providers: &mut Providers<'_>) {
773 method::provide(providers);
774 *providers = Providers {
780 check_item_well_formed,
781 check_trait_item_well_formed,
782 check_impl_item_well_formed,
783 check_mod_item_types,
788 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
789 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
792 /// If this `DefId` is a "primary tables entry", returns
793 /// `Some((body_id, header, decl))` with information about
794 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
797 /// If this function returns `Some`, then `typeck_tables(def_id)` will
798 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
799 /// may not succeed. In some cases where this function returns `None`
800 /// (notably closures), `typeck_tables(def_id)` would wind up
801 /// redirecting to the owning function.
805 ) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
806 match tcx.hir().get(id) {
807 Node::Item(item) => {
809 hir::ItemKind::Const(ref ty, body) |
810 hir::ItemKind::Static(ref ty, _, body) =>
811 Some((body, Some(ty), None, None)),
812 hir::ItemKind::Fn(ref decl, ref header, .., body) =>
813 Some((body, None, Some(header), Some(decl))),
818 Node::TraitItem(item) => {
820 hir::TraitItemKind::Const(ref ty, Some(body)) =>
821 Some((body, Some(ty), None, None)),
822 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
823 Some((body, None, Some(&sig.header), Some(&sig.decl))),
828 Node::ImplItem(item) => {
830 hir::ImplItemKind::Const(ref ty, body) =>
831 Some((body, Some(ty), None, None)),
832 hir::ImplItemKind::Method(ref sig, body) =>
833 Some((body, None, Some(&sig.header), Some(&sig.decl))),
838 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
843 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
844 // Closures' tables come from their outermost function,
845 // as they are part of the same "inference environment".
846 let outer_def_id = tcx.closure_base_def_id(def_id);
847 if outer_def_id != def_id {
848 return tcx.has_typeck_tables(outer_def_id);
851 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
852 primary_body_of(tcx, id).is_some()
855 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
856 &*tcx.typeck_tables_of(def_id).used_trait_imports
859 fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
860 // Closures' tables come from their outermost function,
861 // as they are part of the same "inference environment".
862 let outer_def_id = tcx.closure_base_def_id(def_id);
863 if outer_def_id != def_id {
864 return tcx.typeck_tables_of(outer_def_id);
867 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
868 let span = tcx.hir().span(id);
870 // Figure out what primary body this item has.
871 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
873 span_bug!(span, "can't type-check body of {:?}", def_id);
875 let body = tcx.hir().body(body_id);
877 let tables = Inherited::build(tcx, def_id).enter(|inh| {
878 let param_env = tcx.param_env(def_id);
879 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
880 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
881 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
882 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl)
887 check_abi(tcx, span, fn_sig.abi());
889 // Compute the fty from point of view of inside the fn.
891 tcx.liberate_late_bound_regions(def_id, &fn_sig);
893 inh.normalize_associated_types_in(body.value.span,
898 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
901 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
902 let expected_type = body_ty.and_then(|ty| match ty.kind {
903 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
905 }).unwrap_or_else(|| tcx.type_of(def_id));
906 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
907 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
909 let revealed_ty = if tcx.features().impl_trait_in_bindings {
910 fcx.instantiate_opaque_types_from_value(
919 // Gather locals in statics (because of block expressions).
920 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
922 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
924 fcx.write_ty(id, revealed_ty);
929 // All type checking constraints were added, try to fallback unsolved variables.
930 fcx.select_obligations_where_possible(false, |_| {});
931 let mut fallback_has_occurred = false;
932 for ty in &fcx.unsolved_variables() {
933 fallback_has_occurred |= fcx.fallback_if_possible(ty);
935 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
937 // Even though coercion casts provide type hints, we check casts after fallback for
938 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
941 // Closure and generator analysis may run after fallback
942 // because they don't constrain other type variables.
943 fcx.closure_analyze(body);
944 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
945 fcx.resolve_generator_interiors(def_id);
947 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
948 let ty = fcx.normalize_ty(span, ty);
949 fcx.require_type_is_sized(ty, span, code);
951 fcx.select_all_obligations_or_error();
953 if fn_decl.is_some() {
954 fcx.regionck_fn(id, body);
956 fcx.regionck_expr(body);
959 fcx.resolve_type_vars_in_body(body)
962 // Consistency check our TypeckTables instance can hold all ItemLocalIds
963 // it will need to hold.
964 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
969 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
970 if !tcx.sess.target.target.is_abi_supported(abi) {
971 struct_span_err!(tcx.sess, span, E0570,
972 "The ABI `{}` is not supported for the current target", abi).emit()
976 struct GatherLocalsVisitor<'a, 'tcx> {
977 fcx: &'a FnCtxt<'a, 'tcx>,
978 parent_id: hir::HirId,
981 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
982 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
985 // infer the variable's type
986 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
987 kind: TypeVariableOriginKind::TypeInference,
990 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
997 // take type that the user specified
998 self.fcx.locals.borrow_mut().insert(nid, typ);
1005 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1006 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
1007 NestedVisitorMap::None
1010 // Add explicitly-declared locals.
1011 fn visit_local(&mut self, local: &'tcx hir::Local) {
1012 let local_ty = match local.ty {
1014 let o_ty = self.fcx.to_ty(&ty);
1016 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1017 self.fcx.instantiate_opaque_types_from_value(
1026 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
1027 &UserType::Ty(revealed_ty)
1029 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1030 ty.hir_id, o_ty, revealed_ty, c_ty);
1031 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1033 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1037 self.assign(local.span, local.hir_id, local_ty);
1039 debug!("local variable {:?} is assigned type {}",
1041 self.fcx.ty_to_string(
1042 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
1043 intravisit::walk_local(self, local);
1046 // Add pattern bindings.
1047 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
1048 if let PatKind::Binding(_, _, ident, _) = p.kind {
1049 let var_ty = self.assign(p.span, p.hir_id, None);
1051 if !self.fcx.tcx.features().unsized_locals {
1052 self.fcx.require_type_is_sized(var_ty, p.span,
1053 traits::VariableType(p.hir_id));
1056 debug!("pattern binding {} is assigned to {} with type {:?}",
1058 self.fcx.ty_to_string(
1059 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1062 intravisit::walk_pat(self, p);
1065 // Don't descend into the bodies of nested closures
1068 _: intravisit::FnKind<'tcx>,
1069 _: &'tcx hir::FnDecl,
1076 /// When `check_fn` is invoked on a generator (i.e., a body that
1077 /// includes yield), it returns back some information about the yield
1079 struct GeneratorTypes<'tcx> {
1080 /// Type of value that is yielded.
1083 /// Types that are captured (see `GeneratorInterior` for more).
1086 /// Indicates if the generator is movable or static (immovable).
1087 movability: hir::GeneratorMovability,
1090 /// Helper used for fns and closures. Does the grungy work of checking a function
1091 /// body and returns the function context used for that purpose, since in the case of a fn item
1092 /// there is still a bit more to do.
1095 /// * inherited: other fields inherited from the enclosing fn (if any)
1096 fn check_fn<'a, 'tcx>(
1097 inherited: &'a Inherited<'a, 'tcx>,
1098 param_env: ty::ParamEnv<'tcx>,
1099 fn_sig: ty::FnSig<'tcx>,
1100 decl: &'tcx hir::FnDecl,
1102 body: &'tcx hir::Body,
1103 can_be_generator: Option<hir::GeneratorMovability>,
1104 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1105 let mut fn_sig = fn_sig.clone();
1107 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1109 // Create the function context. This is either derived from scratch or,
1110 // in the case of closures, based on the outer context.
1111 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1112 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1114 let declared_ret_ty = fn_sig.output();
1115 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1116 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
1121 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1122 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1123 fn_sig = fcx.tcx.mk_fn_sig(
1124 fn_sig.inputs().iter().cloned(),
1131 let span = body.value.span;
1133 fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1135 if body.generator_kind.is_some() && can_be_generator.is_some() {
1136 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1137 kind: TypeVariableOriginKind::TypeInference,
1140 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1141 fcx.yield_ty = Some(yield_ty);
1144 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1145 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1146 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1148 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1149 // (as it's created inside the body itself, not passed in from outside).
1150 let maybe_va_list = if fn_sig.c_variadic {
1151 let va_list_did = fcx.tcx.require_lang_item(
1152 lang_items::VaListTypeLangItem,
1153 Some(body.params.last().unwrap().span),
1155 let region = fcx.tcx.mk_region(ty::ReScope(region::Scope {
1156 id: body.value.hir_id.local_id,
1157 data: region::ScopeData::CallSite
1160 Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()]))
1165 // Add formal parameters.
1166 for (param_ty, param) in
1167 fn_sig.inputs().iter().copied()
1168 .chain(maybe_va_list)
1171 // Check the pattern.
1172 fcx.check_pat_top(¶m.pat, param_ty, None);
1174 // Check that argument is Sized.
1175 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1176 // for simple cases like `fn foo(x: Trait)`,
1177 // where we would error once on the parameter as a whole, and once on the binding `x`.
1178 if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1179 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1182 fcx.write_ty(param.hir_id, param_ty);
1185 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1187 fcx.check_return_expr(&body.value);
1189 // We insert the deferred_generator_interiors entry after visiting the body.
1190 // This ensures that all nested generators appear before the entry of this generator.
1191 // resolve_generator_interiors relies on this property.
1192 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1193 let interior = fcx.next_ty_var(TypeVariableOrigin {
1194 kind: TypeVariableOriginKind::MiscVariable,
1197 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1198 Some(GeneratorTypes {
1199 yield_ty: fcx.yield_ty.unwrap(),
1201 movability: can_be_generator.unwrap(),
1207 // Finalize the return check by taking the LUB of the return types
1208 // we saw and assigning it to the expected return type. This isn't
1209 // really expected to fail, since the coercions would have failed
1210 // earlier when trying to find a LUB.
1212 // However, the behavior around `!` is sort of complex. In the
1213 // event that the `actual_return_ty` comes back as `!`, that
1214 // indicates that the fn either does not return or "returns" only
1215 // values of type `!`. In this case, if there is an expected
1216 // return type that is *not* `!`, that should be ok. But if the
1217 // return type is being inferred, we want to "fallback" to `!`:
1219 // let x = move || panic!();
1221 // To allow for that, I am creating a type variable with diverging
1222 // fallback. This was deemed ever so slightly better than unifying
1223 // the return value with `!` because it allows for the caller to
1224 // make more assumptions about the return type (e.g., they could do
1226 // let y: Option<u32> = Some(x());
1228 // which would then cause this return type to become `u32`, not
1230 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1231 let mut actual_return_ty = coercion.complete(&fcx);
1232 if actual_return_ty.is_never() {
1233 actual_return_ty = fcx.next_diverging_ty_var(
1234 TypeVariableOrigin {
1235 kind: TypeVariableOriginKind::DivergingFn,
1240 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1242 // Check that the main return type implements the termination trait.
1243 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1244 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1245 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1246 if main_id == fn_id {
1247 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1248 let trait_ref = ty::TraitRef::new(term_id, substs);
1249 let return_ty_span = decl.output.span();
1250 let cause = traits::ObligationCause::new(
1251 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1253 inherited.register_predicate(
1254 traits::Obligation::new(
1255 cause, param_env, trait_ref.to_predicate()));
1260 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1261 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1262 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1263 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1264 // at this point we don't care if there are duplicate handlers or if the handler has
1265 // the wrong signature as this value we'll be used when writing metadata and that
1266 // only happens if compilation succeeded
1267 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1269 if declared_ret_ty.kind != ty::Never {
1270 fcx.tcx.sess.span_err(
1272 "return type should be `!`",
1276 let inputs = fn_sig.inputs();
1277 let span = fcx.tcx.hir().span(fn_id);
1278 if inputs.len() == 1 {
1279 let arg_is_panic_info = match inputs[0].kind {
1280 ty::Ref(region, ty, mutbl) => match ty.kind {
1281 ty::Adt(ref adt, _) => {
1282 adt.did == panic_info_did &&
1283 mutbl == hir::Mutability::MutImmutable &&
1284 *region != RegionKind::ReStatic
1291 if !arg_is_panic_info {
1292 fcx.tcx.sess.span_err(
1293 decl.inputs[0].span,
1294 "argument should be `&PanicInfo`",
1298 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1299 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1300 if !generics.params.is_empty() {
1301 fcx.tcx.sess.span_err(
1303 "should have no type parameters",
1309 let span = fcx.tcx.sess.source_map().def_span(span);
1310 fcx.tcx.sess.span_err(span, "function should have one argument");
1313 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1318 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1319 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1320 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1321 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1322 if declared_ret_ty.kind != ty::Never {
1323 fcx.tcx.sess.span_err(
1325 "return type should be `!`",
1329 let inputs = fn_sig.inputs();
1330 let span = fcx.tcx.hir().span(fn_id);
1331 if inputs.len() == 1 {
1332 let arg_is_alloc_layout = match inputs[0].kind {
1333 ty::Adt(ref adt, _) => {
1334 adt.did == alloc_layout_did
1339 if !arg_is_alloc_layout {
1340 fcx.tcx.sess.span_err(
1341 decl.inputs[0].span,
1342 "argument should be `Layout`",
1346 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1347 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1348 if !generics.params.is_empty() {
1349 fcx.tcx.sess.span_err(
1351 "`#[alloc_error_handler]` function should have no type \
1358 let span = fcx.tcx.sess.source_map().def_span(span);
1359 fcx.tcx.sess.span_err(span, "function should have one argument");
1362 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1370 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1371 let def_id = tcx.hir().local_def_id(id);
1372 let def = tcx.adt_def(def_id);
1373 def.destructor(tcx); // force the destructor to be evaluated
1374 check_representable(tcx, span, def_id);
1376 if def.repr.simd() {
1377 check_simd(tcx, span, def_id);
1380 check_transparent(tcx, span, def_id);
1381 check_packed(tcx, span, def_id);
1384 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1385 let def_id = tcx.hir().local_def_id(id);
1386 let def = tcx.adt_def(def_id);
1387 def.destructor(tcx); // force the destructor to be evaluated
1388 check_representable(tcx, span, def_id);
1389 check_transparent(tcx, span, def_id);
1390 check_union_fields(tcx, span, def_id);
1391 check_packed(tcx, span, def_id);
1394 /// When the `#![feature(untagged_unions)]` gate is active,
1395 /// check that the fields of the `union` does not contain fields that need dropping.
1396 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1397 // Without the feature we check that all fields are `Copy` in our stability checking
1399 if !tcx.features().untagged_unions {
1402 let item_type = tcx.type_of(item_def_id);
1403 if let ty::Adt(def, substs) = item_type.kind {
1404 assert!(def.is_union());
1405 let fields = &def.non_enum_variant().fields;
1406 for field in fields {
1407 let field_ty = field.ty(tcx, substs);
1408 // We are currently checking the type this field came from, so it must be local.
1409 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1410 let param_env = tcx.param_env(field.did);
1411 if field_ty.needs_drop(tcx, param_env) {
1412 struct_span_err!(tcx.sess, field_span, E0740,
1413 "unions may not contain fields that need dropping")
1414 .span_note(field_span,
1415 "`std::mem::ManuallyDrop` can be used to wrap the type")
1421 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1426 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1427 /// projections that would result in "inheriting lifetimes".
1428 fn check_opaque<'tcx>(
1431 substs: SubstsRef<'tcx>,
1433 origin: &hir::OpaqueTyOrigin,
1435 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1436 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1439 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1440 /// in "inheriting lifetimes".
1441 fn check_opaque_for_inheriting_lifetimes(
1446 let item = tcx.hir().expect_item(
1447 tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1448 debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1449 def_id, span, item);
1452 struct ProhibitOpaqueVisitor<'tcx> {
1453 opaque_identity_ty: Ty<'tcx>,
1454 generics: &'tcx ty::Generics,
1457 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1458 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1459 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1460 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1463 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1464 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1465 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1466 return *index < self.generics.parent_count as u32;
1469 r.super_visit_with(self)
1473 let prohibit_opaque = match item.kind {
1474 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
1475 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1476 let mut visitor = ProhibitOpaqueVisitor {
1477 opaque_identity_ty: tcx.mk_opaque(
1478 def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1479 generics: tcx.generics_of(def_id),
1481 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1483 tcx.predicates_of(def_id).predicates.iter().any(
1484 |(predicate, _)| predicate.visit_with(&mut visitor))
1489 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1490 if prohibit_opaque {
1491 let is_async = match item.kind {
1492 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1493 hir::OpaqueTyOrigin::AsyncFn => true,
1496 _ => unreachable!(),
1499 tcx.sess.span_err(span, &format!(
1500 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1502 if is_async { "async fn" } else { "impl Trait" },
1507 /// Checks that an opaque type does not contain cycles.
1508 fn check_opaque_for_cycles<'tcx>(
1511 substs: SubstsRef<'tcx>,
1513 origin: &hir::OpaqueTyOrigin,
1515 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1516 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1518 tcx.sess, span, E0733,
1519 "recursion in an `async fn` requires boxing",
1521 .span_label(span, "recursive `async fn`")
1522 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
1525 let mut err = struct_span_err!(
1526 tcx.sess, span, E0720,
1527 "opaque type expands to a recursive type",
1529 err.span_label(span, "expands to a recursive type");
1530 if let ty::Opaque(..) = partially_expanded_type.kind {
1531 err.note("type resolves to itself");
1533 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1540 // Forbid defining intrinsics in Rust code,
1541 // as they must always be defined by the compiler.
1542 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1543 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1544 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1548 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1550 "check_item_type(it.hir_id={}, it.name={})",
1552 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1554 let _indenter = indenter();
1556 // Consts can play a role in type-checking, so they are included here.
1557 hir::ItemKind::Static(..) => {
1558 let def_id = tcx.hir().local_def_id(it.hir_id);
1559 tcx.typeck_tables_of(def_id);
1560 maybe_check_static_with_link_section(tcx, def_id, it.span);
1562 hir::ItemKind::Const(..) => {
1563 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1565 hir::ItemKind::Enum(ref enum_definition, _) => {
1566 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1568 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1569 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1570 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1571 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1572 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1573 check_impl_items_against_trait(
1580 let trait_def_id = impl_trait_ref.def_id;
1581 check_on_unimplemented(tcx, trait_def_id, it);
1584 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1585 let def_id = tcx.hir().local_def_id(it.hir_id);
1586 check_on_unimplemented(tcx, def_id, it);
1588 for item in items.iter() {
1589 let item = tcx.hir().trait_item(item.id);
1590 if let hir::TraitItemKind::Method(sig, _) = &item.kind {
1591 let abi = sig.header.abi;
1592 fn_maybe_err(tcx, item.ident.span, abi);
1596 hir::ItemKind::Struct(..) => {
1597 check_struct(tcx, it.hir_id, it.span);
1599 hir::ItemKind::Union(..) => {
1600 check_union(tcx, it.hir_id, it.span);
1602 hir::ItemKind::OpaqueTy(hir::OpaqueTy{origin, ..}) => {
1603 let def_id = tcx.hir().local_def_id(it.hir_id);
1605 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1606 check_opaque(tcx, def_id, substs, it.span, &origin);
1608 hir::ItemKind::TyAlias(..) => {
1609 let def_id = tcx.hir().local_def_id(it.hir_id);
1610 let pty_ty = tcx.type_of(def_id);
1611 let generics = tcx.generics_of(def_id);
1612 check_bounds_are_used(tcx, &generics, pty_ty);
1614 hir::ItemKind::ForeignMod(ref m) => {
1615 check_abi(tcx, it.span, m.abi);
1617 if m.abi == Abi::RustIntrinsic {
1618 for item in &m.items {
1619 intrinsic::check_intrinsic_type(tcx, item);
1621 } else if m.abi == Abi::PlatformIntrinsic {
1622 for item in &m.items {
1623 intrinsic::check_platform_intrinsic_type(tcx, item);
1626 for item in &m.items {
1627 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1628 let own_counts = generics.own_counts();
1629 if generics.params.len() - own_counts.lifetimes != 0 {
1630 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1631 (_, 0) => ("type", "types", Some("u32")),
1632 // We don't specify an example value, because we can't generate
1633 // a valid value for any type.
1634 (0, _) => ("const", "consts", None),
1635 _ => ("type or const", "types or consts", None),
1641 "foreign items may not have {} parameters",
1645 &format!("can't have {} parameters", kinds),
1647 // FIXME: once we start storing spans for type arguments, turn this
1648 // into a suggestion.
1650 "replace the {} parameters with concrete {}{}",
1653 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1658 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1659 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1664 _ => { /* nothing to do */ }
1668 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1669 // Only restricted on wasm32 target for now
1670 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1674 // If `#[link_section]` is missing, then nothing to verify
1675 let attrs = tcx.codegen_fn_attrs(id);
1676 if attrs.link_section.is_none() {
1680 // For the wasm32 target statics with `#[link_section]` are placed into custom
1681 // sections of the final output file, but this isn't link custom sections of
1682 // other executable formats. Namely we can only embed a list of bytes,
1683 // nothing with pointers to anything else or relocations. If any relocation
1684 // show up, reject them here.
1685 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1686 // the consumer's responsibility to ensure all bytes that have been read
1687 // have defined values.
1688 let instance = ty::Instance::mono(tcx, id);
1689 let cid = GlobalId {
1693 let param_env = ty::ParamEnv::reveal_all();
1694 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1695 let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1698 bug!("Matching on non-ByRef static")
1700 if alloc.relocations().len() != 0 {
1701 let msg = "statics with a custom `#[link_section]` must be a \
1702 simple list of bytes on the wasm target with no \
1703 extra levels of indirection such as references";
1704 tcx.sess.span_err(span, msg);
1709 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
1710 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1711 // an error would be reported if this fails.
1712 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1715 fn report_forbidden_specialization(
1717 impl_item: &hir::ImplItem,
1720 let mut err = struct_span_err!(
1721 tcx.sess, impl_item.span, E0520,
1722 "`{}` specializes an item from a parent `impl`, but \
1723 that item is not marked `default`",
1725 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1728 match tcx.span_of_impl(parent_impl) {
1730 err.span_label(span, "parent `impl` is here");
1731 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1735 err.note(&format!("parent implementation is in crate `{}`", cname));
1742 fn check_specialization_validity<'tcx>(
1744 trait_def: &ty::TraitDef,
1745 trait_item: &ty::AssocItem,
1747 impl_item: &hir::ImplItem,
1749 let kind = match impl_item.kind {
1750 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1751 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1752 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1753 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1756 let mut ancestor_impls = trait_def.ancestors(tcx, impl_id)
1758 .filter_map(|parent| {
1759 if parent.is_from_trait() {
1762 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1767 if ancestor_impls.peek().is_none() {
1768 // No parent, nothing to specialize.
1772 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1774 // Parent impl exists, and contains the parent item we're trying to specialize, but
1775 // doesn't mark it `default`.
1776 Some(parent_item) if tcx.impl_item_is_final(&parent_item) => {
1777 Some(Err(parent_impl.def_id()))
1780 // Parent impl contains item and makes it specializable.
1785 // Parent impl doesn't mention the item. This means it's inherited from the
1786 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1787 // "defaultness" from the grandparent, else they are final.
1788 None => if tcx.impl_is_default(parent_impl.def_id()) {
1791 Some(Err(parent_impl.def_id()))
1796 // If `opt_result` is `None`, we have only encoutered `default impl`s that don't contain the
1797 // item. This is allowed, the item isn't actually getting specialized here.
1798 let result = opt_result.unwrap_or(Ok(()));
1800 if let Err(parent_impl) = result {
1801 report_forbidden_specialization(tcx, impl_item, parent_impl);
1805 fn check_impl_items_against_trait<'tcx>(
1809 impl_trait_ref: ty::TraitRef<'tcx>,
1810 impl_item_refs: &[hir::ImplItemRef],
1812 let impl_span = tcx.sess.source_map().def_span(impl_span);
1814 // If the trait reference itself is erroneous (so the compilation is going
1815 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1816 // isn't populated for such impls.
1817 if impl_trait_ref.references_error() { return; }
1819 // Locate trait definition and items
1820 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1821 let mut overridden_associated_type = None;
1823 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1825 // Check existing impl methods to see if they are both present in trait
1826 // and compatible with trait signature
1827 for impl_item in impl_items() {
1828 let ty_impl_item = tcx.associated_item(
1829 tcx.hir().local_def_id(impl_item.hir_id));
1830 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1831 .find(|ac| Namespace::from(&impl_item.kind) == Namespace::from(ac.kind) &&
1832 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1834 // Not compatible, but needed for the error message
1835 tcx.associated_items(impl_trait_ref.def_id)
1836 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1839 // Check that impl definition matches trait definition
1840 if let Some(ty_trait_item) = ty_trait_item {
1841 match impl_item.kind {
1842 hir::ImplItemKind::Const(..) => {
1843 // Find associated const definition.
1844 if ty_trait_item.kind == ty::AssocKind::Const {
1845 compare_const_impl(tcx,
1851 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1852 "item `{}` is an associated const, \
1853 which doesn't match its trait `{}`",
1856 err.span_label(impl_item.span, "does not match trait");
1857 // We can only get the spans from local trait definition
1858 // Same for E0324 and E0325
1859 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1860 err.span_label(trait_span, "item in trait");
1865 hir::ImplItemKind::Method(..) => {
1866 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1867 if ty_trait_item.kind == ty::AssocKind::Method {
1868 compare_impl_method(tcx,
1875 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1876 "item `{}` is an associated method, \
1877 which doesn't match its trait `{}`",
1880 err.span_label(impl_item.span, "does not match trait");
1881 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1882 err.span_label(trait_span, "item in trait");
1887 hir::ImplItemKind::OpaqueTy(..) |
1888 hir::ImplItemKind::TyAlias(_) => {
1889 if ty_trait_item.kind == ty::AssocKind::Type {
1890 if ty_trait_item.defaultness.has_value() {
1891 overridden_associated_type = Some(impl_item);
1894 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1895 "item `{}` is an associated type, \
1896 which doesn't match its trait `{}`",
1899 err.span_label(impl_item.span, "does not match trait");
1900 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1901 err.span_label(trait_span, "item in trait");
1908 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1912 // Check for missing items from trait
1913 let mut missing_items = Vec::new();
1914 let mut invalidated_items = Vec::new();
1915 let associated_type_overridden = overridden_associated_type.is_some();
1916 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1917 let is_implemented = trait_def.ancestors(tcx, impl_id)
1918 .leaf_def(tcx, trait_item.ident, trait_item.kind)
1919 .map(|node_item| !node_item.node.is_from_trait())
1922 if !is_implemented && !tcx.impl_is_default(impl_id) {
1923 if !trait_item.defaultness.has_value() {
1924 missing_items.push(trait_item);
1925 } else if associated_type_overridden {
1926 invalidated_items.push(trait_item.ident);
1931 if !missing_items.is_empty() {
1932 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1933 "not all trait items implemented, missing: `{}`",
1934 missing_items.iter()
1935 .map(|trait_item| trait_item.ident.to_string())
1936 .collect::<Vec<_>>().join("`, `"));
1937 err.span_label(impl_span, format!("missing `{}` in implementation",
1938 missing_items.iter()
1939 .map(|trait_item| trait_item.ident.to_string())
1940 .collect::<Vec<_>>().join("`, `")));
1941 for trait_item in missing_items {
1942 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1943 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1945 err.note_trait_signature(trait_item.ident.to_string(),
1946 trait_item.signature(tcx));
1952 if !invalidated_items.is_empty() {
1953 let invalidator = overridden_associated_type.unwrap();
1954 span_err!(tcx.sess, invalidator.span, E0399,
1955 "the following trait items need to be reimplemented \
1956 as `{}` was overridden: `{}`",
1958 invalidated_items.iter()
1959 .map(|name| name.to_string())
1960 .collect::<Vec<_>>().join("`, `"))
1964 /// Checks whether a type can be represented in memory. In particular, it
1965 /// identifies types that contain themselves without indirection through a
1966 /// pointer, which would mean their size is unbounded.
1967 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
1968 let rty = tcx.type_of(item_def_id);
1970 // Check that it is possible to represent this type. This call identifies
1971 // (1) types that contain themselves and (2) types that contain a different
1972 // recursive type. It is only necessary to throw an error on those that
1973 // contain themselves. For case 2, there must be an inner type that will be
1974 // caught by case 1.
1975 match rty.is_representable(tcx, sp) {
1976 Representability::SelfRecursive(spans) => {
1977 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1979 err.span_label(span, "recursive without indirection");
1984 Representability::Representable | Representability::ContainsRecursive => (),
1989 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1990 let t = tcx.type_of(def_id);
1991 if let ty::Adt(def, substs) = t.kind {
1992 if def.is_struct() {
1993 let fields = &def.non_enum_variant().fields;
1994 if fields.is_empty() {
1995 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1998 let e = fields[0].ty(tcx, substs);
1999 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
2000 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
2001 .span_label(sp, "SIMD elements must have the same type")
2006 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2007 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2009 span_err!(tcx.sess, sp, E0077,
2010 "SIMD vector element type should be machine type");
2018 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2019 let repr = tcx.adt_def(def_id).repr;
2021 for attr in tcx.get_attrs(def_id).iter() {
2022 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2023 if let attr::ReprPacked(pack) = r {
2024 if let Some(repr_pack) = repr.pack {
2025 if pack as u64 != repr_pack.bytes() {
2027 tcx.sess, sp, E0634,
2028 "type has conflicting packed representation hints"
2035 if repr.align.is_some() {
2036 struct_span_err!(tcx.sess, sp, E0587,
2037 "type has conflicting packed and align representation hints").emit();
2039 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
2040 struct_span_err!(tcx.sess, sp, E0588,
2041 "packed type cannot transitively contain a `[repr(align)]` type").emit();
2046 fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
2047 let t = tcx.type_of(def_id);
2048 if stack.contains(&def_id) {
2049 debug!("check_packed_inner: {:?} is recursive", t);
2052 if let ty::Adt(def, substs) = t.kind {
2053 if def.is_struct() || def.is_union() {
2054 if tcx.adt_def(def.did).repr.align.is_some() {
2057 // push struct def_id before checking fields
2059 for field in &def.non_enum_variant().fields {
2060 let f = field.ty(tcx, substs);
2061 if let ty::Adt(def, _) = f.kind {
2062 if check_packed_inner(tcx, def.did, stack) {
2067 // only need to pop if not early out
2074 /// Emit an error when encountering more or less than one variant in a transparent enum.
2075 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2076 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
2077 tcx.hir().span_if_local(variant.def_id).unwrap()
2080 "needs exactly one variant, but has {}",
2083 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2084 err.span_label(sp, &msg);
2085 if let &[ref start @ .., ref end] = &variant_spans[..] {
2086 for variant_span in start {
2087 err.span_label(*variant_span, "");
2089 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2094 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2096 fn bad_non_zero_sized_fields<'tcx>(
2098 adt: &'tcx ty::AdtDef,
2100 field_spans: impl Iterator<Item = Span>,
2103 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2104 let mut err = struct_span_err!(
2108 "{}transparent {} {}",
2109 if adt.is_enum() { "the variant of a " } else { "" },
2113 err.span_label(sp, &msg);
2114 for sp in field_spans {
2115 err.span_label(sp, "this field is non-zero-sized");
2120 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2121 let adt = tcx.adt_def(def_id);
2122 if !adt.repr.transparent() {
2125 let sp = tcx.sess.source_map().def_span(sp);
2128 if !tcx.features().transparent_enums {
2130 &tcx.sess.parse_sess,
2131 sym::transparent_enums,
2133 GateIssue::Language,
2134 "transparent enums are unstable",
2137 if adt.variants.len() != 1 {
2138 bad_variant_count(tcx, adt, sp, def_id);
2139 if adt.variants.is_empty() {
2140 // Don't bother checking the fields. No variants (and thus no fields) exist.
2146 if adt.is_union() && !tcx.features().transparent_unions {
2147 emit_feature_err(&tcx.sess.parse_sess,
2148 sym::transparent_unions,
2150 GateIssue::Language,
2151 "transparent unions are unstable");
2154 // For each field, figure out if it's known to be a ZST and align(1)
2155 let field_infos = adt.all_fields().map(|field| {
2156 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2157 let param_env = tcx.param_env(field.did);
2158 let layout = tcx.layout_of(param_env.and(ty));
2159 // We are currently checking the type this field came from, so it must be local
2160 let span = tcx.hir().span_if_local(field.did).unwrap();
2161 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2162 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2166 let non_zst_fields = field_infos.clone().filter_map(|(span, zst, _align1)| if !zst {
2171 let non_zst_count = non_zst_fields.clone().count();
2172 if non_zst_count != 1 {
2173 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2175 for (span, zst, align1) in field_infos {
2181 "zero-sized field in transparent {} has alignment larger than 1",
2183 ).span_label(span, "has alignment larger than 1").emit();
2188 #[allow(trivial_numeric_casts)]
2189 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
2190 let def_id = tcx.hir().local_def_id(id);
2191 let def = tcx.adt_def(def_id);
2192 def.destructor(tcx); // force the destructor to be evaluated
2195 let attributes = tcx.get_attrs(def_id);
2196 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2198 tcx.sess, attr.span, E0084,
2199 "unsupported representation for zero-variant enum")
2200 .span_label(sp, "zero-variant enum")
2205 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2206 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2207 if !tcx.features().repr128 {
2208 emit_feature_err(&tcx.sess.parse_sess,
2211 GateIssue::Language,
2212 "repr with 128-bit type is unstable");
2217 if let Some(ref e) = v.disr_expr {
2218 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2222 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2224 |var: &hir::Variant| match var.data {
2225 hir::VariantData::Unit(..) => true,
2229 let has_disr = |var: &hir::Variant| var.disr_expr.is_some();
2230 let has_non_units = vs.iter().any(|var| !is_unit(var));
2231 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2232 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2234 if disr_non_unit || (disr_units && has_non_units) {
2235 let mut err = struct_span_err!(tcx.sess, sp, E0732,
2236 "`#[repr(inttype)]` must be specified");
2241 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2242 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2243 // Check for duplicate discriminant values
2244 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2245 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2246 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2247 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2248 let i_span = match variant_i.disr_expr {
2249 Some(ref expr) => tcx.hir().span(expr.hir_id),
2250 None => tcx.hir().span(variant_i_hir_id)
2252 let span = match v.disr_expr {
2253 Some(ref expr) => tcx.hir().span(expr.hir_id),
2256 struct_span_err!(tcx.sess, span, E0081,
2257 "discriminant value `{}` already exists", disr_vals[i])
2258 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2259 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
2262 disr_vals.push(discr);
2265 check_representable(tcx, sp, def_id);
2266 check_transparent(tcx, sp, def_id);
2269 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
2270 span_err!(tcx.sess, span, E0533,
2271 "expected unit struct/variant or constant, found {} `{}`",
2273 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
2276 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2277 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2281 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
2282 -> &'tcx ty::GenericPredicates<'tcx>
2285 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2286 let item_id = tcx.hir().ty_param_owner(hir_id);
2287 let item_def_id = tcx.hir().local_def_id(item_id);
2288 let generics = tcx.generics_of(item_def_id);
2289 let index = generics.param_def_id_to_index[&def_id];
2290 tcx.arena.alloc(ty::GenericPredicates {
2292 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
2294 ty::Predicate::Trait(ref data)
2295 if data.skip_binder().self_ty().is_param(index) => {
2296 // HACK(eddyb) should get the original `Span`.
2297 let span = tcx.def_span(def_id);
2298 Some((predicate, span))
2308 def: Option<&ty::GenericParamDef>,
2310 ) -> Option<ty::Region<'tcx>> {
2312 Some(def) => infer::EarlyBoundRegion(span, def.name),
2313 None => infer::MiscVariable(span)
2315 Some(self.next_region_var(v))
2318 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2319 if let Some(param) = param {
2320 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2325 self.next_ty_var(TypeVariableOrigin {
2326 kind: TypeVariableOriginKind::TypeInference,
2335 param: Option<&ty::GenericParamDef>,
2337 ) -> &'tcx Const<'tcx> {
2338 if let Some(param) = param {
2339 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2344 self.next_const_var(ty, ConstVariableOrigin {
2345 kind: ConstVariableOriginKind::ConstInference,
2351 fn projected_ty_from_poly_trait_ref(&self,
2354 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2357 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2359 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2363 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2366 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2367 if ty.has_escaping_bound_vars() {
2368 ty // FIXME: normalization and escaping regions
2370 self.normalize_associated_types_in(span, &ty)
2374 fn set_tainted_by_errors(&self) {
2375 self.infcx.set_tainted_by_errors()
2378 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2379 self.write_ty(hir_id, ty)
2383 /// Controls whether the arguments are tupled. This is used for the call
2386 /// Tupling means that all call-side arguments are packed into a tuple and
2387 /// passed as a single parameter. For example, if tupling is enabled, this
2390 /// fn f(x: (isize, isize))
2392 /// Can be called as:
2399 #[derive(Clone, Eq, PartialEq)]
2400 enum TupleArgumentsFlag {
2405 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2407 inh: &'a Inherited<'a, 'tcx>,
2408 param_env: ty::ParamEnv<'tcx>,
2409 body_id: hir::HirId,
2410 ) -> FnCtxt<'a, 'tcx> {
2414 err_count_on_creation: inh.tcx.sess.err_count(),
2416 ret_coercion_span: RefCell::new(None),
2418 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2419 hir::CRATE_HIR_ID)),
2420 diverges: Cell::new(Diverges::Maybe),
2421 has_errors: Cell::new(false),
2422 enclosing_breakables: RefCell::new(EnclosingBreakables {
2424 by_id: Default::default(),
2430 pub fn sess(&self) -> &Session {
2434 pub fn errors_reported_since_creation(&self) -> bool {
2435 self.tcx.sess.err_count() > self.err_count_on_creation
2438 /// Produces warning on the given node, if the current point in the
2439 /// function is unreachable, and there hasn't been another warning.
2440 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2441 // FIXME: Combine these two 'if' expressions into one once
2442 // let chains are implemented
2443 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2444 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2445 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2446 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2447 if !span.is_desugaring(DesugaringKind::CondTemporary) &&
2448 !span.is_desugaring(DesugaringKind::Async) &&
2449 !orig_span.is_desugaring(DesugaringKind::Await)
2451 self.diverges.set(Diverges::WarnedAlways);
2453 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2455 let msg = format!("unreachable {}", kind);
2456 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
2457 .span_label(span, &msg)
2460 custom_note.unwrap_or("any code following this expression is unreachable"),
2469 code: ObligationCauseCode<'tcx>)
2470 -> ObligationCause<'tcx> {
2471 ObligationCause::new(span, self.body_id, code)
2474 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2475 self.cause(span, ObligationCauseCode::MiscObligation)
2478 /// Resolves type variables in `ty` if possible. Unlike the infcx
2479 /// version (resolve_vars_if_possible), this version will
2480 /// also select obligations if it seems useful, in an effort
2481 /// to get more type information.
2482 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2483 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2485 // No Infer()? Nothing needs doing.
2486 if !ty.has_infer_types() {
2487 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2491 // If `ty` is a type variable, see whether we already know what it is.
2492 ty = self.resolve_vars_if_possible(&ty);
2493 if !ty.has_infer_types() {
2494 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2498 // If not, try resolving pending obligations as much as
2499 // possible. This can help substantially when there are
2500 // indirect dependencies that don't seem worth tracking
2502 self.select_obligations_where_possible(false, |_| {});
2503 ty = self.resolve_vars_if_possible(&ty);
2505 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2509 fn record_deferred_call_resolution(
2511 closure_def_id: DefId,
2512 r: DeferredCallResolution<'tcx>,
2514 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2515 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2518 fn remove_deferred_call_resolutions(
2520 closure_def_id: DefId,
2521 ) -> Vec<DeferredCallResolution<'tcx>> {
2522 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2523 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2526 pub fn tag(&self) -> String {
2527 format!("{:p}", self)
2530 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2531 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2532 span_bug!(span, "no type for local variable {}",
2533 self.tcx.hir().node_to_string(nid))
2538 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2539 debug!("write_ty({:?}, {:?}) in fcx {}",
2540 id, self.resolve_vars_if_possible(&ty), self.tag());
2541 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2543 if ty.references_error() {
2544 self.has_errors.set(true);
2545 self.set_tainted_by_errors();
2549 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2550 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2553 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2554 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2557 pub fn write_method_call(&self,
2559 method: MethodCallee<'tcx>) {
2560 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2561 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2562 self.write_substs(hir_id, method.substs);
2564 // When the method is confirmed, the `method.substs` includes
2565 // parameters from not just the method, but also the impl of
2566 // the method -- in particular, the `Self` type will be fully
2567 // resolved. However, those are not something that the "user
2568 // specified" -- i.e., those types come from the inferred type
2569 // of the receiver, not something the user wrote. So when we
2570 // create the user-substs, we want to replace those earlier
2571 // types with just the types that the user actually wrote --
2572 // that is, those that appear on the *method itself*.
2574 // As an example, if the user wrote something like
2575 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2576 // type of `foo` (possibly adjusted), but we don't want to
2577 // include that. We want just the `[_, u32]` part.
2578 if !method.substs.is_noop() {
2579 let method_generics = self.tcx.generics_of(method.def_id);
2580 if !method_generics.params.is_empty() {
2581 let user_type_annotation = self.infcx.probe(|_| {
2582 let user_substs = UserSubsts {
2583 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2584 let i = param.index as usize;
2585 if i < method_generics.parent_count {
2586 self.infcx.var_for_def(DUMMY_SP, param)
2591 user_self_ty: None, // not relevant here
2594 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2600 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2601 self.write_user_type_annotation(hir_id, user_type_annotation);
2606 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2607 if !substs.is_noop() {
2608 debug!("write_substs({:?}, {:?}) in fcx {}",
2613 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2617 /// Given the substs that we just converted from the HIR, try to
2618 /// canonicalize them and store them as user-given substitutions
2619 /// (i.e., substitutions that must be respected by the NLL check).
2621 /// This should be invoked **before any unifications have
2622 /// occurred**, so that annotations like `Vec<_>` are preserved
2624 pub fn write_user_type_annotation_from_substs(
2628 substs: SubstsRef<'tcx>,
2629 user_self_ty: Option<UserSelfTy<'tcx>>,
2632 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2633 user_self_ty={:?} in fcx {}",
2634 hir_id, def_id, substs, user_self_ty, self.tag(),
2637 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2638 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2639 &UserType::TypeOf(def_id, UserSubsts {
2644 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2645 self.write_user_type_annotation(hir_id, canonicalized);
2649 pub fn write_user_type_annotation(
2652 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2655 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2656 hir_id, canonical_user_type_annotation, self.tag(),
2659 if !canonical_user_type_annotation.is_identity() {
2660 self.tables.borrow_mut().user_provided_types_mut().insert(
2661 hir_id, canonical_user_type_annotation
2664 debug!("write_user_type_annotation: skipping identity substs");
2668 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2669 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2675 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2676 Entry::Vacant(entry) => { entry.insert(adj); },
2677 Entry::Occupied(mut entry) => {
2678 debug!(" - composing on top of {:?}", entry.get());
2679 match (&entry.get()[..], &adj[..]) {
2680 // Applying any adjustment on top of a NeverToAny
2681 // is a valid NeverToAny adjustment, because it can't
2683 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2685 Adjustment { kind: Adjust::Deref(_), .. },
2686 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2688 Adjustment { kind: Adjust::Deref(_), .. },
2689 .. // Any following adjustments are allowed.
2691 // A reborrow has no effect before a dereference.
2693 // FIXME: currently we never try to compose autoderefs
2694 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2696 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2697 expr, entry.get(), adj)
2699 *entry.get_mut() = adj;
2704 /// Basically whenever we are converting from a type scheme into
2705 /// the fn body space, we always want to normalize associated
2706 /// types as well. This function combines the two.
2707 fn instantiate_type_scheme<T>(&self,
2709 substs: SubstsRef<'tcx>,
2712 where T : TypeFoldable<'tcx>
2714 let value = value.subst(self.tcx, substs);
2715 let result = self.normalize_associated_types_in(span, &value);
2716 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2723 /// As `instantiate_type_scheme`, but for the bounds found in a
2724 /// generic type scheme.
2725 fn instantiate_bounds(
2729 substs: SubstsRef<'tcx>,
2730 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
2731 let bounds = self.tcx.predicates_of(def_id);
2732 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
2733 let result = bounds.instantiate(self.tcx, substs);
2734 let result = self.normalize_associated_types_in(span, &result);
2736 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
2745 /// Replaces the opaque types from the given value with type variables,
2746 /// and records the `OpaqueTypeMap` for later use during writeback. See
2747 /// `InferCtxt::instantiate_opaque_types` for more details.
2748 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2750 parent_id: hir::HirId,
2754 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2755 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2759 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2760 self.instantiate_opaque_types(
2769 let mut opaque_types = self.opaque_types.borrow_mut();
2770 for (ty, decl) in opaque_type_map {
2771 let old_value = opaque_types.insert(ty, decl);
2772 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2778 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2779 where T : TypeFoldable<'tcx>
2781 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2784 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2786 where T : TypeFoldable<'tcx>
2788 self.inh.partially_normalize_associated_types_in(span,
2794 pub fn require_type_meets(&self,
2797 code: traits::ObligationCauseCode<'tcx>,
2800 self.register_bound(
2803 traits::ObligationCause::new(span, self.body_id, code));
2806 pub fn require_type_is_sized(
2810 code: traits::ObligationCauseCode<'tcx>,
2812 if !ty.references_error() {
2813 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2814 self.require_type_meets(ty, span, code, lang_item);
2818 pub fn require_type_is_sized_deferred(
2822 code: traits::ObligationCauseCode<'tcx>,
2824 if !ty.references_error() {
2825 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2829 pub fn register_bound(
2833 cause: traits::ObligationCause<'tcx>,
2835 if !ty.references_error() {
2836 self.fulfillment_cx.borrow_mut()
2837 .register_bound(self, self.param_env, ty, def_id, cause);
2841 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2842 let t = AstConv::ast_ty_to_ty(self, ast_t);
2843 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2847 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2848 let ty = self.to_ty(ast_ty);
2849 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2851 if Self::can_contain_user_lifetime_bounds(ty) {
2852 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2853 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2854 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2860 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2861 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2862 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2865 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2866 AstConv::ast_const_to_const(self, ast_c, ty)
2869 // If the type given by the user has free regions, save it for later, since
2870 // NLL would like to enforce those. Also pass in types that involve
2871 // projections, since those can resolve to `'static` bounds (modulo #54940,
2872 // which hopefully will be fixed by the time you see this comment, dear
2873 // reader, although I have my doubts). Also pass in types with inference
2874 // types, because they may be repeated. Other sorts of things are already
2875 // sufficiently enforced with erased regions. =)
2876 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2878 T: TypeFoldable<'tcx>
2880 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2883 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2884 match self.tables.borrow().node_types().get(id) {
2886 None if self.is_tainted_by_errors() => self.tcx.types.err,
2888 bug!("no type for node {}: {} in fcx {}",
2889 id, self.tcx.hir().node_to_string(id),
2895 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2896 /// outlive the region `r`.
2897 pub fn register_wf_obligation(
2901 code: traits::ObligationCauseCode<'tcx>,
2903 // WF obligations never themselves fail, so no real need to give a detailed cause:
2904 let cause = traits::ObligationCause::new(span, self.body_id, code);
2905 self.register_predicate(
2906 traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
2910 /// Registers obligations that all types appearing in `substs` are well-formed.
2911 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2912 for ty in substs.types() {
2913 if !ty.references_error() {
2914 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2919 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2920 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2921 /// trait/region obligations.
2923 /// For example, if there is a function:
2926 /// fn foo<'a,T:'a>(...)
2929 /// and a reference:
2935 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2936 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2937 pub fn add_obligations_for_parameters(&self,
2938 cause: traits::ObligationCause<'tcx>,
2939 predicates: &ty::InstantiatedPredicates<'tcx>)
2941 assert!(!predicates.has_escaping_bound_vars());
2943 debug!("add_obligations_for_parameters(predicates={:?})",
2946 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2947 self.register_predicate(obligation);
2951 // FIXME(arielb1): use this instead of field.ty everywhere
2952 // Only for fields! Returns <none> for methods>
2953 // Indifferent to privacy flags
2957 field: &'tcx ty::FieldDef,
2958 substs: SubstsRef<'tcx>,
2960 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2963 fn check_casts(&self) {
2964 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2965 for cast in deferred_cast_checks.drain(..) {
2970 fn resolve_generator_interiors(&self, def_id: DefId) {
2971 let mut generators = self.deferred_generator_interiors.borrow_mut();
2972 for (body_id, interior, kind) in generators.drain(..) {
2973 self.select_obligations_where_possible(false, |_| {});
2974 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
2978 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2979 // Non-numerics get replaced with ! or () (depending on whether
2980 // feature(never_type) is enabled, unconstrained ints with i32,
2981 // unconstrained floats with f64.
2982 // Fallback becomes very dubious if we have encountered type-checking errors.
2983 // In that case, fallback to Error.
2984 // The return value indicates whether fallback has occurred.
2985 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2986 use rustc::ty::error::UnconstrainedNumeric::Neither;
2987 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2989 assert!(ty.is_ty_infer());
2990 let fallback = match self.type_is_unconstrained_numeric(ty) {
2991 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2992 UnconstrainedInt => self.tcx.types.i32,
2993 UnconstrainedFloat => self.tcx.types.f64,
2994 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2995 Neither => return false,
2997 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2998 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
3002 fn select_all_obligations_or_error(&self) {
3003 debug!("select_all_obligations_or_error");
3004 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3005 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3009 /// Select as many obligations as we can at present.
3010 fn select_obligations_where_possible(
3012 fallback_has_occurred: bool,
3013 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3015 if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3016 mutate_fullfillment_errors(&mut errors);
3017 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3021 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3022 /// returns a type of `&T`, but the actual type we assign to the
3023 /// *expression* is `T`. So this function just peels off the return
3024 /// type by one layer to yield `T`.
3025 fn make_overloaded_place_return_type(&self,
3026 method: MethodCallee<'tcx>)
3027 -> ty::TypeAndMut<'tcx>
3029 // extract method return type, which will be &T;
3030 let ret_ty = method.sig.output();
3032 // method returns &T, but the type as visible to user is T, so deref
3033 ret_ty.builtin_deref(true).unwrap()
3039 base_expr: &'tcx hir::Expr,
3043 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3044 // FIXME(#18741) -- this is almost but not quite the same as the
3045 // autoderef that normal method probing does. They could likely be
3048 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3049 let mut result = None;
3050 while result.is_none() && autoderef.next().is_some() {
3051 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3053 autoderef.finalize(self);
3057 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3058 /// (and otherwise adjust) `base_expr`, looking for a type which either
3059 /// supports builtin indexing or overloaded indexing.
3060 /// This loop implements one step in that search; the autoderef loop
3061 /// is implemented by `lookup_indexing`.
3065 base_expr: &hir::Expr,
3066 autoderef: &Autoderef<'a, 'tcx>,
3069 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3070 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3071 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3078 for &unsize in &[false, true] {
3079 let mut self_ty = adjusted_ty;
3081 // We only unsize arrays here.
3082 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3083 self_ty = self.tcx.mk_slice(element_ty);
3089 // If some lookup succeeds, write callee into table and extract index/element
3090 // type from the method signature.
3091 // If some lookup succeeded, install method in table
3092 let input_ty = self.next_ty_var(TypeVariableOrigin {
3093 kind: TypeVariableOriginKind::AutoDeref,
3094 span: base_expr.span,
3096 let method = self.try_overloaded_place_op(
3097 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
3099 let result = method.map(|ok| {
3100 debug!("try_index_step: success, using overloaded indexing");
3101 let method = self.register_infer_ok_obligations(ok);
3103 let mut adjustments = autoderef.adjust_steps(self, needs);
3104 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3105 let mutbl = match r_mutbl {
3106 hir::MutImmutable => AutoBorrowMutability::Immutable,
3107 hir::MutMutable => AutoBorrowMutability::Mutable {
3108 // Indexing can be desugared to a method call,
3109 // so maybe we could use two-phase here.
3110 // See the documentation of AllowTwoPhase for why that's
3111 // not the case today.
3112 allow_two_phase_borrow: AllowTwoPhase::No,
3115 adjustments.push(Adjustment {
3116 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3117 target: self.tcx.mk_ref(region, ty::TypeAndMut {
3124 adjustments.push(Adjustment {
3125 kind: Adjust::Pointer(PointerCast::Unsize),
3126 target: method.sig.inputs()[0]
3129 self.apply_adjustments(base_expr, adjustments);
3131 self.write_method_call(expr.hir_id, method);
3132 (input_ty, self.make_overloaded_place_return_type(method).ty)
3134 if result.is_some() {
3142 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3143 let (tr, name) = match (op, is_mut) {
3144 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3145 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3146 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3147 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3149 (tr, ast::Ident::with_dummy_span(name))
3152 fn try_overloaded_place_op(&self,
3155 arg_tys: &[Ty<'tcx>],
3158 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
3160 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
3166 // Try Mut first, if needed.
3167 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3168 let method = match (needs, mut_tr) {
3169 (Needs::MutPlace, Some(trait_did)) => {
3170 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3175 // Otherwise, fall back to the immutable version.
3176 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3177 let method = match (method, imm_tr) {
3178 (None, Some(trait_did)) => {
3179 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3181 (method, _) => method,
3187 fn check_method_argument_types(
3190 expr: &'tcx hir::Expr,
3191 method: Result<MethodCallee<'tcx>, ()>,
3192 args_no_rcvr: &'tcx [hir::Expr],
3193 tuple_arguments: TupleArgumentsFlag,
3194 expected: Expectation<'tcx>,
3197 let has_error = match method {
3199 method.substs.references_error() || method.sig.references_error()
3204 let err_inputs = self.err_args(args_no_rcvr.len());
3206 let err_inputs = match tuple_arguments {
3207 DontTupleArguments => err_inputs,
3208 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3211 self.check_argument_types(
3221 return self.tcx.types.err;
3224 let method = method.unwrap();
3225 // HACK(eddyb) ignore self in the definition (see above).
3226 let expected_arg_tys = self.expected_inputs_for_expected_output(
3229 method.sig.output(),
3230 &method.sig.inputs()[1..]
3232 self.check_argument_types(
3235 &method.sig.inputs()[1..],
3236 &expected_arg_tys[..],
3238 method.sig.c_variadic,
3240 self.tcx.hir().span_if_local(method.def_id),
3245 fn self_type_matches_expected_vid(
3247 trait_ref: ty::PolyTraitRef<'tcx>,
3248 expected_vid: ty::TyVid,
3250 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3252 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3253 trait_ref, self_ty, expected_vid
3255 match self_ty.kind {
3256 ty::Infer(ty::TyVar(found_vid)) => {
3257 // FIXME: consider using `sub_root_var` here so we
3258 // can see through subtyping.
3259 let found_vid = self.root_var(found_vid);
3260 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3261 expected_vid == found_vid
3267 fn obligations_for_self_ty<'b>(
3270 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3273 // FIXME: consider using `sub_root_var` here so we
3274 // can see through subtyping.
3275 let ty_var_root = self.root_var(self_ty);
3276 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3277 self_ty, ty_var_root,
3278 self.fulfillment_cx.borrow().pending_obligations());
3282 .pending_obligations()
3284 .filter_map(move |obligation| match obligation.predicate {
3285 ty::Predicate::Projection(ref data) =>
3286 Some((data.to_poly_trait_ref(self.tcx), obligation)),
3287 ty::Predicate::Trait(ref data) =>
3288 Some((data.to_poly_trait_ref(), obligation)),
3289 ty::Predicate::Subtype(..) => None,
3290 ty::Predicate::RegionOutlives(..) => None,
3291 ty::Predicate::TypeOutlives(..) => None,
3292 ty::Predicate::WellFormed(..) => None,
3293 ty::Predicate::ObjectSafe(..) => None,
3294 ty::Predicate::ConstEvaluatable(..) => None,
3295 // N.B., this predicate is created by breaking down a
3296 // `ClosureType: FnFoo()` predicate, where
3297 // `ClosureType` represents some `Closure`. It can't
3298 // possibly be referring to the current closure,
3299 // because we haven't produced the `Closure` for
3300 // this closure yet; this is exactly why the other
3301 // code is looking for a self type of a unresolved
3302 // inference variable.
3303 ty::Predicate::ClosureKind(..) => None,
3304 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3307 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3308 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
3309 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
3313 /// Generic function that factors out common logic from function calls,
3314 /// method calls and overloaded operators.
3315 fn check_argument_types(
3318 expr: &'tcx hir::Expr,
3319 fn_inputs: &[Ty<'tcx>],
3320 expected_arg_tys: &[Ty<'tcx>],
3321 args: &'tcx [hir::Expr],
3323 tuple_arguments: TupleArgumentsFlag,
3324 def_span: Option<Span>,
3327 // Grab the argument types, supplying fresh type variables
3328 // if the wrong number of arguments were supplied
3329 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
3335 // All the input types from the fn signature must outlive the call
3336 // so as to validate implied bounds.
3337 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3338 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3341 let expected_arg_count = fn_inputs.len();
3343 let param_count_error = |expected_count: usize,
3348 let mut err = tcx.sess.struct_span_err_with_code(sp,
3349 &format!("this function takes {}{} but {} {} supplied",
3350 if c_variadic { "at least " } else { "" },
3351 potentially_plural_count(expected_count, "parameter"),
3352 potentially_plural_count(arg_count, "parameter"),
3353 if arg_count == 1 {"was"} else {"were"}),
3354 DiagnosticId::Error(error_code.to_owned()));
3356 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3357 err.span_label(def_s, "defined here");
3360 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3361 // remove closing `)` from the span
3362 let sugg_span = sugg_span.shrink_to_lo();
3363 err.span_suggestion(
3365 "expected the unit value `()`; create it with empty parentheses",
3367 Applicability::MachineApplicable);
3369 err.span_label(sp, format!("expected {}{}",
3370 if c_variadic { "at least " } else { "" },
3371 potentially_plural_count(expected_count, "parameter")));
3376 let mut expected_arg_tys = expected_arg_tys.to_vec();
3378 let formal_tys = if tuple_arguments == TupleArguments {
3379 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3380 match tuple_type.kind {
3381 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3382 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3383 expected_arg_tys = vec![];
3384 self.err_args(args.len())
3386 ty::Tuple(arg_types) => {
3387 expected_arg_tys = match expected_arg_tys.get(0) {
3388 Some(&ty) => match ty.kind {
3389 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3394 arg_types.iter().map(|k| k.expect_ty()).collect()
3397 span_err!(tcx.sess, sp, E0059,
3398 "cannot use call notation; the first type parameter \
3399 for the function trait is neither a tuple nor unit");
3400 expected_arg_tys = vec![];
3401 self.err_args(args.len())
3404 } else if expected_arg_count == supplied_arg_count {
3406 } else if c_variadic {
3407 if supplied_arg_count >= expected_arg_count {
3410 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3411 expected_arg_tys = vec![];
3412 self.err_args(supplied_arg_count)
3415 // is the missing argument of type `()`?
3416 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3417 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3418 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3419 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3423 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3425 expected_arg_tys = vec![];
3426 self.err_args(supplied_arg_count)
3429 debug!("check_argument_types: formal_tys={:?}",
3430 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3432 // If there is no expectation, expect formal_tys.
3433 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3439 let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
3441 // Check the arguments.
3442 // We do this in a pretty awful way: first we type-check any arguments
3443 // that are not closures, then we type-check the closures. This is so
3444 // that we have more information about the types of arguments when we
3445 // type-check the functions. This isn't really the right way to do this.
3446 for &check_closures in &[false, true] {
3447 debug!("check_closures={}", check_closures);
3449 // More awful hacks: before we check argument types, try to do
3450 // an "opportunistic" vtable resolution of any trait bounds on
3451 // the call. This helps coercions.
3453 self.select_obligations_where_possible(false, |errors| {
3454 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
3455 self.point_at_arg_instead_of_call_if_possible(
3457 &final_arg_types[..],
3464 // For C-variadic functions, we don't have a declared type for all of
3465 // the arguments hence we only do our usual type checking with
3466 // the arguments who's types we do know.
3467 let t = if c_variadic {
3469 } else if tuple_arguments == TupleArguments {
3474 for (i, arg) in args.iter().take(t).enumerate() {
3475 // Warn only for the first loop (the "no closures" one).
3476 // Closure arguments themselves can't be diverging, but
3477 // a previous argument can, e.g., `foo(panic!(), || {})`.
3478 if !check_closures {
3479 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3482 let is_closure = match arg.kind {
3483 ExprKind::Closure(..) => true,
3487 if is_closure != check_closures {
3491 debug!("checking the argument");
3492 let formal_ty = formal_tys[i];
3494 // The special-cased logic below has three functions:
3495 // 1. Provide as good of an expected type as possible.
3496 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3498 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3500 // 2. Coerce to the most detailed type that could be coerced
3501 // to, which is `expected_ty` if `rvalue_hint` returns an
3502 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3503 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3504 // We're processing function arguments so we definitely want to use
3505 // two-phase borrows.
3506 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3507 final_arg_types.push((i, coerce_ty));
3509 // 3. Relate the expected type and the formal one,
3510 // if the expected type was used for the coercion.
3511 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3515 // We also need to make sure we at least write the ty of the other
3516 // arguments which we skipped above.
3518 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3519 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3520 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3523 for arg in args.iter().skip(expected_arg_count) {
3524 let arg_ty = self.check_expr(&arg);
3526 // There are a few types which get autopromoted when passed via varargs
3527 // in C but we just error out instead and require explicit casts.
3528 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3530 ty::Float(ast::FloatTy::F32) => {
3531 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3533 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3534 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3536 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3537 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3540 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3541 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3542 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3550 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3551 vec![self.tcx.types.err; len]
3554 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
3555 /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
3556 /// reference a type argument. If they do, and there's only *one* argument that does, we point
3557 /// at the corresponding argument's expression span instead of the `fn` call path span.
3558 fn point_at_arg_instead_of_call_if_possible(
3560 errors: &mut Vec<traits::FulfillmentError<'_>>,
3561 final_arg_types: &[(usize, Ty<'tcx>)],
3563 args: &'tcx [hir::Expr],
3565 if !call_sp.desugaring_kind().is_some() {
3566 // We *do not* do this for desugared call spans to keep good diagnostics when involving
3567 // the `?` operator.
3568 for error in errors {
3569 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3570 // Collect the argument position for all arguments that could have caused this
3571 // `FullfillmentError`.
3572 let mut referenced_in = final_arg_types.iter()
3573 .flat_map(|(i, ty)| {
3574 let ty = self.resolve_vars_if_possible(ty);
3575 // We walk the argument type because the argument's type could have
3576 // been `Option<T>`, but the `FullfillmentError` references `T`.
3578 .filter(|&ty| ty == predicate.skip_binder().self_ty())
3581 if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3582 // We make sure that only *one* argument matches the obligation failure
3583 // and thet the obligation's span to its expression's.
3584 error.obligation.cause.span = args[ref_in].span;
3585 error.points_at_arg_span = true;
3592 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
3593 /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
3594 /// were caused by them. If they were, we point at the corresponding type argument's span
3595 /// instead of the `fn` call path span.
3596 fn point_at_type_arg_instead_of_call_if_possible(
3598 errors: &mut Vec<traits::FulfillmentError<'_>>,
3599 call_expr: &'tcx hir::Expr,
3601 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
3602 if let hir::ExprKind::Path(qpath) = &path.kind {
3603 if let hir::QPath::Resolved(_, path) = &qpath {
3604 for error in errors {
3605 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3606 // If any of the type arguments in this path segment caused the
3607 // `FullfillmentError`, point at its span (#61860).
3608 for arg in path.segments.iter()
3609 .filter_map(|seg| seg.args.as_ref())
3610 .flat_map(|a| a.args.iter())
3612 if let hir::GenericArg::Type(hir_ty) = &arg {
3613 if let hir::TyKind::Path(
3614 hir::QPath::TypeRelative(..),
3616 // Avoid ICE with associated types. As this is best
3617 // effort only, it's ok to ignore the case. It
3618 // would trigger in `is_send::<T::AssocType>();`
3619 // from `typeck-default-trait-impl-assoc-type.rs`.
3621 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
3622 let ty = self.resolve_vars_if_possible(&ty);
3623 if ty == predicate.skip_binder().self_ty() {
3624 error.obligation.cause.span = hir_ty.span;
3636 // AST fragment checking
3639 expected: Expectation<'tcx>)
3645 ast::LitKind::Str(..) => tcx.mk_static_str(),
3646 ast::LitKind::ByteStr(ref v) => {
3647 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3648 tcx.mk_array(tcx.types.u8, v.len() as u64))
3650 ast::LitKind::Byte(_) => tcx.types.u8,
3651 ast::LitKind::Char(_) => tcx.types.char,
3652 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3653 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3654 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3655 let opt_ty = expected.to_option(self).and_then(|ty| {
3657 ty::Int(_) | ty::Uint(_) => Some(ty),
3658 ty::Char => Some(tcx.types.u8),
3659 ty::RawPtr(..) => Some(tcx.types.usize),
3660 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3664 opt_ty.unwrap_or_else(|| self.next_int_var())
3666 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3667 ast::LitKind::FloatUnsuffixed(_) => {
3668 let opt_ty = expected.to_option(self).and_then(|ty| {
3670 ty::Float(_) => Some(ty),
3674 opt_ty.unwrap_or_else(|| self.next_float_var())
3676 ast::LitKind::Bool(_) => tcx.types.bool,
3677 ast::LitKind::Err(_) => tcx.types.err,
3681 // Determine the `Self` type, using fresh variables for all variables
3682 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3683 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3685 pub fn impl_self_ty(&self,
3686 span: Span, // (potential) receiver for this impl
3688 -> TypeAndSubsts<'tcx> {
3689 let ity = self.tcx.type_of(did);
3690 debug!("impl_self_ty: ity={:?}", ity);
3692 let substs = self.fresh_substs_for_item(span, did);
3693 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3695 TypeAndSubsts { substs: substs, ty: substd_ty }
3698 /// Unifies the output type with the expected type early, for more coercions
3699 /// and forward type information on the input expressions.
3700 fn expected_inputs_for_expected_output(&self,
3702 expected_ret: Expectation<'tcx>,
3703 formal_ret: Ty<'tcx>,
3704 formal_args: &[Ty<'tcx>])
3706 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3707 let ret_ty = match expected_ret.only_has_type(self) {
3709 None => return Vec::new()
3711 let expect_args = self.fudge_inference_if_ok(|| {
3712 // Attempt to apply a subtyping relationship between the formal
3713 // return type (likely containing type variables if the function
3714 // is polymorphic) and the expected return type.
3715 // No argument expectations are produced if unification fails.
3716 let origin = self.misc(call_span);
3717 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3719 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3720 // to identity so the resulting type is not constrained.
3723 // Process any obligations locally as much as
3724 // we can. We don't care if some things turn
3725 // out unconstrained or ambiguous, as we're
3726 // just trying to get hints here.
3727 self.save_and_restore_in_snapshot_flag(|_| {
3728 let mut fulfill = TraitEngine::new(self.tcx);
3729 for obligation in ok.obligations {
3730 fulfill.register_predicate_obligation(self, obligation);
3732 fulfill.select_where_possible(self)
3733 }).map_err(|_| ())?;
3735 Err(_) => return Err(()),
3738 // Record all the argument types, with the substitutions
3739 // produced from the above subtyping unification.
3740 Ok(formal_args.iter().map(|ty| {
3741 self.resolve_vars_if_possible(ty)
3743 }).unwrap_or_default();
3744 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3745 formal_args, formal_ret,
3746 expect_args, expected_ret);
3750 pub fn check_struct_path(&self,
3753 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3754 let path_span = match *qpath {
3755 QPath::Resolved(_, ref path) => path.span,
3756 QPath::TypeRelative(ref qself, _) => qself.span
3758 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3759 let variant = match def {
3761 self.set_tainted_by_errors();
3764 Res::Def(DefKind::Variant, _) => {
3766 ty::Adt(adt, substs) => {
3767 Some((adt.variant_of_res(def), adt.did, substs))
3769 _ => bug!("unexpected type: {:?}", ty)
3772 Res::Def(DefKind::Struct, _)
3773 | Res::Def(DefKind::Union, _)
3774 | Res::Def(DefKind::TyAlias, _)
3775 | Res::Def(DefKind::AssocTy, _)
3776 | Res::SelfTy(..) => {
3778 ty::Adt(adt, substs) if !adt.is_enum() => {
3779 Some((adt.non_enum_variant(), adt.did, substs))
3784 _ => bug!("unexpected definition: {:?}", def)
3787 if let Some((variant, did, substs)) = variant {
3788 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3789 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3791 // Check bounds on type arguments used in the path.
3792 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
3793 let cause = traits::ObligationCause::new(
3796 traits::ItemObligation(did),
3798 self.add_obligations_for_parameters(cause, &bounds);
3802 struct_span_err!(self.tcx.sess, path_span, E0071,
3803 "expected struct, variant or union type, found {}",
3804 ty.sort_string(self.tcx))
3805 .span_label(path_span, "not a struct")
3811 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3812 // The newly resolved definition is written into `type_dependent_defs`.
3813 fn finish_resolving_struct_path(&self,
3820 QPath::Resolved(ref maybe_qself, ref path) => {
3821 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3822 let ty = AstConv::res_to_ty(self, self_ty, path, true);
3825 QPath::TypeRelative(ref qself, ref segment) => {
3826 let ty = self.to_ty(qself);
3828 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
3833 let result = AstConv::associated_path_to_ty(
3842 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
3843 let result = result.map(|(_, kind, def_id)| (kind, def_id));
3845 // Write back the new resolution.
3846 self.write_resolution(hir_id, result);
3848 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
3853 /// Resolves an associated value path into a base type and associated constant, or method
3854 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
3855 pub fn resolve_ty_and_res_ufcs<'b>(&self,
3859 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3861 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
3862 let (ty, qself, item_segment) = match *qpath {
3863 QPath::Resolved(ref opt_qself, ref path) => {
3865 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3866 &path.segments[..]);
3868 QPath::TypeRelative(ref qself, ref segment) => {
3869 (self.to_ty(qself), qself, segment)
3872 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
3873 // Return directly on cache hit. This is useful to avoid doubly reporting
3874 // errors with default match binding modes. See #44614.
3875 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
3876 .unwrap_or(Res::Err);
3877 return (def, Some(ty), slice::from_ref(&**item_segment));
3879 let item_name = item_segment.ident;
3880 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
3881 let result = match error {
3882 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
3883 _ => Err(ErrorReported),
3885 if item_name.name != kw::Invalid {
3886 self.report_method_error(
3890 SelfSource::QPath(qself),
3893 ).map(|mut e| e.emit());
3898 // Write back the new resolution.
3899 self.write_resolution(hir_id, result);
3901 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
3903 slice::from_ref(&**item_segment),
3907 pub fn check_decl_initializer(
3909 local: &'tcx hir::Local,
3910 init: &'tcx hir::Expr,
3912 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
3913 // for #42640 (default match binding modes).
3916 let ref_bindings = local.pat.contains_explicit_ref_binding();
3918 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
3919 if let Some(m) = ref_bindings {
3920 // Somewhat subtle: if we have a `ref` binding in the pattern,
3921 // we want to avoid introducing coercions for the RHS. This is
3922 // both because it helps preserve sanity and, in the case of
3923 // ref mut, for soundness (issue #23116). In particular, in
3924 // the latter case, we need to be clear that the type of the
3925 // referent for the reference that results is *equal to* the
3926 // type of the place it is referencing, and not some
3927 // supertype thereof.
3928 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
3929 self.demand_eqtype(init.span, local_ty, init_ty);
3932 self.check_expr_coercable_to_type(init, local_ty)
3936 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
3937 let t = self.local_ty(local.span, local.hir_id).decl_ty;
3938 self.write_ty(local.hir_id, t);
3940 if let Some(ref init) = local.init {
3941 let init_ty = self.check_decl_initializer(local, &init);
3942 self.overwrite_local_ty_if_err(local, t, init_ty);
3945 self.check_pat_top(&local.pat, t, None);
3946 let pat_ty = self.node_ty(local.pat.hir_id);
3947 self.overwrite_local_ty_if_err(local, t, pat_ty);
3950 fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
3951 if ty.references_error() {
3952 // Override the types everywhere with `types.err` to avoid knock down errors.
3953 self.write_ty(local.hir_id, ty);
3954 self.write_ty(local.pat.hir_id, ty);
3955 let local_ty = LocalTy {
3959 self.locals.borrow_mut().insert(local.hir_id, local_ty);
3960 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
3964 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
3965 err.span_suggestion_short(
3966 span.shrink_to_hi(),
3967 "consider using a semicolon here",
3969 Applicability::MachineApplicable,
3973 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
3974 // Don't do all the complex logic below for `DeclItem`.
3976 hir::StmtKind::Item(..) => return,
3977 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
3980 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
3982 // Hide the outer diverging and `has_errors` flags.
3983 let old_diverges = self.diverges.get();
3984 let old_has_errors = self.has_errors.get();
3985 self.diverges.set(Diverges::Maybe);
3986 self.has_errors.set(false);
3989 hir::StmtKind::Local(ref l) => {
3990 self.check_decl_local(&l);
3993 hir::StmtKind::Item(_) => {}
3994 hir::StmtKind::Expr(ref expr) => {
3995 // Check with expected type of `()`.
3997 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
3998 self.suggest_semicolon_at_end(expr.span, err);
4001 hir::StmtKind::Semi(ref expr) => {
4002 self.check_expr(&expr);
4006 // Combine the diverging and `has_error` flags.
4007 self.diverges.set(self.diverges.get() | old_diverges);
4008 self.has_errors.set(self.has_errors.get() | old_has_errors);
4011 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
4012 let unit = self.tcx.mk_unit();
4013 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4015 // if the block produces a `!` value, that can always be
4016 // (effectively) coerced to unit.
4018 self.demand_suptype(blk.span, unit, ty);
4022 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4023 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4024 /// when given code like the following:
4026 /// if false { return 0i32; } else { 1u32 }
4027 /// // ^^^^ point at this instead of the whole `if` expression
4029 fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
4030 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4031 let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
4032 self.in_progress_tables
4033 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4034 .and_then(|arm_ty| {
4035 if arm_ty.is_never() {
4038 Some(match &arm.body.kind {
4039 // Point at the tail expression when possible.
4040 hir::ExprKind::Block(block, _) => block.expr
4043 .unwrap_or(block.span),
4049 if arm_spans.len() == 1 {
4050 return arm_spans[0];
4056 fn check_block_with_expected(
4058 blk: &'tcx hir::Block,
4059 expected: Expectation<'tcx>,
4062 let mut fcx_ps = self.ps.borrow_mut();
4063 let unsafety_state = fcx_ps.recurse(blk);
4064 replace(&mut *fcx_ps, unsafety_state)
4067 // In some cases, blocks have just one exit, but other blocks
4068 // can be targeted by multiple breaks. This can happen both
4069 // with labeled blocks as well as when we desugar
4070 // a `try { ... }` expression.
4074 // 'a: { if true { break 'a Err(()); } Ok(()) }
4076 // Here we would wind up with two coercions, one from
4077 // `Err(())` and the other from the tail expression
4078 // `Ok(())`. If the tail expression is omitted, that's a
4079 // "forced unit" -- unless the block diverges, in which
4080 // case we can ignore the tail expression (e.g., `'a: {
4081 // break 'a 22; }` would not force the type of the block
4083 let tail_expr = blk.expr.as_ref();
4084 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4085 let coerce = if blk.targeted_by_break {
4086 CoerceMany::new(coerce_to_ty)
4088 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4089 Some(e) => slice::from_ref(e),
4092 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4095 let prev_diverges = self.diverges.get();
4096 let ctxt = BreakableCtxt {
4097 coerce: Some(coerce),
4101 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4102 for s in &blk.stmts {
4106 // check the tail expression **without** holding the
4107 // `enclosing_breakables` lock below.
4108 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4110 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4111 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4112 let coerce = ctxt.coerce.as_mut().unwrap();
4113 if let Some(tail_expr_ty) = tail_expr_ty {
4114 let tail_expr = tail_expr.unwrap();
4115 let span = self.get_expr_coercion_span(tail_expr);
4116 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4117 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4119 // Subtle: if there is no explicit tail expression,
4120 // that is typically equivalent to a tail expression
4121 // of `()` -- except if the block diverges. In that
4122 // case, there is no value supplied from the tail
4123 // expression (assuming there are no other breaks,
4124 // this implies that the type of the block will be
4127 // #41425 -- label the implicit `()` as being the
4128 // "found type" here, rather than the "expected type".
4129 if !self.diverges.get().is_always() {
4130 // #50009 -- Do not point at the entire fn block span, point at the return type
4131 // span, as it is the cause of the requirement, and
4132 // `consider_hint_about_removing_semicolon` will point at the last expression
4133 // if it were a relevant part of the error. This improves usability in editors
4134 // that highlight errors inline.
4135 let mut sp = blk.span;
4136 let mut fn_span = None;
4137 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4138 let ret_sp = decl.output.span();
4139 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4140 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4141 // output would otherwise be incorrect and even misleading. Make sure
4142 // the span we're aiming at correspond to a `fn` body.
4143 if block_sp == blk.span {
4145 fn_span = Some(ident.span);
4149 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
4150 if let Some(expected_ty) = expected.only_has_type(self) {
4151 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4153 if let Some(fn_span) = fn_span {
4156 "implicitly returns `()` as its body has no tail or `return` \
4166 // If we can break from the block, then the block's exit is always reachable
4167 // (... as long as the entry is reachable) - regardless of the tail of the block.
4168 self.diverges.set(prev_diverges);
4171 let mut ty = ctxt.coerce.unwrap().complete(self);
4173 if self.has_errors.get() || ty.references_error() {
4174 ty = self.tcx.types.err
4177 self.write_ty(blk.hir_id, ty);
4179 *self.ps.borrow_mut() = prev;
4183 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4184 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4186 Node::Item(&hir::Item {
4187 kind: hir::ItemKind::Fn(_, _, _, body_id), ..
4189 Node::ImplItem(&hir::ImplItem {
4190 kind: hir::ImplItemKind::Method(_, body_id), ..
4192 let body = self.tcx.hir().body(body_id);
4193 if let ExprKind::Block(block, _) = &body.value.kind {
4194 return Some(block.span);
4202 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4203 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
4204 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4205 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4208 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4209 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
4211 Node::Item(&hir::Item {
4212 ident, kind: hir::ItemKind::Fn(ref decl, ..), ..
4214 // This is less than ideal, it will not suggest a return type span on any
4215 // method called `main`, regardless of whether it is actually the entry point,
4216 // but it will still present it as the reason for the expected type.
4217 Some((decl, ident, ident.name != sym::main))
4219 Node::TraitItem(&hir::TraitItem {
4220 ident, kind: hir::TraitItemKind::Method(hir::MethodSig {
4223 }) => Some((decl, ident, true)),
4224 Node::ImplItem(&hir::ImplItem {
4225 ident, kind: hir::ImplItemKind::Method(hir::MethodSig {
4228 }) => Some((decl, ident, false)),
4233 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4234 /// suggestion can be made, `None` otherwise.
4235 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
4236 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4237 // `while` before reaching it, as block tail returns are not available in them.
4238 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4239 let parent = self.tcx.hir().get(blk_id);
4240 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4244 /// On implicit return expressions with mismatched types, provides the following suggestions:
4246 /// - Points out the method's return type as the reason for the expected type.
4247 /// - Possible missing semicolon.
4248 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4249 pub fn suggest_mismatched_types_on_tail(
4251 err: &mut DiagnosticBuilder<'tcx>,
4252 expr: &'tcx hir::Expr,
4258 let expr = expr.peel_drop_temps();
4259 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4260 let mut pointing_at_return_type = false;
4261 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4262 pointing_at_return_type = self.suggest_missing_return_type(
4263 err, &fn_decl, expected, found, can_suggest);
4265 self.suggest_ref_or_into(err, expr, expected, found);
4266 self.suggest_boxing_when_appropriate(err, expr, expected, found);
4267 pointing_at_return_type
4270 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4271 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4273 /// fn foo(x: usize) -> usize { x }
4274 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4278 err: &mut DiagnosticBuilder<'tcx>,
4283 let hir = self.tcx.hir();
4284 let (def_id, sig) = match found.kind {
4285 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4286 ty::Closure(def_id, substs) => {
4287 // We don't use `closure_sig` to account for malformed closures like
4288 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4289 let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4290 (def_id, match closure_sig_ty.kind {
4291 ty::FnPtr(sig) => sig,
4299 .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
4301 let sig = self.normalize_associated_types_in(expr.span, &sig);
4302 if self.can_coerce(sig.output(), expected) {
4303 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4304 (String::new(), Applicability::MachineApplicable)
4306 ("...".to_string(), Applicability::HasPlaceholders)
4308 let mut msg = "call this function";
4309 match hir.get_if_local(def_id) {
4310 Some(Node::Item(hir::Item {
4311 kind: ItemKind::Fn(.., body_id),
4314 Some(Node::ImplItem(hir::ImplItem {
4315 kind: hir::ImplItemKind::Method(_, body_id),
4318 Some(Node::TraitItem(hir::TraitItem {
4319 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4322 let body = hir.body(*body_id);
4323 sugg_call = body.params.iter()
4324 .map(|param| match ¶m.pat.kind {
4325 hir::PatKind::Binding(_, _, ident, None)
4326 if ident.name != kw::SelfLower => ident.to_string(),
4327 _ => "_".to_string(),
4328 }).collect::<Vec<_>>().join(", ");
4330 Some(Node::Expr(hir::Expr {
4331 kind: ExprKind::Closure(_, _, body_id, closure_span, _),
4332 span: full_closure_span,
4335 if *full_closure_span == expr.span {
4338 err.span_label(*closure_span, "closure defined here");
4339 msg = "call this closure";
4340 let body = hir.body(*body_id);
4341 sugg_call = body.params.iter()
4342 .map(|param| match ¶m.pat.kind {
4343 hir::PatKind::Binding(_, _, ident, None)
4344 if ident.name != kw::SelfLower => ident.to_string(),
4345 _ => "_".to_string(),
4346 }).collect::<Vec<_>>().join(", ");
4348 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4349 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4350 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4351 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4352 msg = "instantiate this tuple variant";
4354 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4355 msg = "instantiate this tuple struct";
4360 Some(Node::ForeignItem(hir::ForeignItem {
4361 kind: hir::ForeignItemKind::Fn(_, idents, _),
4364 Some(Node::TraitItem(hir::TraitItem {
4365 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4367 })) => sugg_call = idents.iter()
4368 .map(|ident| if ident.name != kw::SelfLower {
4372 }).collect::<Vec<_>>()
4376 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4377 err.span_suggestion(
4379 &format!("use parentheses to {}", msg),
4380 format!("{}({})", code, sugg_call),
4389 pub fn suggest_ref_or_into(
4391 err: &mut DiagnosticBuilder<'tcx>,
4396 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4397 err.span_suggestion(
4401 Applicability::MachineApplicable,
4403 } else if let (ty::FnDef(def_id, ..), true) = (
4405 self.suggest_fn_call(err, expr, expected, found),
4407 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4408 let sp = self.sess().source_map().def_span(sp);
4409 err.span_label(sp, &format!("{} defined here", found));
4411 } else if !self.check_for_cast(err, expr, found, expected) {
4412 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4416 let methods = self.get_conversion_methods(expr.span, expected, found);
4417 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4418 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4419 .filter_map(|(receiver, method)| {
4420 let method_call = format!(".{}()", method.ident);
4421 if receiver.ends_with(&method_call) {
4422 None // do not suggest code that is already there (#53348)
4424 let method_call_list = [".to_vec()", ".to_string()"];
4425 let sugg = if receiver.ends_with(".clone()")
4426 && method_call_list.contains(&method_call.as_str()) {
4427 let max_len = receiver.rfind(".").unwrap();
4428 format!("{}{}", &receiver[..max_len], method_call)
4430 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
4431 format!("({}){}", receiver, method_call)
4433 format!("{}{}", receiver, method_call)
4436 Some(if is_struct_pat_shorthand_field {
4437 format!("{}: {}", receiver, sugg)
4443 if suggestions.peek().is_some() {
4444 err.span_suggestions(
4446 "try using a conversion method",
4448 Applicability::MaybeIncorrect,
4455 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
4456 /// in the heap by calling `Box::new()`.
4457 fn suggest_boxing_when_appropriate(
4459 err: &mut DiagnosticBuilder<'tcx>,
4464 if self.tcx.hir().is_const_context(expr.hir_id) {
4465 // Do not suggest `Box::new` in const context.
4468 if !expected.is_box() || found.is_box() {
4471 let boxed_found = self.tcx.mk_box(found);
4472 if let (true, Ok(snippet)) = (
4473 self.can_coerce(boxed_found, expected),
4474 self.sess().source_map().span_to_snippet(expr.span),
4476 err.span_suggestion(
4478 "store this in the heap by calling `Box::new`",
4479 format!("Box::new({})", snippet),
4480 Applicability::MachineApplicable,
4482 err.note("for more on the distinction between the stack and the \
4483 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
4484 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
4485 https://doc.rust-lang.org/std/boxed/index.html");
4490 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4494 /// bar_that_returns_u32()
4498 /// This routine checks if the return expression in a block would make sense on its own as a
4499 /// statement and the return type has been left as default or has been specified as `()`. If so,
4500 /// it suggests adding a semicolon.
4501 fn suggest_missing_semicolon(
4503 err: &mut DiagnosticBuilder<'tcx>,
4504 expression: &'tcx hir::Expr,
4508 if expected.is_unit() {
4509 // `BlockTailExpression` only relevant if the tail expr would be
4510 // useful on its own.
4511 match expression.kind {
4512 ExprKind::Call(..) |
4513 ExprKind::MethodCall(..) |
4514 ExprKind::Loop(..) |
4515 ExprKind::Match(..) |
4516 ExprKind::Block(..) => {
4517 let sp = self.tcx.sess.source_map().next_point(cause_span);
4518 err.span_suggestion(
4520 "try adding a semicolon",
4522 Applicability::MachineApplicable);
4529 /// A possible error is to forget to add a return type that is needed:
4533 /// bar_that_returns_u32()
4537 /// This routine checks if the return type is left as default, the method is not part of an
4538 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4540 fn suggest_missing_return_type(
4542 err: &mut DiagnosticBuilder<'tcx>,
4543 fn_decl: &hir::FnDecl,
4548 // Only suggest changing the return type for methods that
4549 // haven't set a return type at all (and aren't `fn main()` or an impl).
4550 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4551 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4552 err.span_suggestion(
4554 "try adding a return type",
4555 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
4556 Applicability::MachineApplicable);
4559 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4560 err.span_label(span, "possibly return type missing here?");
4563 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4564 // `fn main()` must return `()`, do not suggest changing return type
4565 err.span_label(span, "expected `()` because of default return type");
4568 // expectation was caused by something else, not the default return
4569 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4570 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4571 // Only point to return type if the expected type is the return type, as if they
4572 // are not, the expectation must have been caused by something else.
4573 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
4575 let ty = AstConv::ast_ty_to_ty(self, ty);
4576 debug!("suggest_missing_return_type: return type {:?}", ty);
4577 debug!("suggest_missing_return_type: expected type {:?}", ty);
4578 if ty.kind == expected.kind {
4579 err.span_label(sp, format!("expected `{}` because of return type",
4588 /// A possible error is to forget to add `.await` when using futures:
4591 /// async fn make_u32() -> u32 {
4595 /// fn take_u32(x: u32) {}
4597 /// async fn foo() {
4598 /// let x = make_u32();
4603 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
4604 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
4605 /// `.await` to the tail of the expression.
4606 fn suggest_missing_await(
4608 err: &mut DiagnosticBuilder<'tcx>,
4613 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
4614 // body isn't `async`.
4615 let item_id = self.tcx().hir().get_parent_node(self.body_id);
4616 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
4617 let body = self.tcx().hir().body(body_id);
4618 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
4620 // Check for `Future` implementations by constructing a predicate to
4621 // prove: `<T as Future>::Output == U`
4622 let future_trait = self.tcx.lang_items().future_trait().unwrap();
4623 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
4624 let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
4625 // `<T as Future>::Output`
4626 projection_ty: ty::ProjectionTy {
4628 substs: self.tcx.mk_substs_trait(
4630 self.fresh_substs_for_item(sp, item_def_id)
4637 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
4638 if self.infcx.predicate_may_hold(&obligation) {
4639 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
4640 err.span_suggestion(
4642 "consider using `.await` here",
4643 format!("{}.await", code),
4644 Applicability::MaybeIncorrect,
4652 /// A common error is to add an extra semicolon:
4655 /// fn foo() -> usize {
4660 /// This routine checks if the final statement in a block is an
4661 /// expression with an explicit semicolon whose type is compatible
4662 /// with `expected_ty`. If so, it suggests removing the semicolon.
4663 fn consider_hint_about_removing_semicolon(
4665 blk: &'tcx hir::Block,
4666 expected_ty: Ty<'tcx>,
4667 err: &mut DiagnosticBuilder<'_>,
4669 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4670 err.span_suggestion(
4672 "consider removing this semicolon",
4674 Applicability::MachineApplicable,
4679 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4680 // Be helpful when the user wrote `{... expr;}` and
4681 // taking the `;` off is enough to fix the error.
4682 let last_stmt = blk.stmts.last()?;
4683 let last_expr = match last_stmt.kind {
4684 hir::StmtKind::Semi(ref e) => e,
4687 let last_expr_ty = self.node_ty(last_expr.hir_id);
4688 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4691 let original_span = original_sp(last_stmt.span, blk.span);
4692 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4695 // Instantiates the given path, which must refer to an item with the given
4696 // number of type parameters and type.
4697 pub fn instantiate_value_path(&self,
4698 segments: &[hir::PathSegment],
4699 self_ty: Option<Ty<'tcx>>,
4703 -> (Ty<'tcx>, Res) {
4705 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4714 let path_segs = match res {
4715 Res::Local(_) | Res::SelfCtor(_) => vec![],
4716 Res::Def(kind, def_id) =>
4717 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4718 _ => bug!("instantiate_value_path on {:?}", res),
4721 let mut user_self_ty = None;
4722 let mut is_alias_variant_ctor = false;
4724 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4725 if let Some(self_ty) = self_ty {
4726 let adt_def = self_ty.ty_adt_def().unwrap();
4727 user_self_ty = Some(UserSelfTy {
4728 impl_def_id: adt_def.did,
4731 is_alias_variant_ctor = true;
4734 Res::Def(DefKind::Method, def_id)
4735 | Res::Def(DefKind::AssocConst, def_id) => {
4736 let container = tcx.associated_item(def_id).container;
4737 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4739 ty::TraitContainer(trait_did) => {
4740 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4742 ty::ImplContainer(impl_def_id) => {
4743 if segments.len() == 1 {
4744 // `<T>::assoc` will end up here, and so
4745 // can `T::assoc`. It this came from an
4746 // inherent impl, we need to record the
4747 // `T` for posterity (see `UserSelfTy` for
4749 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4750 user_self_ty = Some(UserSelfTy {
4761 // Now that we have categorized what space the parameters for each
4762 // segment belong to, let's sort out the parameters that the user
4763 // provided (if any) into their appropriate spaces. We'll also report
4764 // errors if type parameters are provided in an inappropriate place.
4766 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4767 let generics_has_err = AstConv::prohibit_generics(
4768 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4769 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4776 if let Res::Local(hid) = res {
4777 let ty = self.local_ty(span, hid).decl_ty;
4778 let ty = self.normalize_associated_types_in(span, &ty);
4779 self.write_ty(hir_id, ty);
4783 if generics_has_err {
4784 // Don't try to infer type parameters when prohibited generic arguments were given.
4785 user_self_ty = None;
4788 // Now we have to compare the types that the user *actually*
4789 // provided against the types that were *expected*. If the user
4790 // did not provide any types, then we want to substitute inference
4791 // variables. If the user provided some types, we may still need
4792 // to add defaults. If the user provided *too many* types, that's
4795 let mut infer_args_for_err = FxHashSet::default();
4796 for &PathSeg(def_id, index) in &path_segs {
4797 let seg = &segments[index];
4798 let generics = tcx.generics_of(def_id);
4799 // Argument-position `impl Trait` is treated as a normal generic
4800 // parameter internally, but we don't allow users to specify the
4801 // parameter's value explicitly, so we have to do some error-
4803 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4808 false, // `is_method_call`
4810 if suppress_errors {
4811 infer_args_for_err.insert(index);
4812 self.set_tainted_by_errors(); // See issue #53251.
4816 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4817 tcx.generics_of(*def_id).has_self
4818 }).unwrap_or(false);
4820 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
4821 let ty = self.impl_self_ty(span, impl_def_id).ty;
4822 let adt_def = ty.ty_adt_def();
4825 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
4826 let variant = adt_def.non_enum_variant();
4827 let ctor_def_id = variant.ctor_def_id.unwrap();
4829 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
4834 let mut err = tcx.sess.struct_span_err(span,
4835 "the `Self` constructor can only be used with tuple or unit structs");
4836 if let Some(adt_def) = adt_def {
4837 match adt_def.adt_kind() {
4839 err.help("did you mean to use one of the enum's variants?");
4843 err.span_suggestion(
4845 "use curly brackets",
4846 String::from("Self { /* fields */ }"),
4847 Applicability::HasPlaceholders,
4854 return (tcx.types.err, res)
4860 let def_id = res.def_id();
4862 // The things we are substituting into the type should not contain
4863 // escaping late-bound regions, and nor should the base type scheme.
4864 let ty = tcx.type_of(def_id);
4866 let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
4872 // Provide the generic args, and whether types should be inferred.
4874 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4877 // If we've encountered an `impl Trait`-related error, we're just
4878 // going to infer the arguments for better error messages.
4879 if !infer_args_for_err.contains(&index) {
4880 // Check whether the user has provided generic arguments.
4881 if let Some(ref data) = segments[index].args {
4882 return (Some(data), segments[index].infer_args);
4885 return (None, segments[index].infer_args);
4890 // Provide substitutions for parameters for which (valid) arguments have been provided.
4892 match (¶m.kind, arg) {
4893 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4894 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4896 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4897 self.to_ty(ty).into()
4899 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4900 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4902 _ => unreachable!(),
4905 // Provide substitutions for parameters for which arguments are inferred.
4906 |substs, param, infer_args| {
4908 GenericParamDefKind::Lifetime => {
4909 self.re_infer(Some(param), span).unwrap().into()
4911 GenericParamDefKind::Type { has_default, .. } => {
4912 if !infer_args && has_default {
4913 // If we have a default, then we it doesn't matter that we're not
4914 // inferring the type arguments: we provide the default where any
4916 let default = tcx.type_of(param.def_id);
4919 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4922 // If no type arguments were provided, we have to infer them.
4923 // This case also occurs as a result of some malformed input, e.g.
4924 // a lifetime argument being given instead of a type parameter.
4925 // Using inference instead of `Error` gives better error messages.
4926 self.var_for_def(span, param)
4929 GenericParamDefKind::Const => {
4930 // FIXME(const_generics:defaults)
4931 // No const parameters were provided, we have to infer them.
4932 self.var_for_def(span, param)
4937 assert!(!substs.has_escaping_bound_vars());
4938 assert!(!ty.has_escaping_bound_vars());
4940 // First, store the "user substs" for later.
4941 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4943 self.add_required_obligations(span, def_id, &substs);
4945 // Substitute the values for the type parameters into the type of
4946 // the referenced item.
4947 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4949 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4950 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4951 // is inherent, there is no `Self` parameter; instead, the impl needs
4952 // type parameters, which we can infer by unifying the provided `Self`
4953 // with the substituted impl type.
4954 // This also occurs for an enum variant on a type alias.
4955 let ty = tcx.type_of(impl_def_id);
4957 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4958 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4959 Ok(ok) => self.register_infer_ok_obligations(ok),
4961 self.tcx.sess.delay_span_bug(span, &format!(
4962 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4970 self.check_rustc_args_require_const(def_id, hir_id, span);
4972 debug!("instantiate_value_path: type of {:?} is {:?}",
4975 self.write_substs(hir_id, substs);
4977 (ty_substituted, res)
4980 /// Add all the obligations that are required, substituting and normalized appropriately.
4981 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
4982 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
4984 for (i, mut obligation) in traits::predicates_for_generics(
4985 traits::ObligationCause::new(
4988 traits::ItemObligation(def_id),
4992 ).into_iter().enumerate() {
4993 // This makes the error point at the bound, but we want to point at the argument
4994 if let Some(span) = spans.get(i) {
4995 obligation.cause.code = traits::BindingObligation(def_id, *span);
4997 self.register_predicate(obligation);
5001 fn check_rustc_args_require_const(&self,
5005 // We're only interested in functions tagged with
5006 // #[rustc_args_required_const], so ignore anything that's not.
5007 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5011 // If our calling expression is indeed the function itself, we're good!
5012 // If not, generate an error that this can only be called directly.
5013 if let Node::Expr(expr) = self.tcx.hir().get(
5014 self.tcx.hir().get_parent_node(hir_id))
5016 if let ExprKind::Call(ref callee, ..) = expr.kind {
5017 if callee.hir_id == hir_id {
5023 self.tcx.sess.span_err(span, "this function can only be invoked \
5024 directly, not through a function pointer");
5027 // Resolves `typ` by a single level if `typ` is a type variable.
5028 // If no resolution is possible, then an error is reported.
5029 // Numeric inference variables may be left unresolved.
5030 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5031 let ty = self.resolve_type_vars_with_obligations(ty);
5032 if !ty.is_ty_var() {
5035 if !self.is_tainted_by_errors() {
5036 self.need_type_info_err((**self).body_id, sp, ty)
5037 .note("type must be known at this point")
5040 self.demand_suptype(sp, self.tcx.types.err, ty);
5045 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5048 ctxt: BreakableCtxt<'tcx>,
5050 ) -> (BreakableCtxt<'tcx>, R) {
5053 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5054 index = enclosing_breakables.stack.len();
5055 enclosing_breakables.by_id.insert(id, index);
5056 enclosing_breakables.stack.push(ctxt);
5060 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5061 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5062 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5063 enclosing_breakables.stack.pop().expect("missing breakable context")
5068 /// Instantiate a QueryResponse in a probe context, without a
5069 /// good ObligationCause.
5070 fn probe_instantiate_query_response(
5073 original_values: &OriginalQueryValues<'tcx>,
5074 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5075 ) -> InferResult<'tcx, Ty<'tcx>>
5077 self.instantiate_query_response_and_region_obligations(
5078 &traits::ObligationCause::misc(span, self.body_id),
5084 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5085 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5086 let mut contained_in_place = false;
5088 while let hir::Node::Expr(parent_expr) =
5089 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5091 match &parent_expr.kind {
5092 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5093 if lhs.hir_id == expr_id {
5094 contained_in_place = true;
5100 expr_id = parent_expr.hir_id;
5107 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5108 let own_counts = generics.own_counts();
5110 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5116 if own_counts.types == 0 {
5120 // Make a vector of booleans initially `false`; set to `true` when used.
5121 let mut types_used = vec![false; own_counts.types];
5123 for leaf_ty in ty.walk() {
5124 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.kind {
5125 debug!("found use of ty param num {}", index);
5126 types_used[index as usize - own_counts.lifetimes] = true;
5127 } else if let ty::Error = leaf_ty.kind {
5128 // If there is already another error, do not emit
5129 // an error for not using a type parameter.
5130 assert!(tcx.sess.has_errors());
5135 let types = generics.params.iter().filter(|param| match param.kind {
5136 ty::GenericParamDefKind::Type { .. } => true,
5139 for (&used, param) in types_used.iter().zip(types) {
5141 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5142 let span = tcx.hir().span(id);
5143 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5144 .span_label(span, "unused type parameter")
5150 fn fatally_break_rust(sess: &Session) {
5151 let handler = sess.diagnostic();
5152 handler.span_bug_no_panic(
5154 "It looks like you're trying to break rust; would you like some ICE?",
5156 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5157 handler.note_without_error(
5158 "we would appreciate a joke overview: \
5159 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5161 handler.note_without_error(&format!("rustc {} running on {}",
5162 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5163 crate::session::config::host_triple(),
5167 fn potentially_plural_count(count: usize, word: &str) -> String {
5168 format!("{} {}{}", count, word, pluralise!(count))