1 // ignore-tidy-filelength
7 Within the check phase of type check, we check each item one at a time
8 (bodies of function expressions are checked as part of the containing
9 function). Inference is used to supply types wherever they are unknown.
11 By far the most complex case is checking the body of a function. This
12 can be broken down into several distinct phases:
14 - gather: creates type variables to represent the type of each local
15 variable and pattern binding.
17 - main: the main pass does the lion's share of the work: it
18 determines the types of all expressions, resolves
19 methods, checks for most invalid conditions, and so forth. In
20 some cases, where a type is unknown, it may create a type or region
21 variable and use that as the type of an expression.
23 In the process of checking, various constraints will be placed on
24 these type variables through the subtyping relationships requested
25 through the `demand` module. The `infer` module is in charge
26 of resolving those constraints.
28 - regionck: after main is complete, the regionck pass goes over all
29 types looking for regions and making sure that they did not escape
30 into places they are not in scope. This may also influence the
31 final assignments of the various region variables if there is some
34 - vtable: find and records the impls to use for each trait bound that
35 appears on a type parameter.
37 - writeback: writes the final types within a function body, replacing
38 type variables with their final inferred types. These final types
39 are written into the `tcx.node_types` table, which should *never* contain
40 any reference to a type variable.
44 While type checking a function, the intermediate types for the
45 expressions, blocks, and so forth contained within the function are
46 stored in `fcx.node_types` and `fcx.node_substs`. These types
47 may contain unresolved type variables. After type checking is
48 complete, the functions in the writeback module are used to take the
49 types from this table, resolve them, and then write them into their
50 permanent home in the type context `tcx`.
52 This means that during inferencing you should use `fcx.write_ty()`
53 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
54 nodes within the function.
56 The types of top-level items, which never contain unbound type
57 variables, are stored directly into the `tcx` tables.
59 N.B., a type variable is not the same thing as a type parameter. A
60 type variable is rather an "instance" of a type parameter: that is,
61 given a generic function `fn foo<T>(t: T)`: while checking the
62 function `foo`, the type `ty_param(0)` refers to the type `T`, which
63 is treated in abstract. When `foo()` is called, however, `T` will be
64 substituted for a fresh type variable `N`. This variable will
65 eventually be resolved to some concrete type (which might itself be
86 mod generator_interior;
90 use crate::astconv::{AstConv, PathSeg};
91 use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
92 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
93 use rustc::hir::def::{CtorOf, Res, DefKind};
94 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
95 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
96 use rustc::hir::itemlikevisit::ItemLikeVisitor;
97 use rustc::hir::ptr::P;
98 use crate::middle::lang_items;
99 use crate::namespace::Namespace;
100 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
101 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
102 use rustc_index::vec::Idx;
103 use rustc_target::spec::abi::Abi;
104 use rustc::infer::opaque_types::OpaqueTypeDecl;
105 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
106 use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
107 use rustc::middle::region;
108 use rustc::mir::interpret::{ConstValue, GlobalId};
109 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
111 self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind,
112 ToPolyTraitRef, ToPredicate, RegionKind, UserType
114 use rustc::ty::adjustment::{
115 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
117 use rustc::ty::fold::TypeFoldable;
118 use rustc::ty::query::Providers;
119 use rustc::ty::subst::{
120 GenericArgKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts,
122 use rustc::ty::util::{Representability, IntTypeExt, Discr};
123 use rustc::ty::layout::VariantIdx;
124 use syntax_pos::{self, BytePos, Span, MultiSpan};
125 use syntax_pos::hygiene::DesugaringKind;
128 use syntax::feature_gate::{GateIssue, emit_feature_err};
129 use syntax::source_map::{DUMMY_SP, original_sp};
130 use syntax::symbol::{kw, sym};
131 use syntax::util::parser::ExprPrecedence;
133 use std::cell::{Cell, RefCell, Ref, RefMut};
134 use std::collections::hash_map::Entry;
137 use std::mem::replace;
138 use std::ops::{self, Deref};
141 use crate::require_c_abi_if_c_variadic;
142 use crate::session::Session;
143 use crate::session::config::EntryFnType;
144 use crate::TypeAndSubsts;
146 use crate::util::captures::Captures;
147 use crate::util::common::{ErrorReported, indenter};
148 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashSet, HirIdMap};
150 pub use self::Expectation::*;
151 use self::autoderef::Autoderef;
152 use self::callee::DeferredCallResolution;
153 use self::coercion::{CoerceMany, DynamicCoerceMany};
154 pub use self::compare_method::{compare_impl_method, compare_const_impl};
155 use self::method::{MethodCallee, SelfSource};
156 use self::TupleArgumentsFlag::*;
158 /// The type of a local binding, including the revealed type for anon types.
159 #[derive(Copy, Clone, Debug)]
160 pub struct LocalTy<'tcx> {
162 revealed_ty: Ty<'tcx>
165 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
166 #[derive(Copy, Clone)]
167 struct MaybeInProgressTables<'a, 'tcx> {
168 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
171 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
172 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
173 match self.maybe_tables {
174 Some(tables) => tables.borrow(),
176 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
181 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
182 match self.maybe_tables {
183 Some(tables) => tables.borrow_mut(),
185 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
191 /// Closures defined within the function. For example:
194 /// bar(move|| { ... })
197 /// Here, the function `foo()` and the closure passed to
198 /// `bar()` will each have their own `FnCtxt`, but they will
199 /// share the inherited fields.
200 pub struct Inherited<'a, 'tcx> {
201 infcx: InferCtxt<'a, 'tcx>,
203 tables: MaybeInProgressTables<'a, 'tcx>,
205 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
207 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
209 // Some additional `Sized` obligations badly affect type inference.
210 // These obligations are added in a later stage of typeck.
211 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
213 // When we process a call like `c()` where `c` is a closure type,
214 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
215 // `FnOnce` closure. In that case, we defer full resolution of the
216 // call until upvar inference can kick in and make the
217 // decision. We keep these deferred resolutions grouped by the
218 // def-id of the closure, so that once we decide, we can easily go
219 // back and process them.
220 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
222 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
224 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
226 // Opaque types found in explicit return types and their
227 // associated fresh inference variable. Writeback resolves these
228 // variables to get the concrete type, which can be used to
229 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
230 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
232 /// Each type parameter has an implicit region bound that
233 /// indicates it must outlive at least the function body (the user
234 /// may specify stronger requirements). This field indicates the
235 /// region of the callee. If it is `None`, then the parameter
236 /// environment is for an item or something where the "callee" is
238 implicit_region_bound: Option<ty::Region<'tcx>>,
240 body_id: Option<hir::BodyId>,
243 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
244 type Target = InferCtxt<'a, 'tcx>;
245 fn deref(&self) -> &Self::Target {
250 /// When type-checking an expression, we propagate downward
251 /// whatever type hint we are able in the form of an `Expectation`.
252 #[derive(Copy, Clone, Debug)]
253 pub enum Expectation<'tcx> {
254 /// We know nothing about what type this expression should have.
257 /// This expression should have the type given (or some subtype).
258 ExpectHasType(Ty<'tcx>),
260 /// This expression will be cast to the `Ty`.
261 ExpectCastableToType(Ty<'tcx>),
263 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
264 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
265 ExpectRvalueLikeUnsized(Ty<'tcx>),
268 impl<'a, 'tcx> Expectation<'tcx> {
269 // Disregard "castable to" expectations because they
270 // can lead us astray. Consider for example `if cond
271 // {22} else {c} as u8` -- if we propagate the
272 // "castable to u8" constraint to 22, it will pick the
273 // type 22u8, which is overly constrained (c might not
274 // be a u8). In effect, the problem is that the
275 // "castable to" expectation is not the tightest thing
276 // we can say, so we want to drop it in this case.
277 // The tightest thing we can say is "must unify with
278 // else branch". Note that in the case of a "has type"
279 // constraint, this limitation does not hold.
281 // If the expected type is just a type variable, then don't use
282 // an expected type. Otherwise, we might write parts of the type
283 // when checking the 'then' block which are incompatible with the
285 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
287 ExpectHasType(ety) => {
288 let ety = fcx.shallow_resolve(ety);
289 if !ety.is_ty_var() {
295 ExpectRvalueLikeUnsized(ety) => {
296 ExpectRvalueLikeUnsized(ety)
302 /// Provides an expectation for an rvalue expression given an *optional*
303 /// hint, which is not required for type safety (the resulting type might
304 /// be checked higher up, as is the case with `&expr` and `box expr`), but
305 /// is useful in determining the concrete type.
307 /// The primary use case is where the expected type is a fat pointer,
308 /// like `&[isize]`. For example, consider the following statement:
310 /// let x: &[isize] = &[1, 2, 3];
312 /// In this case, the expected type for the `&[1, 2, 3]` expression is
313 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
314 /// expectation `ExpectHasType([isize])`, that would be too strong --
315 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
316 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
317 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
318 /// which still is useful, because it informs integer literals and the like.
319 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
320 /// for examples of where this comes up,.
321 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
322 match fcx.tcx.struct_tail_without_normalization(ty).kind {
323 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
324 ExpectRvalueLikeUnsized(ty)
326 _ => ExpectHasType(ty)
330 // Resolves `expected` by a single level if it is a variable. If
331 // there is no expected type or resolution is not possible (e.g.,
332 // no constraints yet present), just returns `None`.
333 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
335 NoExpectation => NoExpectation,
336 ExpectCastableToType(t) => {
337 ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
339 ExpectHasType(t) => {
340 ExpectHasType(fcx.resolve_vars_if_possible(&t))
342 ExpectRvalueLikeUnsized(t) => {
343 ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
348 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
349 match self.resolve(fcx) {
350 NoExpectation => None,
351 ExpectCastableToType(ty) |
353 ExpectRvalueLikeUnsized(ty) => Some(ty),
357 /// It sometimes happens that we want to turn an expectation into
358 /// a **hard constraint** (i.e., something that must be satisfied
359 /// for the program to type-check). `only_has_type` will return
360 /// such a constraint, if it exists.
361 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
362 match self.resolve(fcx) {
363 ExpectHasType(ty) => Some(ty),
364 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
368 /// Like `only_has_type`, but instead of returning `None` if no
369 /// hard constraint exists, creates a fresh type variable.
370 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
371 self.only_has_type(fcx)
373 fcx.next_ty_var(TypeVariableOrigin {
374 kind: TypeVariableOriginKind::MiscVariable,
381 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
388 fn maybe_mut_place(m: hir::Mutability) -> Self {
390 hir::MutMutable => Needs::MutPlace,
391 hir::MutImmutable => Needs::None,
396 #[derive(Copy, Clone)]
397 pub struct UnsafetyState {
399 pub unsafety: hir::Unsafety,
400 pub unsafe_push_count: u32,
405 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
406 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
409 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
410 match self.unsafety {
411 // If this unsafe, then if the outer function was already marked as
412 // unsafe we shouldn't attribute the unsafe'ness to the block. This
413 // way the block can be warned about instead of ignoring this
414 // extraneous block (functions are never warned about).
415 hir::Unsafety::Unsafe if self.from_fn => *self,
418 let (unsafety, def, count) = match blk.rules {
419 hir::PushUnsafeBlock(..) =>
420 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
421 hir::PopUnsafeBlock(..) =>
422 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
423 hir::UnsafeBlock(..) =>
424 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
426 (unsafety, self.def, self.unsafe_push_count),
430 unsafe_push_count: count,
437 #[derive(Debug, Copy, Clone)]
443 /// Tracks whether executing a node may exit normally (versus
444 /// return/break/panic, which "diverge", leaving dead code in their
445 /// wake). Tracked semi-automatically (through type variables marked
446 /// as diverging), with some manual adjustments for control-flow
447 /// primitives (approximating a CFG).
448 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
450 /// Potentially unknown, some cases converge,
451 /// others require a CFG to determine them.
454 /// Definitely known to diverge and therefore
455 /// not reach the next sibling or its parent.
457 /// The `Span` points to the expression
458 /// that caused us to diverge
459 /// (e.g. `return`, `break`, etc).
461 /// In some cases (e.g. a `match` expression
462 /// where all arms diverge), we may be
463 /// able to provide a more informative
464 /// message to the user.
465 /// If this is `None`, a default messsage
466 /// will be generated, which is suitable
468 custom_note: Option<&'static str>
471 /// Same as `Always` but with a reachability
472 /// warning already emitted.
476 // Convenience impls for combining `Diverges`.
478 impl ops::BitAnd for Diverges {
480 fn bitand(self, other: Self) -> Self {
481 cmp::min(self, other)
485 impl ops::BitOr for Diverges {
487 fn bitor(self, other: Self) -> Self {
488 cmp::max(self, other)
492 impl ops::BitAndAssign for Diverges {
493 fn bitand_assign(&mut self, other: Self) {
494 *self = *self & other;
498 impl ops::BitOrAssign for Diverges {
499 fn bitor_assign(&mut self, other: Self) {
500 *self = *self | other;
505 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
506 fn always(span: Span) -> Diverges {
513 fn is_always(self) -> bool {
514 // Enum comparison ignores the
515 // contents of fields, so we just
516 // fill them in with garbage here.
517 self >= Diverges::Always {
524 pub struct BreakableCtxt<'tcx> {
527 // this is `null` for loops where break with a value is illegal,
528 // such as `while`, `for`, and `while let`
529 coerce: Option<DynamicCoerceMany<'tcx>>,
532 pub struct EnclosingBreakables<'tcx> {
533 stack: Vec<BreakableCtxt<'tcx>>,
534 by_id: HirIdMap<usize>,
537 impl<'tcx> EnclosingBreakables<'tcx> {
538 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
539 self.opt_find_breakable(target_id).unwrap_or_else(|| {
540 bug!("could not find enclosing breakable with id {}", target_id);
544 fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
545 match self.by_id.get(&target_id) {
546 Some(ix) => Some(&mut self.stack[*ix]),
552 pub struct FnCtxt<'a, 'tcx> {
555 /// The parameter environment used for proving trait obligations
556 /// in this function. This can change when we descend into
557 /// closures (as they bring new things into scope), hence it is
558 /// not part of `Inherited` (as of the time of this writing,
559 /// closures do not yet change the environment, but they will
561 param_env: ty::ParamEnv<'tcx>,
563 /// Number of errors that had been reported when we started
564 /// checking this function. On exit, if we find that *more* errors
565 /// have been reported, we will skip regionck and other work that
566 /// expects the types within the function to be consistent.
567 // FIXME(matthewjasper) This should not exist, and it's not correct
568 // if type checking is run in parallel.
569 err_count_on_creation: usize,
571 /// If `Some`, this stores coercion information for returned
572 /// expressions. If `None`, this is in a context where return is
573 /// inappropriate, such as a const expression.
575 /// This is a `RefCell<DynamicCoerceMany>`, which means that we
576 /// can track all the return expressions and then use them to
577 /// compute a useful coercion from the set, similar to a match
578 /// expression or other branching context. You can use methods
579 /// like `expected_ty` to access the declared return type (if
581 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
583 /// First span of a return site that we find. Used in error messages.
584 ret_coercion_span: RefCell<Option<Span>>,
586 yield_ty: Option<Ty<'tcx>>,
588 ps: RefCell<UnsafetyState>,
590 /// Whether the last checked node generates a divergence (e.g.,
591 /// `return` will set this to `Always`). In general, when entering
592 /// an expression or other node in the tree, the initial value
593 /// indicates whether prior parts of the containing expression may
594 /// have diverged. It is then typically set to `Maybe` (and the
595 /// old value remembered) for processing the subparts of the
596 /// current expression. As each subpart is processed, they may set
597 /// the flag to `Always`, etc. Finally, at the end, we take the
598 /// result and "union" it with the original value, so that when we
599 /// return the flag indicates if any subpart of the parent
600 /// expression (up to and including this part) has diverged. So,
601 /// if you read it after evaluating a subexpression `X`, the value
602 /// you get indicates whether any subexpression that was
603 /// evaluating up to and including `X` diverged.
605 /// We currently use this flag only for diagnostic purposes:
607 /// - To warn about unreachable code: if, after processing a
608 /// sub-expression but before we have applied the effects of the
609 /// current node, we see that the flag is set to `Always`, we
610 /// can issue a warning. This corresponds to something like
611 /// `foo(return)`; we warn on the `foo()` expression. (We then
612 /// update the flag to `WarnedAlways` to suppress duplicate
613 /// reports.) Similarly, if we traverse to a fresh statement (or
614 /// tail expression) from a `Always` setting, we will issue a
615 /// warning. This corresponds to something like `{return;
616 /// foo();}` or `{return; 22}`, where we would warn on the
619 /// An expression represents dead code if, after checking it,
620 /// the diverges flag is set to something other than `Maybe`.
621 diverges: Cell<Diverges>,
623 /// Whether any child nodes have any type errors.
624 has_errors: Cell<bool>,
626 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
628 inh: &'a Inherited<'a, 'tcx>,
631 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
632 type Target = Inherited<'a, 'tcx>;
633 fn deref(&self) -> &Self::Target {
638 /// Helper type of a temporary returned by `Inherited::build(...)`.
639 /// Necessary because we can't write the following bound:
640 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
641 pub struct InheritedBuilder<'tcx> {
642 infcx: infer::InferCtxtBuilder<'tcx>,
646 impl Inherited<'_, 'tcx> {
647 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
648 let hir_id_root = if def_id.is_local() {
649 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
650 DefId::local(hir_id.owner)
656 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
662 impl<'tcx> InheritedBuilder<'tcx> {
663 fn enter<F, R>(&mut self, f: F) -> R
665 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
667 let def_id = self.def_id;
668 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
672 impl Inherited<'a, 'tcx> {
673 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
675 let item_id = tcx.hir().as_local_hir_id(def_id);
676 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
677 let implicit_region_bound = body_id.map(|body_id| {
678 let body = tcx.hir().body(body_id);
679 tcx.mk_region(ty::ReScope(region::Scope {
680 id: body.value.hir_id.local_id,
681 data: region::ScopeData::CallSite
686 tables: MaybeInProgressTables {
687 maybe_tables: infcx.in_progress_tables,
690 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
691 locals: RefCell::new(Default::default()),
692 deferred_sized_obligations: RefCell::new(Vec::new()),
693 deferred_call_resolutions: RefCell::new(Default::default()),
694 deferred_cast_checks: RefCell::new(Vec::new()),
695 deferred_generator_interiors: RefCell::new(Vec::new()),
696 opaque_types: RefCell::new(Default::default()),
697 implicit_region_bound,
702 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
703 debug!("register_predicate({:?})", obligation);
704 if obligation.has_escaping_bound_vars() {
705 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
710 .register_predicate_obligation(self, obligation);
713 fn register_predicates<I>(&self, obligations: I)
714 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
716 for obligation in obligations {
717 self.register_predicate(obligation);
721 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
722 self.register_predicates(infer_ok.obligations);
726 fn normalize_associated_types_in<T>(&self,
729 param_env: ty::ParamEnv<'tcx>,
731 where T : TypeFoldable<'tcx>
733 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
734 self.register_infer_ok_obligations(ok)
738 struct CheckItemTypesVisitor<'tcx> {
742 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
743 fn visit_item(&mut self, i: &'tcx hir::Item) {
744 check_item_type(self.tcx, i);
746 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
747 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
750 pub fn check_wf_new(tcx: TyCtxt<'_>) {
751 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
752 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
755 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
756 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
759 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
760 debug_assert!(crate_num == LOCAL_CRATE);
761 tcx.par_body_owners(|body_owner_def_id| {
762 tcx.ensure().typeck_tables_of(body_owner_def_id);
766 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
767 wfcheck::check_item_well_formed(tcx, def_id);
770 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
771 wfcheck::check_trait_item(tcx, def_id);
774 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
775 wfcheck::check_impl_item(tcx, def_id);
778 pub fn provide(providers: &mut Providers<'_>) {
779 method::provide(providers);
780 *providers = Providers {
786 check_item_well_formed,
787 check_trait_item_well_formed,
788 check_impl_item_well_formed,
789 check_mod_item_types,
794 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
795 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
798 /// If this `DefId` is a "primary tables entry", returns
799 /// `Some((body_id, header, decl))` with information about
800 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
803 /// If this function returns `Some`, then `typeck_tables(def_id)` will
804 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
805 /// may not succeed. In some cases where this function returns `None`
806 /// (notably closures), `typeck_tables(def_id)` would wind up
807 /// redirecting to the owning function.
811 ) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
812 match tcx.hir().get(id) {
813 Node::Item(item) => {
815 hir::ItemKind::Const(ref ty, body) |
816 hir::ItemKind::Static(ref ty, _, body) =>
817 Some((body, Some(ty), None, None)),
818 hir::ItemKind::Fn(ref decl, ref header, .., body) =>
819 Some((body, None, Some(header), Some(decl))),
824 Node::TraitItem(item) => {
826 hir::TraitItemKind::Const(ref ty, Some(body)) =>
827 Some((body, Some(ty), None, None)),
828 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
829 Some((body, None, Some(&sig.header), Some(&sig.decl))),
834 Node::ImplItem(item) => {
836 hir::ImplItemKind::Const(ref ty, body) =>
837 Some((body, Some(ty), None, None)),
838 hir::ImplItemKind::Method(ref sig, body) =>
839 Some((body, None, Some(&sig.header), Some(&sig.decl))),
844 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
849 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
850 // Closures' tables come from their outermost function,
851 // as they are part of the same "inference environment".
852 let outer_def_id = tcx.closure_base_def_id(def_id);
853 if outer_def_id != def_id {
854 return tcx.has_typeck_tables(outer_def_id);
857 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
858 primary_body_of(tcx, id).is_some()
861 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
862 &*tcx.typeck_tables_of(def_id).used_trait_imports
865 fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
866 // Closures' tables come from their outermost function,
867 // as they are part of the same "inference environment".
868 let outer_def_id = tcx.closure_base_def_id(def_id);
869 if outer_def_id != def_id {
870 return tcx.typeck_tables_of(outer_def_id);
873 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
874 let span = tcx.hir().span(id);
876 // Figure out what primary body this item has.
877 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
879 span_bug!(span, "can't type-check body of {:?}", def_id);
881 let body = tcx.hir().body(body_id);
883 let tables = Inherited::build(tcx, def_id).enter(|inh| {
884 let param_env = tcx.param_env(def_id);
885 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
886 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
887 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
888 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl)
893 check_abi(tcx, span, fn_sig.abi());
895 // Compute the fty from point of view of inside the fn.
897 tcx.liberate_late_bound_regions(def_id, &fn_sig);
899 inh.normalize_associated_types_in(body.value.span,
904 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
907 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
908 let expected_type = body_ty.and_then(|ty| match ty.kind {
909 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
911 }).unwrap_or_else(|| tcx.type_of(def_id));
912 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
913 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
915 let revealed_ty = if tcx.features().impl_trait_in_bindings {
916 fcx.instantiate_opaque_types_from_value(
925 // Gather locals in statics (because of block expressions).
926 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
928 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
930 fcx.write_ty(id, revealed_ty);
935 // All type checking constraints were added, try to fallback unsolved variables.
936 fcx.select_obligations_where_possible(false, |_| {});
937 let mut fallback_has_occurred = false;
938 for ty in &fcx.unsolved_variables() {
939 fallback_has_occurred |= fcx.fallback_if_possible(ty);
941 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
943 // Even though coercion casts provide type hints, we check casts after fallback for
944 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
947 // Closure and generator analysis may run after fallback
948 // because they don't constrain other type variables.
949 fcx.closure_analyze(body);
950 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
951 fcx.resolve_generator_interiors(def_id);
953 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
954 let ty = fcx.normalize_ty(span, ty);
955 fcx.require_type_is_sized(ty, span, code);
957 fcx.select_all_obligations_or_error();
959 if fn_decl.is_some() {
960 fcx.regionck_fn(id, body);
962 fcx.regionck_expr(body);
965 fcx.resolve_type_vars_in_body(body)
968 // Consistency check our TypeckTables instance can hold all ItemLocalIds
969 // it will need to hold.
970 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
975 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
976 if !tcx.sess.target.target.is_abi_supported(abi) {
977 struct_span_err!(tcx.sess, span, E0570,
978 "The ABI `{}` is not supported for the current target", abi).emit()
982 struct GatherLocalsVisitor<'a, 'tcx> {
983 fcx: &'a FnCtxt<'a, 'tcx>,
984 parent_id: hir::HirId,
987 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
988 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
991 // infer the variable's type
992 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
993 kind: TypeVariableOriginKind::TypeInference,
996 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
1003 // take type that the user specified
1004 self.fcx.locals.borrow_mut().insert(nid, typ);
1011 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1012 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
1013 NestedVisitorMap::None
1016 // Add explicitly-declared locals.
1017 fn visit_local(&mut self, local: &'tcx hir::Local) {
1018 let local_ty = match local.ty {
1020 let o_ty = self.fcx.to_ty(&ty);
1022 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1023 self.fcx.instantiate_opaque_types_from_value(
1032 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
1033 &UserType::Ty(revealed_ty)
1035 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1036 ty.hir_id, o_ty, revealed_ty, c_ty);
1037 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1039 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1043 self.assign(local.span, local.hir_id, local_ty);
1045 debug!("local variable {:?} is assigned type {}",
1047 self.fcx.ty_to_string(
1048 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
1049 intravisit::walk_local(self, local);
1052 // Add pattern bindings.
1053 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
1054 if let PatKind::Binding(_, _, ident, _) = p.kind {
1055 let var_ty = self.assign(p.span, p.hir_id, None);
1057 if !self.fcx.tcx.features().unsized_locals {
1058 self.fcx.require_type_is_sized(var_ty, p.span,
1059 traits::VariableType(p.hir_id));
1062 debug!("pattern binding {} is assigned to {} with type {:?}",
1064 self.fcx.ty_to_string(
1065 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1068 intravisit::walk_pat(self, p);
1071 // Don't descend into the bodies of nested closures
1074 _: intravisit::FnKind<'tcx>,
1075 _: &'tcx hir::FnDecl,
1082 /// When `check_fn` is invoked on a generator (i.e., a body that
1083 /// includes yield), it returns back some information about the yield
1085 struct GeneratorTypes<'tcx> {
1086 /// Type of value that is yielded.
1089 /// Types that are captured (see `GeneratorInterior` for more).
1092 /// Indicates if the generator is movable or static (immovable).
1093 movability: hir::GeneratorMovability,
1096 /// Helper used for fns and closures. Does the grungy work of checking a function
1097 /// body and returns the function context used for that purpose, since in the case of a fn item
1098 /// there is still a bit more to do.
1101 /// * inherited: other fields inherited from the enclosing fn (if any)
1102 fn check_fn<'a, 'tcx>(
1103 inherited: &'a Inherited<'a, 'tcx>,
1104 param_env: ty::ParamEnv<'tcx>,
1105 fn_sig: ty::FnSig<'tcx>,
1106 decl: &'tcx hir::FnDecl,
1108 body: &'tcx hir::Body,
1109 can_be_generator: Option<hir::GeneratorMovability>,
1110 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1111 let mut fn_sig = fn_sig.clone();
1113 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1115 // Create the function context. This is either derived from scratch or,
1116 // in the case of closures, based on the outer context.
1117 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1118 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1120 let declared_ret_ty = fn_sig.output();
1121 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1122 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
1127 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1128 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1129 fn_sig = fcx.tcx.mk_fn_sig(
1130 fn_sig.inputs().iter().cloned(),
1137 let span = body.value.span;
1139 fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1141 if body.generator_kind.is_some() && can_be_generator.is_some() {
1142 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1143 kind: TypeVariableOriginKind::TypeInference,
1146 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1147 fcx.yield_ty = Some(yield_ty);
1150 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1151 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1152 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1154 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
1155 // (as it's created inside the body itself, not passed in from outside).
1156 let maybe_va_list = if fn_sig.c_variadic {
1157 let va_list_did = fcx.tcx.require_lang_item(
1158 lang_items::VaListTypeLangItem,
1159 Some(body.params.last().unwrap().span),
1161 let region = fcx.tcx.mk_region(ty::ReScope(region::Scope {
1162 id: body.value.hir_id.local_id,
1163 data: region::ScopeData::CallSite
1166 Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()]))
1171 // Add formal parameters.
1172 for (param_ty, param) in
1173 fn_sig.inputs().iter().copied()
1174 .chain(maybe_va_list)
1177 // Check the pattern.
1178 fcx.check_pat_top(¶m.pat, param_ty, None);
1180 // Check that argument is Sized.
1181 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1182 // for simple cases like `fn foo(x: Trait)`,
1183 // where we would error once on the parameter as a whole, and once on the binding `x`.
1184 if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1185 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1188 fcx.write_ty(param.hir_id, param_ty);
1191 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1193 fcx.check_return_expr(&body.value);
1195 // We insert the deferred_generator_interiors entry after visiting the body.
1196 // This ensures that all nested generators appear before the entry of this generator.
1197 // resolve_generator_interiors relies on this property.
1198 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1199 let interior = fcx.next_ty_var(TypeVariableOrigin {
1200 kind: TypeVariableOriginKind::MiscVariable,
1203 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1204 Some(GeneratorTypes {
1205 yield_ty: fcx.yield_ty.unwrap(),
1207 movability: can_be_generator.unwrap(),
1213 // Finalize the return check by taking the LUB of the return types
1214 // we saw and assigning it to the expected return type. This isn't
1215 // really expected to fail, since the coercions would have failed
1216 // earlier when trying to find a LUB.
1218 // However, the behavior around `!` is sort of complex. In the
1219 // event that the `actual_return_ty` comes back as `!`, that
1220 // indicates that the fn either does not return or "returns" only
1221 // values of type `!`. In this case, if there is an expected
1222 // return type that is *not* `!`, that should be ok. But if the
1223 // return type is being inferred, we want to "fallback" to `!`:
1225 // let x = move || panic!();
1227 // To allow for that, I am creating a type variable with diverging
1228 // fallback. This was deemed ever so slightly better than unifying
1229 // the return value with `!` because it allows for the caller to
1230 // make more assumptions about the return type (e.g., they could do
1232 // let y: Option<u32> = Some(x());
1234 // which would then cause this return type to become `u32`, not
1236 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1237 let mut actual_return_ty = coercion.complete(&fcx);
1238 if actual_return_ty.is_never() {
1239 actual_return_ty = fcx.next_diverging_ty_var(
1240 TypeVariableOrigin {
1241 kind: TypeVariableOriginKind::DivergingFn,
1246 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1248 // Check that the main return type implements the termination trait.
1249 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1250 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1251 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1252 if main_id == fn_id {
1253 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1254 let trait_ref = ty::TraitRef::new(term_id, substs);
1255 let return_ty_span = decl.output.span();
1256 let cause = traits::ObligationCause::new(
1257 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1259 inherited.register_predicate(
1260 traits::Obligation::new(
1261 cause, param_env, trait_ref.to_predicate()));
1266 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1267 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1268 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1269 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1270 if declared_ret_ty.kind != ty::Never {
1271 fcx.tcx.sess.span_err(
1273 "return type should be `!`",
1277 let inputs = fn_sig.inputs();
1278 let span = fcx.tcx.hir().span(fn_id);
1279 if inputs.len() == 1 {
1280 let arg_is_panic_info = match inputs[0].kind {
1281 ty::Ref(region, ty, mutbl) => match ty.kind {
1282 ty::Adt(ref adt, _) => {
1283 adt.did == panic_info_did &&
1284 mutbl == hir::Mutability::MutImmutable &&
1285 *region != RegionKind::ReStatic
1292 if !arg_is_panic_info {
1293 fcx.tcx.sess.span_err(
1294 decl.inputs[0].span,
1295 "argument should be `&PanicInfo`",
1299 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1300 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1301 if !generics.params.is_empty() {
1302 fcx.tcx.sess.span_err(
1304 "should have no type parameters",
1310 let span = fcx.tcx.sess.source_map().def_span(span);
1311 fcx.tcx.sess.span_err(span, "function should have one argument");
1314 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1319 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1320 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1321 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1322 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1323 if declared_ret_ty.kind != ty::Never {
1324 fcx.tcx.sess.span_err(
1326 "return type should be `!`",
1330 let inputs = fn_sig.inputs();
1331 let span = fcx.tcx.hir().span(fn_id);
1332 if inputs.len() == 1 {
1333 let arg_is_alloc_layout = match inputs[0].kind {
1334 ty::Adt(ref adt, _) => {
1335 adt.did == alloc_layout_did
1340 if !arg_is_alloc_layout {
1341 fcx.tcx.sess.span_err(
1342 decl.inputs[0].span,
1343 "argument should be `Layout`",
1347 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1348 if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
1349 if !generics.params.is_empty() {
1350 fcx.tcx.sess.span_err(
1352 "`#[alloc_error_handler]` function should have no type \
1359 let span = fcx.tcx.sess.source_map().def_span(span);
1360 fcx.tcx.sess.span_err(span, "function should have one argument");
1363 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1371 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1372 let def_id = tcx.hir().local_def_id(id);
1373 let def = tcx.adt_def(def_id);
1374 def.destructor(tcx); // force the destructor to be evaluated
1375 check_representable(tcx, span, def_id);
1377 if def.repr.simd() {
1378 check_simd(tcx, span, def_id);
1381 check_transparent(tcx, span, def_id);
1382 check_packed(tcx, span, def_id);
1385 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1386 let def_id = tcx.hir().local_def_id(id);
1387 let def = tcx.adt_def(def_id);
1388 def.destructor(tcx); // force the destructor to be evaluated
1389 check_representable(tcx, span, def_id);
1390 check_transparent(tcx, span, def_id);
1391 check_union_fields(tcx, span, def_id);
1392 check_packed(tcx, span, def_id);
1395 /// When the `#![feature(untagged_unions)]` gate is active,
1396 /// check that the fields of the `union` does not contain fields that need dropping.
1397 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: DefId) -> bool {
1398 let item_type = tcx.type_of(item_def_id);
1399 if let ty::Adt(def, substs) = item_type.kind {
1400 assert!(def.is_union());
1401 let fields = &def.non_enum_variant().fields;
1402 for field in fields {
1403 let field_ty = field.ty(tcx, substs);
1404 // We are currently checking the type this field came from, so it must be local.
1405 let field_span = tcx.hir().span_if_local(field.did).unwrap();
1406 let param_env = tcx.param_env(field.did);
1407 if field_ty.needs_drop(tcx, param_env) {
1408 struct_span_err!(tcx.sess, field_span, E0740,
1409 "unions may not contain fields that need dropping")
1410 .span_note(field_span,
1411 "`std::mem::ManuallyDrop` can be used to wrap the type")
1417 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind);
1422 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1423 /// projections that would result in "inheriting lifetimes".
1424 fn check_opaque<'tcx>(
1427 substs: SubstsRef<'tcx>,
1429 origin: &hir::OpaqueTyOrigin,
1431 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1432 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1435 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1436 /// in "inheriting lifetimes".
1437 fn check_opaque_for_inheriting_lifetimes(
1442 let item = tcx.hir().expect_item(
1443 tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1444 debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1445 def_id, span, item);
1448 struct ProhibitOpaqueVisitor<'tcx> {
1449 opaque_identity_ty: Ty<'tcx>,
1450 generics: &'tcx ty::Generics,
1453 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1454 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1455 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1456 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1459 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1460 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1461 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1462 return *index < self.generics.parent_count as u32;
1465 r.super_visit_with(self)
1469 let prohibit_opaque = match item.kind {
1470 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
1471 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1472 let mut visitor = ProhibitOpaqueVisitor {
1473 opaque_identity_ty: tcx.mk_opaque(
1474 def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1475 generics: tcx.generics_of(def_id),
1477 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1479 tcx.predicates_of(def_id).predicates.iter().any(
1480 |(predicate, _)| predicate.visit_with(&mut visitor))
1485 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1486 if prohibit_opaque {
1487 let is_async = match item.kind {
1488 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1489 hir::OpaqueTyOrigin::AsyncFn => true,
1492 _ => unreachable!(),
1495 tcx.sess.span_err(span, &format!(
1496 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1498 if is_async { "async fn" } else { "impl Trait" },
1503 /// Checks that an opaque type does not contain cycles.
1504 fn check_opaque_for_cycles<'tcx>(
1507 substs: SubstsRef<'tcx>,
1509 origin: &hir::OpaqueTyOrigin,
1511 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1512 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1514 tcx.sess, span, E0733,
1515 "recursion in an `async fn` requires boxing",
1517 .span_label(span, "recursive `async fn`")
1518 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
1521 let mut err = struct_span_err!(
1522 tcx.sess, span, E0720,
1523 "opaque type expands to a recursive type",
1525 err.span_label(span, "expands to a recursive type");
1526 if let ty::Opaque(..) = partially_expanded_type.kind {
1527 err.note("type resolves to itself");
1529 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1536 // Forbid defining intrinsics in Rust code,
1537 // as they must always be defined by the compiler.
1538 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1539 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1540 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1544 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1546 "check_item_type(it.hir_id={}, it.name={})",
1548 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1550 let _indenter = indenter();
1552 // Consts can play a role in type-checking, so they are included here.
1553 hir::ItemKind::Static(..) => {
1554 let def_id = tcx.hir().local_def_id(it.hir_id);
1555 tcx.typeck_tables_of(def_id);
1556 maybe_check_static_with_link_section(tcx, def_id, it.span);
1558 hir::ItemKind::Const(..) => {
1559 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1561 hir::ItemKind::Enum(ref enum_definition, _) => {
1562 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1564 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1565 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1566 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1567 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1568 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1569 check_impl_items_against_trait(
1576 let trait_def_id = impl_trait_ref.def_id;
1577 check_on_unimplemented(tcx, trait_def_id, it);
1580 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1581 let def_id = tcx.hir().local_def_id(it.hir_id);
1582 check_on_unimplemented(tcx, def_id, it);
1584 for item in items.iter() {
1585 let item = tcx.hir().trait_item(item.id);
1586 if let hir::TraitItemKind::Method(sig, _) = &item.kind {
1587 let abi = sig.header.abi;
1588 fn_maybe_err(tcx, item.ident.span, abi);
1592 hir::ItemKind::Struct(..) => {
1593 check_struct(tcx, it.hir_id, it.span);
1595 hir::ItemKind::Union(..) => {
1596 check_union(tcx, it.hir_id, it.span);
1598 hir::ItemKind::OpaqueTy(hir::OpaqueTy{origin, ..}) => {
1599 let def_id = tcx.hir().local_def_id(it.hir_id);
1601 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1602 check_opaque(tcx, def_id, substs, it.span, &origin);
1604 hir::ItemKind::TyAlias(..) => {
1605 let def_id = tcx.hir().local_def_id(it.hir_id);
1606 let pty_ty = tcx.type_of(def_id);
1607 let generics = tcx.generics_of(def_id);
1608 check_bounds_are_used(tcx, &generics, pty_ty);
1610 hir::ItemKind::ForeignMod(ref m) => {
1611 check_abi(tcx, it.span, m.abi);
1613 if m.abi == Abi::RustIntrinsic {
1614 for item in &m.items {
1615 intrinsic::check_intrinsic_type(tcx, item);
1617 } else if m.abi == Abi::PlatformIntrinsic {
1618 for item in &m.items {
1619 intrinsic::check_platform_intrinsic_type(tcx, item);
1622 for item in &m.items {
1623 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1624 let own_counts = generics.own_counts();
1625 if generics.params.len() - own_counts.lifetimes != 0 {
1626 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1627 (_, 0) => ("type", "types", Some("u32")),
1628 // We don't specify an example value, because we can't generate
1629 // a valid value for any type.
1630 (0, _) => ("const", "consts", None),
1631 _ => ("type or const", "types or consts", None),
1637 "foreign items may not have {} parameters",
1641 &format!("can't have {} parameters", kinds),
1643 // FIXME: once we start storing spans for type arguments, turn this
1644 // into a suggestion.
1646 "replace the {} parameters with concrete {}{}",
1649 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1654 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.kind {
1655 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1660 _ => { /* nothing to do */ }
1664 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1665 // Only restricted on wasm32 target for now
1666 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1670 // If `#[link_section]` is missing, then nothing to verify
1671 let attrs = tcx.codegen_fn_attrs(id);
1672 if attrs.link_section.is_none() {
1676 // For the wasm32 target statics with `#[link_section]` are placed into custom
1677 // sections of the final output file, but this isn't link custom sections of
1678 // other executable formats. Namely we can only embed a list of bytes,
1679 // nothing with pointers to anything else or relocations. If any relocation
1680 // show up, reject them here.
1681 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1682 // the consumer's responsibility to ensure all bytes that have been read
1683 // have defined values.
1684 let instance = ty::Instance::mono(tcx, id);
1685 let cid = GlobalId {
1689 let param_env = ty::ParamEnv::reveal_all();
1690 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1691 let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1694 bug!("Matching on non-ByRef static")
1696 if alloc.relocations().len() != 0 {
1697 let msg = "statics with a custom `#[link_section]` must be a \
1698 simple list of bytes on the wasm target with no \
1699 extra levels of indirection such as references";
1700 tcx.sess.span_err(span, msg);
1705 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
1706 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1707 // an error would be reported if this fails.
1708 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1711 fn report_forbidden_specialization(
1713 impl_item: &hir::ImplItem,
1716 let mut err = struct_span_err!(
1717 tcx.sess, impl_item.span, E0520,
1718 "`{}` specializes an item from a parent `impl`, but \
1719 that item is not marked `default`",
1721 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1724 match tcx.span_of_impl(parent_impl) {
1726 err.span_label(span, "parent `impl` is here");
1727 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1731 err.note(&format!("parent implementation is in crate `{}`", cname));
1738 fn check_specialization_validity<'tcx>(
1740 trait_def: &ty::TraitDef,
1741 trait_item: &ty::AssocItem,
1743 impl_item: &hir::ImplItem,
1745 let kind = match impl_item.kind {
1746 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1747 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1748 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1749 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1752 let mut ancestor_impls = trait_def.ancestors(tcx, impl_id)
1754 .filter_map(|parent| {
1755 if parent.is_from_trait() {
1758 Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
1763 if ancestor_impls.peek().is_none() {
1764 // No parent, nothing to specialize.
1768 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1770 // Parent impl exists, and contains the parent item we're trying to specialize, but
1771 // doesn't mark it `default`.
1772 Some(parent_item) if tcx.impl_item_is_final(&parent_item) => {
1773 Some(Err(parent_impl.def_id()))
1776 // Parent impl contains item and makes it specializable.
1781 // Parent impl doesn't mention the item. This means it's inherited from the
1782 // grandparent. In that case, if parent is a `default impl`, inherited items use the
1783 // "defaultness" from the grandparent, else they are final.
1784 None => if tcx.impl_is_default(parent_impl.def_id()) {
1787 Some(Err(parent_impl.def_id()))
1792 // If `opt_result` is `None`, we have only encoutered `default impl`s that don't contain the
1793 // item. This is allowed, the item isn't actually getting specialized here.
1794 let result = opt_result.unwrap_or(Ok(()));
1796 if let Err(parent_impl) = result {
1797 report_forbidden_specialization(tcx, impl_item, parent_impl);
1801 fn check_impl_items_against_trait<'tcx>(
1805 impl_trait_ref: ty::TraitRef<'tcx>,
1806 impl_item_refs: &[hir::ImplItemRef],
1808 let impl_span = tcx.sess.source_map().def_span(impl_span);
1810 // If the trait reference itself is erroneous (so the compilation is going
1811 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1812 // isn't populated for such impls.
1813 if impl_trait_ref.references_error() { return; }
1815 // Locate trait definition and items
1816 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1817 let mut overridden_associated_type = None;
1819 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1821 // Check existing impl methods to see if they are both present in trait
1822 // and compatible with trait signature
1823 for impl_item in impl_items() {
1824 let ty_impl_item = tcx.associated_item(
1825 tcx.hir().local_def_id(impl_item.hir_id));
1826 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1827 .find(|ac| Namespace::from(&impl_item.kind) == Namespace::from(ac.kind) &&
1828 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1830 // Not compatible, but needed for the error message
1831 tcx.associated_items(impl_trait_ref.def_id)
1832 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1835 // Check that impl definition matches trait definition
1836 if let Some(ty_trait_item) = ty_trait_item {
1837 match impl_item.kind {
1838 hir::ImplItemKind::Const(..) => {
1839 // Find associated const definition.
1840 if ty_trait_item.kind == ty::AssocKind::Const {
1841 compare_const_impl(tcx,
1847 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1848 "item `{}` is an associated const, \
1849 which doesn't match its trait `{}`",
1852 err.span_label(impl_item.span, "does not match trait");
1853 // We can only get the spans from local trait definition
1854 // Same for E0324 and E0325
1855 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1856 err.span_label(trait_span, "item in trait");
1861 hir::ImplItemKind::Method(..) => {
1862 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1863 if ty_trait_item.kind == ty::AssocKind::Method {
1864 compare_impl_method(tcx,
1871 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1872 "item `{}` is an associated method, \
1873 which doesn't match its trait `{}`",
1876 err.span_label(impl_item.span, "does not match trait");
1877 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1878 err.span_label(trait_span, "item in trait");
1883 hir::ImplItemKind::OpaqueTy(..) |
1884 hir::ImplItemKind::TyAlias(_) => {
1885 if ty_trait_item.kind == ty::AssocKind::Type {
1886 if ty_trait_item.defaultness.has_value() {
1887 overridden_associated_type = Some(impl_item);
1890 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1891 "item `{}` is an associated type, \
1892 which doesn't match its trait `{}`",
1895 err.span_label(impl_item.span, "does not match trait");
1896 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1897 err.span_label(trait_span, "item in trait");
1904 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1908 // Check for missing items from trait
1909 let mut missing_items = Vec::new();
1910 let mut invalidated_items = Vec::new();
1911 let associated_type_overridden = overridden_associated_type.is_some();
1912 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1913 let is_implemented = trait_def.ancestors(tcx, impl_id)
1914 .leaf_def(tcx, trait_item.ident, trait_item.kind)
1915 .map(|node_item| !node_item.node.is_from_trait())
1918 if !is_implemented && !tcx.impl_is_default(impl_id) {
1919 if !trait_item.defaultness.has_value() {
1920 missing_items.push(trait_item);
1921 } else if associated_type_overridden {
1922 invalidated_items.push(trait_item.ident);
1927 if !missing_items.is_empty() {
1928 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1929 "not all trait items implemented, missing: `{}`",
1930 missing_items.iter()
1931 .map(|trait_item| trait_item.ident.to_string())
1932 .collect::<Vec<_>>().join("`, `"));
1933 err.span_label(impl_span, format!("missing `{}` in implementation",
1934 missing_items.iter()
1935 .map(|trait_item| trait_item.ident.to_string())
1936 .collect::<Vec<_>>().join("`, `")));
1937 for trait_item in missing_items {
1938 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1939 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1941 err.note_trait_signature(trait_item.ident.to_string(),
1942 trait_item.signature(tcx));
1948 if !invalidated_items.is_empty() {
1949 let invalidator = overridden_associated_type.unwrap();
1950 span_err!(tcx.sess, invalidator.span, E0399,
1951 "the following trait items need to be reimplemented \
1952 as `{}` was overridden: `{}`",
1954 invalidated_items.iter()
1955 .map(|name| name.to_string())
1956 .collect::<Vec<_>>().join("`, `"))
1960 /// Checks whether a type can be represented in memory. In particular, it
1961 /// identifies types that contain themselves without indirection through a
1962 /// pointer, which would mean their size is unbounded.
1963 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
1964 let rty = tcx.type_of(item_def_id);
1966 // Check that it is possible to represent this type. This call identifies
1967 // (1) types that contain themselves and (2) types that contain a different
1968 // recursive type. It is only necessary to throw an error on those that
1969 // contain themselves. For case 2, there must be an inner type that will be
1970 // caught by case 1.
1971 match rty.is_representable(tcx, sp) {
1972 Representability::SelfRecursive(spans) => {
1973 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1975 err.span_label(span, "recursive without indirection");
1980 Representability::Representable | Representability::ContainsRecursive => (),
1985 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1986 let t = tcx.type_of(def_id);
1987 if let ty::Adt(def, substs) = t.kind {
1988 if def.is_struct() {
1989 let fields = &def.non_enum_variant().fields;
1990 if fields.is_empty() {
1991 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1994 let e = fields[0].ty(tcx, substs);
1995 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1996 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1997 .span_label(sp, "SIMD elements must have the same type")
2002 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
2003 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
2005 span_err!(tcx.sess, sp, E0077,
2006 "SIMD vector element type should be machine type");
2014 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2015 let repr = tcx.adt_def(def_id).repr;
2017 for attr in tcx.get_attrs(def_id).iter() {
2018 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2019 if let attr::ReprPacked(pack) = r {
2020 if let Some(repr_pack) = repr.pack {
2021 if pack as u64 != repr_pack.bytes() {
2023 tcx.sess, sp, E0634,
2024 "type has conflicting packed representation hints"
2031 if repr.align.is_some() {
2032 struct_span_err!(tcx.sess, sp, E0587,
2033 "type has conflicting packed and align representation hints").emit();
2035 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
2036 struct_span_err!(tcx.sess, sp, E0588,
2037 "packed type cannot transitively contain a `[repr(align)]` type").emit();
2042 fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
2043 let t = tcx.type_of(def_id);
2044 if stack.contains(&def_id) {
2045 debug!("check_packed_inner: {:?} is recursive", t);
2048 if let ty::Adt(def, substs) = t.kind {
2049 if def.is_struct() || def.is_union() {
2050 if tcx.adt_def(def.did).repr.align.is_some() {
2053 // push struct def_id before checking fields
2055 for field in &def.non_enum_variant().fields {
2056 let f = field.ty(tcx, substs);
2057 if let ty::Adt(def, _) = f.kind {
2058 if check_packed_inner(tcx, def.did, stack) {
2063 // only need to pop if not early out
2070 /// Emit an error when encountering more or less than one variant in a transparent enum.
2071 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
2072 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
2073 tcx.hir().span_if_local(variant.def_id).unwrap()
2076 "needs exactly one variant, but has {}",
2079 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
2080 err.span_label(sp, &msg);
2081 if let &[ref start @ .., ref end] = &variant_spans[..] {
2082 for variant_span in start {
2083 err.span_label(*variant_span, "");
2085 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
2090 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
2092 fn bad_non_zero_sized_fields<'tcx>(
2094 adt: &'tcx ty::AdtDef,
2096 field_spans: impl Iterator<Item = Span>,
2099 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2100 let mut err = struct_span_err!(
2104 "{}transparent {} {}",
2105 if adt.is_enum() { "the variant of a " } else { "" },
2109 err.span_label(sp, &msg);
2110 for sp in field_spans {
2111 err.span_label(sp, "this field is non-zero-sized");
2116 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2117 let adt = tcx.adt_def(def_id);
2118 if !adt.repr.transparent() {
2121 let sp = tcx.sess.source_map().def_span(sp);
2124 if !tcx.features().transparent_enums {
2126 &tcx.sess.parse_sess,
2127 sym::transparent_enums,
2129 GateIssue::Language,
2130 "transparent enums are unstable",
2133 if adt.variants.len() != 1 {
2134 bad_variant_count(tcx, adt, sp, def_id);
2135 if adt.variants.is_empty() {
2136 // Don't bother checking the fields. No variants (and thus no fields) exist.
2142 if adt.is_union() && !tcx.features().transparent_unions {
2143 emit_feature_err(&tcx.sess.parse_sess,
2144 sym::transparent_unions,
2146 GateIssue::Language,
2147 "transparent unions are unstable");
2150 // For each field, figure out if it's known to be a ZST and align(1)
2151 let field_infos = adt.all_fields().map(|field| {
2152 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2153 let param_env = tcx.param_env(field.did);
2154 let layout = tcx.layout_of(param_env.and(ty));
2155 // We are currently checking the type this field came from, so it must be local
2156 let span = tcx.hir().span_if_local(field.did).unwrap();
2157 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2158 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2162 let non_zst_fields = field_infos.clone().filter_map(|(span, zst, _align1)| if !zst {
2167 let non_zst_count = non_zst_fields.clone().count();
2168 if non_zst_count != 1 {
2169 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2171 for (span, zst, align1) in field_infos {
2177 "zero-sized field in transparent {} has alignment larger than 1",
2179 ).span_label(span, "has alignment larger than 1").emit();
2184 #[allow(trivial_numeric_casts)]
2185 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
2186 let def_id = tcx.hir().local_def_id(id);
2187 let def = tcx.adt_def(def_id);
2188 def.destructor(tcx); // force the destructor to be evaluated
2191 let attributes = tcx.get_attrs(def_id);
2192 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2194 tcx.sess, attr.span, E0084,
2195 "unsupported representation for zero-variant enum")
2196 .span_label(sp, "zero-variant enum")
2201 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2202 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2203 if !tcx.features().repr128 {
2204 emit_feature_err(&tcx.sess.parse_sess,
2207 GateIssue::Language,
2208 "repr with 128-bit type is unstable");
2213 if let Some(ref e) = v.disr_expr {
2214 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2218 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2220 |var: &hir::Variant| match var.data {
2221 hir::VariantData::Unit(..) => true,
2225 let has_disr = |var: &hir::Variant| var.disr_expr.is_some();
2226 let has_non_units = vs.iter().any(|var| !is_unit(var));
2227 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2228 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2230 if disr_non_unit || (disr_units && has_non_units) {
2231 let mut err = struct_span_err!(tcx.sess, sp, E0732,
2232 "`#[repr(inttype)]` must be specified");
2237 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2238 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2239 // Check for duplicate discriminant values
2240 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2241 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2242 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2243 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2244 let i_span = match variant_i.disr_expr {
2245 Some(ref expr) => tcx.hir().span(expr.hir_id),
2246 None => tcx.hir().span(variant_i_hir_id)
2248 let span = match v.disr_expr {
2249 Some(ref expr) => tcx.hir().span(expr.hir_id),
2252 struct_span_err!(tcx.sess, span, E0081,
2253 "discriminant value `{}` already exists", disr_vals[i])
2254 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2255 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
2258 disr_vals.push(discr);
2261 check_representable(tcx, sp, def_id);
2262 check_transparent(tcx, sp, def_id);
2265 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
2266 span_err!(tcx.sess, span, E0533,
2267 "expected unit struct, unit variant or constant, found {} `{}`",
2269 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
2272 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2273 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2277 fn item_def_id(&self) -> Option<DefId> {
2281 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
2283 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2284 let item_id = tcx.hir().ty_param_owner(hir_id);
2285 let item_def_id = tcx.hir().local_def_id(item_id);
2286 let generics = tcx.generics_of(item_def_id);
2287 let index = generics.param_def_id_to_index[&def_id];
2288 ty::GenericPredicates {
2290 predicates: tcx.arena.alloc_from_iter(
2291 self.param_env.caller_bounds.iter().filter_map(|&predicate| match predicate {
2292 ty::Predicate::Trait(ref data)
2293 if data.skip_binder().self_ty().is_param(index) => {
2294 // HACK(eddyb) should get the original `Span`.
2295 let span = tcx.def_span(def_id);
2296 Some((predicate, span))
2306 def: Option<&ty::GenericParamDef>,
2308 ) -> Option<ty::Region<'tcx>> {
2310 Some(def) => infer::EarlyBoundRegion(span, def.name),
2311 None => infer::MiscVariable(span)
2313 Some(self.next_region_var(v))
2316 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2317 if let Some(param) = param {
2318 if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
2323 self.next_ty_var(TypeVariableOrigin {
2324 kind: TypeVariableOriginKind::TypeInference,
2333 param: Option<&ty::GenericParamDef>,
2335 ) -> &'tcx Const<'tcx> {
2336 if let Some(param) = param {
2337 if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
2342 self.next_const_var(ty, ConstVariableOrigin {
2343 kind: ConstVariableOriginKind::ConstInference,
2349 fn projected_ty_from_poly_trait_ref(&self,
2352 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2355 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2357 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2361 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2364 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2365 if ty.has_escaping_bound_vars() {
2366 ty // FIXME: normalization and escaping regions
2368 self.normalize_associated_types_in(span, &ty)
2372 fn set_tainted_by_errors(&self) {
2373 self.infcx.set_tainted_by_errors()
2376 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2377 self.write_ty(hir_id, ty)
2381 /// Controls whether the arguments are tupled. This is used for the call
2384 /// Tupling means that all call-side arguments are packed into a tuple and
2385 /// passed as a single parameter. For example, if tupling is enabled, this
2388 /// fn f(x: (isize, isize))
2390 /// Can be called as:
2397 #[derive(Clone, Eq, PartialEq)]
2398 enum TupleArgumentsFlag {
2403 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2405 inh: &'a Inherited<'a, 'tcx>,
2406 param_env: ty::ParamEnv<'tcx>,
2407 body_id: hir::HirId,
2408 ) -> FnCtxt<'a, 'tcx> {
2412 err_count_on_creation: inh.tcx.sess.err_count(),
2414 ret_coercion_span: RefCell::new(None),
2416 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2417 hir::CRATE_HIR_ID)),
2418 diverges: Cell::new(Diverges::Maybe),
2419 has_errors: Cell::new(false),
2420 enclosing_breakables: RefCell::new(EnclosingBreakables {
2422 by_id: Default::default(),
2428 pub fn sess(&self) -> &Session {
2432 pub fn errors_reported_since_creation(&self) -> bool {
2433 self.tcx.sess.err_count() > self.err_count_on_creation
2436 /// Produces warning on the given node, if the current point in the
2437 /// function is unreachable, and there hasn't been another warning.
2438 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2439 // FIXME: Combine these two 'if' expressions into one once
2440 // let chains are implemented
2441 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2442 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2443 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2444 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2445 if !span.is_desugaring(DesugaringKind::CondTemporary) &&
2446 !span.is_desugaring(DesugaringKind::Async) &&
2447 !orig_span.is_desugaring(DesugaringKind::Await)
2449 self.diverges.set(Diverges::WarnedAlways);
2451 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2453 let msg = format!("unreachable {}", kind);
2454 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
2455 .span_label(span, &msg)
2458 custom_note.unwrap_or("any code following this expression is unreachable"),
2467 code: ObligationCauseCode<'tcx>)
2468 -> ObligationCause<'tcx> {
2469 ObligationCause::new(span, self.body_id, code)
2472 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2473 self.cause(span, ObligationCauseCode::MiscObligation)
2476 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
2477 /// version (resolve_vars_if_possible), this version will
2478 /// also select obligations if it seems useful, in an effort
2479 /// to get more type information.
2480 fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2481 debug!("resolve_vars_with_obligations(ty={:?})", ty);
2483 // No Infer()? Nothing needs doing.
2484 if !ty.has_infer_types() && !ty.has_infer_consts() {
2485 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2489 // If `ty` is a type variable, see whether we already know what it is.
2490 ty = self.resolve_vars_if_possible(&ty);
2491 if !ty.has_infer_types() && !ty.has_infer_consts() {
2492 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2496 // If not, try resolving pending obligations as much as
2497 // possible. This can help substantially when there are
2498 // indirect dependencies that don't seem worth tracking
2500 self.select_obligations_where_possible(false, |_| {});
2501 ty = self.resolve_vars_if_possible(&ty);
2503 debug!("resolve_vars_with_obligations: ty={:?}", ty);
2507 fn record_deferred_call_resolution(
2509 closure_def_id: DefId,
2510 r: DeferredCallResolution<'tcx>,
2512 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2513 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2516 fn remove_deferred_call_resolutions(
2518 closure_def_id: DefId,
2519 ) -> Vec<DeferredCallResolution<'tcx>> {
2520 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2521 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2524 pub fn tag(&self) -> String {
2525 format!("{:p}", self)
2528 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2529 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2530 span_bug!(span, "no type for local variable {}",
2531 self.tcx.hir().node_to_string(nid))
2536 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2537 debug!("write_ty({:?}, {:?}) in fcx {}",
2538 id, self.resolve_vars_if_possible(&ty), self.tag());
2539 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2541 if ty.references_error() {
2542 self.has_errors.set(true);
2543 self.set_tainted_by_errors();
2547 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2548 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2551 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2552 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2555 pub fn write_method_call(&self,
2557 method: MethodCallee<'tcx>) {
2558 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2559 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2560 self.write_substs(hir_id, method.substs);
2562 // When the method is confirmed, the `method.substs` includes
2563 // parameters from not just the method, but also the impl of
2564 // the method -- in particular, the `Self` type will be fully
2565 // resolved. However, those are not something that the "user
2566 // specified" -- i.e., those types come from the inferred type
2567 // of the receiver, not something the user wrote. So when we
2568 // create the user-substs, we want to replace those earlier
2569 // types with just the types that the user actually wrote --
2570 // that is, those that appear on the *method itself*.
2572 // As an example, if the user wrote something like
2573 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2574 // type of `foo` (possibly adjusted), but we don't want to
2575 // include that. We want just the `[_, u32]` part.
2576 if !method.substs.is_noop() {
2577 let method_generics = self.tcx.generics_of(method.def_id);
2578 if !method_generics.params.is_empty() {
2579 let user_type_annotation = self.infcx.probe(|_| {
2580 let user_substs = UserSubsts {
2581 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2582 let i = param.index as usize;
2583 if i < method_generics.parent_count {
2584 self.infcx.var_for_def(DUMMY_SP, param)
2589 user_self_ty: None, // not relevant here
2592 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2598 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2599 self.write_user_type_annotation(hir_id, user_type_annotation);
2604 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2605 if !substs.is_noop() {
2606 debug!("write_substs({:?}, {:?}) in fcx {}",
2611 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2615 /// Given the substs that we just converted from the HIR, try to
2616 /// canonicalize them and store them as user-given substitutions
2617 /// (i.e., substitutions that must be respected by the NLL check).
2619 /// This should be invoked **before any unifications have
2620 /// occurred**, so that annotations like `Vec<_>` are preserved
2622 pub fn write_user_type_annotation_from_substs(
2626 substs: SubstsRef<'tcx>,
2627 user_self_ty: Option<UserSelfTy<'tcx>>,
2630 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2631 user_self_ty={:?} in fcx {}",
2632 hir_id, def_id, substs, user_self_ty, self.tag(),
2635 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2636 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2637 &UserType::TypeOf(def_id, UserSubsts {
2642 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2643 self.write_user_type_annotation(hir_id, canonicalized);
2647 pub fn write_user_type_annotation(
2650 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2653 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2654 hir_id, canonical_user_type_annotation, self.tag(),
2657 if !canonical_user_type_annotation.is_identity() {
2658 self.tables.borrow_mut().user_provided_types_mut().insert(
2659 hir_id, canonical_user_type_annotation
2662 debug!("write_user_type_annotation: skipping identity substs");
2666 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2667 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2673 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2674 Entry::Vacant(entry) => { entry.insert(adj); },
2675 Entry::Occupied(mut entry) => {
2676 debug!(" - composing on top of {:?}", entry.get());
2677 match (&entry.get()[..], &adj[..]) {
2678 // Applying any adjustment on top of a NeverToAny
2679 // is a valid NeverToAny adjustment, because it can't
2681 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2683 Adjustment { kind: Adjust::Deref(_), .. },
2684 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2686 Adjustment { kind: Adjust::Deref(_), .. },
2687 .. // Any following adjustments are allowed.
2689 // A reborrow has no effect before a dereference.
2691 // FIXME: currently we never try to compose autoderefs
2692 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2694 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2695 expr, entry.get(), adj)
2697 *entry.get_mut() = adj;
2702 /// Basically whenever we are converting from a type scheme into
2703 /// the fn body space, we always want to normalize associated
2704 /// types as well. This function combines the two.
2705 fn instantiate_type_scheme<T>(&self,
2707 substs: SubstsRef<'tcx>,
2710 where T : TypeFoldable<'tcx>
2712 let value = value.subst(self.tcx, substs);
2713 let result = self.normalize_associated_types_in(span, &value);
2714 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2721 /// As `instantiate_type_scheme`, but for the bounds found in a
2722 /// generic type scheme.
2723 fn instantiate_bounds(
2727 substs: SubstsRef<'tcx>,
2728 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
2729 let bounds = self.tcx.predicates_of(def_id);
2730 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
2731 let result = bounds.instantiate(self.tcx, substs);
2732 let result = self.normalize_associated_types_in(span, &result);
2734 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
2743 /// Replaces the opaque types from the given value with type variables,
2744 /// and records the `OpaqueTypeMap` for later use during writeback. See
2745 /// `InferCtxt::instantiate_opaque_types` for more details.
2746 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2748 parent_id: hir::HirId,
2752 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2753 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2757 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2758 self.instantiate_opaque_types(
2767 let mut opaque_types = self.opaque_types.borrow_mut();
2768 for (ty, decl) in opaque_type_map {
2769 let _ = opaque_types.insert(ty, decl);
2775 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2776 where T : TypeFoldable<'tcx>
2778 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2781 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2783 where T : TypeFoldable<'tcx>
2785 self.inh.partially_normalize_associated_types_in(span,
2791 pub fn require_type_meets(&self,
2794 code: traits::ObligationCauseCode<'tcx>,
2797 self.register_bound(
2800 traits::ObligationCause::new(span, self.body_id, code));
2803 pub fn require_type_is_sized(
2807 code: traits::ObligationCauseCode<'tcx>,
2809 if !ty.references_error() {
2810 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2811 self.require_type_meets(ty, span, code, lang_item);
2815 pub fn require_type_is_sized_deferred(
2819 code: traits::ObligationCauseCode<'tcx>,
2821 if !ty.references_error() {
2822 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2826 pub fn register_bound(
2830 cause: traits::ObligationCause<'tcx>,
2832 if !ty.references_error() {
2833 self.fulfillment_cx.borrow_mut()
2834 .register_bound(self, self.param_env, ty, def_id, cause);
2838 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2839 let t = AstConv::ast_ty_to_ty(self, ast_t);
2840 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2844 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2845 let ty = self.to_ty(ast_ty);
2846 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2848 if Self::can_contain_user_lifetime_bounds(ty) {
2849 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2850 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2851 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2857 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2858 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2859 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2862 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2863 AstConv::ast_const_to_const(self, ast_c, ty)
2866 // If the type given by the user has free regions, save it for later, since
2867 // NLL would like to enforce those. Also pass in types that involve
2868 // projections, since those can resolve to `'static` bounds (modulo #54940,
2869 // which hopefully will be fixed by the time you see this comment, dear
2870 // reader, although I have my doubts). Also pass in types with inference
2871 // types, because they may be repeated. Other sorts of things are already
2872 // sufficiently enforced with erased regions. =)
2873 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2875 T: TypeFoldable<'tcx>
2877 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2880 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2881 match self.tables.borrow().node_types().get(id) {
2883 None if self.is_tainted_by_errors() => self.tcx.types.err,
2885 bug!("no type for node {}: {} in fcx {}",
2886 id, self.tcx.hir().node_to_string(id),
2892 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2893 /// outlive the region `r`.
2894 pub fn register_wf_obligation(
2898 code: traits::ObligationCauseCode<'tcx>,
2900 // WF obligations never themselves fail, so no real need to give a detailed cause:
2901 let cause = traits::ObligationCause::new(span, self.body_id, code);
2902 self.register_predicate(
2903 traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
2907 /// Registers obligations that all types appearing in `substs` are well-formed.
2908 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2909 for ty in substs.types() {
2910 if !ty.references_error() {
2911 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2916 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2917 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2918 /// trait/region obligations.
2920 /// For example, if there is a function:
2923 /// fn foo<'a,T:'a>(...)
2926 /// and a reference:
2932 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2933 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2934 pub fn add_obligations_for_parameters(&self,
2935 cause: traits::ObligationCause<'tcx>,
2936 predicates: &ty::InstantiatedPredicates<'tcx>)
2938 assert!(!predicates.has_escaping_bound_vars());
2940 debug!("add_obligations_for_parameters(predicates={:?})",
2943 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2944 self.register_predicate(obligation);
2948 // FIXME(arielb1): use this instead of field.ty everywhere
2949 // Only for fields! Returns <none> for methods>
2950 // Indifferent to privacy flags
2954 field: &'tcx ty::FieldDef,
2955 substs: SubstsRef<'tcx>,
2957 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2960 fn check_casts(&self) {
2961 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2962 for cast in deferred_cast_checks.drain(..) {
2967 fn resolve_generator_interiors(&self, def_id: DefId) {
2968 let mut generators = self.deferred_generator_interiors.borrow_mut();
2969 for (body_id, interior, kind) in generators.drain(..) {
2970 self.select_obligations_where_possible(false, |_| {});
2971 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
2975 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2976 // Non-numerics get replaced with ! or () (depending on whether
2977 // feature(never_type) is enabled, unconstrained ints with i32,
2978 // unconstrained floats with f64.
2979 // Fallback becomes very dubious if we have encountered type-checking errors.
2980 // In that case, fallback to Error.
2981 // The return value indicates whether fallback has occurred.
2982 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2983 use rustc::ty::error::UnconstrainedNumeric::Neither;
2984 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2986 assert!(ty.is_ty_infer());
2987 let fallback = match self.type_is_unconstrained_numeric(ty) {
2988 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2989 UnconstrainedInt => self.tcx.types.i32,
2990 UnconstrainedFloat => self.tcx.types.f64,
2991 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2992 Neither => return false,
2994 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2995 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2999 fn select_all_obligations_or_error(&self) {
3000 debug!("select_all_obligations_or_error");
3001 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
3002 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3006 /// Select as many obligations as we can at present.
3007 fn select_obligations_where_possible(
3009 fallback_has_occurred: bool,
3010 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
3012 if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3013 mutate_fullfillment_errors(&mut errors);
3014 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
3018 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
3019 /// returns a type of `&T`, but the actual type we assign to the
3020 /// *expression* is `T`. So this function just peels off the return
3021 /// type by one layer to yield `T`.
3022 fn make_overloaded_place_return_type(&self,
3023 method: MethodCallee<'tcx>)
3024 -> ty::TypeAndMut<'tcx>
3026 // extract method return type, which will be &T;
3027 let ret_ty = method.sig.output();
3029 // method returns &T, but the type as visible to user is T, so deref
3030 ret_ty.builtin_deref(true).unwrap()
3036 base_expr: &'tcx hir::Expr,
3040 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3041 // FIXME(#18741) -- this is almost but not quite the same as the
3042 // autoderef that normal method probing does. They could likely be
3045 let mut autoderef = self.autoderef(base_expr.span, base_ty);
3046 let mut result = None;
3047 while result.is_none() && autoderef.next().is_some() {
3048 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
3050 autoderef.finalize(self);
3054 /// To type-check `base_expr[index_expr]`, we progressively autoderef
3055 /// (and otherwise adjust) `base_expr`, looking for a type which either
3056 /// supports builtin indexing or overloaded indexing.
3057 /// This loop implements one step in that search; the autoderef loop
3058 /// is implemented by `lookup_indexing`.
3062 base_expr: &hir::Expr,
3063 autoderef: &Autoderef<'a, 'tcx>,
3066 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
3067 let adjusted_ty = autoderef.unambiguous_final_ty(self);
3068 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3075 for &unsize in &[false, true] {
3076 let mut self_ty = adjusted_ty;
3078 // We only unsize arrays here.
3079 if let ty::Array(element_ty, _) = adjusted_ty.kind {
3080 self_ty = self.tcx.mk_slice(element_ty);
3086 // If some lookup succeeds, write callee into table and extract index/element
3087 // type from the method signature.
3088 // If some lookup succeeded, install method in table
3089 let input_ty = self.next_ty_var(TypeVariableOrigin {
3090 kind: TypeVariableOriginKind::AutoDeref,
3091 span: base_expr.span,
3093 let method = self.try_overloaded_place_op(
3094 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
3096 let result = method.map(|ok| {
3097 debug!("try_index_step: success, using overloaded indexing");
3098 let method = self.register_infer_ok_obligations(ok);
3100 let mut adjustments = autoderef.adjust_steps(self, needs);
3101 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
3102 let mutbl = match r_mutbl {
3103 hir::MutImmutable => AutoBorrowMutability::Immutable,
3104 hir::MutMutable => AutoBorrowMutability::Mutable {
3105 // Indexing can be desugared to a method call,
3106 // so maybe we could use two-phase here.
3107 // See the documentation of AllowTwoPhase for why that's
3108 // not the case today.
3109 allow_two_phase_borrow: AllowTwoPhase::No,
3112 adjustments.push(Adjustment {
3113 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3114 target: self.tcx.mk_ref(region, ty::TypeAndMut {
3121 adjustments.push(Adjustment {
3122 kind: Adjust::Pointer(PointerCast::Unsize),
3123 target: method.sig.inputs()[0]
3126 self.apply_adjustments(base_expr, adjustments);
3128 self.write_method_call(expr.hir_id, method);
3129 (input_ty, self.make_overloaded_place_return_type(method).ty)
3131 if result.is_some() {
3139 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3140 let (tr, name) = match (op, is_mut) {
3141 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3142 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3143 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3144 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3146 (tr, ast::Ident::with_dummy_span(name))
3149 fn try_overloaded_place_op(&self,
3152 arg_tys: &[Ty<'tcx>],
3155 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
3157 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
3163 // Try Mut first, if needed.
3164 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3165 let method = match (needs, mut_tr) {
3166 (Needs::MutPlace, Some(trait_did)) => {
3167 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3172 // Otherwise, fall back to the immutable version.
3173 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3174 let method = match (method, imm_tr) {
3175 (None, Some(trait_did)) => {
3176 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3178 (method, _) => method,
3184 fn check_method_argument_types(
3187 expr: &'tcx hir::Expr,
3188 method: Result<MethodCallee<'tcx>, ()>,
3189 args_no_rcvr: &'tcx [hir::Expr],
3190 tuple_arguments: TupleArgumentsFlag,
3191 expected: Expectation<'tcx>,
3194 let has_error = match method {
3196 method.substs.references_error() || method.sig.references_error()
3201 let err_inputs = self.err_args(args_no_rcvr.len());
3203 let err_inputs = match tuple_arguments {
3204 DontTupleArguments => err_inputs,
3205 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3208 self.check_argument_types(
3218 return self.tcx.types.err;
3221 let method = method.unwrap();
3222 // HACK(eddyb) ignore self in the definition (see above).
3223 let expected_arg_tys = self.expected_inputs_for_expected_output(
3226 method.sig.output(),
3227 &method.sig.inputs()[1..]
3229 self.check_argument_types(
3232 &method.sig.inputs()[1..],
3233 &expected_arg_tys[..],
3235 method.sig.c_variadic,
3237 self.tcx.hir().span_if_local(method.def_id),
3242 fn self_type_matches_expected_vid(
3244 trait_ref: ty::PolyTraitRef<'tcx>,
3245 expected_vid: ty::TyVid,
3247 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3249 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3250 trait_ref, self_ty, expected_vid
3252 match self_ty.kind {
3253 ty::Infer(ty::TyVar(found_vid)) => {
3254 // FIXME: consider using `sub_root_var` here so we
3255 // can see through subtyping.
3256 let found_vid = self.root_var(found_vid);
3257 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3258 expected_vid == found_vid
3264 fn obligations_for_self_ty<'b>(
3267 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3270 // FIXME: consider using `sub_root_var` here so we
3271 // can see through subtyping.
3272 let ty_var_root = self.root_var(self_ty);
3273 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3274 self_ty, ty_var_root,
3275 self.fulfillment_cx.borrow().pending_obligations());
3279 .pending_obligations()
3281 .filter_map(move |obligation| match obligation.predicate {
3282 ty::Predicate::Projection(ref data) =>
3283 Some((data.to_poly_trait_ref(self.tcx), obligation)),
3284 ty::Predicate::Trait(ref data) =>
3285 Some((data.to_poly_trait_ref(), obligation)),
3286 ty::Predicate::Subtype(..) => None,
3287 ty::Predicate::RegionOutlives(..) => None,
3288 ty::Predicate::TypeOutlives(..) => None,
3289 ty::Predicate::WellFormed(..) => None,
3290 ty::Predicate::ObjectSafe(..) => None,
3291 ty::Predicate::ConstEvaluatable(..) => None,
3292 // N.B., this predicate is created by breaking down a
3293 // `ClosureType: FnFoo()` predicate, where
3294 // `ClosureType` represents some `Closure`. It can't
3295 // possibly be referring to the current closure,
3296 // because we haven't produced the `Closure` for
3297 // this closure yet; this is exactly why the other
3298 // code is looking for a self type of a unresolved
3299 // inference variable.
3300 ty::Predicate::ClosureKind(..) => None,
3301 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3304 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3305 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
3306 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
3310 /// Generic function that factors out common logic from function calls,
3311 /// method calls and overloaded operators.
3312 fn check_argument_types(
3315 expr: &'tcx hir::Expr,
3316 fn_inputs: &[Ty<'tcx>],
3317 expected_arg_tys: &[Ty<'tcx>],
3318 args: &'tcx [hir::Expr],
3320 tuple_arguments: TupleArgumentsFlag,
3321 def_span: Option<Span>,
3324 // Grab the argument types, supplying fresh type variables
3325 // if the wrong number of arguments were supplied
3326 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
3332 // All the input types from the fn signature must outlive the call
3333 // so as to validate implied bounds.
3334 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3335 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3338 let expected_arg_count = fn_inputs.len();
3340 let param_count_error = |expected_count: usize,
3345 let mut err = tcx.sess.struct_span_err_with_code(sp,
3346 &format!("this function takes {}{} but {} {} supplied",
3347 if c_variadic { "at least " } else { "" },
3348 potentially_plural_count(expected_count, "parameter"),
3349 potentially_plural_count(arg_count, "parameter"),
3350 if arg_count == 1 {"was"} else {"were"}),
3351 DiagnosticId::Error(error_code.to_owned()));
3353 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3354 err.span_label(def_s, "defined here");
3357 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3358 // remove closing `)` from the span
3359 let sugg_span = sugg_span.shrink_to_lo();
3360 err.span_suggestion(
3362 "expected the unit value `()`; create it with empty parentheses",
3364 Applicability::MachineApplicable);
3366 err.span_label(sp, format!("expected {}{}",
3367 if c_variadic { "at least " } else { "" },
3368 potentially_plural_count(expected_count, "parameter")));
3373 let mut expected_arg_tys = expected_arg_tys.to_vec();
3375 let formal_tys = if tuple_arguments == TupleArguments {
3376 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3377 match tuple_type.kind {
3378 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3379 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3380 expected_arg_tys = vec![];
3381 self.err_args(args.len())
3383 ty::Tuple(arg_types) => {
3384 expected_arg_tys = match expected_arg_tys.get(0) {
3385 Some(&ty) => match ty.kind {
3386 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3391 arg_types.iter().map(|k| k.expect_ty()).collect()
3394 span_err!(tcx.sess, sp, E0059,
3395 "cannot use call notation; the first type parameter \
3396 for the function trait is neither a tuple nor unit");
3397 expected_arg_tys = vec![];
3398 self.err_args(args.len())
3401 } else if expected_arg_count == supplied_arg_count {
3403 } else if c_variadic {
3404 if supplied_arg_count >= expected_arg_count {
3407 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3408 expected_arg_tys = vec![];
3409 self.err_args(supplied_arg_count)
3412 // is the missing argument of type `()`?
3413 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3414 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3415 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3416 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3420 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3422 expected_arg_tys = vec![];
3423 self.err_args(supplied_arg_count)
3426 debug!("check_argument_types: formal_tys={:?}",
3427 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3429 // If there is no expectation, expect formal_tys.
3430 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3436 let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
3438 // Check the arguments.
3439 // We do this in a pretty awful way: first we type-check any arguments
3440 // that are not closures, then we type-check the closures. This is so
3441 // that we have more information about the types of arguments when we
3442 // type-check the functions. This isn't really the right way to do this.
3443 for &check_closures in &[false, true] {
3444 debug!("check_closures={}", check_closures);
3446 // More awful hacks: before we check argument types, try to do
3447 // an "opportunistic" vtable resolution of any trait bounds on
3448 // the call. This helps coercions.
3450 self.select_obligations_where_possible(false, |errors| {
3451 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
3452 self.point_at_arg_instead_of_call_if_possible(
3454 &final_arg_types[..],
3461 // For C-variadic functions, we don't have a declared type for all of
3462 // the arguments hence we only do our usual type checking with
3463 // the arguments who's types we do know.
3464 let t = if c_variadic {
3466 } else if tuple_arguments == TupleArguments {
3471 for (i, arg) in args.iter().take(t).enumerate() {
3472 // Warn only for the first loop (the "no closures" one).
3473 // Closure arguments themselves can't be diverging, but
3474 // a previous argument can, e.g., `foo(panic!(), || {})`.
3475 if !check_closures {
3476 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3479 let is_closure = match arg.kind {
3480 ExprKind::Closure(..) => true,
3484 if is_closure != check_closures {
3488 debug!("checking the argument");
3489 let formal_ty = formal_tys[i];
3491 // The special-cased logic below has three functions:
3492 // 1. Provide as good of an expected type as possible.
3493 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3495 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3497 // 2. Coerce to the most detailed type that could be coerced
3498 // to, which is `expected_ty` if `rvalue_hint` returns an
3499 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3500 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3501 // We're processing function arguments so we definitely want to use
3502 // two-phase borrows.
3503 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3504 final_arg_types.push((i, coerce_ty));
3506 // 3. Relate the expected type and the formal one,
3507 // if the expected type was used for the coercion.
3508 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3512 // We also need to make sure we at least write the ty of the other
3513 // arguments which we skipped above.
3515 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3516 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3517 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3520 for arg in args.iter().skip(expected_arg_count) {
3521 let arg_ty = self.check_expr(&arg);
3523 // There are a few types which get autopromoted when passed via varargs
3524 // in C but we just error out instead and require explicit casts.
3525 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3527 ty::Float(ast::FloatTy::F32) => {
3528 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3530 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3531 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3533 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3534 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3537 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3538 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3539 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3547 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3548 vec![self.tcx.types.err; len]
3551 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
3552 /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
3553 /// reference a type argument. If they do, and there's only *one* argument that does, we point
3554 /// at the corresponding argument's expression span instead of the `fn` call path span.
3555 fn point_at_arg_instead_of_call_if_possible(
3557 errors: &mut Vec<traits::FulfillmentError<'_>>,
3558 final_arg_types: &[(usize, Ty<'tcx>)],
3560 args: &'tcx [hir::Expr],
3562 if !call_sp.desugaring_kind().is_some() {
3563 // We *do not* do this for desugared call spans to keep good diagnostics when involving
3564 // the `?` operator.
3565 for error in errors {
3566 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3567 // Collect the argument position for all arguments that could have caused this
3568 // `FullfillmentError`.
3569 let mut referenced_in = final_arg_types.iter()
3570 .flat_map(|(i, ty)| {
3571 let ty = self.resolve_vars_if_possible(ty);
3572 // We walk the argument type because the argument's type could have
3573 // been `Option<T>`, but the `FullfillmentError` references `T`.
3575 .filter(|&ty| ty == predicate.skip_binder().self_ty())
3578 if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3579 // We make sure that only *one* argument matches the obligation failure
3580 // and thet the obligation's span to its expression's.
3581 error.obligation.cause.span = args[ref_in].span;
3582 error.points_at_arg_span = true;
3589 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
3590 /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
3591 /// were caused by them. If they were, we point at the corresponding type argument's span
3592 /// instead of the `fn` call path span.
3593 fn point_at_type_arg_instead_of_call_if_possible(
3595 errors: &mut Vec<traits::FulfillmentError<'_>>,
3596 call_expr: &'tcx hir::Expr,
3598 if let hir::ExprKind::Call(path, _) = &call_expr.kind {
3599 if let hir::ExprKind::Path(qpath) = &path.kind {
3600 if let hir::QPath::Resolved(_, path) = &qpath {
3601 for error in errors {
3602 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3603 // If any of the type arguments in this path segment caused the
3604 // `FullfillmentError`, point at its span (#61860).
3605 for arg in path.segments.iter()
3606 .filter_map(|seg| seg.args.as_ref())
3607 .flat_map(|a| a.args.iter())
3609 if let hir::GenericArg::Type(hir_ty) = &arg {
3610 if let hir::TyKind::Path(
3611 hir::QPath::TypeRelative(..),
3613 // Avoid ICE with associated types. As this is best
3614 // effort only, it's ok to ignore the case. It
3615 // would trigger in `is_send::<T::AssocType>();`
3616 // from `typeck-default-trait-impl-assoc-type.rs`.
3618 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
3619 let ty = self.resolve_vars_if_possible(&ty);
3620 if ty == predicate.skip_binder().self_ty() {
3621 error.obligation.cause.span = hir_ty.span;
3633 // AST fragment checking
3636 expected: Expectation<'tcx>)
3642 ast::LitKind::Str(..) => tcx.mk_static_str(),
3643 ast::LitKind::ByteStr(ref v) => {
3644 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3645 tcx.mk_array(tcx.types.u8, v.len() as u64))
3647 ast::LitKind::Byte(_) => tcx.types.u8,
3648 ast::LitKind::Char(_) => tcx.types.char,
3649 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3650 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3651 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3652 let opt_ty = expected.to_option(self).and_then(|ty| {
3654 ty::Int(_) | ty::Uint(_) => Some(ty),
3655 ty::Char => Some(tcx.types.u8),
3656 ty::RawPtr(..) => Some(tcx.types.usize),
3657 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3661 opt_ty.unwrap_or_else(|| self.next_int_var())
3663 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3664 ast::LitKind::FloatUnsuffixed(_) => {
3665 let opt_ty = expected.to_option(self).and_then(|ty| {
3667 ty::Float(_) => Some(ty),
3671 opt_ty.unwrap_or_else(|| self.next_float_var())
3673 ast::LitKind::Bool(_) => tcx.types.bool,
3674 ast::LitKind::Err(_) => tcx.types.err,
3678 // Determine the `Self` type, using fresh variables for all variables
3679 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3680 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3682 pub fn impl_self_ty(&self,
3683 span: Span, // (potential) receiver for this impl
3685 -> TypeAndSubsts<'tcx> {
3686 let ity = self.tcx.type_of(did);
3687 debug!("impl_self_ty: ity={:?}", ity);
3689 let substs = self.fresh_substs_for_item(span, did);
3690 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3692 TypeAndSubsts { substs: substs, ty: substd_ty }
3695 /// Unifies the output type with the expected type early, for more coercions
3696 /// and forward type information on the input expressions.
3697 fn expected_inputs_for_expected_output(&self,
3699 expected_ret: Expectation<'tcx>,
3700 formal_ret: Ty<'tcx>,
3701 formal_args: &[Ty<'tcx>])
3703 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
3704 let ret_ty = match expected_ret.only_has_type(self) {
3706 None => return Vec::new()
3708 let expect_args = self.fudge_inference_if_ok(|| {
3709 // Attempt to apply a subtyping relationship between the formal
3710 // return type (likely containing type variables if the function
3711 // is polymorphic) and the expected return type.
3712 // No argument expectations are produced if unification fails.
3713 let origin = self.misc(call_span);
3714 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3716 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3717 // to identity so the resulting type is not constrained.
3720 // Process any obligations locally as much as
3721 // we can. We don't care if some things turn
3722 // out unconstrained or ambiguous, as we're
3723 // just trying to get hints here.
3724 self.save_and_restore_in_snapshot_flag(|_| {
3725 let mut fulfill = TraitEngine::new(self.tcx);
3726 for obligation in ok.obligations {
3727 fulfill.register_predicate_obligation(self, obligation);
3729 fulfill.select_where_possible(self)
3730 }).map_err(|_| ())?;
3732 Err(_) => return Err(()),
3735 // Record all the argument types, with the substitutions
3736 // produced from the above subtyping unification.
3737 Ok(formal_args.iter().map(|ty| {
3738 self.resolve_vars_if_possible(ty)
3740 }).unwrap_or_default();
3741 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3742 formal_args, formal_ret,
3743 expect_args, expected_ret);
3747 pub fn check_struct_path(&self,
3750 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3751 let path_span = match *qpath {
3752 QPath::Resolved(_, ref path) => path.span,
3753 QPath::TypeRelative(ref qself, _) => qself.span
3755 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3756 let variant = match def {
3758 self.set_tainted_by_errors();
3761 Res::Def(DefKind::Variant, _) => {
3763 ty::Adt(adt, substs) => {
3764 Some((adt.variant_of_res(def), adt.did, substs))
3766 _ => bug!("unexpected type: {:?}", ty)
3769 Res::Def(DefKind::Struct, _)
3770 | Res::Def(DefKind::Union, _)
3771 | Res::Def(DefKind::TyAlias, _)
3772 | Res::Def(DefKind::AssocTy, _)
3773 | Res::SelfTy(..) => {
3775 ty::Adt(adt, substs) if !adt.is_enum() => {
3776 Some((adt.non_enum_variant(), adt.did, substs))
3781 _ => bug!("unexpected definition: {:?}", def)
3784 if let Some((variant, did, substs)) = variant {
3785 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3786 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3788 // Check bounds on type arguments used in the path.
3789 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
3790 let cause = traits::ObligationCause::new(
3793 traits::ItemObligation(did),
3795 self.add_obligations_for_parameters(cause, &bounds);
3799 struct_span_err!(self.tcx.sess, path_span, E0071,
3800 "expected struct, variant or union type, found {}",
3801 ty.sort_string(self.tcx))
3802 .span_label(path_span, "not a struct")
3808 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3809 // The newly resolved definition is written into `type_dependent_defs`.
3810 fn finish_resolving_struct_path(&self,
3817 QPath::Resolved(ref maybe_qself, ref path) => {
3818 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3819 let ty = AstConv::res_to_ty(self, self_ty, path, true);
3822 QPath::TypeRelative(ref qself, ref segment) => {
3823 let ty = self.to_ty(qself);
3825 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
3830 let result = AstConv::associated_path_to_ty(
3839 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
3840 let result = result.map(|(_, kind, def_id)| (kind, def_id));
3842 // Write back the new resolution.
3843 self.write_resolution(hir_id, result);
3845 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
3850 /// Resolves an associated value path into a base type and associated constant, or method
3851 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
3852 pub fn resolve_ty_and_res_ufcs<'b>(&self,
3856 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3858 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
3859 let (ty, qself, item_segment) = match *qpath {
3860 QPath::Resolved(ref opt_qself, ref path) => {
3862 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3863 &path.segments[..]);
3865 QPath::TypeRelative(ref qself, ref segment) => {
3866 (self.to_ty(qself), qself, segment)
3869 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
3870 // Return directly on cache hit. This is useful to avoid doubly reporting
3871 // errors with default match binding modes. See #44614.
3872 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
3873 .unwrap_or(Res::Err);
3874 return (def, Some(ty), slice::from_ref(&**item_segment));
3876 let item_name = item_segment.ident;
3877 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
3878 let result = match error {
3879 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
3880 _ => Err(ErrorReported),
3882 if item_name.name != kw::Invalid {
3883 self.report_method_error(
3887 SelfSource::QPath(qself),
3890 ).map(|mut e| e.emit());
3895 // Write back the new resolution.
3896 self.write_resolution(hir_id, result);
3898 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
3900 slice::from_ref(&**item_segment),
3904 pub fn check_decl_initializer(
3906 local: &'tcx hir::Local,
3907 init: &'tcx hir::Expr,
3909 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
3910 // for #42640 (default match binding modes).
3913 let ref_bindings = local.pat.contains_explicit_ref_binding();
3915 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
3916 if let Some(m) = ref_bindings {
3917 // Somewhat subtle: if we have a `ref` binding in the pattern,
3918 // we want to avoid introducing coercions for the RHS. This is
3919 // both because it helps preserve sanity and, in the case of
3920 // ref mut, for soundness (issue #23116). In particular, in
3921 // the latter case, we need to be clear that the type of the
3922 // referent for the reference that results is *equal to* the
3923 // type of the place it is referencing, and not some
3924 // supertype thereof.
3925 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
3926 self.demand_eqtype(init.span, local_ty, init_ty);
3929 self.check_expr_coercable_to_type(init, local_ty)
3933 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
3934 let t = self.local_ty(local.span, local.hir_id).decl_ty;
3935 self.write_ty(local.hir_id, t);
3937 if let Some(ref init) = local.init {
3938 let init_ty = self.check_decl_initializer(local, &init);
3939 self.overwrite_local_ty_if_err(local, t, init_ty);
3942 self.check_pat_top(&local.pat, t, None);
3943 let pat_ty = self.node_ty(local.pat.hir_id);
3944 self.overwrite_local_ty_if_err(local, t, pat_ty);
3947 fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
3948 if ty.references_error() {
3949 // Override the types everywhere with `types.err` to avoid knock down errors.
3950 self.write_ty(local.hir_id, ty);
3951 self.write_ty(local.pat.hir_id, ty);
3952 let local_ty = LocalTy {
3956 self.locals.borrow_mut().insert(local.hir_id, local_ty);
3957 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
3961 fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
3962 err.span_suggestion_short(
3963 span.shrink_to_hi(),
3964 "consider using a semicolon here",
3966 Applicability::MachineApplicable,
3970 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
3971 // Don't do all the complex logic below for `DeclItem`.
3973 hir::StmtKind::Item(..) => return,
3974 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
3977 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
3979 // Hide the outer diverging and `has_errors` flags.
3980 let old_diverges = self.diverges.get();
3981 let old_has_errors = self.has_errors.get();
3982 self.diverges.set(Diverges::Maybe);
3983 self.has_errors.set(false);
3986 hir::StmtKind::Local(ref l) => {
3987 self.check_decl_local(&l);
3990 hir::StmtKind::Item(_) => {}
3991 hir::StmtKind::Expr(ref expr) => {
3992 // Check with expected type of `()`.
3994 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
3995 self.suggest_semicolon_at_end(expr.span, err);
3998 hir::StmtKind::Semi(ref expr) => {
3999 self.check_expr(&expr);
4003 // Combine the diverging and `has_error` flags.
4004 self.diverges.set(self.diverges.get() | old_diverges);
4005 self.has_errors.set(self.has_errors.get() | old_has_errors);
4008 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
4009 let unit = self.tcx.mk_unit();
4010 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4012 // if the block produces a `!` value, that can always be
4013 // (effectively) coerced to unit.
4015 self.demand_suptype(blk.span, unit, ty);
4019 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
4020 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
4021 /// when given code like the following:
4023 /// if false { return 0i32; } else { 1u32 }
4024 /// // ^^^^ point at this instead of the whole `if` expression
4026 fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
4027 if let hir::ExprKind::Match(_, arms, _) = &expr.kind {
4028 let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
4029 self.in_progress_tables
4030 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
4031 .and_then(|arm_ty| {
4032 if arm_ty.is_never() {
4035 Some(match &arm.body.kind {
4036 // Point at the tail expression when possible.
4037 hir::ExprKind::Block(block, _) => block.expr
4040 .unwrap_or(block.span),
4046 if arm_spans.len() == 1 {
4047 return arm_spans[0];
4053 fn check_block_with_expected(
4055 blk: &'tcx hir::Block,
4056 expected: Expectation<'tcx>,
4059 let mut fcx_ps = self.ps.borrow_mut();
4060 let unsafety_state = fcx_ps.recurse(blk);
4061 replace(&mut *fcx_ps, unsafety_state)
4064 // In some cases, blocks have just one exit, but other blocks
4065 // can be targeted by multiple breaks. This can happen both
4066 // with labeled blocks as well as when we desugar
4067 // a `try { ... }` expression.
4071 // 'a: { if true { break 'a Err(()); } Ok(()) }
4073 // Here we would wind up with two coercions, one from
4074 // `Err(())` and the other from the tail expression
4075 // `Ok(())`. If the tail expression is omitted, that's a
4076 // "forced unit" -- unless the block diverges, in which
4077 // case we can ignore the tail expression (e.g., `'a: {
4078 // break 'a 22; }` would not force the type of the block
4080 let tail_expr = blk.expr.as_ref();
4081 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4082 let coerce = if blk.targeted_by_break {
4083 CoerceMany::new(coerce_to_ty)
4085 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4086 Some(e) => slice::from_ref(e),
4089 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4092 let prev_diverges = self.diverges.get();
4093 let ctxt = BreakableCtxt {
4094 coerce: Some(coerce),
4098 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
4099 for s in &blk.stmts {
4103 // check the tail expression **without** holding the
4104 // `enclosing_breakables` lock below.
4105 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4107 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4108 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
4109 let coerce = ctxt.coerce.as_mut().unwrap();
4110 if let Some(tail_expr_ty) = tail_expr_ty {
4111 let tail_expr = tail_expr.unwrap();
4112 let span = self.get_expr_coercion_span(tail_expr);
4113 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4114 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4116 // Subtle: if there is no explicit tail expression,
4117 // that is typically equivalent to a tail expression
4118 // of `()` -- except if the block diverges. In that
4119 // case, there is no value supplied from the tail
4120 // expression (assuming there are no other breaks,
4121 // this implies that the type of the block will be
4124 // #41425 -- label the implicit `()` as being the
4125 // "found type" here, rather than the "expected type".
4126 if !self.diverges.get().is_always() {
4127 // #50009 -- Do not point at the entire fn block span, point at the return type
4128 // span, as it is the cause of the requirement, and
4129 // `consider_hint_about_removing_semicolon` will point at the last expression
4130 // if it were a relevant part of the error. This improves usability in editors
4131 // that highlight errors inline.
4132 let mut sp = blk.span;
4133 let mut fn_span = None;
4134 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4135 let ret_sp = decl.output.span();
4136 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4137 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4138 // output would otherwise be incorrect and even misleading. Make sure
4139 // the span we're aiming at correspond to a `fn` body.
4140 if block_sp == blk.span {
4142 fn_span = Some(ident.span);
4146 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
4147 if let Some(expected_ty) = expected.only_has_type(self) {
4148 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4150 if let Some(fn_span) = fn_span {
4153 "implicitly returns `()` as its body has no tail or `return` \
4163 // If we can break from the block, then the block's exit is always reachable
4164 // (... as long as the entry is reachable) - regardless of the tail of the block.
4165 self.diverges.set(prev_diverges);
4168 let mut ty = ctxt.coerce.unwrap().complete(self);
4170 if self.has_errors.get() || ty.references_error() {
4171 ty = self.tcx.types.err
4174 self.write_ty(blk.hir_id, ty);
4176 *self.ps.borrow_mut() = prev;
4180 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4181 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4183 Node::Item(&hir::Item {
4184 kind: hir::ItemKind::Fn(_, _, _, body_id), ..
4186 Node::ImplItem(&hir::ImplItem {
4187 kind: hir::ImplItemKind::Method(_, body_id), ..
4189 let body = self.tcx.hir().body(body_id);
4190 if let ExprKind::Block(block, _) = &body.value.kind {
4191 return Some(block.span);
4199 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4200 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
4201 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4202 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4205 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4206 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
4208 Node::Item(&hir::Item {
4209 ident, kind: hir::ItemKind::Fn(ref decl, ..), ..
4211 // This is less than ideal, it will not suggest a return type span on any
4212 // method called `main`, regardless of whether it is actually the entry point,
4213 // but it will still present it as the reason for the expected type.
4214 Some((decl, ident, ident.name != sym::main))
4216 Node::TraitItem(&hir::TraitItem {
4217 ident, kind: hir::TraitItemKind::Method(hir::MethodSig {
4220 }) => Some((decl, ident, true)),
4221 Node::ImplItem(&hir::ImplItem {
4222 ident, kind: hir::ImplItemKind::Method(hir::MethodSig {
4225 }) => Some((decl, ident, false)),
4230 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4231 /// suggestion can be made, `None` otherwise.
4232 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
4233 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4234 // `while` before reaching it, as block tail returns are not available in them.
4235 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4236 let parent = self.tcx.hir().get(blk_id);
4237 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4241 /// On implicit return expressions with mismatched types, provides the following suggestions:
4243 /// - Points out the method's return type as the reason for the expected type.
4244 /// - Possible missing semicolon.
4245 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4246 pub fn suggest_mismatched_types_on_tail(
4248 err: &mut DiagnosticBuilder<'tcx>,
4249 expr: &'tcx hir::Expr,
4255 let expr = expr.peel_drop_temps();
4256 self.suggest_missing_semicolon(err, expr, expected, cause_span);
4257 let mut pointing_at_return_type = false;
4258 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4259 pointing_at_return_type = self.suggest_missing_return_type(
4260 err, &fn_decl, expected, found, can_suggest);
4262 self.suggest_ref_or_into(err, expr, expected, found);
4263 self.suggest_boxing_when_appropriate(err, expr, expected, found);
4264 pointing_at_return_type
4267 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4268 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4270 /// fn foo(x: usize) -> usize { x }
4271 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4275 err: &mut DiagnosticBuilder<'tcx>,
4280 let hir = self.tcx.hir();
4281 let (def_id, sig) = match found.kind {
4282 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4283 ty::Closure(def_id, substs) => {
4284 // We don't use `closure_sig` to account for malformed closures like
4285 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4286 let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4287 (def_id, match closure_sig_ty.kind {
4288 ty::FnPtr(sig) => sig,
4296 .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
4298 let sig = self.normalize_associated_types_in(expr.span, &sig);
4299 if self.can_coerce(sig.output(), expected) {
4300 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4301 (String::new(), Applicability::MachineApplicable)
4303 ("...".to_string(), Applicability::HasPlaceholders)
4305 let mut msg = "call this function";
4306 match hir.get_if_local(def_id) {
4307 Some(Node::Item(hir::Item {
4308 kind: ItemKind::Fn(.., body_id),
4311 Some(Node::ImplItem(hir::ImplItem {
4312 kind: hir::ImplItemKind::Method(_, body_id),
4315 Some(Node::TraitItem(hir::TraitItem {
4316 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4319 let body = hir.body(*body_id);
4320 sugg_call = body.params.iter()
4321 .map(|param| match ¶m.pat.kind {
4322 hir::PatKind::Binding(_, _, ident, None)
4323 if ident.name != kw::SelfLower => ident.to_string(),
4324 _ => "_".to_string(),
4325 }).collect::<Vec<_>>().join(", ");
4327 Some(Node::Expr(hir::Expr {
4328 kind: ExprKind::Closure(_, _, body_id, closure_span, _),
4329 span: full_closure_span,
4332 if *full_closure_span == expr.span {
4335 err.span_label(*closure_span, "closure defined here");
4336 msg = "call this closure";
4337 let body = hir.body(*body_id);
4338 sugg_call = body.params.iter()
4339 .map(|param| match ¶m.pat.kind {
4340 hir::PatKind::Binding(_, _, ident, None)
4341 if ident.name != kw::SelfLower => ident.to_string(),
4342 _ => "_".to_string(),
4343 }).collect::<Vec<_>>().join(", ");
4345 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4346 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4347 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4348 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4349 msg = "instantiate this tuple variant";
4351 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4352 msg = "instantiate this tuple struct";
4357 Some(Node::ForeignItem(hir::ForeignItem {
4358 kind: hir::ForeignItemKind::Fn(_, idents, _),
4361 Some(Node::TraitItem(hir::TraitItem {
4362 kind: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4364 })) => sugg_call = idents.iter()
4365 .map(|ident| if ident.name != kw::SelfLower {
4369 }).collect::<Vec<_>>()
4373 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4374 err.span_suggestion(
4376 &format!("use parentheses to {}", msg),
4377 format!("{}({})", code, sugg_call),
4386 pub fn suggest_ref_or_into(
4388 err: &mut DiagnosticBuilder<'tcx>,
4393 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4394 err.span_suggestion(
4398 Applicability::MachineApplicable,
4400 } else if let (ty::FnDef(def_id, ..), true) = (
4402 self.suggest_fn_call(err, expr, expected, found),
4404 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4405 let sp = self.sess().source_map().def_span(sp);
4406 err.span_label(sp, &format!("{} defined here", found));
4408 } else if !self.check_for_cast(err, expr, found, expected) {
4409 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4413 let methods = self.get_conversion_methods(expr.span, expected, found);
4414 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4415 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4416 .filter_map(|(receiver, method)| {
4417 let method_call = format!(".{}()", method.ident);
4418 if receiver.ends_with(&method_call) {
4419 None // do not suggest code that is already there (#53348)
4421 let method_call_list = [".to_vec()", ".to_string()"];
4422 let sugg = if receiver.ends_with(".clone()")
4423 && method_call_list.contains(&method_call.as_str()) {
4424 let max_len = receiver.rfind(".").unwrap();
4425 format!("{}{}", &receiver[..max_len], method_call)
4427 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
4428 format!("({}){}", receiver, method_call)
4430 format!("{}{}", receiver, method_call)
4433 Some(if is_struct_pat_shorthand_field {
4434 format!("{}: {}", receiver, sugg)
4440 if suggestions.peek().is_some() {
4441 err.span_suggestions(
4443 "try using a conversion method",
4445 Applicability::MaybeIncorrect,
4452 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
4453 /// in the heap by calling `Box::new()`.
4454 fn suggest_boxing_when_appropriate(
4456 err: &mut DiagnosticBuilder<'tcx>,
4461 if self.tcx.hir().is_const_context(expr.hir_id) {
4462 // Do not suggest `Box::new` in const context.
4465 if !expected.is_box() || found.is_box() {
4468 let boxed_found = self.tcx.mk_box(found);
4469 if let (true, Ok(snippet)) = (
4470 self.can_coerce(boxed_found, expected),
4471 self.sess().source_map().span_to_snippet(expr.span),
4473 err.span_suggestion(
4475 "store this in the heap by calling `Box::new`",
4476 format!("Box::new({})", snippet),
4477 Applicability::MachineApplicable,
4479 err.note("for more on the distinction between the stack and the \
4480 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
4481 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
4482 https://doc.rust-lang.org/std/boxed/index.html");
4487 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4491 /// bar_that_returns_u32()
4495 /// This routine checks if the return expression in a block would make sense on its own as a
4496 /// statement and the return type has been left as default or has been specified as `()`. If so,
4497 /// it suggests adding a semicolon.
4498 fn suggest_missing_semicolon(
4500 err: &mut DiagnosticBuilder<'tcx>,
4501 expression: &'tcx hir::Expr,
4505 if expected.is_unit() {
4506 // `BlockTailExpression` only relevant if the tail expr would be
4507 // useful on its own.
4508 match expression.kind {
4509 ExprKind::Call(..) |
4510 ExprKind::MethodCall(..) |
4511 ExprKind::Loop(..) |
4512 ExprKind::Match(..) |
4513 ExprKind::Block(..) => {
4514 let sp = self.tcx.sess.source_map().next_point(cause_span);
4515 err.span_suggestion(
4517 "try adding a semicolon",
4519 Applicability::MachineApplicable);
4526 /// A possible error is to forget to add a return type that is needed:
4530 /// bar_that_returns_u32()
4534 /// This routine checks if the return type is left as default, the method is not part of an
4535 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4537 fn suggest_missing_return_type(
4539 err: &mut DiagnosticBuilder<'tcx>,
4540 fn_decl: &hir::FnDecl,
4545 // Only suggest changing the return type for methods that
4546 // haven't set a return type at all (and aren't `fn main()` or an impl).
4547 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4548 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4549 err.span_suggestion(
4551 "try adding a return type",
4552 format!("-> {} ", self.resolve_vars_with_obligations(found)),
4553 Applicability::MachineApplicable);
4556 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4557 err.span_label(span, "possibly return type missing here?");
4560 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4561 // `fn main()` must return `()`, do not suggest changing return type
4562 err.span_label(span, "expected `()` because of default return type");
4565 // expectation was caused by something else, not the default return
4566 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4567 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4568 // Only point to return type if the expected type is the return type, as if they
4569 // are not, the expectation must have been caused by something else.
4570 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
4572 let ty = AstConv::ast_ty_to_ty(self, ty);
4573 debug!("suggest_missing_return_type: return type {:?}", ty);
4574 debug!("suggest_missing_return_type: expected type {:?}", ty);
4575 if ty.kind == expected.kind {
4576 err.span_label(sp, format!("expected `{}` because of return type",
4585 /// A possible error is to forget to add `.await` when using futures:
4588 /// async fn make_u32() -> u32 {
4592 /// fn take_u32(x: u32) {}
4594 /// async fn foo() {
4595 /// let x = make_u32();
4600 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
4601 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
4602 /// `.await` to the tail of the expression.
4603 fn suggest_missing_await(
4605 err: &mut DiagnosticBuilder<'tcx>,
4610 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
4611 // body isn't `async`.
4612 let item_id = self.tcx().hir().get_parent_node(self.body_id);
4613 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
4614 let body = self.tcx().hir().body(body_id);
4615 if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
4617 // Check for `Future` implementations by constructing a predicate to
4618 // prove: `<T as Future>::Output == U`
4619 let future_trait = self.tcx.lang_items().future_trait().unwrap();
4620 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
4621 let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
4622 // `<T as Future>::Output`
4623 projection_ty: ty::ProjectionTy {
4625 substs: self.tcx.mk_substs_trait(
4627 self.fresh_substs_for_item(sp, item_def_id)
4634 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
4635 if self.infcx.predicate_may_hold(&obligation) {
4636 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
4637 err.span_suggestion(
4639 "consider using `.await` here",
4640 format!("{}.await", code),
4641 Applicability::MaybeIncorrect,
4649 /// A common error is to add an extra semicolon:
4652 /// fn foo() -> usize {
4657 /// This routine checks if the final statement in a block is an
4658 /// expression with an explicit semicolon whose type is compatible
4659 /// with `expected_ty`. If so, it suggests removing the semicolon.
4660 fn consider_hint_about_removing_semicolon(
4662 blk: &'tcx hir::Block,
4663 expected_ty: Ty<'tcx>,
4664 err: &mut DiagnosticBuilder<'_>,
4666 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4667 err.span_suggestion(
4669 "consider removing this semicolon",
4671 Applicability::MachineApplicable,
4676 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4677 // Be helpful when the user wrote `{... expr;}` and
4678 // taking the `;` off is enough to fix the error.
4679 let last_stmt = blk.stmts.last()?;
4680 let last_expr = match last_stmt.kind {
4681 hir::StmtKind::Semi(ref e) => e,
4684 let last_expr_ty = self.node_ty(last_expr.hir_id);
4685 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4688 let original_span = original_sp(last_stmt.span, blk.span);
4689 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4692 // Instantiates the given path, which must refer to an item with the given
4693 // number of type parameters and type.
4694 pub fn instantiate_value_path(&self,
4695 segments: &[hir::PathSegment],
4696 self_ty: Option<Ty<'tcx>>,
4700 -> (Ty<'tcx>, Res) {
4702 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4711 let path_segs = match res {
4712 Res::Local(_) | Res::SelfCtor(_) => vec![],
4713 Res::Def(kind, def_id) =>
4714 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4715 _ => bug!("instantiate_value_path on {:?}", res),
4718 let mut user_self_ty = None;
4719 let mut is_alias_variant_ctor = false;
4721 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4722 if let Some(self_ty) = self_ty {
4723 let adt_def = self_ty.ty_adt_def().unwrap();
4724 user_self_ty = Some(UserSelfTy {
4725 impl_def_id: adt_def.did,
4728 is_alias_variant_ctor = true;
4731 Res::Def(DefKind::Method, def_id)
4732 | Res::Def(DefKind::AssocConst, def_id) => {
4733 let container = tcx.associated_item(def_id).container;
4734 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4736 ty::TraitContainer(trait_did) => {
4737 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4739 ty::ImplContainer(impl_def_id) => {
4740 if segments.len() == 1 {
4741 // `<T>::assoc` will end up here, and so
4742 // can `T::assoc`. It this came from an
4743 // inherent impl, we need to record the
4744 // `T` for posterity (see `UserSelfTy` for
4746 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4747 user_self_ty = Some(UserSelfTy {
4758 // Now that we have categorized what space the parameters for each
4759 // segment belong to, let's sort out the parameters that the user
4760 // provided (if any) into their appropriate spaces. We'll also report
4761 // errors if type parameters are provided in an inappropriate place.
4763 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4764 let generics_has_err = AstConv::prohibit_generics(
4765 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4766 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4773 if let Res::Local(hid) = res {
4774 let ty = self.local_ty(span, hid).decl_ty;
4775 let ty = self.normalize_associated_types_in(span, &ty);
4776 self.write_ty(hir_id, ty);
4780 if generics_has_err {
4781 // Don't try to infer type parameters when prohibited generic arguments were given.
4782 user_self_ty = None;
4785 // Now we have to compare the types that the user *actually*
4786 // provided against the types that were *expected*. If the user
4787 // did not provide any types, then we want to substitute inference
4788 // variables. If the user provided some types, we may still need
4789 // to add defaults. If the user provided *too many* types, that's
4792 let mut infer_args_for_err = FxHashSet::default();
4793 for &PathSeg(def_id, index) in &path_segs {
4794 let seg = &segments[index];
4795 let generics = tcx.generics_of(def_id);
4796 // Argument-position `impl Trait` is treated as a normal generic
4797 // parameter internally, but we don't allow users to specify the
4798 // parameter's value explicitly, so we have to do some error-
4800 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4805 false, // `is_method_call`
4807 if suppress_errors {
4808 infer_args_for_err.insert(index);
4809 self.set_tainted_by_errors(); // See issue #53251.
4813 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4814 tcx.generics_of(*def_id).has_self
4815 }).unwrap_or(false);
4817 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
4818 let ty = self.impl_self_ty(span, impl_def_id).ty;
4819 let adt_def = ty.ty_adt_def();
4822 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
4823 let variant = adt_def.non_enum_variant();
4824 let ctor_def_id = variant.ctor_def_id.unwrap();
4826 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
4831 let mut err = tcx.sess.struct_span_err(span,
4832 "the `Self` constructor can only be used with tuple or unit structs");
4833 if let Some(adt_def) = adt_def {
4834 match adt_def.adt_kind() {
4836 err.help("did you mean to use one of the enum's variants?");
4840 err.span_suggestion(
4842 "use curly brackets",
4843 String::from("Self { /* fields */ }"),
4844 Applicability::HasPlaceholders,
4851 return (tcx.types.err, res)
4857 let def_id = res.def_id();
4859 // The things we are substituting into the type should not contain
4860 // escaping late-bound regions, and nor should the base type scheme.
4861 let ty = tcx.type_of(def_id);
4863 let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
4869 // Provide the generic args, and whether types should be inferred.
4871 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4874 // If we've encountered an `impl Trait`-related error, we're just
4875 // going to infer the arguments for better error messages.
4876 if !infer_args_for_err.contains(&index) {
4877 // Check whether the user has provided generic arguments.
4878 if let Some(ref data) = segments[index].args {
4879 return (Some(data), segments[index].infer_args);
4882 return (None, segments[index].infer_args);
4887 // Provide substitutions for parameters for which (valid) arguments have been provided.
4889 match (¶m.kind, arg) {
4890 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4891 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4893 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4894 self.to_ty(ty).into()
4896 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4897 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4899 _ => unreachable!(),
4902 // Provide substitutions for parameters for which arguments are inferred.
4903 |substs, param, infer_args| {
4905 GenericParamDefKind::Lifetime => {
4906 self.re_infer(Some(param), span).unwrap().into()
4908 GenericParamDefKind::Type { has_default, .. } => {
4909 if !infer_args && has_default {
4910 // If we have a default, then we it doesn't matter that we're not
4911 // inferring the type arguments: we provide the default where any
4913 let default = tcx.type_of(param.def_id);
4916 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4919 // If no type arguments were provided, we have to infer them.
4920 // This case also occurs as a result of some malformed input, e.g.
4921 // a lifetime argument being given instead of a type parameter.
4922 // Using inference instead of `Error` gives better error messages.
4923 self.var_for_def(span, param)
4926 GenericParamDefKind::Const => {
4927 // FIXME(const_generics:defaults)
4928 // No const parameters were provided, we have to infer them.
4929 self.var_for_def(span, param)
4934 assert!(!substs.has_escaping_bound_vars());
4935 assert!(!ty.has_escaping_bound_vars());
4937 // First, store the "user substs" for later.
4938 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4940 self.add_required_obligations(span, def_id, &substs);
4942 // Substitute the values for the type parameters into the type of
4943 // the referenced item.
4944 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4946 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4947 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4948 // is inherent, there is no `Self` parameter; instead, the impl needs
4949 // type parameters, which we can infer by unifying the provided `Self`
4950 // with the substituted impl type.
4951 // This also occurs for an enum variant on a type alias.
4952 let ty = tcx.type_of(impl_def_id);
4954 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4955 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4956 Ok(ok) => self.register_infer_ok_obligations(ok),
4958 self.tcx.sess.delay_span_bug(span, &format!(
4959 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4967 self.check_rustc_args_require_const(def_id, hir_id, span);
4969 debug!("instantiate_value_path: type of {:?} is {:?}",
4972 self.write_substs(hir_id, substs);
4974 (ty_substituted, res)
4977 /// Add all the obligations that are required, substituting and normalized appropriately.
4978 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
4979 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
4981 for (i, mut obligation) in traits::predicates_for_generics(
4982 traits::ObligationCause::new(
4985 traits::ItemObligation(def_id),
4989 ).into_iter().enumerate() {
4990 // This makes the error point at the bound, but we want to point at the argument
4991 if let Some(span) = spans.get(i) {
4992 obligation.cause.code = traits::BindingObligation(def_id, *span);
4994 self.register_predicate(obligation);
4998 fn check_rustc_args_require_const(&self,
5002 // We're only interested in functions tagged with
5003 // #[rustc_args_required_const], so ignore anything that's not.
5004 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
5008 // If our calling expression is indeed the function itself, we're good!
5009 // If not, generate an error that this can only be called directly.
5010 if let Node::Expr(expr) = self.tcx.hir().get(
5011 self.tcx.hir().get_parent_node(hir_id))
5013 if let ExprKind::Call(ref callee, ..) = expr.kind {
5014 if callee.hir_id == hir_id {
5020 self.tcx.sess.span_err(span, "this function can only be invoked \
5021 directly, not through a function pointer");
5024 // Resolves `typ` by a single level if `typ` is a type variable.
5025 // If no resolution is possible, then an error is reported.
5026 // Numeric inference variables may be left unresolved.
5027 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5028 let ty = self.resolve_vars_with_obligations(ty);
5029 if !ty.is_ty_var() {
5032 if !self.is_tainted_by_errors() {
5033 self.need_type_info_err((**self).body_id, sp, ty)
5034 .note("type must be known at this point")
5037 self.demand_suptype(sp, self.tcx.types.err, ty);
5042 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
5045 ctxt: BreakableCtxt<'tcx>,
5047 ) -> (BreakableCtxt<'tcx>, R) {
5050 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5051 index = enclosing_breakables.stack.len();
5052 enclosing_breakables.by_id.insert(id, index);
5053 enclosing_breakables.stack.push(ctxt);
5057 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5058 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5059 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5060 enclosing_breakables.stack.pop().expect("missing breakable context")
5065 /// Instantiate a QueryResponse in a probe context, without a
5066 /// good ObligationCause.
5067 fn probe_instantiate_query_response(
5070 original_values: &OriginalQueryValues<'tcx>,
5071 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5072 ) -> InferResult<'tcx, Ty<'tcx>>
5074 self.instantiate_query_response_and_region_obligations(
5075 &traits::ObligationCause::misc(span, self.body_id),
5081 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
5082 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
5083 let mut contained_in_place = false;
5085 while let hir::Node::Expr(parent_expr) =
5086 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
5088 match &parent_expr.kind {
5089 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
5090 if lhs.hir_id == expr_id {
5091 contained_in_place = true;
5097 expr_id = parent_expr.hir_id;
5104 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
5105 let own_counts = generics.own_counts();
5107 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
5113 if own_counts.types == 0 {
5117 // Make a vector of booleans initially `false`; set to `true` when used.
5118 let mut types_used = vec![false; own_counts.types];
5120 for leaf_ty in ty.walk() {
5121 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.kind {
5122 debug!("found use of ty param num {}", index);
5123 types_used[index as usize - own_counts.lifetimes] = true;
5124 } else if let ty::Error = leaf_ty.kind {
5125 // If there is already another error, do not emit
5126 // an error for not using a type parameter.
5127 assert!(tcx.sess.has_errors());
5132 let types = generics.params.iter().filter(|param| match param.kind {
5133 ty::GenericParamDefKind::Type { .. } => true,
5136 for (&used, param) in types_used.iter().zip(types) {
5138 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5139 let span = tcx.hir().span(id);
5140 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5141 .span_label(span, "unused type parameter")
5147 fn fatally_break_rust(sess: &Session) {
5148 let handler = sess.diagnostic();
5149 handler.span_bug_no_panic(
5151 "It looks like you're trying to break rust; would you like some ICE?",
5153 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5154 handler.note_without_error(
5155 "we would appreciate a joke overview: \
5156 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5158 handler.note_without_error(&format!("rustc {} running on {}",
5159 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5160 crate::session::config::host_triple(),
5164 fn potentially_plural_count(count: usize, word: &str) -> String {
5165 format!("{} {}{}", count, word, pluralise!(count))