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_data_structures::indexed_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::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
120 use rustc::ty::util::{Representability, IntTypeExt, Discr};
121 use rustc::ty::layout::VariantIdx;
122 use syntax_pos::{self, BytePos, Span, MultiSpan};
123 use syntax_pos::hygiene::DesugaringKind;
126 use syntax::feature_gate::{GateIssue, emit_feature_err};
127 use syntax::source_map::{DUMMY_SP, original_sp};
128 use syntax::symbol::{kw, sym};
130 use std::cell::{Cell, RefCell, Ref, RefMut};
131 use std::collections::hash_map::Entry;
134 use std::mem::replace;
135 use std::ops::{self, Deref};
138 use crate::require_c_abi_if_c_variadic;
139 use crate::session::Session;
140 use crate::session::config::EntryFnType;
141 use crate::TypeAndSubsts;
143 use crate::util::captures::Captures;
144 use crate::util::common::{ErrorReported, indenter};
145 use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashSet, HirIdMap};
147 pub use self::Expectation::*;
148 use self::autoderef::Autoderef;
149 use self::callee::DeferredCallResolution;
150 use self::coercion::{CoerceMany, DynamicCoerceMany};
151 pub use self::compare_method::{compare_impl_method, compare_const_impl};
152 use self::method::{MethodCallee, SelfSource};
153 use self::TupleArgumentsFlag::*;
155 /// The type of a local binding, including the revealed type for anon types.
156 #[derive(Copy, Clone, Debug)]
157 pub struct LocalTy<'tcx> {
159 revealed_ty: Ty<'tcx>
162 /// A wrapper for `InferCtxt`'s `in_progress_tables` field.
163 #[derive(Copy, Clone)]
164 struct MaybeInProgressTables<'a, 'tcx> {
165 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
168 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
169 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
170 match self.maybe_tables {
171 Some(tables) => tables.borrow(),
173 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
178 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
179 match self.maybe_tables {
180 Some(tables) => tables.borrow_mut(),
182 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
188 /// Closures defined within the function. For example:
191 /// bar(move|| { ... })
194 /// Here, the function `foo()` and the closure passed to
195 /// `bar()` will each have their own `FnCtxt`, but they will
196 /// share the inherited fields.
197 pub struct Inherited<'a, 'tcx> {
198 infcx: InferCtxt<'a, 'tcx>,
200 tables: MaybeInProgressTables<'a, 'tcx>,
202 locals: RefCell<HirIdMap<LocalTy<'tcx>>>,
204 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
206 // Some additional `Sized` obligations badly affect type inference.
207 // These obligations are added in a later stage of typeck.
208 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
210 // When we process a call like `c()` where `c` is a closure type,
211 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
212 // `FnOnce` closure. In that case, we defer full resolution of the
213 // call until upvar inference can kick in and make the
214 // decision. We keep these deferred resolutions grouped by the
215 // def-id of the closure, so that once we decide, we can easily go
216 // back and process them.
217 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'tcx>>>>,
219 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
221 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
223 // Opaque types found in explicit return types and their
224 // associated fresh inference variable. Writeback resolves these
225 // variables to get the concrete type, which can be used to
226 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
227 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
229 /// Each type parameter has an implicit region bound that
230 /// indicates it must outlive at least the function body (the user
231 /// may specify stronger requirements). This field indicates the
232 /// region of the callee. If it is `None`, then the parameter
233 /// environment is for an item or something where the "callee" is
235 implicit_region_bound: Option<ty::Region<'tcx>>,
237 body_id: Option<hir::BodyId>,
240 impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
241 type Target = InferCtxt<'a, 'tcx>;
242 fn deref(&self) -> &Self::Target {
247 /// When type-checking an expression, we propagate downward
248 /// whatever type hint we are able in the form of an `Expectation`.
249 #[derive(Copy, Clone, Debug)]
250 pub enum Expectation<'tcx> {
251 /// We know nothing about what type this expression should have.
254 /// This expression should have the type given (or some subtype).
255 ExpectHasType(Ty<'tcx>),
257 /// This expression will be cast to the `Ty`.
258 ExpectCastableToType(Ty<'tcx>),
260 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
261 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
262 ExpectRvalueLikeUnsized(Ty<'tcx>),
265 impl<'a, 'tcx> Expectation<'tcx> {
266 // Disregard "castable to" expectations because they
267 // can lead us astray. Consider for example `if cond
268 // {22} else {c} as u8` -- if we propagate the
269 // "castable to u8" constraint to 22, it will pick the
270 // type 22u8, which is overly constrained (c might not
271 // be a u8). In effect, the problem is that the
272 // "castable to" expectation is not the tightest thing
273 // we can say, so we want to drop it in this case.
274 // The tightest thing we can say is "must unify with
275 // else branch". Note that in the case of a "has type"
276 // constraint, this limitation does not hold.
278 // If the expected type is just a type variable, then don't use
279 // an expected type. Otherwise, we might write parts of the type
280 // when checking the 'then' block which are incompatible with the
282 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
284 ExpectHasType(ety) => {
285 let ety = fcx.shallow_resolve(ety);
286 if !ety.is_ty_var() {
292 ExpectRvalueLikeUnsized(ety) => {
293 ExpectRvalueLikeUnsized(ety)
299 /// Provides an expectation for an rvalue expression given an *optional*
300 /// hint, which is not required for type safety (the resulting type might
301 /// be checked higher up, as is the case with `&expr` and `box expr`), but
302 /// is useful in determining the concrete type.
304 /// The primary use case is where the expected type is a fat pointer,
305 /// like `&[isize]`. For example, consider the following statement:
307 /// let x: &[isize] = &[1, 2, 3];
309 /// In this case, the expected type for the `&[1, 2, 3]` expression is
310 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
311 /// expectation `ExpectHasType([isize])`, that would be too strong --
312 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
313 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
314 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
315 /// which still is useful, because it informs integer literals and the like.
316 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
317 /// for examples of where this comes up,.
318 fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
319 match fcx.tcx.struct_tail_without_normalization(ty).sty {
320 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
321 ExpectRvalueLikeUnsized(ty)
323 _ => ExpectHasType(ty)
327 // Resolves `expected` by a single level if it is a variable. If
328 // there is no expected type or resolution is not possible (e.g.,
329 // no constraints yet present), just returns `None`.
330 fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
332 NoExpectation => NoExpectation,
333 ExpectCastableToType(t) => {
334 ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
336 ExpectHasType(t) => {
337 ExpectHasType(fcx.resolve_vars_if_possible(&t))
339 ExpectRvalueLikeUnsized(t) => {
340 ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
345 fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
346 match self.resolve(fcx) {
347 NoExpectation => None,
348 ExpectCastableToType(ty) |
350 ExpectRvalueLikeUnsized(ty) => Some(ty),
354 /// It sometimes happens that we want to turn an expectation into
355 /// a **hard constraint** (i.e., something that must be satisfied
356 /// for the program to type-check). `only_has_type` will return
357 /// such a constraint, if it exists.
358 fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
359 match self.resolve(fcx) {
360 ExpectHasType(ty) => Some(ty),
361 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
365 /// Like `only_has_type`, but instead of returning `None` if no
366 /// hard constraint exists, creates a fresh type variable.
367 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
368 self.only_has_type(fcx)
370 fcx.next_ty_var(TypeVariableOrigin {
371 kind: TypeVariableOriginKind::MiscVariable,
378 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
385 fn maybe_mut_place(m: hir::Mutability) -> Self {
387 hir::MutMutable => Needs::MutPlace,
388 hir::MutImmutable => Needs::None,
393 #[derive(Copy, Clone)]
394 pub struct UnsafetyState {
396 pub unsafety: hir::Unsafety,
397 pub unsafe_push_count: u32,
402 pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
403 UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
406 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
407 match self.unsafety {
408 // If this unsafe, then if the outer function was already marked as
409 // unsafe we shouldn't attribute the unsafe'ness to the block. This
410 // way the block can be warned about instead of ignoring this
411 // extraneous block (functions are never warned about).
412 hir::Unsafety::Unsafe if self.from_fn => *self,
415 let (unsafety, def, count) = match blk.rules {
416 hir::PushUnsafeBlock(..) =>
417 (unsafety, blk.hir_id, self.unsafe_push_count.checked_add(1).unwrap()),
418 hir::PopUnsafeBlock(..) =>
419 (unsafety, blk.hir_id, self.unsafe_push_count.checked_sub(1).unwrap()),
420 hir::UnsafeBlock(..) =>
421 (hir::Unsafety::Unsafe, blk.hir_id, self.unsafe_push_count),
423 (unsafety, self.def, self.unsafe_push_count),
427 unsafe_push_count: count,
434 #[derive(Debug, Copy, Clone)]
440 /// Tracks whether executing a node may exit normally (versus
441 /// return/break/panic, which "diverge", leaving dead code in their
442 /// wake). Tracked semi-automatically (through type variables marked
443 /// as diverging), with some manual adjustments for control-flow
444 /// primitives (approximating a CFG).
445 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
447 /// Potentially unknown, some cases converge,
448 /// others require a CFG to determine them.
451 /// Definitely known to diverge and therefore
452 /// not reach the next sibling or its parent.
454 /// The `Span` points to the expression
455 /// that caused us to diverge
456 /// (e.g. `return`, `break`, etc).
458 /// In some cases (e.g. a `match` expression
459 /// where all arms diverge), we may be
460 /// able to provide a more informative
461 /// message to the user.
462 /// If this is `None`, a default messsage
463 /// will be generated, which is suitable
465 custom_note: Option<&'static str>
468 /// Same as `Always` but with a reachability
469 /// warning already emitted.
473 // Convenience impls for combinig `Diverges`.
475 impl ops::BitAnd for Diverges {
477 fn bitand(self, other: Self) -> Self {
478 cmp::min(self, other)
482 impl ops::BitOr for Diverges {
484 fn bitor(self, other: Self) -> Self {
485 cmp::max(self, other)
489 impl ops::BitAndAssign for Diverges {
490 fn bitand_assign(&mut self, other: Self) {
491 *self = *self & other;
495 impl ops::BitOrAssign for Diverges {
496 fn bitor_assign(&mut self, other: Self) {
497 *self = *self | other;
502 /// Creates a `Diverges::Always` with the provided `span` and the default note message.
503 fn always(span: Span) -> Diverges {
510 fn is_always(self) -> bool {
511 // Enum comparison ignores the
512 // contents of fields, so we just
513 // fill them in with garbage here.
514 self >= Diverges::Always {
521 pub struct BreakableCtxt<'tcx> {
524 // this is `null` for loops where break with a value is illegal,
525 // such as `while`, `for`, and `while let`
526 coerce: Option<DynamicCoerceMany<'tcx>>,
529 pub struct EnclosingBreakables<'tcx> {
530 stack: Vec<BreakableCtxt<'tcx>>,
531 by_id: HirIdMap<usize>,
534 impl<'tcx> EnclosingBreakables<'tcx> {
535 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
536 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
537 bug!("could not find enclosing breakable with id {}", target_id);
543 pub struct FnCtxt<'a, 'tcx> {
546 /// The parameter environment used for proving trait obligations
547 /// in this function. This can change when we descend into
548 /// closures (as they bring new things into scope), hence it is
549 /// not part of `Inherited` (as of the time of this writing,
550 /// closures do not yet change the environment, but they will
552 param_env: ty::ParamEnv<'tcx>,
554 /// Number of errors that had been reported when we started
555 /// checking this function. On exit, if we find that *more* errors
556 /// have been reported, we will skip regionck and other work that
557 /// expects the types within the function to be consistent.
558 // FIXME(matthewjasper) This should not exist, and it's not correct
559 // if type checking is run in parallel.
560 err_count_on_creation: usize,
562 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
563 ret_coercion_span: RefCell<Option<Span>>,
565 yield_ty: Option<Ty<'tcx>>,
567 ps: RefCell<UnsafetyState>,
569 /// Whether the last checked node generates a divergence (e.g.,
570 /// `return` will set this to `Always`). In general, when entering
571 /// an expression or other node in the tree, the initial value
572 /// indicates whether prior parts of the containing expression may
573 /// have diverged. It is then typically set to `Maybe` (and the
574 /// old value remembered) for processing the subparts of the
575 /// current expression. As each subpart is processed, they may set
576 /// the flag to `Always`, etc. Finally, at the end, we take the
577 /// result and "union" it with the original value, so that when we
578 /// return the flag indicates if any subpart of the parent
579 /// expression (up to and including this part) has diverged. So,
580 /// if you read it after evaluating a subexpression `X`, the value
581 /// you get indicates whether any subexpression that was
582 /// evaluating up to and including `X` diverged.
584 /// We currently use this flag only for diagnostic purposes:
586 /// - To warn about unreachable code: if, after processing a
587 /// sub-expression but before we have applied the effects of the
588 /// current node, we see that the flag is set to `Always`, we
589 /// can issue a warning. This corresponds to something like
590 /// `foo(return)`; we warn on the `foo()` expression. (We then
591 /// update the flag to `WarnedAlways` to suppress duplicate
592 /// reports.) Similarly, if we traverse to a fresh statement (or
593 /// tail expression) from a `Always` setting, we will issue a
594 /// warning. This corresponds to something like `{return;
595 /// foo();}` or `{return; 22}`, where we would warn on the
598 /// An expression represents dead code if, after checking it,
599 /// the diverges flag is set to something other than `Maybe`.
600 diverges: Cell<Diverges>,
602 /// Whether any child nodes have any type errors.
603 has_errors: Cell<bool>,
605 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
607 inh: &'a Inherited<'a, 'tcx>,
610 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
611 type Target = Inherited<'a, 'tcx>;
612 fn deref(&self) -> &Self::Target {
617 /// Helper type of a temporary returned by `Inherited::build(...)`.
618 /// Necessary because we can't write the following bound:
619 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
620 pub struct InheritedBuilder<'tcx> {
621 infcx: infer::InferCtxtBuilder<'tcx>,
625 impl Inherited<'_, 'tcx> {
626 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
627 let hir_id_root = if def_id.is_local() {
628 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
629 DefId::local(hir_id.owner)
635 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
641 impl<'tcx> InheritedBuilder<'tcx> {
642 fn enter<F, R>(&mut self, f: F) -> R
644 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
646 let def_id = self.def_id;
647 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
651 impl Inherited<'a, 'tcx> {
652 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
654 let item_id = tcx.hir().as_local_hir_id(def_id);
655 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
656 let implicit_region_bound = body_id.map(|body_id| {
657 let body = tcx.hir().body(body_id);
658 tcx.mk_region(ty::ReScope(region::Scope {
659 id: body.value.hir_id.local_id,
660 data: region::ScopeData::CallSite
665 tables: MaybeInProgressTables {
666 maybe_tables: infcx.in_progress_tables,
669 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
670 locals: RefCell::new(Default::default()),
671 deferred_sized_obligations: RefCell::new(Vec::new()),
672 deferred_call_resolutions: RefCell::new(Default::default()),
673 deferred_cast_checks: RefCell::new(Vec::new()),
674 deferred_generator_interiors: RefCell::new(Vec::new()),
675 opaque_types: RefCell::new(Default::default()),
676 implicit_region_bound,
681 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
682 debug!("register_predicate({:?})", obligation);
683 if obligation.has_escaping_bound_vars() {
684 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
689 .register_predicate_obligation(self, obligation);
692 fn register_predicates<I>(&self, obligations: I)
693 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
695 for obligation in obligations {
696 self.register_predicate(obligation);
700 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
701 self.register_predicates(infer_ok.obligations);
705 fn normalize_associated_types_in<T>(&self,
708 param_env: ty::ParamEnv<'tcx>,
710 where T : TypeFoldable<'tcx>
712 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
713 self.register_infer_ok_obligations(ok)
717 struct CheckItemTypesVisitor<'tcx> {
721 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
722 fn visit_item(&mut self, i: &'tcx hir::Item) {
723 check_item_type(self.tcx, i);
725 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
726 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
729 pub fn check_wf_new(tcx: TyCtxt<'_>) {
730 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
731 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
734 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
735 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
738 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
739 debug_assert!(crate_num == LOCAL_CRATE);
740 tcx.par_body_owners(|body_owner_def_id| {
741 tcx.ensure().typeck_tables_of(body_owner_def_id);
745 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
746 wfcheck::check_item_well_formed(tcx, def_id);
749 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
750 wfcheck::check_trait_item(tcx, def_id);
753 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
754 wfcheck::check_impl_item(tcx, def_id);
757 pub fn provide(providers: &mut Providers<'_>) {
758 method::provide(providers);
759 *providers = Providers {
765 check_item_well_formed,
766 check_trait_item_well_formed,
767 check_impl_item_well_formed,
768 check_mod_item_types,
773 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
774 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
777 /// If this `DefId` is a "primary tables entry", returns
778 /// `Some((body_id, header, decl))` with information about
779 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
782 /// If this function returns `Some`, then `typeck_tables(def_id)` will
783 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
784 /// may not succeed. In some cases where this function returns `None`
785 /// (notably closures), `typeck_tables(def_id)` would wind up
786 /// redirecting to the owning function.
790 ) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
791 match tcx.hir().get(id) {
792 Node::Item(item) => {
794 hir::ItemKind::Const(ref ty, body) |
795 hir::ItemKind::Static(ref ty, _, body) =>
796 Some((body, Some(ty), None, None)),
797 hir::ItemKind::Fn(ref decl, ref header, .., body) =>
798 Some((body, None, Some(header), Some(decl))),
803 Node::TraitItem(item) => {
805 hir::TraitItemKind::Const(ref ty, Some(body)) =>
806 Some((body, Some(ty), None, None)),
807 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
808 Some((body, None, Some(&sig.header), Some(&sig.decl))),
813 Node::ImplItem(item) => {
815 hir::ImplItemKind::Const(ref ty, body) =>
816 Some((body, Some(ty), None, None)),
817 hir::ImplItemKind::Method(ref sig, body) =>
818 Some((body, None, Some(&sig.header), Some(&sig.decl))),
823 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
828 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
829 // Closures' tables come from their outermost function,
830 // as they are part of the same "inference environment".
831 let outer_def_id = tcx.closure_base_def_id(def_id);
832 if outer_def_id != def_id {
833 return tcx.has_typeck_tables(outer_def_id);
836 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
837 primary_body_of(tcx, id).is_some()
840 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
841 &*tcx.typeck_tables_of(def_id).used_trait_imports
844 fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
845 // Closures' tables come from their outermost function,
846 // as they are part of the same "inference environment".
847 let outer_def_id = tcx.closure_base_def_id(def_id);
848 if outer_def_id != def_id {
849 return tcx.typeck_tables_of(outer_def_id);
852 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
853 let span = tcx.hir().span(id);
855 // Figure out what primary body this item has.
856 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
858 span_bug!(span, "can't type-check body of {:?}", def_id);
860 let body = tcx.hir().body(body_id);
862 let tables = Inherited::build(tcx, def_id).enter(|inh| {
863 let param_env = tcx.param_env(def_id);
864 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
865 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
866 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
867 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl)
872 check_abi(tcx, span, fn_sig.abi());
874 // Compute the fty from point of view of inside the fn.
876 tcx.liberate_late_bound_regions(def_id, &fn_sig);
878 inh.normalize_associated_types_in(body.value.span,
883 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
886 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
887 let expected_type = body_ty.and_then(|ty| match ty.node {
888 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
890 }).unwrap_or_else(|| tcx.type_of(def_id));
891 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
892 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
894 let revealed_ty = if tcx.features().impl_trait_in_bindings {
895 fcx.instantiate_opaque_types_from_value(
904 // Gather locals in statics (because of block expressions).
905 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
907 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
909 fcx.write_ty(id, revealed_ty);
914 // All type checking constraints were added, try to fallback unsolved variables.
915 fcx.select_obligations_where_possible(false, |_| {});
916 let mut fallback_has_occurred = false;
917 for ty in &fcx.unsolved_variables() {
918 fallback_has_occurred |= fcx.fallback_if_possible(ty);
920 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
922 // Even though coercion casts provide type hints, we check casts after fallback for
923 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
926 // Closure and generator analysis may run after fallback
927 // because they don't constrain other type variables.
928 fcx.closure_analyze(body);
929 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
930 fcx.resolve_generator_interiors(def_id);
932 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
933 let ty = fcx.normalize_ty(span, ty);
934 fcx.require_type_is_sized(ty, span, code);
936 fcx.select_all_obligations_or_error();
938 if fn_decl.is_some() {
939 fcx.regionck_fn(id, body);
941 fcx.regionck_expr(body);
944 fcx.resolve_type_vars_in_body(body)
947 // Consistency check our TypeckTables instance can hold all ItemLocalIds
948 // it will need to hold.
949 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
954 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
955 if !tcx.sess.target.target.is_abi_supported(abi) {
956 struct_span_err!(tcx.sess, span, E0570,
957 "The ABI `{}` is not supported for the current target", abi).emit()
961 struct GatherLocalsVisitor<'a, 'tcx> {
962 fcx: &'a FnCtxt<'a, 'tcx>,
963 parent_id: hir::HirId,
966 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
967 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
970 // infer the variable's type
971 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
972 kind: TypeVariableOriginKind::TypeInference,
975 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
982 // take type that the user specified
983 self.fcx.locals.borrow_mut().insert(nid, typ);
990 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
991 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
992 NestedVisitorMap::None
995 // Add explicitly-declared locals.
996 fn visit_local(&mut self, local: &'tcx hir::Local) {
997 let local_ty = match local.ty {
999 let o_ty = self.fcx.to_ty(&ty);
1001 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
1002 self.fcx.instantiate_opaque_types_from_value(
1011 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
1012 &UserType::Ty(revealed_ty)
1014 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
1015 ty.hir_id, o_ty, revealed_ty, c_ty);
1016 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
1018 Some(LocalTy { decl_ty: o_ty, revealed_ty })
1022 self.assign(local.span, local.hir_id, local_ty);
1024 debug!("local variable {:?} is assigned type {}",
1026 self.fcx.ty_to_string(
1027 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
1028 intravisit::walk_local(self, local);
1031 // Add pattern bindings.
1032 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
1033 if let PatKind::Binding(_, _, ident, _) = p.node {
1034 let var_ty = self.assign(p.span, p.hir_id, None);
1036 if !self.fcx.tcx.features().unsized_locals {
1037 self.fcx.require_type_is_sized(var_ty, p.span,
1038 traits::VariableType(p.hir_id));
1041 debug!("pattern binding {} is assigned to {} with type {:?}",
1043 self.fcx.ty_to_string(
1044 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1047 intravisit::walk_pat(self, p);
1050 // Don't descend into the bodies of nested closures
1053 _: intravisit::FnKind<'tcx>,
1054 _: &'tcx hir::FnDecl,
1061 /// When `check_fn` is invoked on a generator (i.e., a body that
1062 /// includes yield), it returns back some information about the yield
1064 struct GeneratorTypes<'tcx> {
1065 /// Type of value that is yielded.
1068 /// Types that are captured (see `GeneratorInterior` for more).
1071 /// Indicates if the generator is movable or static (immovable).
1072 movability: hir::GeneratorMovability,
1075 /// Helper used for fns and closures. Does the grungy work of checking a function
1076 /// body and returns the function context used for that purpose, since in the case of a fn item
1077 /// there is still a bit more to do.
1080 /// * inherited: other fields inherited from the enclosing fn (if any)
1081 fn check_fn<'a, 'tcx>(
1082 inherited: &'a Inherited<'a, 'tcx>,
1083 param_env: ty::ParamEnv<'tcx>,
1084 fn_sig: ty::FnSig<'tcx>,
1085 decl: &'tcx hir::FnDecl,
1087 body: &'tcx hir::Body,
1088 can_be_generator: Option<hir::GeneratorMovability>,
1089 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1090 let mut fn_sig = fn_sig.clone();
1092 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1094 // Create the function context. This is either derived from scratch or,
1095 // in the case of closures, based on the outer context.
1096 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1097 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1099 let declared_ret_ty = fn_sig.output();
1100 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1101 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
1106 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1107 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1108 fn_sig = fcx.tcx.mk_fn_sig(
1109 fn_sig.inputs().iter().cloned(),
1116 let span = body.value.span;
1118 fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1120 if body.generator_kind.is_some() && can_be_generator.is_some() {
1121 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1122 kind: TypeVariableOriginKind::TypeInference,
1125 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1126 fcx.yield_ty = Some(yield_ty);
1129 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1130 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1131 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1133 // Add formal parameters.
1134 for (param_ty, param) in fn_sig.inputs().iter().zip(&body.params) {
1135 // Check the pattern.
1136 fcx.check_pat_top(¶m.pat, param_ty, None);
1138 // Check that argument is Sized.
1139 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1140 // for simple cases like `fn foo(x: Trait)`,
1141 // where we would error once on the parameter as a whole, and once on the binding `x`.
1142 if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1143 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1146 fcx.write_ty(param.hir_id, param_ty);
1149 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1151 fcx.check_return_expr(&body.value);
1153 // We insert the deferred_generator_interiors entry after visiting the body.
1154 // This ensures that all nested generators appear before the entry of this generator.
1155 // resolve_generator_interiors relies on this property.
1156 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1157 let interior = fcx.next_ty_var(TypeVariableOrigin {
1158 kind: TypeVariableOriginKind::MiscVariable,
1161 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1162 Some(GeneratorTypes {
1163 yield_ty: fcx.yield_ty.unwrap(),
1165 movability: can_be_generator.unwrap(),
1171 // Finalize the return check by taking the LUB of the return types
1172 // we saw and assigning it to the expected return type. This isn't
1173 // really expected to fail, since the coercions would have failed
1174 // earlier when trying to find a LUB.
1176 // However, the behavior around `!` is sort of complex. In the
1177 // event that the `actual_return_ty` comes back as `!`, that
1178 // indicates that the fn either does not return or "returns" only
1179 // values of type `!`. In this case, if there is an expected
1180 // return type that is *not* `!`, that should be ok. But if the
1181 // return type is being inferred, we want to "fallback" to `!`:
1183 // let x = move || panic!();
1185 // To allow for that, I am creating a type variable with diverging
1186 // fallback. This was deemed ever so slightly better than unifying
1187 // the return value with `!` because it allows for the caller to
1188 // make more assumptions about the return type (e.g., they could do
1190 // let y: Option<u32> = Some(x());
1192 // which would then cause this return type to become `u32`, not
1194 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1195 let mut actual_return_ty = coercion.complete(&fcx);
1196 if actual_return_ty.is_never() {
1197 actual_return_ty = fcx.next_diverging_ty_var(
1198 TypeVariableOrigin {
1199 kind: TypeVariableOriginKind::DivergingFn,
1204 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1206 // Check that the main return type implements the termination trait.
1207 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1208 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1209 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1210 if main_id == fn_id {
1211 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1212 let trait_ref = ty::TraitRef::new(term_id, substs);
1213 let return_ty_span = decl.output.span();
1214 let cause = traits::ObligationCause::new(
1215 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1217 inherited.register_predicate(
1218 traits::Obligation::new(
1219 cause, param_env, trait_ref.to_predicate()));
1224 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1225 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1226 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1227 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1228 // at this point we don't care if there are duplicate handlers or if the handler has
1229 // the wrong signature as this value we'll be used when writing metadata and that
1230 // only happens if compilation succeeded
1231 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1233 if declared_ret_ty.sty != ty::Never {
1234 fcx.tcx.sess.span_err(
1236 "return type should be `!`",
1240 let inputs = fn_sig.inputs();
1241 let span = fcx.tcx.hir().span(fn_id);
1242 if inputs.len() == 1 {
1243 let arg_is_panic_info = match inputs[0].sty {
1244 ty::Ref(region, ty, mutbl) => match ty.sty {
1245 ty::Adt(ref adt, _) => {
1246 adt.did == panic_info_did &&
1247 mutbl == hir::Mutability::MutImmutable &&
1248 *region != RegionKind::ReStatic
1255 if !arg_is_panic_info {
1256 fcx.tcx.sess.span_err(
1257 decl.inputs[0].span,
1258 "argument should be `&PanicInfo`",
1262 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1263 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1264 if !generics.params.is_empty() {
1265 fcx.tcx.sess.span_err(
1267 "should have no type parameters",
1273 let span = fcx.tcx.sess.source_map().def_span(span);
1274 fcx.tcx.sess.span_err(span, "function should have one argument");
1277 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1282 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1283 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1284 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1285 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1286 if declared_ret_ty.sty != ty::Never {
1287 fcx.tcx.sess.span_err(
1289 "return type should be `!`",
1293 let inputs = fn_sig.inputs();
1294 let span = fcx.tcx.hir().span(fn_id);
1295 if inputs.len() == 1 {
1296 let arg_is_alloc_layout = match inputs[0].sty {
1297 ty::Adt(ref adt, _) => {
1298 adt.did == alloc_layout_did
1303 if !arg_is_alloc_layout {
1304 fcx.tcx.sess.span_err(
1305 decl.inputs[0].span,
1306 "argument should be `Layout`",
1310 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1311 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1312 if !generics.params.is_empty() {
1313 fcx.tcx.sess.span_err(
1315 "`#[alloc_error_handler]` function should have no type \
1322 let span = fcx.tcx.sess.source_map().def_span(span);
1323 fcx.tcx.sess.span_err(span, "function should have one argument");
1326 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1334 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1335 let def_id = tcx.hir().local_def_id(id);
1336 let def = tcx.adt_def(def_id);
1337 def.destructor(tcx); // force the destructor to be evaluated
1338 check_representable(tcx, span, def_id);
1340 if def.repr.simd() {
1341 check_simd(tcx, span, def_id);
1344 check_transparent(tcx, span, def_id);
1345 check_packed(tcx, span, def_id);
1348 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1349 let def_id = tcx.hir().local_def_id(id);
1350 let def = tcx.adt_def(def_id);
1351 def.destructor(tcx); // force the destructor to be evaluated
1352 check_representable(tcx, span, def_id);
1353 check_transparent(tcx, span, def_id);
1354 check_packed(tcx, span, def_id);
1357 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1358 /// projections that would result in "inheriting lifetimes".
1359 fn check_opaque<'tcx>(
1362 substs: SubstsRef<'tcx>,
1364 origin: &hir::OpaqueTyOrigin,
1366 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1367 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1370 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1371 /// in "inheriting lifetimes".
1372 fn check_opaque_for_inheriting_lifetimes(
1377 let item = tcx.hir().expect_item(
1378 tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1379 debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1380 def_id, span, item);
1383 struct ProhibitOpaqueVisitor<'tcx> {
1384 opaque_identity_ty: Ty<'tcx>,
1385 generics: &'tcx ty::Generics,
1388 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1389 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1390 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1391 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1394 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1395 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1396 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1397 return *index < self.generics.parent_count as u32;
1400 r.super_visit_with(self)
1404 let prohibit_opaque = match item.node {
1405 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
1406 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1407 let mut visitor = ProhibitOpaqueVisitor {
1408 opaque_identity_ty: tcx.mk_opaque(
1409 def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1410 generics: tcx.generics_of(def_id),
1412 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1414 tcx.predicates_of(def_id).predicates.iter().any(
1415 |(predicate, _)| predicate.visit_with(&mut visitor))
1420 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1421 if prohibit_opaque {
1422 let is_async = match item.node {
1423 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1424 hir::OpaqueTyOrigin::AsyncFn => true,
1427 _ => unreachable!(),
1430 tcx.sess.span_err(span, &format!(
1431 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1433 if is_async { "async fn" } else { "impl Trait" },
1438 /// Checks that an opaque type does not contain cycles.
1439 fn check_opaque_for_cycles<'tcx>(
1442 substs: SubstsRef<'tcx>,
1444 origin: &hir::OpaqueTyOrigin,
1446 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1447 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1449 tcx.sess, span, E0733,
1450 "recursion in an `async fn` requires boxing",
1452 .span_label(span, "recursive `async fn`")
1453 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
1456 let mut err = struct_span_err!(
1457 tcx.sess, span, E0720,
1458 "opaque type expands to a recursive type",
1460 err.span_label(span, "expands to a recursive type");
1461 if let ty::Opaque(..) = partially_expanded_type.sty {
1462 err.note("type resolves to itself");
1464 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1471 // Forbid defining intrinsics in Rust code,
1472 // as they must always be defined by the compiler.
1473 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1474 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1475 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1479 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1481 "check_item_type(it.hir_id={}, it.name={})",
1483 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1485 let _indenter = indenter();
1487 // Consts can play a role in type-checking, so they are included here.
1488 hir::ItemKind::Static(..) => {
1489 let def_id = tcx.hir().local_def_id(it.hir_id);
1490 tcx.typeck_tables_of(def_id);
1491 maybe_check_static_with_link_section(tcx, def_id, it.span);
1493 hir::ItemKind::Const(..) => {
1494 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1496 hir::ItemKind::Enum(ref enum_definition, _) => {
1497 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1499 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1500 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1501 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1502 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1503 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1504 check_impl_items_against_trait(
1511 let trait_def_id = impl_trait_ref.def_id;
1512 check_on_unimplemented(tcx, trait_def_id, it);
1515 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1516 let def_id = tcx.hir().local_def_id(it.hir_id);
1517 check_on_unimplemented(tcx, def_id, it);
1519 for item in items.iter() {
1520 let item = tcx.hir().trait_item(item.id);
1521 if let hir::TraitItemKind::Method(sig, _) = &item.node {
1522 let abi = sig.header.abi;
1523 fn_maybe_err(tcx, item.ident.span, abi);
1527 hir::ItemKind::Struct(..) => {
1528 check_struct(tcx, it.hir_id, it.span);
1530 hir::ItemKind::Union(..) => {
1531 check_union(tcx, it.hir_id, it.span);
1533 hir::ItemKind::OpaqueTy(hir::OpaqueTy{origin, ..}) => {
1534 let def_id = tcx.hir().local_def_id(it.hir_id);
1536 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1537 check_opaque(tcx, def_id, substs, it.span, &origin);
1539 hir::ItemKind::TyAlias(..) => {
1540 let def_id = tcx.hir().local_def_id(it.hir_id);
1541 let pty_ty = tcx.type_of(def_id);
1542 let generics = tcx.generics_of(def_id);
1543 check_bounds_are_used(tcx, &generics, pty_ty);
1545 hir::ItemKind::ForeignMod(ref m) => {
1546 check_abi(tcx, it.span, m.abi);
1548 if m.abi == Abi::RustIntrinsic {
1549 for item in &m.items {
1550 intrinsic::check_intrinsic_type(tcx, item);
1552 } else if m.abi == Abi::PlatformIntrinsic {
1553 for item in &m.items {
1554 intrinsic::check_platform_intrinsic_type(tcx, item);
1557 for item in &m.items {
1558 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1559 let own_counts = generics.own_counts();
1560 if generics.params.len() - own_counts.lifetimes != 0 {
1561 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1562 (_, 0) => ("type", "types", Some("u32")),
1563 // We don't specify an example value, because we can't generate
1564 // a valid value for any type.
1565 (0, _) => ("const", "consts", None),
1566 _ => ("type or const", "types or consts", None),
1572 "foreign items may not have {} parameters",
1576 &format!("can't have {} parameters", kinds),
1578 // FIXME: once we start storing spans for type arguments, turn this
1579 // into a suggestion.
1581 "replace the {} parameters with concrete {}{}",
1584 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1589 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1590 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1595 _ => { /* nothing to do */ }
1599 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1600 // Only restricted on wasm32 target for now
1601 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1605 // If `#[link_section]` is missing, then nothing to verify
1606 let attrs = tcx.codegen_fn_attrs(id);
1607 if attrs.link_section.is_none() {
1611 // For the wasm32 target statics with `#[link_section]` are placed into custom
1612 // sections of the final output file, but this isn't link custom sections of
1613 // other executable formats. Namely we can only embed a list of bytes,
1614 // nothing with pointers to anything else or relocations. If any relocation
1615 // show up, reject them here.
1616 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1617 // the consumer's responsibility to ensure all bytes that have been read
1618 // have defined values.
1619 let instance = ty::Instance::mono(tcx, id);
1620 let cid = GlobalId {
1624 let param_env = ty::ParamEnv::reveal_all();
1625 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1626 let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1629 bug!("Matching on non-ByRef static")
1631 if alloc.relocations().len() != 0 {
1632 let msg = "statics with a custom `#[link_section]` must be a \
1633 simple list of bytes on the wasm target with no \
1634 extra levels of indirection such as references";
1635 tcx.sess.span_err(span, msg);
1640 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
1641 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1642 // an error would be reported if this fails.
1643 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1646 fn report_forbidden_specialization(
1648 impl_item: &hir::ImplItem,
1651 let mut err = struct_span_err!(
1652 tcx.sess, impl_item.span, E0520,
1653 "`{}` specializes an item from a parent `impl`, but \
1654 that item is not marked `default`",
1656 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1659 match tcx.span_of_impl(parent_impl) {
1661 err.span_label(span, "parent `impl` is here");
1662 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1666 err.note(&format!("parent implementation is in crate `{}`", cname));
1673 fn check_specialization_validity<'tcx>(
1675 trait_def: &ty::TraitDef,
1676 trait_item: &ty::AssocItem,
1678 impl_item: &hir::ImplItem,
1680 let ancestors = trait_def.ancestors(tcx, impl_id);
1682 let kind = match impl_item.node {
1683 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1684 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1685 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1686 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1689 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1690 .map(|node_item| node_item.map(|parent| parent.defaultness));
1692 if let Some(parent) = parent {
1693 if tcx.impl_item_is_final(&parent) {
1694 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1700 fn check_impl_items_against_trait<'tcx>(
1704 impl_trait_ref: ty::TraitRef<'tcx>,
1705 impl_item_refs: &[hir::ImplItemRef],
1707 let impl_span = tcx.sess.source_map().def_span(impl_span);
1709 // If the trait reference itself is erroneous (so the compilation is going
1710 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1711 // isn't populated for such impls.
1712 if impl_trait_ref.references_error() { return; }
1714 // Locate trait definition and items
1715 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1716 let mut overridden_associated_type = None;
1718 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1720 // Check existing impl methods to see if they are both present in trait
1721 // and compatible with trait signature
1722 for impl_item in impl_items() {
1723 let ty_impl_item = tcx.associated_item(
1724 tcx.hir().local_def_id(impl_item.hir_id));
1725 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1726 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1727 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1729 // Not compatible, but needed for the error message
1730 tcx.associated_items(impl_trait_ref.def_id)
1731 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1734 // Check that impl definition matches trait definition
1735 if let Some(ty_trait_item) = ty_trait_item {
1736 match impl_item.node {
1737 hir::ImplItemKind::Const(..) => {
1738 // Find associated const definition.
1739 if ty_trait_item.kind == ty::AssocKind::Const {
1740 compare_const_impl(tcx,
1746 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1747 "item `{}` is an associated const, \
1748 which doesn't match its trait `{}`",
1751 err.span_label(impl_item.span, "does not match trait");
1752 // We can only get the spans from local trait definition
1753 // Same for E0324 and E0325
1754 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1755 err.span_label(trait_span, "item in trait");
1760 hir::ImplItemKind::Method(..) => {
1761 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1762 if ty_trait_item.kind == ty::AssocKind::Method {
1763 compare_impl_method(tcx,
1770 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1771 "item `{}` is an associated method, \
1772 which doesn't match its trait `{}`",
1775 err.span_label(impl_item.span, "does not match trait");
1776 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1777 err.span_label(trait_span, "item in trait");
1782 hir::ImplItemKind::OpaqueTy(..) |
1783 hir::ImplItemKind::TyAlias(_) => {
1784 if ty_trait_item.kind == ty::AssocKind::Type {
1785 if ty_trait_item.defaultness.has_value() {
1786 overridden_associated_type = Some(impl_item);
1789 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1790 "item `{}` is an associated type, \
1791 which doesn't match its trait `{}`",
1794 err.span_label(impl_item.span, "does not match trait");
1795 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1796 err.span_label(trait_span, "item in trait");
1803 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1807 // Check for missing items from trait
1808 let mut missing_items = Vec::new();
1809 let mut invalidated_items = Vec::new();
1810 let associated_type_overridden = overridden_associated_type.is_some();
1811 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1812 let is_implemented = trait_def.ancestors(tcx, impl_id)
1813 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1815 .map(|node_item| !node_item.node.is_from_trait())
1818 if !is_implemented && !tcx.impl_is_default(impl_id) {
1819 if !trait_item.defaultness.has_value() {
1820 missing_items.push(trait_item);
1821 } else if associated_type_overridden {
1822 invalidated_items.push(trait_item.ident);
1827 if !missing_items.is_empty() {
1828 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1829 "not all trait items implemented, missing: `{}`",
1830 missing_items.iter()
1831 .map(|trait_item| trait_item.ident.to_string())
1832 .collect::<Vec<_>>().join("`, `"));
1833 err.span_label(impl_span, format!("missing `{}` in implementation",
1834 missing_items.iter()
1835 .map(|trait_item| trait_item.ident.to_string())
1836 .collect::<Vec<_>>().join("`, `")));
1837 for trait_item in missing_items {
1838 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1839 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1841 err.note_trait_signature(trait_item.ident.to_string(),
1842 trait_item.signature(tcx));
1848 if !invalidated_items.is_empty() {
1849 let invalidator = overridden_associated_type.unwrap();
1850 span_err!(tcx.sess, invalidator.span, E0399,
1851 "the following trait items need to be reimplemented \
1852 as `{}` was overridden: `{}`",
1854 invalidated_items.iter()
1855 .map(|name| name.to_string())
1856 .collect::<Vec<_>>().join("`, `"))
1860 /// Checks whether a type can be represented in memory. In particular, it
1861 /// identifies types that contain themselves without indirection through a
1862 /// pointer, which would mean their size is unbounded.
1863 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
1864 let rty = tcx.type_of(item_def_id);
1866 // Check that it is possible to represent this type. This call identifies
1867 // (1) types that contain themselves and (2) types that contain a different
1868 // recursive type. It is only necessary to throw an error on those that
1869 // contain themselves. For case 2, there must be an inner type that will be
1870 // caught by case 1.
1871 match rty.is_representable(tcx, sp) {
1872 Representability::SelfRecursive(spans) => {
1873 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1875 err.span_label(span, "recursive without indirection");
1880 Representability::Representable | Representability::ContainsRecursive => (),
1885 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1886 let t = tcx.type_of(def_id);
1887 if let ty::Adt(def, substs) = t.sty {
1888 if def.is_struct() {
1889 let fields = &def.non_enum_variant().fields;
1890 if fields.is_empty() {
1891 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1894 let e = fields[0].ty(tcx, substs);
1895 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1896 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1897 .span_label(sp, "SIMD elements must have the same type")
1902 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1903 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1905 span_err!(tcx.sess, sp, E0077,
1906 "SIMD vector element type should be machine type");
1914 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1915 let repr = tcx.adt_def(def_id).repr;
1917 for attr in tcx.get_attrs(def_id).iter() {
1918 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1919 if let attr::ReprPacked(pack) = r {
1920 if let Some(repr_pack) = repr.pack {
1921 if pack as u64 != repr_pack.bytes() {
1923 tcx.sess, sp, E0634,
1924 "type has conflicting packed representation hints"
1931 if repr.align.is_some() {
1932 struct_span_err!(tcx.sess, sp, E0587,
1933 "type has conflicting packed and align representation hints").emit();
1935 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1936 struct_span_err!(tcx.sess, sp, E0588,
1937 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1942 fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
1943 let t = tcx.type_of(def_id);
1944 if stack.contains(&def_id) {
1945 debug!("check_packed_inner: {:?} is recursive", t);
1948 if let ty::Adt(def, substs) = t.sty {
1949 if def.is_struct() || def.is_union() {
1950 if tcx.adt_def(def.did).repr.align.is_some() {
1953 // push struct def_id before checking fields
1955 for field in &def.non_enum_variant().fields {
1956 let f = field.ty(tcx, substs);
1957 if let ty::Adt(def, _) = f.sty {
1958 if check_packed_inner(tcx, def.did, stack) {
1963 // only need to pop if not early out
1970 /// Emit an error when encountering more or less than one variant in a transparent enum.
1971 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
1972 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
1973 tcx.hir().span_if_local(variant.def_id).unwrap()
1976 "needs exactly one variant, but has {}",
1979 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
1980 err.span_label(sp, &msg);
1981 if let &[ref start @ .., ref end] = &variant_spans[..] {
1982 for variant_span in start {
1983 err.span_label(*variant_span, "");
1985 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
1990 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
1992 fn bad_non_zero_sized_fields<'tcx>(
1994 adt: &'tcx ty::AdtDef,
1996 field_spans: impl Iterator<Item = Span>,
1999 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
2000 let mut err = struct_span_err!(
2004 "{}transparent {} {}",
2005 if adt.is_enum() { "the variant of a " } else { "" },
2009 err.span_label(sp, &msg);
2010 for sp in field_spans {
2011 err.span_label(sp, "this field is non-zero-sized");
2016 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
2017 let adt = tcx.adt_def(def_id);
2018 if !adt.repr.transparent() {
2021 let sp = tcx.sess.source_map().def_span(sp);
2024 if !tcx.features().transparent_enums {
2026 &tcx.sess.parse_sess,
2027 sym::transparent_enums,
2029 GateIssue::Language,
2030 "transparent enums are unstable",
2033 if adt.variants.len() != 1 {
2034 bad_variant_count(tcx, adt, sp, def_id);
2035 if adt.variants.is_empty() {
2036 // Don't bother checking the fields. No variants (and thus no fields) exist.
2042 if adt.is_union() && !tcx.features().transparent_unions {
2043 emit_feature_err(&tcx.sess.parse_sess,
2044 sym::transparent_unions,
2046 GateIssue::Language,
2047 "transparent unions are unstable");
2050 // For each field, figure out if it's known to be a ZST and align(1)
2051 let field_infos = adt.all_fields().map(|field| {
2052 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2053 let param_env = tcx.param_env(field.did);
2054 let layout = tcx.layout_of(param_env.and(ty));
2055 // We are currently checking the type this field came from, so it must be local
2056 let span = tcx.hir().span_if_local(field.did).unwrap();
2057 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2058 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2062 let non_zst_fields = field_infos.clone().filter_map(|(span, zst, _align1)| if !zst {
2067 let non_zst_count = non_zst_fields.clone().count();
2068 if non_zst_count != 1 {
2069 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2071 for (span, zst, align1) in field_infos {
2077 "zero-sized field in transparent {} has alignment larger than 1",
2079 ).span_label(span, "has alignment larger than 1").emit();
2084 #[allow(trivial_numeric_casts)]
2085 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
2086 let def_id = tcx.hir().local_def_id(id);
2087 let def = tcx.adt_def(def_id);
2088 def.destructor(tcx); // force the destructor to be evaluated
2091 let attributes = tcx.get_attrs(def_id);
2092 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2094 tcx.sess, attr.span, E0084,
2095 "unsupported representation for zero-variant enum")
2096 .span_label(sp, "zero-variant enum")
2101 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2102 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2103 if !tcx.features().repr128 {
2104 emit_feature_err(&tcx.sess.parse_sess,
2107 GateIssue::Language,
2108 "repr with 128-bit type is unstable");
2113 if let Some(ref e) = v.disr_expr {
2114 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2118 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2120 |var: &hir::Variant| match var.data {
2121 hir::VariantData::Unit(..) => true,
2125 let has_disr = |var: &hir::Variant| var.disr_expr.is_some();
2126 let has_non_units = vs.iter().any(|var| !is_unit(var));
2127 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2128 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2130 if disr_non_unit || (disr_units && has_non_units) {
2131 let mut err = struct_span_err!(tcx.sess, sp, E0732,
2132 "`#[repr(inttype)]` must be specified");
2137 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2138 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2139 // Check for duplicate discriminant values
2140 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2141 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2142 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2143 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2144 let i_span = match variant_i.disr_expr {
2145 Some(ref expr) => tcx.hir().span(expr.hir_id),
2146 None => tcx.hir().span(variant_i_hir_id)
2148 let span = match v.disr_expr {
2149 Some(ref expr) => tcx.hir().span(expr.hir_id),
2152 struct_span_err!(tcx.sess, span, E0081,
2153 "discriminant value `{}` already exists", disr_vals[i])
2154 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2155 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
2158 disr_vals.push(discr);
2161 check_representable(tcx, sp, def_id);
2162 check_transparent(tcx, sp, def_id);
2165 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
2166 span_err!(tcx.sess, span, E0533,
2167 "expected unit struct/variant or constant, found {} `{}`",
2169 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
2172 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2173 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2177 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
2178 -> &'tcx ty::GenericPredicates<'tcx>
2181 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2182 let item_id = tcx.hir().ty_param_owner(hir_id);
2183 let item_def_id = tcx.hir().local_def_id(item_id);
2184 let generics = tcx.generics_of(item_def_id);
2185 let index = generics.param_def_id_to_index[&def_id];
2186 tcx.arena.alloc(ty::GenericPredicates {
2188 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
2190 ty::Predicate::Trait(ref data)
2191 if data.skip_binder().self_ty().is_param(index) => {
2192 // HACK(eddyb) should get the original `Span`.
2193 let span = tcx.def_span(def_id);
2194 Some((predicate, span))
2204 def: Option<&ty::GenericParamDef>,
2206 ) -> Option<ty::Region<'tcx>> {
2208 Some(def) => infer::EarlyBoundRegion(span, def.name),
2209 None => infer::MiscVariable(span)
2211 Some(self.next_region_var(v))
2214 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2215 if let Some(param) = param {
2216 if let UnpackedKind::Type(ty) = self.var_for_def(span, param).unpack() {
2221 self.next_ty_var(TypeVariableOrigin {
2222 kind: TypeVariableOriginKind::TypeInference,
2231 param: Option<&ty::GenericParamDef>,
2233 ) -> &'tcx Const<'tcx> {
2234 if let Some(param) = param {
2235 if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
2240 self.next_const_var(ty, ConstVariableOrigin {
2241 kind: ConstVariableOriginKind::ConstInference,
2247 fn projected_ty_from_poly_trait_ref(&self,
2250 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2253 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2255 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2259 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2262 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2263 if ty.has_escaping_bound_vars() {
2264 ty // FIXME: normalization and escaping regions
2266 self.normalize_associated_types_in(span, &ty)
2270 fn set_tainted_by_errors(&self) {
2271 self.infcx.set_tainted_by_errors()
2274 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2275 self.write_ty(hir_id, ty)
2279 /// Controls whether the arguments are tupled. This is used for the call
2282 /// Tupling means that all call-side arguments are packed into a tuple and
2283 /// passed as a single parameter. For example, if tupling is enabled, this
2286 /// fn f(x: (isize, isize))
2288 /// Can be called as:
2295 #[derive(Clone, Eq, PartialEq)]
2296 enum TupleArgumentsFlag {
2301 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2303 inh: &'a Inherited<'a, 'tcx>,
2304 param_env: ty::ParamEnv<'tcx>,
2305 body_id: hir::HirId,
2306 ) -> FnCtxt<'a, 'tcx> {
2310 err_count_on_creation: inh.tcx.sess.err_count(),
2312 ret_coercion_span: RefCell::new(None),
2314 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2315 hir::CRATE_HIR_ID)),
2316 diverges: Cell::new(Diverges::Maybe),
2317 has_errors: Cell::new(false),
2318 enclosing_breakables: RefCell::new(EnclosingBreakables {
2320 by_id: Default::default(),
2326 pub fn sess(&self) -> &Session {
2330 pub fn errors_reported_since_creation(&self) -> bool {
2331 self.tcx.sess.err_count() > self.err_count_on_creation
2334 /// Produces warning on the given node, if the current point in the
2335 /// function is unreachable, and there hasn't been another warning.
2336 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2337 // FIXME: Combine these two 'if' expressions into one once
2338 // let chains are implemented
2339 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
2340 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2341 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2342 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2343 if !span.is_desugaring(DesugaringKind::CondTemporary) &&
2344 !span.is_desugaring(DesugaringKind::Async)
2346 self.diverges.set(Diverges::WarnedAlways);
2348 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2350 let msg = format!("unreachable {}", kind);
2351 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
2352 .span_label(span, &msg)
2355 custom_note.unwrap_or("any code following this expression is unreachable"),
2364 code: ObligationCauseCode<'tcx>)
2365 -> ObligationCause<'tcx> {
2366 ObligationCause::new(span, self.body_id, code)
2369 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2370 self.cause(span, ObligationCauseCode::MiscObligation)
2373 /// Resolves type variables in `ty` if possible. Unlike the infcx
2374 /// version (resolve_vars_if_possible), this version will
2375 /// also select obligations if it seems useful, in an effort
2376 /// to get more type information.
2377 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2378 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2380 // No Infer()? Nothing needs doing.
2381 if !ty.has_infer_types() {
2382 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2386 // If `ty` is a type variable, see whether we already know what it is.
2387 ty = self.resolve_vars_if_possible(&ty);
2388 if !ty.has_infer_types() {
2389 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2393 // If not, try resolving pending obligations as much as
2394 // possible. This can help substantially when there are
2395 // indirect dependencies that don't seem worth tracking
2397 self.select_obligations_where_possible(false, |_| {});
2398 ty = self.resolve_vars_if_possible(&ty);
2400 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2404 fn record_deferred_call_resolution(
2406 closure_def_id: DefId,
2407 r: DeferredCallResolution<'tcx>,
2409 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2410 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2413 fn remove_deferred_call_resolutions(
2415 closure_def_id: DefId,
2416 ) -> Vec<DeferredCallResolution<'tcx>> {
2417 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2418 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2421 pub fn tag(&self) -> String {
2422 format!("{:p}", self)
2425 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2426 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2427 span_bug!(span, "no type for local variable {}",
2428 self.tcx.hir().node_to_string(nid))
2433 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2434 debug!("write_ty({:?}, {:?}) in fcx {}",
2435 id, self.resolve_vars_if_possible(&ty), self.tag());
2436 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2438 if ty.references_error() {
2439 self.has_errors.set(true);
2440 self.set_tainted_by_errors();
2444 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2445 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2448 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2449 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2452 pub fn write_method_call(&self,
2454 method: MethodCallee<'tcx>) {
2455 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2456 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2457 self.write_substs(hir_id, method.substs);
2459 // When the method is confirmed, the `method.substs` includes
2460 // parameters from not just the method, but also the impl of
2461 // the method -- in particular, the `Self` type will be fully
2462 // resolved. However, those are not something that the "user
2463 // specified" -- i.e., those types come from the inferred type
2464 // of the receiver, not something the user wrote. So when we
2465 // create the user-substs, we want to replace those earlier
2466 // types with just the types that the user actually wrote --
2467 // that is, those that appear on the *method itself*.
2469 // As an example, if the user wrote something like
2470 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2471 // type of `foo` (possibly adjusted), but we don't want to
2472 // include that. We want just the `[_, u32]` part.
2473 if !method.substs.is_noop() {
2474 let method_generics = self.tcx.generics_of(method.def_id);
2475 if !method_generics.params.is_empty() {
2476 let user_type_annotation = self.infcx.probe(|_| {
2477 let user_substs = UserSubsts {
2478 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2479 let i = param.index as usize;
2480 if i < method_generics.parent_count {
2481 self.infcx.var_for_def(DUMMY_SP, param)
2486 user_self_ty: None, // not relevant here
2489 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2495 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2496 self.write_user_type_annotation(hir_id, user_type_annotation);
2501 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2502 if !substs.is_noop() {
2503 debug!("write_substs({:?}, {:?}) in fcx {}",
2508 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2512 /// Given the substs that we just converted from the HIR, try to
2513 /// canonicalize them and store them as user-given substitutions
2514 /// (i.e., substitutions that must be respected by the NLL check).
2516 /// This should be invoked **before any unifications have
2517 /// occurred**, so that annotations like `Vec<_>` are preserved
2519 pub fn write_user_type_annotation_from_substs(
2523 substs: SubstsRef<'tcx>,
2524 user_self_ty: Option<UserSelfTy<'tcx>>,
2527 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2528 user_self_ty={:?} in fcx {}",
2529 hir_id, def_id, substs, user_self_ty, self.tag(),
2532 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2533 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2534 &UserType::TypeOf(def_id, UserSubsts {
2539 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2540 self.write_user_type_annotation(hir_id, canonicalized);
2544 pub fn write_user_type_annotation(
2547 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2550 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2551 hir_id, canonical_user_type_annotation, self.tag(),
2554 if !canonical_user_type_annotation.is_identity() {
2555 self.tables.borrow_mut().user_provided_types_mut().insert(
2556 hir_id, canonical_user_type_annotation
2559 debug!("write_user_type_annotation: skipping identity substs");
2563 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2564 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2570 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2571 Entry::Vacant(entry) => { entry.insert(adj); },
2572 Entry::Occupied(mut entry) => {
2573 debug!(" - composing on top of {:?}", entry.get());
2574 match (&entry.get()[..], &adj[..]) {
2575 // Applying any adjustment on top of a NeverToAny
2576 // is a valid NeverToAny adjustment, because it can't
2578 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2580 Adjustment { kind: Adjust::Deref(_), .. },
2581 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2583 Adjustment { kind: Adjust::Deref(_), .. },
2584 .. // Any following adjustments are allowed.
2586 // A reborrow has no effect before a dereference.
2588 // FIXME: currently we never try to compose autoderefs
2589 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2591 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2592 expr, entry.get(), adj)
2594 *entry.get_mut() = adj;
2599 /// Basically whenever we are converting from a type scheme into
2600 /// the fn body space, we always want to normalize associated
2601 /// types as well. This function combines the two.
2602 fn instantiate_type_scheme<T>(&self,
2604 substs: SubstsRef<'tcx>,
2607 where T : TypeFoldable<'tcx>
2609 let value = value.subst(self.tcx, substs);
2610 let result = self.normalize_associated_types_in(span, &value);
2611 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2618 /// As `instantiate_type_scheme`, but for the bounds found in a
2619 /// generic type scheme.
2620 fn instantiate_bounds(
2624 substs: SubstsRef<'tcx>,
2625 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
2626 let bounds = self.tcx.predicates_of(def_id);
2627 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
2628 let result = bounds.instantiate(self.tcx, substs);
2629 let result = self.normalize_associated_types_in(span, &result);
2631 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
2640 /// Replaces the opaque types from the given value with type variables,
2641 /// and records the `OpaqueTypeMap` for later use during writeback. See
2642 /// `InferCtxt::instantiate_opaque_types` for more details.
2643 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2645 parent_id: hir::HirId,
2649 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2650 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2654 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2655 self.instantiate_opaque_types(
2664 let mut opaque_types = self.opaque_types.borrow_mut();
2665 for (ty, decl) in opaque_type_map {
2666 let old_value = opaque_types.insert(ty, decl);
2667 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2673 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2674 where T : TypeFoldable<'tcx>
2676 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2679 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2681 where T : TypeFoldable<'tcx>
2683 self.inh.partially_normalize_associated_types_in(span,
2689 pub fn require_type_meets(&self,
2692 code: traits::ObligationCauseCode<'tcx>,
2695 self.register_bound(
2698 traits::ObligationCause::new(span, self.body_id, code));
2701 pub fn require_type_is_sized(
2705 code: traits::ObligationCauseCode<'tcx>,
2707 if !ty.references_error() {
2708 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2709 self.require_type_meets(ty, span, code, lang_item);
2713 pub fn require_type_is_sized_deferred(
2717 code: traits::ObligationCauseCode<'tcx>,
2719 if !ty.references_error() {
2720 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2724 pub fn register_bound(
2728 cause: traits::ObligationCause<'tcx>,
2730 if !ty.references_error() {
2731 self.fulfillment_cx.borrow_mut()
2732 .register_bound(self, self.param_env, ty, def_id, cause);
2736 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2737 let t = AstConv::ast_ty_to_ty(self, ast_t);
2738 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2742 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2743 let ty = self.to_ty(ast_ty);
2744 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2746 if Self::can_contain_user_lifetime_bounds(ty) {
2747 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2748 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2749 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2755 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2756 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2757 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2760 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2761 AstConv::ast_const_to_const(self, ast_c, ty)
2764 // If the type given by the user has free regions, save it for later, since
2765 // NLL would like to enforce those. Also pass in types that involve
2766 // projections, since those can resolve to `'static` bounds (modulo #54940,
2767 // which hopefully will be fixed by the time you see this comment, dear
2768 // reader, although I have my doubts). Also pass in types with inference
2769 // types, because they may be repeated. Other sorts of things are already
2770 // sufficiently enforced with erased regions. =)
2771 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2773 T: TypeFoldable<'tcx>
2775 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2778 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2779 match self.tables.borrow().node_types().get(id) {
2781 None if self.is_tainted_by_errors() => self.tcx.types.err,
2783 bug!("no type for node {}: {} in fcx {}",
2784 id, self.tcx.hir().node_to_string(id),
2790 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2791 /// outlive the region `r`.
2792 pub fn register_wf_obligation(
2796 code: traits::ObligationCauseCode<'tcx>,
2798 // WF obligations never themselves fail, so no real need to give a detailed cause:
2799 let cause = traits::ObligationCause::new(span, self.body_id, code);
2800 self.register_predicate(
2801 traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
2805 /// Registers obligations that all types appearing in `substs` are well-formed.
2806 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2807 for ty in substs.types() {
2808 if !ty.references_error() {
2809 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2814 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2815 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2816 /// trait/region obligations.
2818 /// For example, if there is a function:
2821 /// fn foo<'a,T:'a>(...)
2824 /// and a reference:
2830 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2831 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2832 pub fn add_obligations_for_parameters(&self,
2833 cause: traits::ObligationCause<'tcx>,
2834 predicates: &ty::InstantiatedPredicates<'tcx>)
2836 assert!(!predicates.has_escaping_bound_vars());
2838 debug!("add_obligations_for_parameters(predicates={:?})",
2841 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2842 self.register_predicate(obligation);
2846 // FIXME(arielb1): use this instead of field.ty everywhere
2847 // Only for fields! Returns <none> for methods>
2848 // Indifferent to privacy flags
2852 field: &'tcx ty::FieldDef,
2853 substs: SubstsRef<'tcx>,
2855 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2858 fn check_casts(&self) {
2859 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2860 for cast in deferred_cast_checks.drain(..) {
2865 fn resolve_generator_interiors(&self, def_id: DefId) {
2866 let mut generators = self.deferred_generator_interiors.borrow_mut();
2867 for (body_id, interior, kind) in generators.drain(..) {
2868 self.select_obligations_where_possible(false, |_| {});
2869 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
2873 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2874 // Non-numerics get replaced with ! or () (depending on whether
2875 // feature(never_type) is enabled, unconstrained ints with i32,
2876 // unconstrained floats with f64.
2877 // Fallback becomes very dubious if we have encountered type-checking errors.
2878 // In that case, fallback to Error.
2879 // The return value indicates whether fallback has occurred.
2880 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2881 use rustc::ty::error::UnconstrainedNumeric::Neither;
2882 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2884 assert!(ty.is_ty_infer());
2885 let fallback = match self.type_is_unconstrained_numeric(ty) {
2886 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2887 UnconstrainedInt => self.tcx.types.i32,
2888 UnconstrainedFloat => self.tcx.types.f64,
2889 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2890 Neither => return false,
2892 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2893 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2897 fn select_all_obligations_or_error(&self) {
2898 debug!("select_all_obligations_or_error");
2899 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2900 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2904 /// Select as many obligations as we can at present.
2905 fn select_obligations_where_possible(
2907 fallback_has_occurred: bool,
2908 mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
2910 if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2911 mutate_fullfillment_errors(&mut errors);
2912 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2916 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2917 /// returns a type of `&T`, but the actual type we assign to the
2918 /// *expression* is `T`. So this function just peels off the return
2919 /// type by one layer to yield `T`.
2920 fn make_overloaded_place_return_type(&self,
2921 method: MethodCallee<'tcx>)
2922 -> ty::TypeAndMut<'tcx>
2924 // extract method return type, which will be &T;
2925 let ret_ty = method.sig.output();
2927 // method returns &T, but the type as visible to user is T, so deref
2928 ret_ty.builtin_deref(true).unwrap()
2934 base_expr: &'tcx hir::Expr,
2938 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2939 // FIXME(#18741) -- this is almost but not quite the same as the
2940 // autoderef that normal method probing does. They could likely be
2943 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2944 let mut result = None;
2945 while result.is_none() && autoderef.next().is_some() {
2946 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2948 autoderef.finalize(self);
2952 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2953 /// (and otherwise adjust) `base_expr`, looking for a type which either
2954 /// supports builtin indexing or overloaded indexing.
2955 /// This loop implements one step in that search; the autoderef loop
2956 /// is implemented by `lookup_indexing`.
2960 base_expr: &hir::Expr,
2961 autoderef: &Autoderef<'a, 'tcx>,
2964 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2965 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2966 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2973 for &unsize in &[false, true] {
2974 let mut self_ty = adjusted_ty;
2976 // We only unsize arrays here.
2977 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2978 self_ty = self.tcx.mk_slice(element_ty);
2984 // If some lookup succeeds, write callee into table and extract index/element
2985 // type from the method signature.
2986 // If some lookup succeeded, install method in table
2987 let input_ty = self.next_ty_var(TypeVariableOrigin {
2988 kind: TypeVariableOriginKind::AutoDeref,
2989 span: base_expr.span,
2991 let method = self.try_overloaded_place_op(
2992 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2994 let result = method.map(|ok| {
2995 debug!("try_index_step: success, using overloaded indexing");
2996 let method = self.register_infer_ok_obligations(ok);
2998 let mut adjustments = autoderef.adjust_steps(self, needs);
2999 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
3000 let mutbl = match r_mutbl {
3001 hir::MutImmutable => AutoBorrowMutability::Immutable,
3002 hir::MutMutable => AutoBorrowMutability::Mutable {
3003 // Indexing can be desugared to a method call,
3004 // so maybe we could use two-phase here.
3005 // See the documentation of AllowTwoPhase for why that's
3006 // not the case today.
3007 allow_two_phase_borrow: AllowTwoPhase::No,
3010 adjustments.push(Adjustment {
3011 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3012 target: self.tcx.mk_ref(region, ty::TypeAndMut {
3019 adjustments.push(Adjustment {
3020 kind: Adjust::Pointer(PointerCast::Unsize),
3021 target: method.sig.inputs()[0]
3024 self.apply_adjustments(base_expr, adjustments);
3026 self.write_method_call(expr.hir_id, method);
3027 (input_ty, self.make_overloaded_place_return_type(method).ty)
3029 if result.is_some() {
3037 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
3038 let (tr, name) = match (op, is_mut) {
3039 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
3040 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
3041 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
3042 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
3044 (tr, ast::Ident::with_dummy_span(name))
3047 fn try_overloaded_place_op(&self,
3050 arg_tys: &[Ty<'tcx>],
3053 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
3055 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
3061 // Try Mut first, if needed.
3062 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3063 let method = match (needs, mut_tr) {
3064 (Needs::MutPlace, Some(trait_did)) => {
3065 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3070 // Otherwise, fall back to the immutable version.
3071 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3072 let method = match (method, imm_tr) {
3073 (None, Some(trait_did)) => {
3074 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3076 (method, _) => method,
3082 fn check_method_argument_types(
3085 expr: &'tcx hir::Expr,
3086 method: Result<MethodCallee<'tcx>, ()>,
3087 args_no_rcvr: &'tcx [hir::Expr],
3088 tuple_arguments: TupleArgumentsFlag,
3089 expected: Expectation<'tcx>,
3092 let has_error = match method {
3094 method.substs.references_error() || method.sig.references_error()
3099 let err_inputs = self.err_args(args_no_rcvr.len());
3101 let err_inputs = match tuple_arguments {
3102 DontTupleArguments => err_inputs,
3103 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3106 self.check_argument_types(
3116 return self.tcx.types.err;
3119 let method = method.unwrap();
3120 // HACK(eddyb) ignore self in the definition (see above).
3121 let expected_arg_tys = self.expected_inputs_for_expected_output(
3124 method.sig.output(),
3125 &method.sig.inputs()[1..]
3127 self.check_argument_types(
3130 &method.sig.inputs()[1..],
3131 &expected_arg_tys[..],
3133 method.sig.c_variadic,
3135 self.tcx.hir().span_if_local(method.def_id),
3140 fn self_type_matches_expected_vid(
3142 trait_ref: ty::PolyTraitRef<'tcx>,
3143 expected_vid: ty::TyVid,
3145 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3147 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3148 trait_ref, self_ty, expected_vid
3151 ty::Infer(ty::TyVar(found_vid)) => {
3152 // FIXME: consider using `sub_root_var` here so we
3153 // can see through subtyping.
3154 let found_vid = self.root_var(found_vid);
3155 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3156 expected_vid == found_vid
3162 fn obligations_for_self_ty<'b>(
3165 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3168 // FIXME: consider using `sub_root_var` here so we
3169 // can see through subtyping.
3170 let ty_var_root = self.root_var(self_ty);
3171 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3172 self_ty, ty_var_root,
3173 self.fulfillment_cx.borrow().pending_obligations());
3177 .pending_obligations()
3179 .filter_map(move |obligation| match obligation.predicate {
3180 ty::Predicate::Projection(ref data) =>
3181 Some((data.to_poly_trait_ref(self.tcx), obligation)),
3182 ty::Predicate::Trait(ref data) =>
3183 Some((data.to_poly_trait_ref(), obligation)),
3184 ty::Predicate::Subtype(..) => None,
3185 ty::Predicate::RegionOutlives(..) => None,
3186 ty::Predicate::TypeOutlives(..) => None,
3187 ty::Predicate::WellFormed(..) => None,
3188 ty::Predicate::ObjectSafe(..) => None,
3189 ty::Predicate::ConstEvaluatable(..) => None,
3190 // N.B., this predicate is created by breaking down a
3191 // `ClosureType: FnFoo()` predicate, where
3192 // `ClosureType` represents some `Closure`. It can't
3193 // possibly be referring to the current closure,
3194 // because we haven't produced the `Closure` for
3195 // this closure yet; this is exactly why the other
3196 // code is looking for a self type of a unresolved
3197 // inference variable.
3198 ty::Predicate::ClosureKind(..) => None,
3199 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3202 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3203 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
3204 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
3208 /// Generic function that factors out common logic from function calls,
3209 /// method calls and overloaded operators.
3210 fn check_argument_types(
3213 expr: &'tcx hir::Expr,
3214 fn_inputs: &[Ty<'tcx>],
3215 expected_arg_tys: &[Ty<'tcx>],
3216 args: &'tcx [hir::Expr],
3218 tuple_arguments: TupleArgumentsFlag,
3219 def_span: Option<Span>,
3222 // Grab the argument types, supplying fresh type variables
3223 // if the wrong number of arguments were supplied
3224 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
3230 // All the input types from the fn signature must outlive the call
3231 // so as to validate implied bounds.
3232 for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
3233 self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
3236 let expected_arg_count = fn_inputs.len();
3238 let param_count_error = |expected_count: usize,
3243 let mut err = tcx.sess.struct_span_err_with_code(sp,
3244 &format!("this function takes {}{} but {} {} supplied",
3245 if c_variadic { "at least " } else { "" },
3246 potentially_plural_count(expected_count, "parameter"),
3247 potentially_plural_count(arg_count, "parameter"),
3248 if arg_count == 1 {"was"} else {"were"}),
3249 DiagnosticId::Error(error_code.to_owned()));
3251 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3252 err.span_label(def_s, "defined here");
3255 let sugg_span = tcx.sess.source_map().end_point(expr.span);
3256 // remove closing `)` from the span
3257 let sugg_span = sugg_span.shrink_to_lo();
3258 err.span_suggestion(
3260 "expected the unit value `()`; create it with empty parentheses",
3262 Applicability::MachineApplicable);
3264 err.span_label(sp, format!("expected {}{}",
3265 if c_variadic { "at least " } else { "" },
3266 potentially_plural_count(expected_count, "parameter")));
3271 let mut expected_arg_tys = expected_arg_tys.to_vec();
3273 let formal_tys = if tuple_arguments == TupleArguments {
3274 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3275 match tuple_type.sty {
3276 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3277 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3278 expected_arg_tys = vec![];
3279 self.err_args(args.len())
3281 ty::Tuple(arg_types) => {
3282 expected_arg_tys = match expected_arg_tys.get(0) {
3283 Some(&ty) => match ty.sty {
3284 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3289 arg_types.iter().map(|k| k.expect_ty()).collect()
3292 span_err!(tcx.sess, sp, E0059,
3293 "cannot use call notation; the first type parameter \
3294 for the function trait is neither a tuple nor unit");
3295 expected_arg_tys = vec![];
3296 self.err_args(args.len())
3299 } else if expected_arg_count == supplied_arg_count {
3301 } else if c_variadic {
3302 if supplied_arg_count >= expected_arg_count {
3305 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3306 expected_arg_tys = vec![];
3307 self.err_args(supplied_arg_count)
3310 // is the missing argument of type `()`?
3311 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3312 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3313 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3314 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3318 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3320 expected_arg_tys = vec![];
3321 self.err_args(supplied_arg_count)
3324 debug!("check_argument_types: formal_tys={:?}",
3325 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3327 // If there is no expectation, expect formal_tys.
3328 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3334 let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
3336 // Check the arguments.
3337 // We do this in a pretty awful way: first we type-check any arguments
3338 // that are not closures, then we type-check the closures. This is so
3339 // that we have more information about the types of arguments when we
3340 // type-check the functions. This isn't really the right way to do this.
3341 for &check_closures in &[false, true] {
3342 debug!("check_closures={}", check_closures);
3344 // More awful hacks: before we check argument types, try to do
3345 // an "opportunistic" vtable resolution of any trait bounds on
3346 // the call. This helps coercions.
3348 self.select_obligations_where_possible(false, |errors| {
3349 self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
3350 self.point_at_arg_instead_of_call_if_possible(
3352 &final_arg_types[..],
3359 // For C-variadic functions, we don't have a declared type for all of
3360 // the arguments hence we only do our usual type checking with
3361 // the arguments who's types we do know.
3362 let t = if c_variadic {
3364 } else if tuple_arguments == TupleArguments {
3369 for (i, arg) in args.iter().take(t).enumerate() {
3370 // Warn only for the first loop (the "no closures" one).
3371 // Closure arguments themselves can't be diverging, but
3372 // a previous argument can, e.g., `foo(panic!(), || {})`.
3373 if !check_closures {
3374 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3377 let is_closure = match arg.node {
3378 ExprKind::Closure(..) => true,
3382 if is_closure != check_closures {
3386 debug!("checking the argument");
3387 let formal_ty = formal_tys[i];
3389 // The special-cased logic below has three functions:
3390 // 1. Provide as good of an expected type as possible.
3391 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3393 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3395 // 2. Coerce to the most detailed type that could be coerced
3396 // to, which is `expected_ty` if `rvalue_hint` returns an
3397 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3398 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3399 // We're processing function arguments so we definitely want to use
3400 // two-phase borrows.
3401 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3402 final_arg_types.push((i, coerce_ty));
3404 // 3. Relate the expected type and the formal one,
3405 // if the expected type was used for the coercion.
3406 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3410 // We also need to make sure we at least write the ty of the other
3411 // arguments which we skipped above.
3413 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3414 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3415 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3418 for arg in args.iter().skip(expected_arg_count) {
3419 let arg_ty = self.check_expr(&arg);
3421 // There are a few types which get autopromoted when passed via varargs
3422 // in C but we just error out instead and require explicit casts.
3423 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3425 ty::Float(ast::FloatTy::F32) => {
3426 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3428 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3429 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3431 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3432 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3435 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3436 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3437 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3445 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3446 vec![self.tcx.types.err; len]
3449 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
3450 /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
3451 /// reference a type argument. If they do, and there's only *one* argument that does, we point
3452 /// at the corresponding argument's expression span instead of the `fn` call path span.
3453 fn point_at_arg_instead_of_call_if_possible(
3455 errors: &mut Vec<traits::FulfillmentError<'_>>,
3456 final_arg_types: &[(usize, Ty<'tcx>)],
3458 args: &'tcx [hir::Expr],
3460 if !call_sp.desugaring_kind().is_some() {
3461 // We *do not* do this for desugared call spans to keep good diagnostics when involving
3462 // the `?` operator.
3463 for error in errors {
3464 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3465 // Collect the argument position for all arguments that could have caused this
3466 // `FullfillmentError`.
3467 let mut referenced_in = final_arg_types.iter()
3468 .flat_map(|(i, ty)| {
3469 let ty = self.resolve_vars_if_possible(ty);
3470 // We walk the argument type because the argument's type could have
3471 // been `Option<T>`, but the `FullfillmentError` references `T`.
3473 .filter(|&ty| ty == predicate.skip_binder().self_ty())
3476 if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3477 // We make sure that only *one* argument matches the obligation failure
3478 // and thet the obligation's span to its expression's.
3479 error.obligation.cause.span = args[ref_in].span;
3480 error.points_at_arg_span = true;
3487 /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
3488 /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
3489 /// were caused by them. If they were, we point at the corresponding type argument's span
3490 /// instead of the `fn` call path span.
3491 fn point_at_type_arg_instead_of_call_if_possible(
3493 errors: &mut Vec<traits::FulfillmentError<'_>>,
3494 call_expr: &'tcx hir::Expr,
3496 if let hir::ExprKind::Call(path, _) = &call_expr.node {
3497 if let hir::ExprKind::Path(qpath) = &path.node {
3498 if let hir::QPath::Resolved(_, path) = &qpath {
3499 for error in errors {
3500 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3501 // If any of the type arguments in this path segment caused the
3502 // `FullfillmentError`, point at its span (#61860).
3503 for arg in path.segments.iter()
3504 .filter_map(|seg| seg.args.as_ref())
3505 .flat_map(|a| a.args.iter())
3507 if let hir::GenericArg::Type(hir_ty) = &arg {
3508 if let hir::TyKind::Path(
3509 hir::QPath::TypeRelative(..),
3511 // Avoid ICE with associated types. As this is best
3512 // effort only, it's ok to ignore the case. It
3513 // would trigger in `is_send::<T::AssocType>();`
3514 // from `typeck-default-trait-impl-assoc-type.rs`.
3516 let ty = AstConv::ast_ty_to_ty(self, hir_ty);
3517 let ty = self.resolve_vars_if_possible(&ty);
3518 if ty == predicate.skip_binder().self_ty() {
3519 error.obligation.cause.span = hir_ty.span;
3531 // AST fragment checking
3534 expected: Expectation<'tcx>)
3540 ast::LitKind::Str(..) => tcx.mk_static_str(),
3541 ast::LitKind::ByteStr(ref v) => {
3542 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3543 tcx.mk_array(tcx.types.u8, v.len() as u64))
3545 ast::LitKind::Byte(_) => tcx.types.u8,
3546 ast::LitKind::Char(_) => tcx.types.char,
3547 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3548 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3549 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3550 let opt_ty = expected.to_option(self).and_then(|ty| {
3552 ty::Int(_) | ty::Uint(_) => Some(ty),
3553 ty::Char => Some(tcx.types.u8),
3554 ty::RawPtr(..) => Some(tcx.types.usize),
3555 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3559 opt_ty.unwrap_or_else(|| self.next_int_var())
3561 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3562 ast::LitKind::FloatUnsuffixed(_) => {
3563 let opt_ty = expected.to_option(self).and_then(|ty| {
3565 ty::Float(_) => Some(ty),
3569 opt_ty.unwrap_or_else(|| self.next_float_var())
3571 ast::LitKind::Bool(_) => tcx.types.bool,
3572 ast::LitKind::Err(_) => tcx.types.err,
3576 // Determine the `Self` type, using fresh variables for all variables
3577 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3578 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3580 pub fn impl_self_ty(&self,
3581 span: Span, // (potential) receiver for this impl
3583 -> TypeAndSubsts<'tcx> {
3584 let ity = self.tcx.type_of(did);
3585 debug!("impl_self_ty: ity={:?}", ity);
3587 let substs = self.fresh_substs_for_item(span, did);
3588 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3590 TypeAndSubsts { substs: substs, ty: substd_ty }
3593 /// Unifies the output type with the expected type early, for more coercions
3594 /// and forward type information on the input expressions.
3595 fn expected_inputs_for_expected_output(&self,
3597 expected_ret: Expectation<'tcx>,
3598 formal_ret: Ty<'tcx>,
3599 formal_args: &[Ty<'tcx>])
3601 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3602 let ret_ty = match expected_ret.only_has_type(self) {
3604 None => return Vec::new()
3606 let expect_args = self.fudge_inference_if_ok(|| {
3607 // Attempt to apply a subtyping relationship between the formal
3608 // return type (likely containing type variables if the function
3609 // is polymorphic) and the expected return type.
3610 // No argument expectations are produced if unification fails.
3611 let origin = self.misc(call_span);
3612 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3614 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3615 // to identity so the resulting type is not constrained.
3618 // Process any obligations locally as much as
3619 // we can. We don't care if some things turn
3620 // out unconstrained or ambiguous, as we're
3621 // just trying to get hints here.
3622 self.save_and_restore_in_snapshot_flag(|_| {
3623 let mut fulfill = TraitEngine::new(self.tcx);
3624 for obligation in ok.obligations {
3625 fulfill.register_predicate_obligation(self, obligation);
3627 fulfill.select_where_possible(self)
3628 }).map_err(|_| ())?;
3630 Err(_) => return Err(()),
3633 // Record all the argument types, with the substitutions
3634 // produced from the above subtyping unification.
3635 Ok(formal_args.iter().map(|ty| {
3636 self.resolve_vars_if_possible(ty)
3638 }).unwrap_or_default();
3639 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3640 formal_args, formal_ret,
3641 expect_args, expected_ret);
3645 pub fn check_struct_path(&self,
3648 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3649 let path_span = match *qpath {
3650 QPath::Resolved(_, ref path) => path.span,
3651 QPath::TypeRelative(ref qself, _) => qself.span
3653 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3654 let variant = match def {
3656 self.set_tainted_by_errors();
3659 Res::Def(DefKind::Variant, _) => {
3661 ty::Adt(adt, substs) => {
3662 Some((adt.variant_of_res(def), adt.did, substs))
3664 _ => bug!("unexpected type: {:?}", ty)
3667 Res::Def(DefKind::Struct, _)
3668 | Res::Def(DefKind::Union, _)
3669 | Res::Def(DefKind::TyAlias, _)
3670 | Res::Def(DefKind::AssocTy, _)
3671 | Res::SelfTy(..) => {
3673 ty::Adt(adt, substs) if !adt.is_enum() => {
3674 Some((adt.non_enum_variant(), adt.did, substs))
3679 _ => bug!("unexpected definition: {:?}", def)
3682 if let Some((variant, did, substs)) = variant {
3683 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3684 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3686 // Check bounds on type arguments used in the path.
3687 let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
3688 let cause = traits::ObligationCause::new(
3691 traits::ItemObligation(did),
3693 self.add_obligations_for_parameters(cause, &bounds);
3697 struct_span_err!(self.tcx.sess, path_span, E0071,
3698 "expected struct, variant or union type, found {}",
3699 ty.sort_string(self.tcx))
3700 .span_label(path_span, "not a struct")
3706 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3707 // The newly resolved definition is written into `type_dependent_defs`.
3708 fn finish_resolving_struct_path(&self,
3715 QPath::Resolved(ref maybe_qself, ref path) => {
3716 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3717 let ty = AstConv::res_to_ty(self, self_ty, path, true);
3720 QPath::TypeRelative(ref qself, ref segment) => {
3721 let ty = self.to_ty(qself);
3723 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
3728 let result = AstConv::associated_path_to_ty(
3737 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
3738 let result = result.map(|(_, kind, def_id)| (kind, def_id));
3740 // Write back the new resolution.
3741 self.write_resolution(hir_id, result);
3743 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
3748 /// Resolves an associated value path into a base type and associated constant, or method
3749 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
3750 pub fn resolve_ty_and_res_ufcs<'b>(&self,
3754 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3756 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
3757 let (ty, qself, item_segment) = match *qpath {
3758 QPath::Resolved(ref opt_qself, ref path) => {
3760 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3761 &path.segments[..]);
3763 QPath::TypeRelative(ref qself, ref segment) => {
3764 (self.to_ty(qself), qself, segment)
3767 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
3768 // Return directly on cache hit. This is useful to avoid doubly reporting
3769 // errors with default match binding modes. See #44614.
3770 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
3771 .unwrap_or(Res::Err);
3772 return (def, Some(ty), slice::from_ref(&**item_segment));
3774 let item_name = item_segment.ident;
3775 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
3776 let result = match error {
3777 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
3778 _ => Err(ErrorReported),
3780 if item_name.name != kw::Invalid {
3781 self.report_method_error(
3785 SelfSource::QPath(qself),
3788 ).map(|mut e| e.emit());
3793 // Write back the new resolution.
3794 self.write_resolution(hir_id, result);
3796 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
3798 slice::from_ref(&**item_segment),
3802 pub fn check_decl_initializer(
3804 local: &'tcx hir::Local,
3805 init: &'tcx hir::Expr,
3807 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
3808 // for #42640 (default match binding modes).
3811 let ref_bindings = local.pat.contains_explicit_ref_binding();
3813 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
3814 if let Some(m) = ref_bindings {
3815 // Somewhat subtle: if we have a `ref` binding in the pattern,
3816 // we want to avoid introducing coercions for the RHS. This is
3817 // both because it helps preserve sanity and, in the case of
3818 // ref mut, for soundness (issue #23116). In particular, in
3819 // the latter case, we need to be clear that the type of the
3820 // referent for the reference that results is *equal to* the
3821 // type of the place it is referencing, and not some
3822 // supertype thereof.
3823 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
3824 self.demand_eqtype(init.span, local_ty, init_ty);
3827 self.check_expr_coercable_to_type(init, local_ty)
3831 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
3832 let t = self.local_ty(local.span, local.hir_id).decl_ty;
3833 self.write_ty(local.hir_id, t);
3835 if let Some(ref init) = local.init {
3836 let init_ty = self.check_decl_initializer(local, &init);
3837 self.overwrite_local_ty_if_err(local, t, init_ty);
3840 self.check_pat_top(&local.pat, t, None);
3841 let pat_ty = self.node_ty(local.pat.hir_id);
3842 self.overwrite_local_ty_if_err(local, t, pat_ty);
3845 fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
3846 if ty.references_error() {
3847 // Override the types everywhere with `types.err` to avoid knock down errors.
3848 self.write_ty(local.hir_id, ty);
3849 self.write_ty(local.pat.hir_id, ty);
3850 let local_ty = LocalTy {
3854 self.locals.borrow_mut().insert(local.hir_id, local_ty);
3855 self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
3859 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
3860 // Don't do all the complex logic below for `DeclItem`.
3862 hir::StmtKind::Item(..) => return,
3863 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
3866 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
3868 // Hide the outer diverging and `has_errors` flags.
3869 let old_diverges = self.diverges.get();
3870 let old_has_errors = self.has_errors.get();
3871 self.diverges.set(Diverges::Maybe);
3872 self.has_errors.set(false);
3875 hir::StmtKind::Local(ref l) => {
3876 self.check_decl_local(&l);
3879 hir::StmtKind::Item(_) => {}
3880 hir::StmtKind::Expr(ref expr) => {
3881 // Check with expected type of `()`.
3882 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
3884 hir::StmtKind::Semi(ref expr) => {
3885 self.check_expr(&expr);
3889 // Combine the diverging and `has_error` flags.
3890 self.diverges.set(self.diverges.get() | old_diverges);
3891 self.has_errors.set(self.has_errors.get() | old_has_errors);
3894 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
3895 let unit = self.tcx.mk_unit();
3896 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
3898 // if the block produces a `!` value, that can always be
3899 // (effectively) coerced to unit.
3901 self.demand_suptype(blk.span, unit, ty);
3905 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
3906 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
3907 /// when given code like the following:
3909 /// if false { return 0i32; } else { 1u32 }
3910 /// // ^^^^ point at this instead of the whole `if` expression
3912 fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
3913 if let hir::ExprKind::Match(_, arms, _) = &expr.node {
3914 let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
3915 self.in_progress_tables
3916 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
3917 .and_then(|arm_ty| {
3918 if arm_ty.is_never() {
3921 Some(match &arm.body.node {
3922 // Point at the tail expression when possible.
3923 hir::ExprKind::Block(block, _) => block.expr
3926 .unwrap_or(block.span),
3932 if arm_spans.len() == 1 {
3933 return arm_spans[0];
3939 fn check_block_with_expected(
3941 blk: &'tcx hir::Block,
3942 expected: Expectation<'tcx>,
3945 let mut fcx_ps = self.ps.borrow_mut();
3946 let unsafety_state = fcx_ps.recurse(blk);
3947 replace(&mut *fcx_ps, unsafety_state)
3950 // In some cases, blocks have just one exit, but other blocks
3951 // can be targeted by multiple breaks. This can happen both
3952 // with labeled blocks as well as when we desugar
3953 // a `try { ... }` expression.
3957 // 'a: { if true { break 'a Err(()); } Ok(()) }
3959 // Here we would wind up with two coercions, one from
3960 // `Err(())` and the other from the tail expression
3961 // `Ok(())`. If the tail expression is omitted, that's a
3962 // "forced unit" -- unless the block diverges, in which
3963 // case we can ignore the tail expression (e.g., `'a: {
3964 // break 'a 22; }` would not force the type of the block
3966 let tail_expr = blk.expr.as_ref();
3967 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
3968 let coerce = if blk.targeted_by_break {
3969 CoerceMany::new(coerce_to_ty)
3971 let tail_expr: &[P<hir::Expr>] = match tail_expr {
3972 Some(e) => slice::from_ref(e),
3975 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
3978 let prev_diverges = self.diverges.get();
3979 let ctxt = BreakableCtxt {
3980 coerce: Some(coerce),
3984 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
3985 for s in &blk.stmts {
3989 // check the tail expression **without** holding the
3990 // `enclosing_breakables` lock below.
3991 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
3993 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3994 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
3995 let coerce = ctxt.coerce.as_mut().unwrap();
3996 if let Some(tail_expr_ty) = tail_expr_ty {
3997 let tail_expr = tail_expr.unwrap();
3998 let span = self.get_expr_coercion_span(tail_expr);
3999 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
4000 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
4002 // Subtle: if there is no explicit tail expression,
4003 // that is typically equivalent to a tail expression
4004 // of `()` -- except if the block diverges. In that
4005 // case, there is no value supplied from the tail
4006 // expression (assuming there are no other breaks,
4007 // this implies that the type of the block will be
4010 // #41425 -- label the implicit `()` as being the
4011 // "found type" here, rather than the "expected type".
4012 if !self.diverges.get().is_always() {
4013 // #50009 -- Do not point at the entire fn block span, point at the return type
4014 // span, as it is the cause of the requirement, and
4015 // `consider_hint_about_removing_semicolon` will point at the last expression
4016 // if it were a relevant part of the error. This improves usability in editors
4017 // that highlight errors inline.
4018 let mut sp = blk.span;
4019 let mut fn_span = None;
4020 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
4021 let ret_sp = decl.output.span();
4022 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
4023 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4024 // output would otherwise be incorrect and even misleading. Make sure
4025 // the span we're aiming at correspond to a `fn` body.
4026 if block_sp == blk.span {
4028 fn_span = Some(ident.span);
4032 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
4033 if let Some(expected_ty) = expected.only_has_type(self) {
4034 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4036 if let Some(fn_span) = fn_span {
4039 "implicitly returns `()` as its body has no tail or `return` \
4049 // If we can break from the block, then the block's exit is always reachable
4050 // (... as long as the entry is reachable) - regardless of the tail of the block.
4051 self.diverges.set(prev_diverges);
4054 let mut ty = ctxt.coerce.unwrap().complete(self);
4056 if self.has_errors.get() || ty.references_error() {
4057 ty = self.tcx.types.err
4060 self.write_ty(blk.hir_id, ty);
4062 *self.ps.borrow_mut() = prev;
4066 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
4067 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
4069 Node::Item(&hir::Item {
4070 node: hir::ItemKind::Fn(_, _, _, body_id), ..
4072 Node::ImplItem(&hir::ImplItem {
4073 node: hir::ImplItemKind::Method(_, body_id), ..
4075 let body = self.tcx.hir().body(body_id);
4076 if let ExprKind::Block(block, _) = &body.value.node {
4077 return Some(block.span);
4085 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
4086 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
4087 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
4088 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
4091 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
4092 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
4094 Node::Item(&hir::Item {
4095 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4097 // This is less than ideal, it will not suggest a return type span on any
4098 // method called `main`, regardless of whether it is actually the entry point,
4099 // but it will still present it as the reason for the expected type.
4100 Some((decl, ident, ident.name != sym::main))
4102 Node::TraitItem(&hir::TraitItem {
4103 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
4106 }) => Some((decl, ident, true)),
4107 Node::ImplItem(&hir::ImplItem {
4108 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
4111 }) => Some((decl, ident, false)),
4116 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
4117 /// suggestion can be made, `None` otherwise.
4118 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
4119 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4120 // `while` before reaching it, as block tail returns are not available in them.
4121 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4122 let parent = self.tcx.hir().get(blk_id);
4123 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4127 /// On implicit return expressions with mismatched types, provides the following suggestions:
4129 /// - Points out the method's return type as the reason for the expected type.
4130 /// - Possible missing semicolon.
4131 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4132 pub fn suggest_mismatched_types_on_tail(
4134 err: &mut DiagnosticBuilder<'tcx>,
4135 expression: &'tcx hir::Expr,
4141 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4142 let mut pointing_at_return_type = false;
4143 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4144 pointing_at_return_type = self.suggest_missing_return_type(
4145 err, &fn_decl, expected, found, can_suggest);
4147 self.suggest_ref_or_into(err, expression, expected, found);
4148 self.suggest_boxing_when_appropriate(err, expression, expected, found);
4149 pointing_at_return_type
4152 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4153 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4155 /// fn foo(x: usize) -> usize { x }
4156 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4160 err: &mut DiagnosticBuilder<'tcx>,
4165 let hir = self.tcx.hir();
4166 let (def_id, sig) = match found.sty {
4167 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4168 ty::Closure(def_id, substs) => {
4169 // We don't use `closure_sig` to account for malformed closures like
4170 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4171 let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
4172 (def_id, match closure_sig_ty.sty {
4173 ty::FnPtr(sig) => sig,
4181 .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
4183 let sig = self.normalize_associated_types_in(expr.span, &sig);
4184 if self.can_coerce(sig.output(), expected) {
4185 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4186 (String::new(), Applicability::MachineApplicable)
4188 ("...".to_string(), Applicability::HasPlaceholders)
4190 let mut msg = "call this function";
4191 match hir.get_if_local(def_id) {
4192 Some(Node::Item(hir::Item {
4193 node: ItemKind::Fn(.., body_id),
4196 Some(Node::ImplItem(hir::ImplItem {
4197 node: hir::ImplItemKind::Method(_, body_id),
4200 Some(Node::TraitItem(hir::TraitItem {
4201 node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4204 let body = hir.body(*body_id);
4205 sugg_call = body.params.iter()
4206 .map(|param| match ¶m.pat.node {
4207 hir::PatKind::Binding(_, _, ident, None)
4208 if ident.name != kw::SelfLower => ident.to_string(),
4209 _ => "_".to_string(),
4210 }).collect::<Vec<_>>().join(", ");
4212 Some(Node::Expr(hir::Expr {
4213 node: ExprKind::Closure(_, _, body_id, closure_span, _),
4214 span: full_closure_span,
4217 if *full_closure_span == expr.span {
4220 err.span_label(*closure_span, "closure defined here");
4221 msg = "call this closure";
4222 let body = hir.body(*body_id);
4223 sugg_call = body.params.iter()
4224 .map(|param| match ¶m.pat.node {
4225 hir::PatKind::Binding(_, _, ident, None)
4226 if ident.name != kw::SelfLower => ident.to_string(),
4227 _ => "_".to_string(),
4228 }).collect::<Vec<_>>().join(", ");
4230 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4231 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4232 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4233 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4234 msg = "instantiate this tuple variant";
4236 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4237 msg = "instantiate this tuple struct";
4242 Some(Node::ForeignItem(hir::ForeignItem {
4243 node: hir::ForeignItemKind::Fn(_, idents, _),
4246 Some(Node::TraitItem(hir::TraitItem {
4247 node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4249 })) => sugg_call = idents.iter()
4250 .map(|ident| if ident.name != kw::SelfLower {
4254 }).collect::<Vec<_>>()
4258 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4259 err.span_suggestion(
4261 &format!("use parentheses to {}", msg),
4262 format!("{}({})", code, sugg_call),
4271 pub fn suggest_ref_or_into(
4273 err: &mut DiagnosticBuilder<'tcx>,
4278 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4279 err.span_suggestion(
4283 Applicability::MachineApplicable,
4285 } else if let (ty::FnDef(def_id, ..), true) = (
4287 self.suggest_fn_call(err, expr, expected, found),
4289 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4290 let sp = self.sess().source_map().def_span(sp);
4291 err.span_label(sp, &format!("{} defined here", found));
4293 } else if !self.check_for_cast(err, expr, found, expected) {
4294 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4298 let methods = self.get_conversion_methods(expr.span, expected, found);
4299 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4300 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4301 .filter_map(|(receiver, method)| {
4302 let method_call = format!(".{}()", method.ident);
4303 if receiver.ends_with(&method_call) {
4304 None // do not suggest code that is already there (#53348)
4306 let method_call_list = [".to_vec()", ".to_string()"];
4307 let sugg = if receiver.ends_with(".clone()")
4308 && method_call_list.contains(&method_call.as_str()) {
4309 let max_len = receiver.rfind(".").unwrap();
4310 format!("{}{}", &receiver[..max_len], method_call)
4312 format!("{}{}", receiver, method_call)
4314 Some(if is_struct_pat_shorthand_field {
4315 format!("{}: {}", receiver, sugg)
4321 if suggestions.peek().is_some() {
4322 err.span_suggestions(
4324 "try using a conversion method",
4326 Applicability::MaybeIncorrect,
4333 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
4334 /// in the heap by calling `Box::new()`.
4335 fn suggest_boxing_when_appropriate(
4337 err: &mut DiagnosticBuilder<'tcx>,
4342 if self.tcx.hir().is_const_context(expr.hir_id) {
4343 // Do not suggest `Box::new` in const context.
4346 if !expected.is_box() || found.is_box() {
4349 let boxed_found = self.tcx.mk_box(found);
4350 if let (true, Ok(snippet)) = (
4351 self.can_coerce(boxed_found, expected),
4352 self.sess().source_map().span_to_snippet(expr.span),
4354 err.span_suggestion(
4356 "store this in the heap by calling `Box::new`",
4357 format!("Box::new({})", snippet),
4358 Applicability::MachineApplicable,
4360 err.note("for more on the distinction between the stack and the \
4361 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
4362 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
4363 https://doc.rust-lang.org/std/boxed/index.html");
4368 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4372 /// bar_that_returns_u32()
4376 /// This routine checks if the return expression in a block would make sense on its own as a
4377 /// statement and the return type has been left as default or has been specified as `()`. If so,
4378 /// it suggests adding a semicolon.
4379 fn suggest_missing_semicolon(
4381 err: &mut DiagnosticBuilder<'tcx>,
4382 expression: &'tcx hir::Expr,
4386 if expected.is_unit() {
4387 // `BlockTailExpression` only relevant if the tail expr would be
4388 // useful on its own.
4389 match expression.node {
4390 ExprKind::Call(..) |
4391 ExprKind::MethodCall(..) |
4392 ExprKind::Loop(..) |
4393 ExprKind::Match(..) |
4394 ExprKind::Block(..) => {
4395 let sp = self.tcx.sess.source_map().next_point(cause_span);
4396 err.span_suggestion(
4398 "try adding a semicolon",
4400 Applicability::MachineApplicable);
4407 /// A possible error is to forget to add a return type that is needed:
4411 /// bar_that_returns_u32()
4415 /// This routine checks if the return type is left as default, the method is not part of an
4416 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4418 fn suggest_missing_return_type(
4420 err: &mut DiagnosticBuilder<'tcx>,
4421 fn_decl: &hir::FnDecl,
4426 // Only suggest changing the return type for methods that
4427 // haven't set a return type at all (and aren't `fn main()` or an impl).
4428 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4429 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4430 err.span_suggestion(
4432 "try adding a return type",
4433 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
4434 Applicability::MachineApplicable);
4437 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4438 err.span_label(span, "possibly return type missing here?");
4441 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4442 // `fn main()` must return `()`, do not suggest changing return type
4443 err.span_label(span, "expected `()` because of default return type");
4446 // expectation was caused by something else, not the default return
4447 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4448 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4449 // Only point to return type if the expected type is the return type, as if they
4450 // are not, the expectation must have been caused by something else.
4451 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4453 let ty = AstConv::ast_ty_to_ty(self, ty);
4454 debug!("suggest_missing_return_type: return type {:?}", ty);
4455 debug!("suggest_missing_return_type: expected type {:?}", ty);
4456 if ty.sty == expected.sty {
4457 err.span_label(sp, format!("expected `{}` because of return type",
4466 /// A possible error is to forget to add `.await` when using futures:
4469 /// async fn make_u32() -> u32 {
4473 /// fn take_u32(x: u32) {}
4475 /// async fn foo() {
4476 /// let x = make_u32();
4481 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
4482 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
4483 /// `.await` to the tail of the expression.
4484 fn suggest_missing_await(
4486 err: &mut DiagnosticBuilder<'tcx>,
4491 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
4492 // body isn't `async`.
4493 let item_id = self.tcx().hir().get_parent_node(self.body_id);
4494 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
4495 let body = self.tcx().hir().body(body_id);
4496 if let Some(hir::GeneratorKind::Async) = body.generator_kind {
4498 // Check for `Future` implementations by constructing a predicate to
4499 // prove: `<T as Future>::Output == U`
4500 let future_trait = self.tcx.lang_items().future_trait().unwrap();
4501 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
4502 let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
4503 // `<T as Future>::Output`
4504 projection_ty: ty::ProjectionTy {
4506 substs: self.tcx.mk_substs_trait(
4508 self.fresh_substs_for_item(sp, item_def_id)
4515 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
4516 if self.infcx.predicate_may_hold(&obligation) {
4517 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
4518 err.span_suggestion(
4520 "consider using `.await` here",
4521 format!("{}.await", code),
4522 Applicability::MaybeIncorrect,
4530 /// A common error is to add an extra semicolon:
4533 /// fn foo() -> usize {
4538 /// This routine checks if the final statement in a block is an
4539 /// expression with an explicit semicolon whose type is compatible
4540 /// with `expected_ty`. If so, it suggests removing the semicolon.
4541 fn consider_hint_about_removing_semicolon(
4543 blk: &'tcx hir::Block,
4544 expected_ty: Ty<'tcx>,
4545 err: &mut DiagnosticBuilder<'_>,
4547 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4548 err.span_suggestion(
4550 "consider removing this semicolon",
4552 Applicability::MachineApplicable,
4557 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4558 // Be helpful when the user wrote `{... expr;}` and
4559 // taking the `;` off is enough to fix the error.
4560 let last_stmt = blk.stmts.last()?;
4561 let last_expr = match last_stmt.node {
4562 hir::StmtKind::Semi(ref e) => e,
4565 let last_expr_ty = self.node_ty(last_expr.hir_id);
4566 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4569 let original_span = original_sp(last_stmt.span, blk.span);
4570 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4573 // Instantiates the given path, which must refer to an item with the given
4574 // number of type parameters and type.
4575 pub fn instantiate_value_path(&self,
4576 segments: &[hir::PathSegment],
4577 self_ty: Option<Ty<'tcx>>,
4581 -> (Ty<'tcx>, Res) {
4583 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4592 let path_segs = match res {
4593 Res::Local(_) | Res::SelfCtor(_) => vec![],
4594 Res::Def(kind, def_id) =>
4595 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4596 _ => bug!("instantiate_value_path on {:?}", res),
4599 let mut user_self_ty = None;
4600 let mut is_alias_variant_ctor = false;
4602 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4603 if let Some(self_ty) = self_ty {
4604 let adt_def = self_ty.ty_adt_def().unwrap();
4605 user_self_ty = Some(UserSelfTy {
4606 impl_def_id: adt_def.did,
4609 is_alias_variant_ctor = true;
4612 Res::Def(DefKind::Method, def_id)
4613 | Res::Def(DefKind::AssocConst, def_id) => {
4614 let container = tcx.associated_item(def_id).container;
4615 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4617 ty::TraitContainer(trait_did) => {
4618 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4620 ty::ImplContainer(impl_def_id) => {
4621 if segments.len() == 1 {
4622 // `<T>::assoc` will end up here, and so
4623 // can `T::assoc`. It this came from an
4624 // inherent impl, we need to record the
4625 // `T` for posterity (see `UserSelfTy` for
4627 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4628 user_self_ty = Some(UserSelfTy {
4639 // Now that we have categorized what space the parameters for each
4640 // segment belong to, let's sort out the parameters that the user
4641 // provided (if any) into their appropriate spaces. We'll also report
4642 // errors if type parameters are provided in an inappropriate place.
4644 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4645 let generics_has_err = AstConv::prohibit_generics(
4646 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4647 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4654 if let Res::Local(hid) = res {
4655 let ty = self.local_ty(span, hid).decl_ty;
4656 let ty = self.normalize_associated_types_in(span, &ty);
4657 self.write_ty(hir_id, ty);
4661 if generics_has_err {
4662 // Don't try to infer type parameters when prohibited generic arguments were given.
4663 user_self_ty = None;
4666 // Now we have to compare the types that the user *actually*
4667 // provided against the types that were *expected*. If the user
4668 // did not provide any types, then we want to substitute inference
4669 // variables. If the user provided some types, we may still need
4670 // to add defaults. If the user provided *too many* types, that's
4673 let mut infer_args_for_err = FxHashSet::default();
4674 for &PathSeg(def_id, index) in &path_segs {
4675 let seg = &segments[index];
4676 let generics = tcx.generics_of(def_id);
4677 // Argument-position `impl Trait` is treated as a normal generic
4678 // parameter internally, but we don't allow users to specify the
4679 // parameter's value explicitly, so we have to do some error-
4681 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4686 false, // `is_method_call`
4688 if suppress_errors {
4689 infer_args_for_err.insert(index);
4690 self.set_tainted_by_errors(); // See issue #53251.
4694 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4695 tcx.generics_of(*def_id).has_self
4696 }).unwrap_or(false);
4698 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
4699 let ty = self.impl_self_ty(span, impl_def_id).ty;
4700 let adt_def = ty.ty_adt_def();
4703 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
4704 let variant = adt_def.non_enum_variant();
4705 let ctor_def_id = variant.ctor_def_id.unwrap();
4707 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
4712 let mut err = tcx.sess.struct_span_err(span,
4713 "the `Self` constructor can only be used with tuple or unit structs");
4714 if let Some(adt_def) = adt_def {
4715 match adt_def.adt_kind() {
4717 err.help("did you mean to use one of the enum's variants?");
4721 err.span_suggestion(
4723 "use curly brackets",
4724 String::from("Self { /* fields */ }"),
4725 Applicability::HasPlaceholders,
4732 return (tcx.types.err, res)
4738 let def_id = res.def_id();
4740 // The things we are substituting into the type should not contain
4741 // escaping late-bound regions, and nor should the base type scheme.
4742 let ty = tcx.type_of(def_id);
4744 let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
4750 // Provide the generic args, and whether types should be inferred.
4752 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4755 // If we've encountered an `impl Trait`-related error, we're just
4756 // going to infer the arguments for better error messages.
4757 if !infer_args_for_err.contains(&index) {
4758 // Check whether the user has provided generic arguments.
4759 if let Some(ref data) = segments[index].args {
4760 return (Some(data), segments[index].infer_args);
4763 return (None, segments[index].infer_args);
4768 // Provide substitutions for parameters for which (valid) arguments have been provided.
4770 match (¶m.kind, arg) {
4771 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4772 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4774 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4775 self.to_ty(ty).into()
4777 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4778 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4780 _ => unreachable!(),
4783 // Provide substitutions for parameters for which arguments are inferred.
4784 |substs, param, infer_args| {
4786 GenericParamDefKind::Lifetime => {
4787 self.re_infer(Some(param), span).unwrap().into()
4789 GenericParamDefKind::Type { has_default, .. } => {
4790 if !infer_args && has_default {
4791 // If we have a default, then we it doesn't matter that we're not
4792 // inferring the type arguments: we provide the default where any
4794 let default = tcx.type_of(param.def_id);
4797 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4800 // If no type arguments were provided, we have to infer them.
4801 // This case also occurs as a result of some malformed input, e.g.
4802 // a lifetime argument being given instead of a type parameter.
4803 // Using inference instead of `Error` gives better error messages.
4804 self.var_for_def(span, param)
4807 GenericParamDefKind::Const => {
4808 // FIXME(const_generics:defaults)
4809 // No const parameters were provided, we have to infer them.
4810 self.var_for_def(span, param)
4815 assert!(!substs.has_escaping_bound_vars());
4816 assert!(!ty.has_escaping_bound_vars());
4818 // First, store the "user substs" for later.
4819 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4821 self.add_required_obligations(span, def_id, &substs);
4823 // Substitute the values for the type parameters into the type of
4824 // the referenced item.
4825 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4827 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4828 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4829 // is inherent, there is no `Self` parameter; instead, the impl needs
4830 // type parameters, which we can infer by unifying the provided `Self`
4831 // with the substituted impl type.
4832 // This also occurs for an enum variant on a type alias.
4833 let ty = tcx.type_of(impl_def_id);
4835 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4836 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4837 Ok(ok) => self.register_infer_ok_obligations(ok),
4839 self.tcx.sess.delay_span_bug(span, &format!(
4840 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4848 self.check_rustc_args_require_const(def_id, hir_id, span);
4850 debug!("instantiate_value_path: type of {:?} is {:?}",
4853 self.write_substs(hir_id, substs);
4855 (ty_substituted, res)
4858 /// Add all the obligations that are required, substituting and normalized appropriately.
4859 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
4860 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
4862 for (i, mut obligation) in traits::predicates_for_generics(
4863 traits::ObligationCause::new(
4866 traits::ItemObligation(def_id),
4870 ).into_iter().enumerate() {
4871 // This makes the error point at the bound, but we want to point at the argument
4872 if let Some(span) = spans.get(i) {
4873 obligation.cause.code = traits::BindingObligation(def_id, *span);
4875 self.register_predicate(obligation);
4879 fn check_rustc_args_require_const(&self,
4883 // We're only interested in functions tagged with
4884 // #[rustc_args_required_const], so ignore anything that's not.
4885 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
4889 // If our calling expression is indeed the function itself, we're good!
4890 // If not, generate an error that this can only be called directly.
4891 if let Node::Expr(expr) = self.tcx.hir().get(
4892 self.tcx.hir().get_parent_node(hir_id))
4894 if let ExprKind::Call(ref callee, ..) = expr.node {
4895 if callee.hir_id == hir_id {
4901 self.tcx.sess.span_err(span, "this function can only be invoked \
4902 directly, not through a function pointer");
4905 // Resolves `typ` by a single level if `typ` is a type variable.
4906 // If no resolution is possible, then an error is reported.
4907 // Numeric inference variables may be left unresolved.
4908 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4909 let ty = self.resolve_type_vars_with_obligations(ty);
4910 if !ty.is_ty_var() {
4913 if !self.is_tainted_by_errors() {
4914 self.need_type_info_err((**self).body_id, sp, ty)
4915 .note("type must be known at this point")
4918 self.demand_suptype(sp, self.tcx.types.err, ty);
4923 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
4926 ctxt: BreakableCtxt<'tcx>,
4928 ) -> (BreakableCtxt<'tcx>, R) {
4931 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4932 index = enclosing_breakables.stack.len();
4933 enclosing_breakables.by_id.insert(id, index);
4934 enclosing_breakables.stack.push(ctxt);
4938 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4939 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4940 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4941 enclosing_breakables.stack.pop().expect("missing breakable context")
4946 /// Instantiate a QueryResponse in a probe context, without a
4947 /// good ObligationCause.
4948 fn probe_instantiate_query_response(
4951 original_values: &OriginalQueryValues<'tcx>,
4952 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
4953 ) -> InferResult<'tcx, Ty<'tcx>>
4955 self.instantiate_query_response_and_region_obligations(
4956 &traits::ObligationCause::misc(span, self.body_id),
4962 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
4963 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
4964 let mut contained_in_place = false;
4966 while let hir::Node::Expr(parent_expr) =
4967 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
4969 match &parent_expr.node {
4970 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
4971 if lhs.hir_id == expr_id {
4972 contained_in_place = true;
4978 expr_id = parent_expr.hir_id;
4985 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
4986 let own_counts = generics.own_counts();
4988 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
4994 if own_counts.types == 0 {
4998 // Make a vector of booleans initially `false`; set to `true` when used.
4999 let mut types_used = vec![false; own_counts.types];
5001 for leaf_ty in ty.walk() {
5002 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.sty {
5003 debug!("found use of ty param num {}", index);
5004 types_used[index as usize - own_counts.lifetimes] = true;
5005 } else if let ty::Error = leaf_ty.sty {
5006 // If there is already another error, do not emit
5007 // an error for not using a type parameter.
5008 assert!(tcx.sess.has_errors());
5013 let types = generics.params.iter().filter(|param| match param.kind {
5014 ty::GenericParamDefKind::Type { .. } => true,
5017 for (&used, param) in types_used.iter().zip(types) {
5019 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
5020 let span = tcx.hir().span(id);
5021 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5022 .span_label(span, "unused type parameter")
5028 fn fatally_break_rust(sess: &Session) {
5029 let handler = sess.diagnostic();
5030 handler.span_bug_no_panic(
5032 "It looks like you're trying to break rust; would you like some ICE?",
5034 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5035 handler.note_without_error(
5036 "we would appreciate a joke overview: \
5037 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5039 handler.note_without_error(&format!("rustc {} running on {}",
5040 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5041 crate::session::config::host_triple(),
5045 fn potentially_plural_count(count: usize, word: &str) -> String {
5046 format!("{} {}{}", count, word, pluralise!(count))