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};
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)]
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.
455 /// Same as `Always` but with a reachability
456 /// warning already emitted.
460 // Convenience impls for combinig `Diverges`.
462 impl ops::BitAnd for Diverges {
464 fn bitand(self, other: Self) -> Self {
465 cmp::min(self, other)
469 impl ops::BitOr for Diverges {
471 fn bitor(self, other: Self) -> Self {
472 cmp::max(self, other)
476 impl ops::BitAndAssign for Diverges {
477 fn bitand_assign(&mut self, other: Self) {
478 *self = *self & other;
482 impl ops::BitOrAssign for Diverges {
483 fn bitor_assign(&mut self, other: Self) {
484 *self = *self | other;
489 fn always(self) -> bool {
490 self >= Diverges::Always
494 pub struct BreakableCtxt<'tcx> {
497 // this is `null` for loops where break with a value is illegal,
498 // such as `while`, `for`, and `while let`
499 coerce: Option<DynamicCoerceMany<'tcx>>,
502 pub struct EnclosingBreakables<'tcx> {
503 stack: Vec<BreakableCtxt<'tcx>>,
504 by_id: HirIdMap<usize>,
507 impl<'tcx> EnclosingBreakables<'tcx> {
508 fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
509 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
510 bug!("could not find enclosing breakable with id {}", target_id);
516 pub struct FnCtxt<'a, 'tcx> {
519 /// The parameter environment used for proving trait obligations
520 /// in this function. This can change when we descend into
521 /// closures (as they bring new things into scope), hence it is
522 /// not part of `Inherited` (as of the time of this writing,
523 /// closures do not yet change the environment, but they will
525 param_env: ty::ParamEnv<'tcx>,
527 /// Number of errors that had been reported when we started
528 /// checking this function. On exit, if we find that *more* errors
529 /// have been reported, we will skip regionck and other work that
530 /// expects the types within the function to be consistent.
531 // FIXME(matthewjasper) This should not exist, and it's not correct
532 // if type checking is run in parallel.
533 err_count_on_creation: usize,
535 ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
536 ret_coercion_span: RefCell<Option<Span>>,
538 yield_ty: Option<Ty<'tcx>>,
540 ps: RefCell<UnsafetyState>,
542 /// Whether the last checked node generates a divergence (e.g.,
543 /// `return` will set this to `Always`). In general, when entering
544 /// an expression or other node in the tree, the initial value
545 /// indicates whether prior parts of the containing expression may
546 /// have diverged. It is then typically set to `Maybe` (and the
547 /// old value remembered) for processing the subparts of the
548 /// current expression. As each subpart is processed, they may set
549 /// the flag to `Always`, etc. Finally, at the end, we take the
550 /// result and "union" it with the original value, so that when we
551 /// return the flag indicates if any subpart of the parent
552 /// expression (up to and including this part) has diverged. So,
553 /// if you read it after evaluating a subexpression `X`, the value
554 /// you get indicates whether any subexpression that was
555 /// evaluating up to and including `X` diverged.
557 /// We currently use this flag only for diagnostic purposes:
559 /// - To warn about unreachable code: if, after processing a
560 /// sub-expression but before we have applied the effects of the
561 /// current node, we see that the flag is set to `Always`, we
562 /// can issue a warning. This corresponds to something like
563 /// `foo(return)`; we warn on the `foo()` expression. (We then
564 /// update the flag to `WarnedAlways` to suppress duplicate
565 /// reports.) Similarly, if we traverse to a fresh statement (or
566 /// tail expression) from a `Always` setting, we will issue a
567 /// warning. This corresponds to something like `{return;
568 /// foo();}` or `{return; 22}`, where we would warn on the
571 /// An expression represents dead code if, after checking it,
572 /// the diverges flag is set to something other than `Maybe`.
573 diverges: Cell<Diverges>,
575 /// Whether any child nodes have any type errors.
576 has_errors: Cell<bool>,
578 enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
580 inh: &'a Inherited<'a, 'tcx>,
583 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
584 type Target = Inherited<'a, 'tcx>;
585 fn deref(&self) -> &Self::Target {
590 /// Helper type of a temporary returned by `Inherited::build(...)`.
591 /// Necessary because we can't write the following bound:
592 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
593 pub struct InheritedBuilder<'tcx> {
594 infcx: infer::InferCtxtBuilder<'tcx>,
598 impl Inherited<'_, 'tcx> {
599 pub fn build(tcx: TyCtxt<'tcx>, def_id: DefId) -> InheritedBuilder<'tcx> {
600 let hir_id_root = if def_id.is_local() {
601 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
602 DefId::local(hir_id.owner)
608 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
614 impl<'tcx> InheritedBuilder<'tcx> {
615 fn enter<F, R>(&mut self, f: F) -> R
617 F: for<'a> FnOnce(Inherited<'a, 'tcx>) -> R,
619 let def_id = self.def_id;
620 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
624 impl Inherited<'a, 'tcx> {
625 fn new(infcx: InferCtxt<'a, 'tcx>, def_id: DefId) -> Self {
627 let item_id = tcx.hir().as_local_hir_id(def_id);
628 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
629 let implicit_region_bound = body_id.map(|body_id| {
630 let body = tcx.hir().body(body_id);
631 tcx.mk_region(ty::ReScope(region::Scope {
632 id: body.value.hir_id.local_id,
633 data: region::ScopeData::CallSite
638 tables: MaybeInProgressTables {
639 maybe_tables: infcx.in_progress_tables,
642 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
643 locals: RefCell::new(Default::default()),
644 deferred_sized_obligations: RefCell::new(Vec::new()),
645 deferred_call_resolutions: RefCell::new(Default::default()),
646 deferred_cast_checks: RefCell::new(Vec::new()),
647 deferred_generator_interiors: RefCell::new(Vec::new()),
648 opaque_types: RefCell::new(Default::default()),
649 implicit_region_bound,
654 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
655 debug!("register_predicate({:?})", obligation);
656 if obligation.has_escaping_bound_vars() {
657 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
662 .register_predicate_obligation(self, obligation);
665 fn register_predicates<I>(&self, obligations: I)
666 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
668 for obligation in obligations {
669 self.register_predicate(obligation);
673 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
674 self.register_predicates(infer_ok.obligations);
678 fn normalize_associated_types_in<T>(&self,
681 param_env: ty::ParamEnv<'tcx>,
683 where T : TypeFoldable<'tcx>
685 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
686 self.register_infer_ok_obligations(ok)
690 struct CheckItemTypesVisitor<'tcx> {
694 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
695 fn visit_item(&mut self, i: &'tcx hir::Item) {
696 check_item_type(self.tcx, i);
698 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
699 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
702 pub fn check_wf_new(tcx: TyCtxt<'_>) {
703 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
704 tcx.hir().krate().par_visit_all_item_likes(&mut visit);
707 fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
708 tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
711 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
712 debug_assert!(crate_num == LOCAL_CRATE);
713 tcx.par_body_owners(|body_owner_def_id| {
714 tcx.ensure().typeck_tables_of(body_owner_def_id);
718 fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
719 wfcheck::check_item_well_formed(tcx, def_id);
722 fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
723 wfcheck::check_trait_item(tcx, def_id);
726 fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
727 wfcheck::check_impl_item(tcx, def_id);
730 pub fn provide(providers: &mut Providers<'_>) {
731 method::provide(providers);
732 *providers = Providers {
738 check_item_well_formed,
739 check_trait_item_well_formed,
740 check_impl_item_well_formed,
741 check_mod_item_types,
746 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
747 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
750 /// If this `DefId` is a "primary tables entry", returns
751 /// `Some((body_id, header, decl))` with information about
752 /// it's body-id, fn-header and fn-decl (if any). Otherwise,
755 /// If this function returns `Some`, then `typeck_tables(def_id)` will
756 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
757 /// may not succeed. In some cases where this function returns `None`
758 /// (notably closures), `typeck_tables(def_id)` would wind up
759 /// redirecting to the owning function.
763 ) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
764 match tcx.hir().get(id) {
765 Node::Item(item) => {
767 hir::ItemKind::Const(ref ty, body) |
768 hir::ItemKind::Static(ref ty, _, body) =>
769 Some((body, Some(ty), None, None)),
770 hir::ItemKind::Fn(ref decl, ref header, .., body) =>
771 Some((body, None, Some(header), Some(decl))),
776 Node::TraitItem(item) => {
778 hir::TraitItemKind::Const(ref ty, Some(body)) =>
779 Some((body, Some(ty), None, None)),
780 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
781 Some((body, None, Some(&sig.header), Some(&sig.decl))),
786 Node::ImplItem(item) => {
788 hir::ImplItemKind::Const(ref ty, body) =>
789 Some((body, Some(ty), None, None)),
790 hir::ImplItemKind::Method(ref sig, body) =>
791 Some((body, None, Some(&sig.header), Some(&sig.decl))),
796 Node::AnonConst(constant) => Some((constant.body, None, None, None)),
801 fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
802 // Closures' tables come from their outermost function,
803 // as they are part of the same "inference environment".
804 let outer_def_id = tcx.closure_base_def_id(def_id);
805 if outer_def_id != def_id {
806 return tcx.has_typeck_tables(outer_def_id);
809 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
810 primary_body_of(tcx, id).is_some()
813 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
814 &*tcx.typeck_tables_of(def_id).used_trait_imports
817 fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
818 // Closures' tables come from their outermost function,
819 // as they are part of the same "inference environment".
820 let outer_def_id = tcx.closure_base_def_id(def_id);
821 if outer_def_id != def_id {
822 return tcx.typeck_tables_of(outer_def_id);
825 let id = tcx.hir().as_local_hir_id(def_id).unwrap();
826 let span = tcx.hir().span(id);
828 // Figure out what primary body this item has.
829 let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
831 span_bug!(span, "can't type-check body of {:?}", def_id);
833 let body = tcx.hir().body(body_id);
835 let tables = Inherited::build(tcx, def_id).enter(|inh| {
836 let param_env = tcx.param_env(def_id);
837 let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
838 let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
839 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
840 AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl)
845 check_abi(tcx, span, fn_sig.abi());
847 // Compute the fty from point of view of inside the fn.
849 tcx.liberate_late_bound_regions(def_id, &fn_sig);
851 inh.normalize_associated_types_in(body.value.span,
856 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
859 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
860 let expected_type = body_ty.and_then(|ty| match ty.node {
861 hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
863 }).unwrap_or_else(|| tcx.type_of(def_id));
864 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
865 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
867 let revealed_ty = if tcx.features().impl_trait_in_bindings {
868 fcx.instantiate_opaque_types_from_value(
877 // Gather locals in statics (because of block expressions).
878 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
880 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
882 fcx.write_ty(id, revealed_ty);
887 // All type checking constraints were added, try to fallback unsolved variables.
888 fcx.select_obligations_where_possible(false, |_| {});
889 let mut fallback_has_occurred = false;
890 for ty in &fcx.unsolved_variables() {
891 fallback_has_occurred |= fcx.fallback_if_possible(ty);
893 fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
895 // Even though coercion casts provide type hints, we check casts after fallback for
896 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
899 // Closure and generator analysis may run after fallback
900 // because they don't constrain other type variables.
901 fcx.closure_analyze(body);
902 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
903 fcx.resolve_generator_interiors(def_id);
905 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
906 let ty = fcx.normalize_ty(span, ty);
907 fcx.require_type_is_sized(ty, span, code);
909 fcx.select_all_obligations_or_error();
911 if fn_decl.is_some() {
912 fcx.regionck_fn(id, body);
914 fcx.regionck_expr(body);
917 fcx.resolve_type_vars_in_body(body)
920 // Consistency check our TypeckTables instance can hold all ItemLocalIds
921 // it will need to hold.
922 assert_eq!(tables.local_id_root, Some(DefId::local(id.owner)));
927 fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
928 if !tcx.sess.target.target.is_abi_supported(abi) {
929 struct_span_err!(tcx.sess, span, E0570,
930 "The ABI `{}` is not supported for the current target", abi).emit()
934 struct GatherLocalsVisitor<'a, 'tcx> {
935 fcx: &'a FnCtxt<'a, 'tcx>,
936 parent_id: hir::HirId,
939 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
940 fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
943 // infer the variable's type
944 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
945 kind: TypeVariableOriginKind::TypeInference,
948 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
955 // take type that the user specified
956 self.fcx.locals.borrow_mut().insert(nid, typ);
963 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
964 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
965 NestedVisitorMap::None
968 // Add explicitly-declared locals.
969 fn visit_local(&mut self, local: &'tcx hir::Local) {
970 let local_ty = match local.ty {
972 let o_ty = self.fcx.to_ty(&ty);
974 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
975 self.fcx.instantiate_opaque_types_from_value(
984 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(
985 &UserType::Ty(revealed_ty)
987 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
988 ty.hir_id, o_ty, revealed_ty, c_ty);
989 self.fcx.tables.borrow_mut().user_provided_types_mut().insert(ty.hir_id, c_ty);
991 Some(LocalTy { decl_ty: o_ty, revealed_ty })
995 self.assign(local.span, local.hir_id, local_ty);
997 debug!("local variable {:?} is assigned type {}",
999 self.fcx.ty_to_string(
1000 self.fcx.locals.borrow().get(&local.hir_id).unwrap().clone().decl_ty));
1001 intravisit::walk_local(self, local);
1004 // Add pattern bindings.
1005 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
1006 if let PatKind::Binding(_, _, ident, _) = p.node {
1007 let var_ty = self.assign(p.span, p.hir_id, None);
1009 if !self.fcx.tcx.features().unsized_locals {
1010 self.fcx.require_type_is_sized(var_ty, p.span,
1011 traits::VariableType(p.hir_id));
1014 debug!("pattern binding {} is assigned to {} with type {:?}",
1016 self.fcx.ty_to_string(
1017 self.fcx.locals.borrow().get(&p.hir_id).unwrap().clone().decl_ty),
1020 intravisit::walk_pat(self, p);
1023 // Don't descend into the bodies of nested closures
1026 _: intravisit::FnKind<'tcx>,
1027 _: &'tcx hir::FnDecl,
1034 /// When `check_fn` is invoked on a generator (i.e., a body that
1035 /// includes yield), it returns back some information about the yield
1037 struct GeneratorTypes<'tcx> {
1038 /// Type of value that is yielded.
1041 /// Types that are captured (see `GeneratorInterior` for more).
1044 /// Indicates if the generator is movable or static (immovable).
1045 movability: hir::GeneratorMovability,
1048 /// Helper used for fns and closures. Does the grungy work of checking a function
1049 /// body and returns the function context used for that purpose, since in the case of a fn item
1050 /// there is still a bit more to do.
1053 /// * inherited: other fields inherited from the enclosing fn (if any)
1054 fn check_fn<'a, 'tcx>(
1055 inherited: &'a Inherited<'a, 'tcx>,
1056 param_env: ty::ParamEnv<'tcx>,
1057 fn_sig: ty::FnSig<'tcx>,
1058 decl: &'tcx hir::FnDecl,
1060 body: &'tcx hir::Body,
1061 can_be_generator: Option<hir::GeneratorMovability>,
1062 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
1063 let mut fn_sig = fn_sig.clone();
1065 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1067 // Create the function context. This is either derived from scratch or,
1068 // in the case of closures, based on the outer context.
1069 let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
1070 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1072 let declared_ret_ty = fn_sig.output();
1073 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1074 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
1079 debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
1080 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1081 fn_sig = fcx.tcx.mk_fn_sig(
1082 fn_sig.inputs().iter().cloned(),
1089 let span = body.value.span;
1091 fn_maybe_err(fcx.tcx, span, fn_sig.abi);
1093 if body.generator_kind.is_some() && can_be_generator.is_some() {
1094 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
1095 kind: TypeVariableOriginKind::TypeInference,
1098 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1099 fcx.yield_ty = Some(yield_ty);
1102 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1103 let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
1104 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
1106 // Add formal parameters.
1107 for (param_ty, param) in fn_sig.inputs().iter().zip(&body.params) {
1108 // Check the pattern.
1109 fcx.check_pat_top(¶m.pat, param_ty, None);
1111 // Check that argument is Sized.
1112 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1113 // for simple cases like `fn foo(x: Trait)`,
1114 // where we would error once on the parameter as a whole, and once on the binding `x`.
1115 if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1116 fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
1119 fcx.write_ty(param.hir_id, param_ty);
1122 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
1124 fcx.check_return_expr(&body.value);
1126 // We insert the deferred_generator_interiors entry after visiting the body.
1127 // This ensures that all nested generators appear before the entry of this generator.
1128 // resolve_generator_interiors relies on this property.
1129 let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
1130 let interior = fcx.next_ty_var(TypeVariableOrigin {
1131 kind: TypeVariableOriginKind::MiscVariable,
1134 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1135 Some(GeneratorTypes {
1136 yield_ty: fcx.yield_ty.unwrap(),
1138 movability: can_be_generator.unwrap(),
1144 // Finalize the return check by taking the LUB of the return types
1145 // we saw and assigning it to the expected return type. This isn't
1146 // really expected to fail, since the coercions would have failed
1147 // earlier when trying to find a LUB.
1149 // However, the behavior around `!` is sort of complex. In the
1150 // event that the `actual_return_ty` comes back as `!`, that
1151 // indicates that the fn either does not return or "returns" only
1152 // values of type `!`. In this case, if there is an expected
1153 // return type that is *not* `!`, that should be ok. But if the
1154 // return type is being inferred, we want to "fallback" to `!`:
1156 // let x = move || panic!();
1158 // To allow for that, I am creating a type variable with diverging
1159 // fallback. This was deemed ever so slightly better than unifying
1160 // the return value with `!` because it allows for the caller to
1161 // make more assumptions about the return type (e.g., they could do
1163 // let y: Option<u32> = Some(x());
1165 // which would then cause this return type to become `u32`, not
1167 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1168 let mut actual_return_ty = coercion.complete(&fcx);
1169 if actual_return_ty.is_never() {
1170 actual_return_ty = fcx.next_diverging_ty_var(
1171 TypeVariableOrigin {
1172 kind: TypeVariableOriginKind::DivergingFn,
1177 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1179 // Check that the main return type implements the termination trait.
1180 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1181 if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
1182 let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
1183 if main_id == fn_id {
1184 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1185 let trait_ref = ty::TraitRef::new(term_id, substs);
1186 let return_ty_span = decl.output.span();
1187 let cause = traits::ObligationCause::new(
1188 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1190 inherited.register_predicate(
1191 traits::Obligation::new(
1192 cause, param_env, trait_ref.to_predicate()));
1197 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1198 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1199 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1200 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1201 // at this point we don't care if there are duplicate handlers or if the handler has
1202 // the wrong signature as this value we'll be used when writing metadata and that
1203 // only happens if compilation succeeded
1204 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1206 if declared_ret_ty.sty != ty::Never {
1207 fcx.tcx.sess.span_err(
1209 "return type should be `!`",
1213 let inputs = fn_sig.inputs();
1214 let span = fcx.tcx.hir().span(fn_id);
1215 if inputs.len() == 1 {
1216 let arg_is_panic_info = match inputs[0].sty {
1217 ty::Ref(region, ty, mutbl) => match ty.sty {
1218 ty::Adt(ref adt, _) => {
1219 adt.did == panic_info_did &&
1220 mutbl == hir::Mutability::MutImmutable &&
1221 *region != RegionKind::ReStatic
1228 if !arg_is_panic_info {
1229 fcx.tcx.sess.span_err(
1230 decl.inputs[0].span,
1231 "argument should be `&PanicInfo`",
1235 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1236 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1237 if !generics.params.is_empty() {
1238 fcx.tcx.sess.span_err(
1240 "should have no type parameters",
1246 let span = fcx.tcx.sess.source_map().def_span(span);
1247 fcx.tcx.sess.span_err(span, "function should have one argument");
1250 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1255 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1256 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1257 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1258 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1259 if declared_ret_ty.sty != ty::Never {
1260 fcx.tcx.sess.span_err(
1262 "return type should be `!`",
1266 let inputs = fn_sig.inputs();
1267 let span = fcx.tcx.hir().span(fn_id);
1268 if inputs.len() == 1 {
1269 let arg_is_alloc_layout = match inputs[0].sty {
1270 ty::Adt(ref adt, _) => {
1271 adt.did == alloc_layout_did
1276 if !arg_is_alloc_layout {
1277 fcx.tcx.sess.span_err(
1278 decl.inputs[0].span,
1279 "argument should be `Layout`",
1283 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1284 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1285 if !generics.params.is_empty() {
1286 fcx.tcx.sess.span_err(
1288 "`#[alloc_error_handler]` function should have no type \
1295 let span = fcx.tcx.sess.source_map().def_span(span);
1296 fcx.tcx.sess.span_err(span, "function should have one argument");
1299 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1307 fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1308 let def_id = tcx.hir().local_def_id(id);
1309 let def = tcx.adt_def(def_id);
1310 def.destructor(tcx); // force the destructor to be evaluated
1311 check_representable(tcx, span, def_id);
1313 if def.repr.simd() {
1314 check_simd(tcx, span, def_id);
1317 check_transparent(tcx, span, def_id);
1318 check_packed(tcx, span, def_id);
1321 fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
1322 let def_id = tcx.hir().local_def_id(id);
1323 let def = tcx.adt_def(def_id);
1324 def.destructor(tcx); // force the destructor to be evaluated
1325 check_representable(tcx, span, def_id);
1326 check_transparent(tcx, span, def_id);
1327 check_packed(tcx, span, def_id);
1330 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
1331 /// projections that would result in "inheriting lifetimes".
1332 fn check_opaque<'tcx>(
1335 substs: SubstsRef<'tcx>,
1337 origin: &hir::OpaqueTyOrigin,
1339 check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
1340 check_opaque_for_cycles(tcx, def_id, substs, span, origin);
1343 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
1344 /// in "inheriting lifetimes".
1345 fn check_opaque_for_inheriting_lifetimes(
1350 let item = tcx.hir().expect_item(
1351 tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
1352 debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
1353 def_id, span, item);
1356 struct ProhibitOpaqueVisitor<'tcx> {
1357 opaque_identity_ty: Ty<'tcx>,
1358 generics: &'tcx ty::Generics,
1361 impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
1362 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
1363 debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
1364 if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
1367 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1368 debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
1369 if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
1370 return *index < self.generics.parent_count as u32;
1373 r.super_visit_with(self)
1377 let prohibit_opaque = match item.node {
1378 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
1379 ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
1380 let mut visitor = ProhibitOpaqueVisitor {
1381 opaque_identity_ty: tcx.mk_opaque(
1382 def_id, InternalSubsts::identity_for_item(tcx, def_id)),
1383 generics: tcx.generics_of(def_id),
1385 debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
1387 tcx.predicates_of(def_id).predicates.iter().any(
1388 |(predicate, _)| predicate.visit_with(&mut visitor))
1393 debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
1394 if prohibit_opaque {
1395 let is_async = match item.node {
1396 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
1397 hir::OpaqueTyOrigin::AsyncFn => true,
1400 _ => unreachable!(),
1403 tcx.sess.span_err(span, &format!(
1404 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1406 if is_async { "async fn" } else { "impl Trait" },
1411 /// Checks that an opaque type does not contain cycles.
1412 fn check_opaque_for_cycles<'tcx>(
1415 substs: SubstsRef<'tcx>,
1417 origin: &hir::OpaqueTyOrigin,
1419 if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
1420 if let hir::OpaqueTyOrigin::AsyncFn = origin {
1422 tcx.sess, span, E0733,
1423 "recursion in an `async fn` requires boxing",
1425 .span_label(span, "recursive `async fn`")
1426 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
1429 let mut err = struct_span_err!(
1430 tcx.sess, span, E0720,
1431 "opaque type expands to a recursive type",
1433 err.span_label(span, "expands to a recursive type");
1434 if let ty::Opaque(..) = partially_expanded_type.sty {
1435 err.note("type resolves to itself");
1437 err.note(&format!("expanded type is `{}`", partially_expanded_type));
1444 // Forbid defining intrinsics in Rust code,
1445 // as they must always be defined by the compiler.
1446 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
1447 if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1448 tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
1452 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
1454 "check_item_type(it.hir_id={}, it.name={})",
1456 tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
1458 let _indenter = indenter();
1460 // Consts can play a role in type-checking, so they are included here.
1461 hir::ItemKind::Static(..) => {
1462 let def_id = tcx.hir().local_def_id(it.hir_id);
1463 tcx.typeck_tables_of(def_id);
1464 maybe_check_static_with_link_section(tcx, def_id, it.span);
1466 hir::ItemKind::Const(..) => {
1467 tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
1469 hir::ItemKind::Enum(ref enum_definition, _) => {
1470 check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
1472 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1473 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1474 debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
1475 let impl_def_id = tcx.hir().local_def_id(it.hir_id);
1476 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1477 check_impl_items_against_trait(
1484 let trait_def_id = impl_trait_ref.def_id;
1485 check_on_unimplemented(tcx, trait_def_id, it);
1488 hir::ItemKind::Trait(_, _, _, _, ref items) => {
1489 let def_id = tcx.hir().local_def_id(it.hir_id);
1490 check_on_unimplemented(tcx, def_id, it);
1492 for item in items.iter() {
1493 let item = tcx.hir().trait_item(item.id);
1494 if let hir::TraitItemKind::Method(sig, _) = &item.node {
1495 let abi = sig.header.abi;
1496 fn_maybe_err(tcx, item.ident.span, abi);
1500 hir::ItemKind::Struct(..) => {
1501 check_struct(tcx, it.hir_id, it.span);
1503 hir::ItemKind::Union(..) => {
1504 check_union(tcx, it.hir_id, it.span);
1506 hir::ItemKind::OpaqueTy(hir::OpaqueTy{origin, ..}) => {
1507 let def_id = tcx.hir().local_def_id(it.hir_id);
1509 let substs = InternalSubsts::identity_for_item(tcx, def_id);
1510 check_opaque(tcx, def_id, substs, it.span, &origin);
1512 hir::ItemKind::TyAlias(..) => {
1513 let def_id = tcx.hir().local_def_id(it.hir_id);
1514 let pty_ty = tcx.type_of(def_id);
1515 let generics = tcx.generics_of(def_id);
1516 check_bounds_are_used(tcx, &generics, pty_ty);
1518 hir::ItemKind::ForeignMod(ref m) => {
1519 check_abi(tcx, it.span, m.abi);
1521 if m.abi == Abi::RustIntrinsic {
1522 for item in &m.items {
1523 intrinsic::check_intrinsic_type(tcx, item);
1525 } else if m.abi == Abi::PlatformIntrinsic {
1526 for item in &m.items {
1527 intrinsic::check_platform_intrinsic_type(tcx, item);
1530 for item in &m.items {
1531 let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1532 let own_counts = generics.own_counts();
1533 if generics.params.len() - own_counts.lifetimes != 0 {
1534 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1535 (_, 0) => ("type", "types", Some("u32")),
1536 // We don't specify an example value, because we can't generate
1537 // a valid value for any type.
1538 (0, _) => ("const", "consts", None),
1539 _ => ("type or const", "types or consts", None),
1545 "foreign items may not have {} parameters",
1549 &format!("can't have {} parameters", kinds),
1551 // FIXME: once we start storing spans for type arguments, turn this
1552 // into a suggestion.
1554 "replace the {} parameters with concrete {}{}",
1557 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1562 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1563 require_c_abi_if_c_variadic(tcx, fn_decl, m.abi, item.span);
1568 _ => { /* nothing to do */ }
1572 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) {
1573 // Only restricted on wasm32 target for now
1574 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1578 // If `#[link_section]` is missing, then nothing to verify
1579 let attrs = tcx.codegen_fn_attrs(id);
1580 if attrs.link_section.is_none() {
1584 // For the wasm32 target statics with `#[link_section]` are placed into custom
1585 // sections of the final output file, but this isn't link custom sections of
1586 // other executable formats. Namely we can only embed a list of bytes,
1587 // nothing with pointers to anything else or relocations. If any relocation
1588 // show up, reject them here.
1589 // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
1590 // the consumer's responsibility to ensure all bytes that have been read
1591 // have defined values.
1592 let instance = ty::Instance::mono(tcx, id);
1593 let cid = GlobalId {
1597 let param_env = ty::ParamEnv::reveal_all();
1598 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1599 let alloc = if let ConstValue::ByRef { alloc, .. } = static_.val {
1602 bug!("Matching on non-ByRef static")
1604 if alloc.relocations().len() != 0 {
1605 let msg = "statics with a custom `#[link_section]` must be a \
1606 simple list of bytes on the wasm target with no \
1607 extra levels of indirection such as references";
1608 tcx.sess.span_err(span, msg);
1613 fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
1614 let item_def_id = tcx.hir().local_def_id(item.hir_id);
1615 // an error would be reported if this fails.
1616 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1619 fn report_forbidden_specialization(
1621 impl_item: &hir::ImplItem,
1624 let mut err = struct_span_err!(
1625 tcx.sess, impl_item.span, E0520,
1626 "`{}` specializes an item from a parent `impl`, but \
1627 that item is not marked `default`",
1629 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1632 match tcx.span_of_impl(parent_impl) {
1634 err.span_label(span, "parent `impl` is here");
1635 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1639 err.note(&format!("parent implementation is in crate `{}`", cname));
1646 fn check_specialization_validity<'tcx>(
1648 trait_def: &ty::TraitDef,
1649 trait_item: &ty::AssocItem,
1651 impl_item: &hir::ImplItem,
1653 let ancestors = trait_def.ancestors(tcx, impl_id);
1655 let kind = match impl_item.node {
1656 hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
1657 hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
1658 hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
1659 hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
1662 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1663 .map(|node_item| node_item.map(|parent| parent.defaultness));
1665 if let Some(parent) = parent {
1666 if tcx.impl_item_is_final(&parent) {
1667 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1673 fn check_impl_items_against_trait<'tcx>(
1677 impl_trait_ref: ty::TraitRef<'tcx>,
1678 impl_item_refs: &[hir::ImplItemRef],
1680 let impl_span = tcx.sess.source_map().def_span(impl_span);
1682 // If the trait reference itself is erroneous (so the compilation is going
1683 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1684 // isn't populated for such impls.
1685 if impl_trait_ref.references_error() { return; }
1687 // Locate trait definition and items
1688 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1689 let mut overridden_associated_type = None;
1691 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1693 // Check existing impl methods to see if they are both present in trait
1694 // and compatible with trait signature
1695 for impl_item in impl_items() {
1696 let ty_impl_item = tcx.associated_item(
1697 tcx.hir().local_def_id(impl_item.hir_id));
1698 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1699 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1700 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1702 // Not compatible, but needed for the error message
1703 tcx.associated_items(impl_trait_ref.def_id)
1704 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1707 // Check that impl definition matches trait definition
1708 if let Some(ty_trait_item) = ty_trait_item {
1709 match impl_item.node {
1710 hir::ImplItemKind::Const(..) => {
1711 // Find associated const definition.
1712 if ty_trait_item.kind == ty::AssocKind::Const {
1713 compare_const_impl(tcx,
1719 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1720 "item `{}` is an associated const, \
1721 which doesn't match its trait `{}`",
1724 err.span_label(impl_item.span, "does not match trait");
1725 // We can only get the spans from local trait definition
1726 // Same for E0324 and E0325
1727 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1728 err.span_label(trait_span, "item in trait");
1733 hir::ImplItemKind::Method(..) => {
1734 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1735 if ty_trait_item.kind == ty::AssocKind::Method {
1736 compare_impl_method(tcx,
1743 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1744 "item `{}` is an associated method, \
1745 which doesn't match its trait `{}`",
1748 err.span_label(impl_item.span, "does not match trait");
1749 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1750 err.span_label(trait_span, "item in trait");
1755 hir::ImplItemKind::OpaqueTy(..) |
1756 hir::ImplItemKind::TyAlias(_) => {
1757 if ty_trait_item.kind == ty::AssocKind::Type {
1758 if ty_trait_item.defaultness.has_value() {
1759 overridden_associated_type = Some(impl_item);
1762 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1763 "item `{}` is an associated type, \
1764 which doesn't match its trait `{}`",
1767 err.span_label(impl_item.span, "does not match trait");
1768 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1769 err.span_label(trait_span, "item in trait");
1776 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1780 // Check for missing items from trait
1781 let mut missing_items = Vec::new();
1782 let mut invalidated_items = Vec::new();
1783 let associated_type_overridden = overridden_associated_type.is_some();
1784 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1785 let is_implemented = trait_def.ancestors(tcx, impl_id)
1786 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1788 .map(|node_item| !node_item.node.is_from_trait())
1791 if !is_implemented && !tcx.impl_is_default(impl_id) {
1792 if !trait_item.defaultness.has_value() {
1793 missing_items.push(trait_item);
1794 } else if associated_type_overridden {
1795 invalidated_items.push(trait_item.ident);
1800 if !missing_items.is_empty() {
1801 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1802 "not all trait items implemented, missing: `{}`",
1803 missing_items.iter()
1804 .map(|trait_item| trait_item.ident.to_string())
1805 .collect::<Vec<_>>().join("`, `"));
1806 err.span_label(impl_span, format!("missing `{}` in implementation",
1807 missing_items.iter()
1808 .map(|trait_item| trait_item.ident.to_string())
1809 .collect::<Vec<_>>().join("`, `")));
1810 for trait_item in missing_items {
1811 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1812 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1814 err.note_trait_signature(trait_item.ident.to_string(),
1815 trait_item.signature(tcx));
1821 if !invalidated_items.is_empty() {
1822 let invalidator = overridden_associated_type.unwrap();
1823 span_err!(tcx.sess, invalidator.span, E0399,
1824 "the following trait items need to be reimplemented \
1825 as `{}` was overridden: `{}`",
1827 invalidated_items.iter()
1828 .map(|name| name.to_string())
1829 .collect::<Vec<_>>().join("`, `"))
1833 /// Checks whether a type can be represented in memory. In particular, it
1834 /// identifies types that contain themselves without indirection through a
1835 /// pointer, which would mean their size is unbounded.
1836 fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
1837 let rty = tcx.type_of(item_def_id);
1839 // Check that it is possible to represent this type. This call identifies
1840 // (1) types that contain themselves and (2) types that contain a different
1841 // recursive type. It is only necessary to throw an error on those that
1842 // contain themselves. For case 2, there must be an inner type that will be
1843 // caught by case 1.
1844 match rty.is_representable(tcx, sp) {
1845 Representability::SelfRecursive(spans) => {
1846 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1848 err.span_label(span, "recursive without indirection");
1853 Representability::Representable | Representability::ContainsRecursive => (),
1858 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1859 let t = tcx.type_of(def_id);
1860 if let ty::Adt(def, substs) = t.sty {
1861 if def.is_struct() {
1862 let fields = &def.non_enum_variant().fields;
1863 if fields.is_empty() {
1864 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1867 let e = fields[0].ty(tcx, substs);
1868 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1869 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1870 .span_label(sp, "SIMD elements must have the same type")
1875 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1876 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1878 span_err!(tcx.sess, sp, E0077,
1879 "SIMD vector element type should be machine type");
1887 fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1888 let repr = tcx.adt_def(def_id).repr;
1890 for attr in tcx.get_attrs(def_id).iter() {
1891 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1892 if let attr::ReprPacked(pack) = r {
1893 if let Some(repr_pack) = repr.pack {
1894 if pack as u64 != repr_pack.bytes() {
1896 tcx.sess, sp, E0634,
1897 "type has conflicting packed representation hints"
1904 if repr.align.is_some() {
1905 struct_span_err!(tcx.sess, sp, E0587,
1906 "type has conflicting packed and align representation hints").emit();
1908 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1909 struct_span_err!(tcx.sess, sp, E0588,
1910 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1915 fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
1916 let t = tcx.type_of(def_id);
1917 if stack.contains(&def_id) {
1918 debug!("check_packed_inner: {:?} is recursive", t);
1921 if let ty::Adt(def, substs) = t.sty {
1922 if def.is_struct() || def.is_union() {
1923 if tcx.adt_def(def.did).repr.align.is_some() {
1926 // push struct def_id before checking fields
1928 for field in &def.non_enum_variant().fields {
1929 let f = field.ty(tcx, substs);
1930 if let ty::Adt(def, _) = f.sty {
1931 if check_packed_inner(tcx, def.did, stack) {
1936 // only need to pop if not early out
1943 /// Emit an error when encountering more or less than one variant in a transparent enum.
1944 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
1945 let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
1946 tcx.hir().span_if_local(variant.def_id).unwrap()
1949 "needs exactly one variant, but has {}",
1952 let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
1953 err.span_label(sp, &msg);
1954 if let &[ref start @ .., ref end] = &variant_spans[..] {
1955 for variant_span in start {
1956 err.span_label(*variant_span, "");
1958 err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
1963 /// Emit an error when encountering more or less than one non-zero-sized field in a transparent
1965 fn bad_non_zero_sized_fields<'tcx>(
1967 adt: &'tcx ty::AdtDef,
1969 field_spans: impl Iterator<Item = Span>,
1972 let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
1973 let mut err = struct_span_err!(
1977 "{}transparent {} {}",
1978 if adt.is_enum() { "the variant of a " } else { "" },
1982 err.span_label(sp, &msg);
1983 for sp in field_spans {
1984 err.span_label(sp, "this field is non-zero-sized");
1989 fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
1990 let adt = tcx.adt_def(def_id);
1991 if !adt.repr.transparent() {
1994 let sp = tcx.sess.source_map().def_span(sp);
1997 if !tcx.features().transparent_enums {
1999 &tcx.sess.parse_sess,
2000 sym::transparent_enums,
2002 GateIssue::Language,
2003 "transparent enums are unstable",
2006 if adt.variants.len() != 1 {
2007 bad_variant_count(tcx, adt, sp, def_id);
2008 if adt.variants.is_empty() {
2009 // Don't bother checking the fields. No variants (and thus no fields) exist.
2015 if adt.is_union() && !tcx.features().transparent_unions {
2016 emit_feature_err(&tcx.sess.parse_sess,
2017 sym::transparent_unions,
2019 GateIssue::Language,
2020 "transparent unions are unstable");
2023 // For each field, figure out if it's known to be a ZST and align(1)
2024 let field_infos = adt.all_fields().map(|field| {
2025 let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
2026 let param_env = tcx.param_env(field.did);
2027 let layout = tcx.layout_of(param_env.and(ty));
2028 // We are currently checking the type this field came from, so it must be local
2029 let span = tcx.hir().span_if_local(field.did).unwrap();
2030 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
2031 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
2035 let non_zst_fields = field_infos.clone().filter_map(|(span, zst, _align1)| if !zst {
2040 let non_zst_count = non_zst_fields.clone().count();
2041 if non_zst_count != 1 {
2042 bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
2044 for (span, zst, align1) in field_infos {
2050 "zero-sized field in transparent {} has alignment larger than 1",
2052 ).span_label(span, "has alignment larger than 1").emit();
2057 #[allow(trivial_numeric_casts)]
2058 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
2059 let def_id = tcx.hir().local_def_id(id);
2060 let def = tcx.adt_def(def_id);
2061 def.destructor(tcx); // force the destructor to be evaluated
2064 let attributes = tcx.get_attrs(def_id);
2065 if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
2067 tcx.sess, attr.span, E0084,
2068 "unsupported representation for zero-variant enum")
2069 .span_label(sp, "zero-variant enum")
2074 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
2075 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
2076 if !tcx.features().repr128 {
2077 emit_feature_err(&tcx.sess.parse_sess,
2080 GateIssue::Language,
2081 "repr with 128-bit type is unstable");
2086 if let Some(ref e) = v.disr_expr {
2087 tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
2091 if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
2093 |var: &hir::Variant| match var.data {
2094 hir::VariantData::Unit(..) => true,
2098 let has_disr = |var: &hir::Variant| var.disr_expr.is_some();
2099 let has_non_units = vs.iter().any(|var| !is_unit(var));
2100 let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
2101 let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
2103 if disr_non_unit || (disr_units && has_non_units) {
2104 let mut err = struct_span_err!(tcx.sess, sp, E0732,
2105 "`#[repr(inttype)]` must be specified");
2110 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
2111 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
2112 // Check for duplicate discriminant values
2113 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
2114 let variant_did = def.variants[VariantIdx::new(i)].def_id;
2115 let variant_i_hir_id = tcx.hir().as_local_hir_id(variant_did).unwrap();
2116 let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
2117 let i_span = match variant_i.disr_expr {
2118 Some(ref expr) => tcx.hir().span(expr.hir_id),
2119 None => tcx.hir().span(variant_i_hir_id)
2121 let span = match v.disr_expr {
2122 Some(ref expr) => tcx.hir().span(expr.hir_id),
2125 struct_span_err!(tcx.sess, span, E0081,
2126 "discriminant value `{}` already exists", disr_vals[i])
2127 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
2128 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
2131 disr_vals.push(discr);
2134 check_representable(tcx, sp, def_id);
2135 check_transparent(tcx, sp, def_id);
2138 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
2139 span_err!(tcx.sess, span, E0533,
2140 "expected unit struct/variant or constant, found {} `{}`",
2142 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
2145 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
2146 fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2150 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
2151 -> &'tcx ty::GenericPredicates<'tcx>
2154 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
2155 let item_id = tcx.hir().ty_param_owner(hir_id);
2156 let item_def_id = tcx.hir().local_def_id(item_id);
2157 let generics = tcx.generics_of(item_def_id);
2158 let index = generics.param_def_id_to_index[&def_id];
2159 tcx.arena.alloc(ty::GenericPredicates {
2161 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
2163 ty::Predicate::Trait(ref data)
2164 if data.skip_binder().self_ty().is_param(index) => {
2165 // HACK(eddyb) should get the original `Span`.
2166 let span = tcx.def_span(def_id);
2167 Some((predicate, span))
2177 def: Option<&ty::GenericParamDef>,
2179 ) -> Option<ty::Region<'tcx>> {
2181 Some(def) => infer::EarlyBoundRegion(span, def.name),
2182 None => infer::MiscVariable(span)
2184 Some(self.next_region_var(v))
2187 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
2188 if let Some(param) = param {
2189 if let UnpackedKind::Type(ty) = self.var_for_def(span, param).unpack() {
2194 self.next_ty_var(TypeVariableOrigin {
2195 kind: TypeVariableOriginKind::TypeInference,
2204 param: Option<&ty::GenericParamDef>,
2206 ) -> &'tcx Const<'tcx> {
2207 if let Some(param) = param {
2208 if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
2213 self.next_const_var(ty, ConstVariableOrigin {
2214 kind: ConstVariableOriginKind::ConstInference,
2220 fn projected_ty_from_poly_trait_ref(&self,
2223 poly_trait_ref: ty::PolyTraitRef<'tcx>)
2226 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
2228 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
2232 self.tcx().mk_projection(item_def_id, trait_ref.substs)
2235 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
2236 if ty.has_escaping_bound_vars() {
2237 ty // FIXME: normalization and escaping regions
2239 self.normalize_associated_types_in(span, &ty)
2243 fn set_tainted_by_errors(&self) {
2244 self.infcx.set_tainted_by_errors()
2247 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
2248 self.write_ty(hir_id, ty)
2252 /// Controls whether the arguments are tupled. This is used for the call
2255 /// Tupling means that all call-side arguments are packed into a tuple and
2256 /// passed as a single parameter. For example, if tupling is enabled, this
2259 /// fn f(x: (isize, isize))
2261 /// Can be called as:
2268 #[derive(Clone, Eq, PartialEq)]
2269 enum TupleArgumentsFlag {
2274 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2276 inh: &'a Inherited<'a, 'tcx>,
2277 param_env: ty::ParamEnv<'tcx>,
2278 body_id: hir::HirId,
2279 ) -> FnCtxt<'a, 'tcx> {
2283 err_count_on_creation: inh.tcx.sess.err_count(),
2285 ret_coercion_span: RefCell::new(None),
2287 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
2288 hir::CRATE_HIR_ID)),
2289 diverges: Cell::new(Diverges::Maybe),
2290 has_errors: Cell::new(false),
2291 enclosing_breakables: RefCell::new(EnclosingBreakables {
2293 by_id: Default::default(),
2299 pub fn sess(&self) -> &Session {
2303 pub fn errors_reported_since_creation(&self) -> bool {
2304 self.tcx.sess.err_count() > self.err_count_on_creation
2307 /// Produces warning on the given node, if the current point in the
2308 /// function is unreachable, and there hasn't been another warning.
2309 fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
2310 if self.diverges.get() == Diverges::Always &&
2311 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
2312 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
2313 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
2314 !span.is_desugaring(DesugaringKind::CondTemporary) {
2315 self.diverges.set(Diverges::WarnedAlways);
2317 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2319 let msg = format!("unreachable {}", kind);
2320 self.tcx().lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg);
2326 code: ObligationCauseCode<'tcx>)
2327 -> ObligationCause<'tcx> {
2328 ObligationCause::new(span, self.body_id, code)
2331 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2332 self.cause(span, ObligationCauseCode::MiscObligation)
2335 /// Resolves type variables in `ty` if possible. Unlike the infcx
2336 /// version (resolve_vars_if_possible), this version will
2337 /// also select obligations if it seems useful, in an effort
2338 /// to get more type information.
2339 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2340 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2342 // No Infer()? Nothing needs doing.
2343 if !ty.has_infer_types() {
2344 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2348 // If `ty` is a type variable, see whether we already know what it is.
2349 ty = self.resolve_vars_if_possible(&ty);
2350 if !ty.has_infer_types() {
2351 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2355 // If not, try resolving pending obligations as much as
2356 // possible. This can help substantially when there are
2357 // indirect dependencies that don't seem worth tracking
2359 self.select_obligations_where_possible(false, |_| {});
2360 ty = self.resolve_vars_if_possible(&ty);
2362 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2366 fn record_deferred_call_resolution(
2368 closure_def_id: DefId,
2369 r: DeferredCallResolution<'tcx>,
2371 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2372 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2375 fn remove_deferred_call_resolutions(
2377 closure_def_id: DefId,
2378 ) -> Vec<DeferredCallResolution<'tcx>> {
2379 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2380 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2383 pub fn tag(&self) -> String {
2384 format!("{:p}", self)
2387 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
2388 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2389 span_bug!(span, "no type for local variable {}",
2390 self.tcx.hir().node_to_string(nid))
2395 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2396 debug!("write_ty({:?}, {:?}) in fcx {}",
2397 id, self.resolve_vars_if_possible(&ty), self.tag());
2398 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2400 if ty.references_error() {
2401 self.has_errors.set(true);
2402 self.set_tainted_by_errors();
2406 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
2407 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2410 fn write_resolution(&self, hir_id: hir::HirId, r: Result<(DefKind, DefId), ErrorReported>) {
2411 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
2414 pub fn write_method_call(&self,
2416 method: MethodCallee<'tcx>) {
2417 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2418 self.write_resolution(hir_id, Ok((DefKind::Method, method.def_id)));
2419 self.write_substs(hir_id, method.substs);
2421 // When the method is confirmed, the `method.substs` includes
2422 // parameters from not just the method, but also the impl of
2423 // the method -- in particular, the `Self` type will be fully
2424 // resolved. However, those are not something that the "user
2425 // specified" -- i.e., those types come from the inferred type
2426 // of the receiver, not something the user wrote. So when we
2427 // create the user-substs, we want to replace those earlier
2428 // types with just the types that the user actually wrote --
2429 // that is, those that appear on the *method itself*.
2431 // As an example, if the user wrote something like
2432 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2433 // type of `foo` (possibly adjusted), but we don't want to
2434 // include that. We want just the `[_, u32]` part.
2435 if !method.substs.is_noop() {
2436 let method_generics = self.tcx.generics_of(method.def_id);
2437 if !method_generics.params.is_empty() {
2438 let user_type_annotation = self.infcx.probe(|_| {
2439 let user_substs = UserSubsts {
2440 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
2441 let i = param.index as usize;
2442 if i < method_generics.parent_count {
2443 self.infcx.var_for_def(DUMMY_SP, param)
2448 user_self_ty: None, // not relevant here
2451 self.infcx.canonicalize_user_type_annotation(&UserType::TypeOf(
2457 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
2458 self.write_user_type_annotation(hir_id, user_type_annotation);
2463 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
2464 if !substs.is_noop() {
2465 debug!("write_substs({:?}, {:?}) in fcx {}",
2470 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2474 /// Given the substs that we just converted from the HIR, try to
2475 /// canonicalize them and store them as user-given substitutions
2476 /// (i.e., substitutions that must be respected by the NLL check).
2478 /// This should be invoked **before any unifications have
2479 /// occurred**, so that annotations like `Vec<_>` are preserved
2481 pub fn write_user_type_annotation_from_substs(
2485 substs: SubstsRef<'tcx>,
2486 user_self_ty: Option<UserSelfTy<'tcx>>,
2489 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
2490 user_self_ty={:?} in fcx {}",
2491 hir_id, def_id, substs, user_self_ty, self.tag(),
2494 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
2495 let canonicalized = self.infcx.canonicalize_user_type_annotation(
2496 &UserType::TypeOf(def_id, UserSubsts {
2501 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
2502 self.write_user_type_annotation(hir_id, canonicalized);
2506 pub fn write_user_type_annotation(
2509 canonical_user_type_annotation: CanonicalUserType<'tcx>,
2512 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
2513 hir_id, canonical_user_type_annotation, self.tag(),
2516 if !canonical_user_type_annotation.is_identity() {
2517 self.tables.borrow_mut().user_provided_types_mut().insert(
2518 hir_id, canonical_user_type_annotation
2521 debug!("write_user_type_annotation: skipping identity substs");
2525 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2526 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2532 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2533 Entry::Vacant(entry) => { entry.insert(adj); },
2534 Entry::Occupied(mut entry) => {
2535 debug!(" - composing on top of {:?}", entry.get());
2536 match (&entry.get()[..], &adj[..]) {
2537 // Applying any adjustment on top of a NeverToAny
2538 // is a valid NeverToAny adjustment, because it can't
2540 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2542 Adjustment { kind: Adjust::Deref(_), .. },
2543 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2545 Adjustment { kind: Adjust::Deref(_), .. },
2546 .. // Any following adjustments are allowed.
2548 // A reborrow has no effect before a dereference.
2550 // FIXME: currently we never try to compose autoderefs
2551 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2553 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2554 expr, entry.get(), adj)
2556 *entry.get_mut() = adj;
2561 /// Basically whenever we are converting from a type scheme into
2562 /// the fn body space, we always want to normalize associated
2563 /// types as well. This function combines the two.
2564 fn instantiate_type_scheme<T>(&self,
2566 substs: SubstsRef<'tcx>,
2569 where T : TypeFoldable<'tcx>
2571 let value = value.subst(self.tcx, substs);
2572 let result = self.normalize_associated_types_in(span, &value);
2573 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2580 /// As `instantiate_type_scheme`, but for the bounds found in a
2581 /// generic type scheme.
2582 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: SubstsRef<'tcx>)
2583 -> ty::InstantiatedPredicates<'tcx> {
2584 let bounds = self.tcx.predicates_of(def_id);
2585 let result = bounds.instantiate(self.tcx, substs);
2586 let result = self.normalize_associated_types_in(span, &result);
2587 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2594 /// Replaces the opaque types from the given value with type variables,
2595 /// and records the `OpaqueTypeMap` for later use during writeback. See
2596 /// `InferCtxt::instantiate_opaque_types` for more details.
2597 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2599 parent_id: hir::HirId,
2603 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2604 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2608 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2609 self.instantiate_opaque_types(
2618 let mut opaque_types = self.opaque_types.borrow_mut();
2619 for (ty, decl) in opaque_type_map {
2620 let old_value = opaque_types.insert(ty, decl);
2621 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2627 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2628 where T : TypeFoldable<'tcx>
2630 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2633 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2635 where T : TypeFoldable<'tcx>
2637 self.inh.partially_normalize_associated_types_in(span,
2643 pub fn require_type_meets(&self,
2646 code: traits::ObligationCauseCode<'tcx>,
2649 self.register_bound(
2652 traits::ObligationCause::new(span, self.body_id, code));
2655 pub fn require_type_is_sized(&self,
2658 code: traits::ObligationCauseCode<'tcx>)
2660 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2661 self.require_type_meets(ty, span, code, lang_item);
2664 pub fn require_type_is_sized_deferred(&self,
2667 code: traits::ObligationCauseCode<'tcx>)
2669 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2672 pub fn register_bound(&self,
2675 cause: traits::ObligationCause<'tcx>)
2677 self.fulfillment_cx.borrow_mut()
2678 .register_bound(self, self.param_env, ty, def_id, cause);
2681 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2682 let t = AstConv::ast_ty_to_ty(self, ast_t);
2683 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2687 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2688 let ty = self.to_ty(ast_ty);
2689 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
2691 if Self::can_contain_user_lifetime_bounds(ty) {
2692 let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
2693 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
2694 self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
2700 /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
2701 pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
2702 AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
2705 pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
2706 AstConv::ast_const_to_const(self, ast_c, ty)
2709 // If the type given by the user has free regions, save it for later, since
2710 // NLL would like to enforce those. Also pass in types that involve
2711 // projections, since those can resolve to `'static` bounds (modulo #54940,
2712 // which hopefully will be fixed by the time you see this comment, dear
2713 // reader, although I have my doubts). Also pass in types with inference
2714 // types, because they may be repeated. Other sorts of things are already
2715 // sufficiently enforced with erased regions. =)
2716 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2718 T: TypeFoldable<'tcx>
2720 t.has_free_regions() || t.has_projections() || t.has_infer_types()
2723 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2724 match self.tables.borrow().node_types().get(id) {
2726 None if self.is_tainted_by_errors() => self.tcx.types.err,
2728 bug!("no type for node {}: {} in fcx {}",
2729 id, self.tcx.hir().node_to_string(id),
2735 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2736 /// outlive the region `r`.
2737 pub fn register_wf_obligation(&self,
2740 code: traits::ObligationCauseCode<'tcx>)
2742 // WF obligations never themselves fail, so no real need to give a detailed cause:
2743 let cause = traits::ObligationCause::new(span, self.body_id, code);
2744 self.register_predicate(traits::Obligation::new(cause,
2746 ty::Predicate::WellFormed(ty)));
2749 /// Registers obligations that all types appearing in `substs` are well-formed.
2750 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
2751 for ty in substs.types() {
2752 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2756 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2757 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2758 /// trait/region obligations.
2760 /// For example, if there is a function:
2763 /// fn foo<'a,T:'a>(...)
2766 /// and a reference:
2772 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2773 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2774 pub fn add_obligations_for_parameters(&self,
2775 cause: traits::ObligationCause<'tcx>,
2776 predicates: &ty::InstantiatedPredicates<'tcx>)
2778 assert!(!predicates.has_escaping_bound_vars());
2780 debug!("add_obligations_for_parameters(predicates={:?})",
2783 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2784 self.register_predicate(obligation);
2788 // FIXME(arielb1): use this instead of field.ty everywhere
2789 // Only for fields! Returns <none> for methods>
2790 // Indifferent to privacy flags
2791 pub fn field_ty(&self,
2793 field: &'tcx ty::FieldDef,
2794 substs: SubstsRef<'tcx>)
2797 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2800 fn check_casts(&self) {
2801 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2802 for cast in deferred_cast_checks.drain(..) {
2807 fn resolve_generator_interiors(&self, def_id: DefId) {
2808 let mut generators = self.deferred_generator_interiors.borrow_mut();
2809 for (body_id, interior, kind) in generators.drain(..) {
2810 self.select_obligations_where_possible(false, |_| {});
2811 generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
2815 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2816 // Non-numerics get replaced with ! or () (depending on whether
2817 // feature(never_type) is enabled, unconstrained ints with i32,
2818 // unconstrained floats with f64.
2819 // Fallback becomes very dubious if we have encountered type-checking errors.
2820 // In that case, fallback to Error.
2821 // The return value indicates whether fallback has occurred.
2822 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2823 use rustc::ty::error::UnconstrainedNumeric::Neither;
2824 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2826 assert!(ty.is_ty_infer());
2827 let fallback = match self.type_is_unconstrained_numeric(ty) {
2828 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2829 UnconstrainedInt => self.tcx.types.i32,
2830 UnconstrainedFloat => self.tcx.types.f64,
2831 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2832 Neither => return false,
2834 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
2835 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2839 fn select_all_obligations_or_error(&self) {
2840 debug!("select_all_obligations_or_error");
2841 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2842 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2846 /// Select as many obligations as we can at present.
2847 fn select_obligations_where_possible(
2849 fallback_has_occurred: bool,
2850 f: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
2852 if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2854 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2858 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2859 /// returns a type of `&T`, but the actual type we assign to the
2860 /// *expression* is `T`. So this function just peels off the return
2861 /// type by one layer to yield `T`.
2862 fn make_overloaded_place_return_type(&self,
2863 method: MethodCallee<'tcx>)
2864 -> ty::TypeAndMut<'tcx>
2866 // extract method return type, which will be &T;
2867 let ret_ty = method.sig.output();
2869 // method returns &T, but the type as visible to user is T, so deref
2870 ret_ty.builtin_deref(true).unwrap()
2876 base_expr: &'tcx hir::Expr,
2880 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2881 // FIXME(#18741) -- this is almost but not quite the same as the
2882 // autoderef that normal method probing does. They could likely be
2885 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2886 let mut result = None;
2887 while result.is_none() && autoderef.next().is_some() {
2888 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2890 autoderef.finalize(self);
2894 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2895 /// (and otherwise adjust) `base_expr`, looking for a type which either
2896 /// supports builtin indexing or overloaded indexing.
2897 /// This loop implements one step in that search; the autoderef loop
2898 /// is implemented by `lookup_indexing`.
2902 base_expr: &hir::Expr,
2903 autoderef: &Autoderef<'a, 'tcx>,
2906 ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
2907 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2908 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2915 for &unsize in &[false, true] {
2916 let mut self_ty = adjusted_ty;
2918 // We only unsize arrays here.
2919 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2920 self_ty = self.tcx.mk_slice(element_ty);
2926 // If some lookup succeeds, write callee into table and extract index/element
2927 // type from the method signature.
2928 // If some lookup succeeded, install method in table
2929 let input_ty = self.next_ty_var(TypeVariableOrigin {
2930 kind: TypeVariableOriginKind::AutoDeref,
2931 span: base_expr.span,
2933 let method = self.try_overloaded_place_op(
2934 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2936 let result = method.map(|ok| {
2937 debug!("try_index_step: success, using overloaded indexing");
2938 let method = self.register_infer_ok_obligations(ok);
2940 let mut adjustments = autoderef.adjust_steps(self, needs);
2941 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2942 let mutbl = match r_mutbl {
2943 hir::MutImmutable => AutoBorrowMutability::Immutable,
2944 hir::MutMutable => AutoBorrowMutability::Mutable {
2945 // Indexing can be desugared to a method call,
2946 // so maybe we could use two-phase here.
2947 // See the documentation of AllowTwoPhase for why that's
2948 // not the case today.
2949 allow_two_phase_borrow: AllowTwoPhase::No,
2952 adjustments.push(Adjustment {
2953 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2954 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2961 adjustments.push(Adjustment {
2962 kind: Adjust::Pointer(PointerCast::Unsize),
2963 target: method.sig.inputs()[0]
2966 self.apply_adjustments(base_expr, adjustments);
2968 self.write_method_call(expr.hir_id, method);
2969 (input_ty, self.make_overloaded_place_return_type(method).ty)
2971 if result.is_some() {
2979 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
2980 let (tr, name) = match (op, is_mut) {
2981 (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
2982 (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
2983 (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
2984 (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
2986 (tr, ast::Ident::with_dummy_span(name))
2989 fn try_overloaded_place_op(&self,
2992 arg_tys: &[Ty<'tcx>],
2995 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2997 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
3003 // Try Mut first, if needed.
3004 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
3005 let method = match (needs, mut_tr) {
3006 (Needs::MutPlace, Some(trait_did)) => {
3007 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
3012 // Otherwise, fall back to the immutable version.
3013 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
3014 let method = match (method, imm_tr) {
3015 (None, Some(trait_did)) => {
3016 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
3018 (method, _) => method,
3024 fn check_method_argument_types(
3028 method: Result<MethodCallee<'tcx>, ()>,
3029 args_no_rcvr: &'tcx [hir::Expr],
3030 tuple_arguments: TupleArgumentsFlag,
3031 expected: Expectation<'tcx>,
3033 let has_error = match method {
3035 method.substs.references_error() || method.sig.references_error()
3040 let err_inputs = self.err_args(args_no_rcvr.len());
3042 let err_inputs = match tuple_arguments {
3043 DontTupleArguments => err_inputs,
3044 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
3047 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
3048 false, tuple_arguments, None);
3049 return self.tcx.types.err;
3052 let method = method.unwrap();
3053 // HACK(eddyb) ignore self in the definition (see above).
3054 let expected_arg_tys = self.expected_inputs_for_expected_output(
3057 method.sig.output(),
3058 &method.sig.inputs()[1..]
3060 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
3061 args_no_rcvr, method.sig.c_variadic, tuple_arguments,
3062 self.tcx.hir().span_if_local(method.def_id));
3066 fn self_type_matches_expected_vid(
3068 trait_ref: ty::PolyTraitRef<'tcx>,
3069 expected_vid: ty::TyVid,
3071 let self_ty = self.shallow_resolve(trait_ref.self_ty());
3073 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
3074 trait_ref, self_ty, expected_vid
3077 ty::Infer(ty::TyVar(found_vid)) => {
3078 // FIXME: consider using `sub_root_var` here so we
3079 // can see through subtyping.
3080 let found_vid = self.root_var(found_vid);
3081 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
3082 expected_vid == found_vid
3088 fn obligations_for_self_ty<'b>(
3091 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
3094 // FIXME: consider using `sub_root_var` here so we
3095 // can see through subtyping.
3096 let ty_var_root = self.root_var(self_ty);
3097 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
3098 self_ty, ty_var_root,
3099 self.fulfillment_cx.borrow().pending_obligations());
3103 .pending_obligations()
3105 .filter_map(move |obligation| match obligation.predicate {
3106 ty::Predicate::Projection(ref data) =>
3107 Some((data.to_poly_trait_ref(self.tcx), obligation)),
3108 ty::Predicate::Trait(ref data) =>
3109 Some((data.to_poly_trait_ref(), obligation)),
3110 ty::Predicate::Subtype(..) => None,
3111 ty::Predicate::RegionOutlives(..) => None,
3112 ty::Predicate::TypeOutlives(..) => None,
3113 ty::Predicate::WellFormed(..) => None,
3114 ty::Predicate::ObjectSafe(..) => None,
3115 ty::Predicate::ConstEvaluatable(..) => None,
3116 // N.B., this predicate is created by breaking down a
3117 // `ClosureType: FnFoo()` predicate, where
3118 // `ClosureType` represents some `Closure`. It can't
3119 // possibly be referring to the current closure,
3120 // because we haven't produced the `Closure` for
3121 // this closure yet; this is exactly why the other
3122 // code is looking for a self type of a unresolved
3123 // inference variable.
3124 ty::Predicate::ClosureKind(..) => None,
3125 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
3128 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
3129 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
3130 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
3134 /// Generic function that factors out common logic from function calls,
3135 /// method calls and overloaded operators.
3136 fn check_argument_types(
3140 fn_inputs: &[Ty<'tcx>],
3141 expected_arg_tys: &[Ty<'tcx>],
3142 args: &'tcx [hir::Expr],
3144 tuple_arguments: TupleArgumentsFlag,
3145 def_span: Option<Span>,
3149 // Grab the argument types, supplying fresh type variables
3150 // if the wrong number of arguments were supplied
3151 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
3157 // All the input types from the fn signature must outlive the call
3158 // so as to validate implied bounds.
3159 for &fn_input_ty in fn_inputs {
3160 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
3163 let expected_arg_count = fn_inputs.len();
3165 let param_count_error = |expected_count: usize,
3170 let mut err = tcx.sess.struct_span_err_with_code(sp,
3171 &format!("this function takes {}{} but {} {} supplied",
3172 if c_variadic { "at least " } else { "" },
3173 potentially_plural_count(expected_count, "parameter"),
3174 potentially_plural_count(arg_count, "parameter"),
3175 if arg_count == 1 {"was"} else {"were"}),
3176 DiagnosticId::Error(error_code.to_owned()));
3178 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
3179 err.span_label(def_s, "defined here");
3182 let sugg_span = tcx.sess.source_map().end_point(expr_sp);
3183 // remove closing `)` from the span
3184 let sugg_span = sugg_span.shrink_to_lo();
3185 err.span_suggestion(
3187 "expected the unit value `()`; create it with empty parentheses",
3189 Applicability::MachineApplicable);
3191 err.span_label(sp, format!("expected {}{}",
3192 if c_variadic { "at least " } else { "" },
3193 potentially_plural_count(expected_count, "parameter")));
3198 let mut expected_arg_tys = expected_arg_tys.to_vec();
3200 let formal_tys = if tuple_arguments == TupleArguments {
3201 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
3202 match tuple_type.sty {
3203 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
3204 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
3205 expected_arg_tys = vec![];
3206 self.err_args(args.len())
3208 ty::Tuple(arg_types) => {
3209 expected_arg_tys = match expected_arg_tys.get(0) {
3210 Some(&ty) => match ty.sty {
3211 ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
3216 arg_types.iter().map(|k| k.expect_ty()).collect()
3219 span_err!(tcx.sess, sp, E0059,
3220 "cannot use call notation; the first type parameter \
3221 for the function trait is neither a tuple nor unit");
3222 expected_arg_tys = vec![];
3223 self.err_args(args.len())
3226 } else if expected_arg_count == supplied_arg_count {
3228 } else if c_variadic {
3229 if supplied_arg_count >= expected_arg_count {
3232 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
3233 expected_arg_tys = vec![];
3234 self.err_args(supplied_arg_count)
3237 // is the missing argument of type `()`?
3238 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
3239 self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
3240 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
3241 self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
3245 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
3247 expected_arg_tys = vec![];
3248 self.err_args(supplied_arg_count)
3251 debug!("check_argument_types: formal_tys={:?}",
3252 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
3254 // If there is no expectation, expect formal_tys.
3255 let expected_arg_tys = if !expected_arg_tys.is_empty() {
3261 let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
3263 // Check the arguments.
3264 // We do this in a pretty awful way: first we type-check any arguments
3265 // that are not closures, then we type-check the closures. This is so
3266 // that we have more information about the types of arguments when we
3267 // type-check the functions. This isn't really the right way to do this.
3268 for &check_closures in &[false, true] {
3269 debug!("check_closures={}", check_closures);
3271 // More awful hacks: before we check argument types, try to do
3272 // an "opportunistic" vtable resolution of any trait bounds on
3273 // the call. This helps coercions.
3275 self.select_obligations_where_possible(false, |errors| {
3276 self.point_at_arg_instead_of_call_if_possible(
3278 &final_arg_types[..],
3285 // For C-variadic functions, we don't have a declared type for all of
3286 // the arguments hence we only do our usual type checking with
3287 // the arguments who's types we do know.
3288 let t = if c_variadic {
3290 } else if tuple_arguments == TupleArguments {
3295 for (i, arg) in args.iter().take(t).enumerate() {
3296 // Warn only for the first loop (the "no closures" one).
3297 // Closure arguments themselves can't be diverging, but
3298 // a previous argument can, e.g., `foo(panic!(), || {})`.
3299 if !check_closures {
3300 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
3303 let is_closure = match arg.node {
3304 ExprKind::Closure(..) => true,
3308 if is_closure != check_closures {
3312 debug!("checking the argument");
3313 let formal_ty = formal_tys[i];
3315 // The special-cased logic below has three functions:
3316 // 1. Provide as good of an expected type as possible.
3317 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
3319 let checked_ty = self.check_expr_with_expectation(&arg, expected);
3321 // 2. Coerce to the most detailed type that could be coerced
3322 // to, which is `expected_ty` if `rvalue_hint` returns an
3323 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
3324 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
3325 // We're processing function arguments so we definitely want to use
3326 // two-phase borrows.
3327 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
3328 final_arg_types.push((i, coerce_ty));
3330 // 3. Relate the expected type and the formal one,
3331 // if the expected type was used for the coercion.
3332 self.demand_suptype(arg.span, formal_ty, coerce_ty);
3336 // We also need to make sure we at least write the ty of the other
3337 // arguments which we skipped above.
3339 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
3340 use crate::structured_errors::{VariadicError, StructuredDiagnostic};
3341 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
3344 for arg in args.iter().skip(expected_arg_count) {
3345 let arg_ty = self.check_expr(&arg);
3347 // There are a few types which get autopromoted when passed via varargs
3348 // in C but we just error out instead and require explicit casts.
3349 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3351 ty::Float(ast::FloatTy::F32) => {
3352 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3354 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3355 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3357 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3358 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3361 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3362 let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
3363 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3371 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3372 vec![self.tcx.types.err; len]
3375 fn point_at_arg_instead_of_call_if_possible(
3377 errors: &mut Vec<traits::FulfillmentError<'_>>,
3378 final_arg_types: &[(usize, Ty<'tcx>)],
3380 args: &'tcx [hir::Expr],
3382 if !call_sp.desugaring_kind().is_some() {
3383 // We *do not* do this for desugared call spans to keep good diagnostics when involving
3384 // the `?` operator.
3385 for error in errors {
3386 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
3387 let mut referenced_in = vec![];
3388 for (i, ty) in final_arg_types {
3389 let ty = self.resolve_vars_if_possible(ty);
3390 for ty in ty.walk() {
3391 if ty == predicate.skip_binder().self_ty() {
3392 referenced_in.push(*i);
3396 let mut referenced_in = final_arg_types.iter()
3397 .flat_map(|(i, ty)| {
3398 let ty = self.resolve_vars_if_possible(ty);
3400 .filter(|&ty| ty == predicate.skip_binder().self_ty())
3403 if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3404 // We make sure that only *one* argument matches the obligation failure
3405 // and thet the obligation's span to its expression's.
3406 error.obligation.cause.span = args[ref_in].span;
3407 error.points_at_arg_span = true;
3414 // AST fragment checking
3417 expected: Expectation<'tcx>)
3423 ast::LitKind::Str(..) => tcx.mk_static_str(),
3424 ast::LitKind::ByteStr(ref v) => {
3425 tcx.mk_imm_ref(tcx.lifetimes.re_static,
3426 tcx.mk_array(tcx.types.u8, v.len() as u64))
3428 ast::LitKind::Byte(_) => tcx.types.u8,
3429 ast::LitKind::Char(_) => tcx.types.char,
3430 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3431 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3432 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3433 let opt_ty = expected.to_option(self).and_then(|ty| {
3435 ty::Int(_) | ty::Uint(_) => Some(ty),
3436 ty::Char => Some(tcx.types.u8),
3437 ty::RawPtr(..) => Some(tcx.types.usize),
3438 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3442 opt_ty.unwrap_or_else(|| self.next_int_var())
3444 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3445 ast::LitKind::FloatUnsuffixed(_) => {
3446 let opt_ty = expected.to_option(self).and_then(|ty| {
3448 ty::Float(_) => Some(ty),
3452 opt_ty.unwrap_or_else(|| self.next_float_var())
3454 ast::LitKind::Bool(_) => tcx.types.bool,
3455 ast::LitKind::Err(_) => tcx.types.err,
3459 // Determine the `Self` type, using fresh variables for all variables
3460 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3461 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3463 pub fn impl_self_ty(&self,
3464 span: Span, // (potential) receiver for this impl
3466 -> TypeAndSubsts<'tcx> {
3467 let ity = self.tcx.type_of(did);
3468 debug!("impl_self_ty: ity={:?}", ity);
3470 let substs = self.fresh_substs_for_item(span, did);
3471 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3473 TypeAndSubsts { substs: substs, ty: substd_ty }
3476 /// Unifies the output type with the expected type early, for more coercions
3477 /// and forward type information on the input expressions.
3478 fn expected_inputs_for_expected_output(&self,
3480 expected_ret: Expectation<'tcx>,
3481 formal_ret: Ty<'tcx>,
3482 formal_args: &[Ty<'tcx>])
3484 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3485 let ret_ty = match expected_ret.only_has_type(self) {
3487 None => return Vec::new()
3489 let expect_args = self.fudge_inference_if_ok(|| {
3490 // Attempt to apply a subtyping relationship between the formal
3491 // return type (likely containing type variables if the function
3492 // is polymorphic) and the expected return type.
3493 // No argument expectations are produced if unification fails.
3494 let origin = self.misc(call_span);
3495 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3497 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3498 // to identity so the resulting type is not constrained.
3501 // Process any obligations locally as much as
3502 // we can. We don't care if some things turn
3503 // out unconstrained or ambiguous, as we're
3504 // just trying to get hints here.
3505 self.save_and_restore_in_snapshot_flag(|_| {
3506 let mut fulfill = TraitEngine::new(self.tcx);
3507 for obligation in ok.obligations {
3508 fulfill.register_predicate_obligation(self, obligation);
3510 fulfill.select_where_possible(self)
3511 }).map_err(|_| ())?;
3513 Err(_) => return Err(()),
3516 // Record all the argument types, with the substitutions
3517 // produced from the above subtyping unification.
3518 Ok(formal_args.iter().map(|ty| {
3519 self.resolve_vars_if_possible(ty)
3521 }).unwrap_or_default();
3522 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3523 formal_args, formal_ret,
3524 expect_args, expected_ret);
3528 pub fn check_struct_path(&self,
3531 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3532 let path_span = match *qpath {
3533 QPath::Resolved(_, ref path) => path.span,
3534 QPath::TypeRelative(ref qself, _) => qself.span
3536 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
3537 let variant = match def {
3539 self.set_tainted_by_errors();
3542 Res::Def(DefKind::Variant, _) => {
3544 ty::Adt(adt, substs) => {
3545 Some((adt.variant_of_res(def), adt.did, substs))
3547 _ => bug!("unexpected type: {:?}", ty)
3550 Res::Def(DefKind::Struct, _)
3551 | Res::Def(DefKind::Union, _)
3552 | Res::Def(DefKind::TyAlias, _)
3553 | Res::Def(DefKind::AssocTy, _)
3554 | Res::SelfTy(..) => {
3556 ty::Adt(adt, substs) if !adt.is_enum() => {
3557 Some((adt.non_enum_variant(), adt.did, substs))
3562 _ => bug!("unexpected definition: {:?}", def)
3565 if let Some((variant, did, substs)) = variant {
3566 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3567 self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
3569 // Check bounds on type arguments used in the path.
3570 let bounds = self.instantiate_bounds(path_span, did, substs);
3571 let cause = traits::ObligationCause::new(
3574 traits::ItemObligation(did),
3576 self.add_obligations_for_parameters(cause, &bounds);
3580 struct_span_err!(self.tcx.sess, path_span, E0071,
3581 "expected struct, variant or union type, found {}",
3582 ty.sort_string(self.tcx))
3583 .span_label(path_span, "not a struct")
3589 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3590 // The newly resolved definition is written into `type_dependent_defs`.
3591 fn finish_resolving_struct_path(&self,
3598 QPath::Resolved(ref maybe_qself, ref path) => {
3599 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3600 let ty = AstConv::res_to_ty(self, self_ty, path, true);
3603 QPath::TypeRelative(ref qself, ref segment) => {
3604 let ty = self.to_ty(qself);
3606 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
3611 let result = AstConv::associated_path_to_ty(
3620 let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
3621 let result = result.map(|(_, kind, def_id)| (kind, def_id));
3623 // Write back the new resolution.
3624 self.write_resolution(hir_id, result);
3626 (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
3631 /// Resolves an associated value path into a base type and associated constant, or method
3632 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
3633 pub fn resolve_ty_and_res_ufcs<'b>(&self,
3637 -> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3639 debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
3640 let (ty, qself, item_segment) = match *qpath {
3641 QPath::Resolved(ref opt_qself, ref path) => {
3643 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3644 &path.segments[..]);
3646 QPath::TypeRelative(ref qself, ref segment) => {
3647 (self.to_ty(qself), qself, segment)
3650 if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
3651 // Return directly on cache hit. This is useful to avoid doubly reporting
3652 // errors with default match binding modes. See #44614.
3653 let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
3654 .unwrap_or(Res::Err);
3655 return (def, Some(ty), slice::from_ref(&**item_segment));
3657 let item_name = item_segment.ident;
3658 let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
3659 let result = match error {
3660 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
3661 _ => Err(ErrorReported),
3663 if item_name.name != kw::Invalid {
3664 self.report_method_error(
3668 SelfSource::QPath(qself),
3671 ).map(|mut e| e.emit());
3676 // Write back the new resolution.
3677 self.write_resolution(hir_id, result);
3679 result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
3681 slice::from_ref(&**item_segment),
3685 pub fn check_decl_initializer(
3687 local: &'tcx hir::Local,
3688 init: &'tcx hir::Expr,
3690 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
3691 // for #42640 (default match binding modes).
3694 let ref_bindings = local.pat.contains_explicit_ref_binding();
3696 let local_ty = self.local_ty(init.span, local.hir_id).revealed_ty;
3697 if let Some(m) = ref_bindings {
3698 // Somewhat subtle: if we have a `ref` binding in the pattern,
3699 // we want to avoid introducing coercions for the RHS. This is
3700 // both because it helps preserve sanity and, in the case of
3701 // ref mut, for soundness (issue #23116). In particular, in
3702 // the latter case, we need to be clear that the type of the
3703 // referent for the reference that results is *equal to* the
3704 // type of the place it is referencing, and not some
3705 // supertype thereof.
3706 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
3707 self.demand_eqtype(init.span, local_ty, init_ty);
3710 self.check_expr_coercable_to_type(init, local_ty)
3714 pub fn check_decl_local(&self, local: &'tcx hir::Local) {
3715 let t = self.local_ty(local.span, local.hir_id).decl_ty;
3716 self.write_ty(local.hir_id, t);
3718 if let Some(ref init) = local.init {
3719 let init_ty = self.check_decl_initializer(local, &init);
3720 if init_ty.references_error() {
3721 self.write_ty(local.hir_id, init_ty);
3725 self.check_pat_top(&local.pat, t, None);
3726 let pat_ty = self.node_ty(local.pat.hir_id);
3727 if pat_ty.references_error() {
3728 self.write_ty(local.hir_id, pat_ty);
3732 pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
3733 // Don't do all the complex logic below for `DeclItem`.
3735 hir::StmtKind::Item(..) => return,
3736 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
3739 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
3741 // Hide the outer diverging and `has_errors` flags.
3742 let old_diverges = self.diverges.get();
3743 let old_has_errors = self.has_errors.get();
3744 self.diverges.set(Diverges::Maybe);
3745 self.has_errors.set(false);
3748 hir::StmtKind::Local(ref l) => {
3749 self.check_decl_local(&l);
3752 hir::StmtKind::Item(_) => {}
3753 hir::StmtKind::Expr(ref expr) => {
3754 // Check with expected type of `()`.
3755 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
3757 hir::StmtKind::Semi(ref expr) => {
3758 self.check_expr(&expr);
3762 // Combine the diverging and `has_error` flags.
3763 self.diverges.set(self.diverges.get() | old_diverges);
3764 self.has_errors.set(self.has_errors.get() | old_has_errors);
3767 pub fn check_block_no_value(&self, blk: &'tcx hir::Block) {
3768 let unit = self.tcx.mk_unit();
3769 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
3771 // if the block produces a `!` value, that can always be
3772 // (effectively) coerced to unit.
3774 self.demand_suptype(blk.span, unit, ty);
3778 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
3779 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
3780 /// when given code like the following:
3782 /// if false { return 0i32; } else { 1u32 }
3783 /// // ^^^^ point at this instead of the whole `if` expression
3785 fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
3786 if let hir::ExprKind::Match(_, arms, _) = &expr.node {
3787 let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
3788 self.in_progress_tables
3789 .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
3790 .and_then(|arm_ty| {
3791 if arm_ty.is_never() {
3794 Some(match &arm.body.node {
3795 // Point at the tail expression when possible.
3796 hir::ExprKind::Block(block, _) => block.expr
3799 .unwrap_or(block.span),
3805 if arm_spans.len() == 1 {
3806 return arm_spans[0];
3812 fn check_block_with_expected(
3814 blk: &'tcx hir::Block,
3815 expected: Expectation<'tcx>,
3818 let mut fcx_ps = self.ps.borrow_mut();
3819 let unsafety_state = fcx_ps.recurse(blk);
3820 replace(&mut *fcx_ps, unsafety_state)
3823 // In some cases, blocks have just one exit, but other blocks
3824 // can be targeted by multiple breaks. This can happen both
3825 // with labeled blocks as well as when we desugar
3826 // a `try { ... }` expression.
3830 // 'a: { if true { break 'a Err(()); } Ok(()) }
3832 // Here we would wind up with two coercions, one from
3833 // `Err(())` and the other from the tail expression
3834 // `Ok(())`. If the tail expression is omitted, that's a
3835 // "forced unit" -- unless the block diverges, in which
3836 // case we can ignore the tail expression (e.g., `'a: {
3837 // break 'a 22; }` would not force the type of the block
3839 let tail_expr = blk.expr.as_ref();
3840 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
3841 let coerce = if blk.targeted_by_break {
3842 CoerceMany::new(coerce_to_ty)
3844 let tail_expr: &[P<hir::Expr>] = match tail_expr {
3845 Some(e) => slice::from_ref(e),
3848 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
3851 let prev_diverges = self.diverges.get();
3852 let ctxt = BreakableCtxt {
3853 coerce: Some(coerce),
3857 let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
3858 for s in &blk.stmts {
3862 // check the tail expression **without** holding the
3863 // `enclosing_breakables` lock below.
3864 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
3866 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3867 let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
3868 let coerce = ctxt.coerce.as_mut().unwrap();
3869 if let Some(tail_expr_ty) = tail_expr_ty {
3870 let tail_expr = tail_expr.unwrap();
3871 let span = self.get_expr_coercion_span(tail_expr);
3872 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
3873 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
3875 // Subtle: if there is no explicit tail expression,
3876 // that is typically equivalent to a tail expression
3877 // of `()` -- except if the block diverges. In that
3878 // case, there is no value supplied from the tail
3879 // expression (assuming there are no other breaks,
3880 // this implies that the type of the block will be
3883 // #41425 -- label the implicit `()` as being the
3884 // "found type" here, rather than the "expected type".
3885 if !self.diverges.get().always() {
3886 // #50009 -- Do not point at the entire fn block span, point at the return type
3887 // span, as it is the cause of the requirement, and
3888 // `consider_hint_about_removing_semicolon` will point at the last expression
3889 // if it were a relevant part of the error. This improves usability in editors
3890 // that highlight errors inline.
3891 let mut sp = blk.span;
3892 let mut fn_span = None;
3893 if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
3894 let ret_sp = decl.output.span();
3895 if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
3896 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
3897 // output would otherwise be incorrect and even misleading. Make sure
3898 // the span we're aiming at correspond to a `fn` body.
3899 if block_sp == blk.span {
3901 fn_span = Some(ident.span);
3905 coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
3906 if let Some(expected_ty) = expected.only_has_type(self) {
3907 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
3909 if let Some(fn_span) = fn_span {
3912 "implicitly returns `()` as its body has no tail or `return` \
3922 // If we can break from the block, then the block's exit is always reachable
3923 // (... as long as the entry is reachable) - regardless of the tail of the block.
3924 self.diverges.set(prev_diverges);
3927 let mut ty = ctxt.coerce.unwrap().complete(self);
3929 if self.has_errors.get() || ty.references_error() {
3930 ty = self.tcx.types.err
3933 self.write_ty(blk.hir_id, ty);
3935 *self.ps.borrow_mut() = prev;
3939 fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
3940 let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
3942 Node::Item(&hir::Item {
3943 node: hir::ItemKind::Fn(_, _, _, body_id), ..
3945 Node::ImplItem(&hir::ImplItem {
3946 node: hir::ImplItemKind::Method(_, body_id), ..
3948 let body = self.tcx.hir().body(body_id);
3949 if let ExprKind::Block(block, _) = &body.value.node {
3950 return Some(block.span);
3958 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
3959 fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
3960 let parent = self.tcx.hir().get(self.tcx.hir().get_parent_item(blk_id));
3961 self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
3964 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
3965 fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
3967 Node::Item(&hir::Item {
3968 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
3970 // This is less than ideal, it will not suggest a return type span on any
3971 // method called `main`, regardless of whether it is actually the entry point,
3972 // but it will still present it as the reason for the expected type.
3973 Some((decl, ident, ident.name != sym::main))
3975 Node::TraitItem(&hir::TraitItem {
3976 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
3979 }) => Some((decl, ident, true)),
3980 Node::ImplItem(&hir::ImplItem {
3981 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
3984 }) => Some((decl, ident, false)),
3989 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
3990 /// suggestion can be made, `None` otherwise.
3991 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
3992 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
3993 // `while` before reaching it, as block tail returns are not available in them.
3994 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
3995 let parent = self.tcx.hir().get(blk_id);
3996 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4000 /// On implicit return expressions with mismatched types, provides the following suggestions:
4002 /// - Points out the method's return type as the reason for the expected type.
4003 /// - Possible missing semicolon.
4004 /// - Possible missing return type if the return type is the default, and not `fn main()`.
4005 pub fn suggest_mismatched_types_on_tail(
4007 err: &mut DiagnosticBuilder<'tcx>,
4008 expression: &'tcx hir::Expr,
4014 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4015 let mut pointing_at_return_type = false;
4016 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4017 pointing_at_return_type = self.suggest_missing_return_type(
4018 err, &fn_decl, expected, found, can_suggest);
4020 self.suggest_ref_or_into(err, expression, expected, found);
4021 self.suggest_boxing_when_appropriate(err, expression, expected, found);
4022 pointing_at_return_type
4025 /// When encountering an fn-like ctor that needs to unify with a value, check whether calling
4026 /// the ctor would successfully solve the type mismatch and if so, suggest it:
4028 /// fn foo(x: usize) -> usize { x }
4029 /// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
4033 err: &mut DiagnosticBuilder<'tcx>,
4038 let hir = self.tcx.hir();
4039 let (def_id, sig) = match found.sty {
4040 ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4041 ty::Closure(def_id, substs) => {
4042 // We don't use `closure_sig` to account for malformed closures like
4043 // `|_: [_; continue]| {}` and instead we don't suggest anything.
4044 let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
4045 (def_id, match closure_sig_ty.sty {
4046 ty::FnPtr(sig) => sig,
4054 .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
4056 let sig = self.normalize_associated_types_in(expr.span, &sig);
4057 if self.can_coerce(sig.output(), expected) {
4058 let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
4059 (String::new(), Applicability::MachineApplicable)
4061 ("...".to_string(), Applicability::HasPlaceholders)
4063 let mut msg = "call this function";
4064 match hir.get_if_local(def_id) {
4065 Some(Node::Item(hir::Item {
4066 node: ItemKind::Fn(.., body_id),
4069 Some(Node::ImplItem(hir::ImplItem {
4070 node: hir::ImplItemKind::Method(_, body_id),
4073 Some(Node::TraitItem(hir::TraitItem {
4074 node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
4077 let body = hir.body(*body_id);
4078 sugg_call = body.params.iter()
4079 .map(|param| match ¶m.pat.node {
4080 hir::PatKind::Binding(_, _, ident, None)
4081 if ident.name != kw::SelfLower => ident.to_string(),
4082 _ => "_".to_string(),
4083 }).collect::<Vec<_>>().join(", ");
4085 Some(Node::Expr(hir::Expr {
4086 node: ExprKind::Closure(_, _, body_id, closure_span, _),
4087 span: full_closure_span,
4090 if *full_closure_span == expr.span {
4093 err.span_label(*closure_span, "closure defined here");
4094 msg = "call this closure";
4095 let body = hir.body(*body_id);
4096 sugg_call = body.params.iter()
4097 .map(|param| match ¶m.pat.node {
4098 hir::PatKind::Binding(_, _, ident, None)
4099 if ident.name != kw::SelfLower => ident.to_string(),
4100 _ => "_".to_string(),
4101 }).collect::<Vec<_>>().join(", ");
4103 Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
4104 sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
4105 match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
4106 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
4107 msg = "instantiate this tuple variant";
4109 Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
4110 msg = "instantiate this tuple struct";
4115 Some(Node::ForeignItem(hir::ForeignItem {
4116 node: hir::ForeignItemKind::Fn(_, idents, _),
4119 Some(Node::TraitItem(hir::TraitItem {
4120 node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
4122 })) => sugg_call = idents.iter()
4123 .map(|ident| if ident.name != kw::SelfLower {
4127 }).collect::<Vec<_>>()
4131 if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
4132 err.span_suggestion(
4134 &format!("use parentheses to {}", msg),
4135 format!("{}({})", code, sugg_call),
4144 pub fn suggest_ref_or_into(
4146 err: &mut DiagnosticBuilder<'tcx>,
4151 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4152 err.span_suggestion(
4156 Applicability::MachineApplicable,
4158 } else if let (ty::FnDef(def_id, ..), true) = (
4160 self.suggest_fn_call(err, expr, expected, found),
4162 if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
4163 let sp = self.sess().source_map().def_span(sp);
4164 err.span_label(sp, &format!("{} defined here", found));
4166 } else if !self.check_for_cast(err, expr, found, expected) {
4167 let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
4171 let methods = self.get_conversion_methods(expr.span, expected, found);
4172 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4173 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4174 .filter_map(|(receiver, method)| {
4175 let method_call = format!(".{}()", method.ident);
4176 if receiver.ends_with(&method_call) {
4177 None // do not suggest code that is already there (#53348)
4179 let method_call_list = [".to_vec()", ".to_string()"];
4180 let sugg = if receiver.ends_with(".clone()")
4181 && method_call_list.contains(&method_call.as_str()) {
4182 let max_len = receiver.rfind(".").unwrap();
4183 format!("{}{}", &receiver[..max_len], method_call)
4185 format!("{}{}", receiver, method_call)
4187 Some(if is_struct_pat_shorthand_field {
4188 format!("{}: {}", receiver, sugg)
4194 if suggestions.peek().is_some() {
4195 err.span_suggestions(
4197 "try using a conversion method",
4199 Applicability::MaybeIncorrect,
4206 /// When encountering the expected boxed value allocated in the stack, suggest allocating it
4207 /// in the heap by calling `Box::new()`.
4208 fn suggest_boxing_when_appropriate(
4210 err: &mut DiagnosticBuilder<'tcx>,
4215 if self.tcx.hir().is_const_context(expr.hir_id) {
4216 // Do not suggest `Box::new` in const context.
4219 if !expected.is_box() || found.is_box() {
4222 let boxed_found = self.tcx.mk_box(found);
4223 if let (true, Ok(snippet)) = (
4224 self.can_coerce(boxed_found, expected),
4225 self.sess().source_map().span_to_snippet(expr.span),
4227 err.span_suggestion(
4229 "store this in the heap by calling `Box::new`",
4230 format!("Box::new({})", snippet),
4231 Applicability::MachineApplicable,
4233 err.note("for more on the distinction between the stack and the \
4234 heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
4235 https://doc.rust-lang.org/rust-by-example/std/box.html, and \
4236 https://doc.rust-lang.org/std/boxed/index.html");
4241 /// A common error is to forget to add a semicolon at the end of a block, e.g.,
4245 /// bar_that_returns_u32()
4249 /// This routine checks if the return expression in a block would make sense on its own as a
4250 /// statement and the return type has been left as default or has been specified as `()`. If so,
4251 /// it suggests adding a semicolon.
4252 fn suggest_missing_semicolon(
4254 err: &mut DiagnosticBuilder<'tcx>,
4255 expression: &'tcx hir::Expr,
4259 if expected.is_unit() {
4260 // `BlockTailExpression` only relevant if the tail expr would be
4261 // useful on its own.
4262 match expression.node {
4263 ExprKind::Call(..) |
4264 ExprKind::MethodCall(..) |
4265 ExprKind::Loop(..) |
4266 ExprKind::Match(..) |
4267 ExprKind::Block(..) => {
4268 let sp = self.tcx.sess.source_map().next_point(cause_span);
4269 err.span_suggestion(
4271 "try adding a semicolon",
4273 Applicability::MachineApplicable);
4280 /// A possible error is to forget to add a return type that is needed:
4284 /// bar_that_returns_u32()
4288 /// This routine checks if the return type is left as default, the method is not part of an
4289 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4291 fn suggest_missing_return_type(
4293 err: &mut DiagnosticBuilder<'tcx>,
4294 fn_decl: &hir::FnDecl,
4299 // Only suggest changing the return type for methods that
4300 // haven't set a return type at all (and aren't `fn main()` or an impl).
4301 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4302 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4303 err.span_suggestion(
4305 "try adding a return type",
4306 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
4307 Applicability::MachineApplicable);
4310 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
4311 err.span_label(span, "possibly return type missing here?");
4314 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
4315 // `fn main()` must return `()`, do not suggest changing return type
4316 err.span_label(span, "expected `()` because of default return type");
4319 // expectation was caused by something else, not the default return
4320 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
4321 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
4322 // Only point to return type if the expected type is the return type, as if they
4323 // are not, the expectation must have been caused by something else.
4324 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4326 let ty = AstConv::ast_ty_to_ty(self, ty);
4327 debug!("suggest_missing_return_type: return type {:?}", ty);
4328 debug!("suggest_missing_return_type: expected type {:?}", ty);
4329 if ty.sty == expected.sty {
4330 err.span_label(sp, format!("expected `{}` because of return type",
4339 /// A possible error is to forget to add `.await` when using futures:
4342 /// async fn make_u32() -> u32 {
4346 /// fn take_u32(x: u32) {}
4348 /// async fn foo() {
4349 /// let x = make_u32();
4354 /// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
4355 /// expected type. If this is the case, and we are inside of an async body, it suggests adding
4356 /// `.await` to the tail of the expression.
4357 fn suggest_missing_await(
4359 err: &mut DiagnosticBuilder<'tcx>,
4364 // `.await` is not permitted outside of `async` bodies, so don't bother to suggest if the
4365 // body isn't `async`.
4366 let item_id = self.tcx().hir().get_parent_node(self.body_id);
4367 if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
4368 let body = self.tcx().hir().body(body_id);
4369 if let Some(hir::GeneratorKind::Async) = body.generator_kind {
4371 // Check for `Future` implementations by constructing a predicate to
4372 // prove: `<T as Future>::Output == U`
4373 let future_trait = self.tcx.lang_items().future_trait().unwrap();
4374 let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id;
4375 let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate {
4376 // `<T as Future>::Output`
4377 projection_ty: ty::ProjectionTy {
4379 substs: self.tcx.mk_substs_trait(
4381 self.fresh_substs_for_item(sp, item_def_id)
4388 let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
4389 if self.infcx.predicate_may_hold(&obligation) {
4390 if let Ok(code) = self.sess().source_map().span_to_snippet(sp) {
4391 err.span_suggestion(
4393 "consider using `.await` here",
4394 format!("{}.await", code),
4395 Applicability::MaybeIncorrect,
4403 /// A common error is to add an extra semicolon:
4406 /// fn foo() -> usize {
4411 /// This routine checks if the final statement in a block is an
4412 /// expression with an explicit semicolon whose type is compatible
4413 /// with `expected_ty`. If so, it suggests removing the semicolon.
4414 fn consider_hint_about_removing_semicolon(
4416 blk: &'tcx hir::Block,
4417 expected_ty: Ty<'tcx>,
4418 err: &mut DiagnosticBuilder<'_>,
4420 if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
4421 err.span_suggestion(
4423 "consider removing this semicolon",
4425 Applicability::MachineApplicable,
4430 fn could_remove_semicolon(&self, blk: &'tcx hir::Block, expected_ty: Ty<'tcx>) -> Option<Span> {
4431 // Be helpful when the user wrote `{... expr;}` and
4432 // taking the `;` off is enough to fix the error.
4433 let last_stmt = blk.stmts.last()?;
4434 let last_expr = match last_stmt.node {
4435 hir::StmtKind::Semi(ref e) => e,
4438 let last_expr_ty = self.node_ty(last_expr.hir_id);
4439 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4442 let original_span = original_sp(last_stmt.span, blk.span);
4443 Some(original_span.with_lo(original_span.hi() - BytePos(1)))
4446 // Instantiates the given path, which must refer to an item with the given
4447 // number of type parameters and type.
4448 pub fn instantiate_value_path(&self,
4449 segments: &[hir::PathSegment],
4450 self_ty: Option<Ty<'tcx>>,
4454 -> (Ty<'tcx>, Res) {
4456 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
4465 let path_segs = match res {
4466 Res::Local(_) | Res::SelfCtor(_) => vec![],
4467 Res::Def(kind, def_id) =>
4468 AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
4469 _ => bug!("instantiate_value_path on {:?}", res),
4472 let mut user_self_ty = None;
4473 let mut is_alias_variant_ctor = false;
4475 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
4476 if let Some(self_ty) = self_ty {
4477 let adt_def = self_ty.ty_adt_def().unwrap();
4478 user_self_ty = Some(UserSelfTy {
4479 impl_def_id: adt_def.did,
4482 is_alias_variant_ctor = true;
4485 Res::Def(DefKind::Method, def_id)
4486 | Res::Def(DefKind::AssocConst, def_id) => {
4487 let container = tcx.associated_item(def_id).container;
4488 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
4490 ty::TraitContainer(trait_did) => {
4491 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
4493 ty::ImplContainer(impl_def_id) => {
4494 if segments.len() == 1 {
4495 // `<T>::assoc` will end up here, and so
4496 // can `T::assoc`. It this came from an
4497 // inherent impl, we need to record the
4498 // `T` for posterity (see `UserSelfTy` for
4500 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
4501 user_self_ty = Some(UserSelfTy {
4512 // Now that we have categorized what space the parameters for each
4513 // segment belong to, let's sort out the parameters that the user
4514 // provided (if any) into their appropriate spaces. We'll also report
4515 // errors if type parameters are provided in an inappropriate place.
4517 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
4518 let generics_has_err = AstConv::prohibit_generics(
4519 self, segments.iter().enumerate().filter_map(|(index, seg)| {
4520 if !generic_segs.contains(&index) || is_alias_variant_ctor {
4527 if let Res::Local(hid) = res {
4528 let ty = self.local_ty(span, hid).decl_ty;
4529 let ty = self.normalize_associated_types_in(span, &ty);
4530 self.write_ty(hir_id, ty);
4534 if generics_has_err {
4535 // Don't try to infer type parameters when prohibited generic arguments were given.
4536 user_self_ty = None;
4539 // Now we have to compare the types that the user *actually*
4540 // provided against the types that were *expected*. If the user
4541 // did not provide any types, then we want to substitute inference
4542 // variables. If the user provided some types, we may still need
4543 // to add defaults. If the user provided *too many* types, that's
4546 let mut infer_args_for_err = FxHashSet::default();
4547 for &PathSeg(def_id, index) in &path_segs {
4548 let seg = &segments[index];
4549 let generics = tcx.generics_of(def_id);
4550 // Argument-position `impl Trait` is treated as a normal generic
4551 // parameter internally, but we don't allow users to specify the
4552 // parameter's value explicitly, so we have to do some error-
4554 let suppress_errors = AstConv::check_generic_arg_count_for_call(
4559 false, // `is_method_call`
4561 if suppress_errors {
4562 infer_args_for_err.insert(index);
4563 self.set_tainted_by_errors(); // See issue #53251.
4567 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
4568 tcx.generics_of(*def_id).has_self
4569 }).unwrap_or(false);
4571 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
4572 let ty = self.impl_self_ty(span, impl_def_id).ty;
4573 let adt_def = ty.ty_adt_def();
4576 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
4577 let variant = adt_def.non_enum_variant();
4578 let ctor_def_id = variant.ctor_def_id.unwrap();
4580 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
4585 let mut err = tcx.sess.struct_span_err(span,
4586 "the `Self` constructor can only be used with tuple or unit structs");
4587 if let Some(adt_def) = adt_def {
4588 match adt_def.adt_kind() {
4590 err.help("did you mean to use one of the enum's variants?");
4594 err.span_suggestion(
4596 "use curly brackets",
4597 String::from("Self { /* fields */ }"),
4598 Applicability::HasPlaceholders,
4605 return (tcx.types.err, res)
4611 let def_id = res.def_id();
4613 // The things we are substituting into the type should not contain
4614 // escaping late-bound regions, and nor should the base type scheme.
4615 let ty = tcx.type_of(def_id);
4617 let substs = self_ctor_substs.unwrap_or_else(|| AstConv::create_substs_for_generic_args(
4623 // Provide the generic args, and whether types should be inferred.
4625 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
4628 // If we've encountered an `impl Trait`-related error, we're just
4629 // going to infer the arguments for better error messages.
4630 if !infer_args_for_err.contains(&index) {
4631 // Check whether the user has provided generic arguments.
4632 if let Some(ref data) = segments[index].args {
4633 return (Some(data), segments[index].infer_args);
4636 return (None, segments[index].infer_args);
4641 // Provide substitutions for parameters for which (valid) arguments have been provided.
4643 match (¶m.kind, arg) {
4644 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
4645 AstConv::ast_region_to_region(self, lt, Some(param)).into()
4647 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
4648 self.to_ty(ty).into()
4650 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
4651 self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
4653 _ => unreachable!(),
4656 // Provide substitutions for parameters for which arguments are inferred.
4657 |substs, param, infer_args| {
4659 GenericParamDefKind::Lifetime => {
4660 self.re_infer(Some(param), span).unwrap().into()
4662 GenericParamDefKind::Type { has_default, .. } => {
4663 if !infer_args && has_default {
4664 // If we have a default, then we it doesn't matter that we're not
4665 // inferring the type arguments: we provide the default where any
4667 let default = tcx.type_of(param.def_id);
4670 default.subst_spanned(tcx, substs.unwrap(), Some(span))
4673 // If no type arguments were provided, we have to infer them.
4674 // This case also occurs as a result of some malformed input, e.g.
4675 // a lifetime argument being given instead of a type parameter.
4676 // Using inference instead of `Error` gives better error messages.
4677 self.var_for_def(span, param)
4680 GenericParamDefKind::Const => {
4681 // FIXME(const_generics:defaults)
4682 // No const parameters were provided, we have to infer them.
4683 self.var_for_def(span, param)
4688 assert!(!substs.has_escaping_bound_vars());
4689 assert!(!ty.has_escaping_bound_vars());
4691 // First, store the "user substs" for later.
4692 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
4694 // Add all the obligations that are required, substituting and
4695 // normalized appropriately.
4696 let bounds = self.instantiate_bounds(span, def_id, &substs);
4697 self.add_obligations_for_parameters(
4698 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
4702 // Substitute the values for the type parameters into the type of
4703 // the referenced item.
4704 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4706 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
4707 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4708 // is inherent, there is no `Self` parameter; instead, the impl needs
4709 // type parameters, which we can infer by unifying the provided `Self`
4710 // with the substituted impl type.
4711 // This also occurs for an enum variant on a type alias.
4712 let ty = tcx.type_of(impl_def_id);
4714 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4715 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4716 Ok(ok) => self.register_infer_ok_obligations(ok),
4718 self.tcx.sess.delay_span_bug(span, &format!(
4719 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4727 self.check_rustc_args_require_const(def_id, hir_id, span);
4729 debug!("instantiate_value_path: type of {:?} is {:?}",
4732 self.write_substs(hir_id, substs);
4734 (ty_substituted, res)
4737 fn check_rustc_args_require_const(&self,
4741 // We're only interested in functions tagged with
4742 // #[rustc_args_required_const], so ignore anything that's not.
4743 if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
4747 // If our calling expression is indeed the function itself, we're good!
4748 // If not, generate an error that this can only be called directly.
4749 if let Node::Expr(expr) = self.tcx.hir().get(
4750 self.tcx.hir().get_parent_node(hir_id))
4752 if let ExprKind::Call(ref callee, ..) = expr.node {
4753 if callee.hir_id == hir_id {
4759 self.tcx.sess.span_err(span, "this function can only be invoked \
4760 directly, not through a function pointer");
4763 // Resolves `typ` by a single level if `typ` is a type variable.
4764 // If no resolution is possible, then an error is reported.
4765 // Numeric inference variables may be left unresolved.
4766 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4767 let ty = self.resolve_type_vars_with_obligations(ty);
4768 if !ty.is_ty_var() {
4771 if !self.is_tainted_by_errors() {
4772 self.need_type_info_err((**self).body_id, sp, ty)
4773 .note("type must be known at this point")
4776 self.demand_suptype(sp, self.tcx.types.err, ty);
4781 fn with_breakable_ctxt<F: FnOnce() -> R, R>(
4784 ctxt: BreakableCtxt<'tcx>,
4786 ) -> (BreakableCtxt<'tcx>, R) {
4789 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4790 index = enclosing_breakables.stack.len();
4791 enclosing_breakables.by_id.insert(id, index);
4792 enclosing_breakables.stack.push(ctxt);
4796 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4797 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4798 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4799 enclosing_breakables.stack.pop().expect("missing breakable context")
4804 /// Instantiate a QueryResponse in a probe context, without a
4805 /// good ObligationCause.
4806 fn probe_instantiate_query_response(
4809 original_values: &OriginalQueryValues<'tcx>,
4810 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
4811 ) -> InferResult<'tcx, Ty<'tcx>>
4813 self.instantiate_query_response_and_region_obligations(
4814 &traits::ObligationCause::misc(span, self.body_id),
4820 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
4821 fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
4822 let mut contained_in_place = false;
4824 while let hir::Node::Expr(parent_expr) =
4825 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
4827 match &parent_expr.node {
4828 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
4829 if lhs.hir_id == expr_id {
4830 contained_in_place = true;
4836 expr_id = parent_expr.hir_id;
4843 pub fn check_bounds_are_used<'tcx>(tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>) {
4844 let own_counts = generics.own_counts();
4846 "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
4852 if own_counts.types == 0 {
4856 // Make a vector of booleans initially `false`; set to `true` when used.
4857 let mut types_used = vec![false; own_counts.types];
4859 for leaf_ty in ty.walk() {
4860 if let ty::Param(ty::ParamTy { index, .. }) = leaf_ty.sty {
4861 debug!("found use of ty param num {}", index);
4862 types_used[index as usize - own_counts.lifetimes] = true;
4863 } else if let ty::Error = leaf_ty.sty {
4864 // If there is already another error, do not emit
4865 // an error for not using a type parameter.
4866 assert!(tcx.sess.has_errors());
4871 let types = generics.params.iter().filter(|param| match param.kind {
4872 ty::GenericParamDefKind::Type { .. } => true,
4875 for (&used, param) in types_used.iter().zip(types) {
4877 let id = tcx.hir().as_local_hir_id(param.def_id).unwrap();
4878 let span = tcx.hir().span(id);
4879 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
4880 .span_label(span, "unused type parameter")
4886 fn fatally_break_rust(sess: &Session) {
4887 let handler = sess.diagnostic();
4888 handler.span_bug_no_panic(
4890 "It looks like you're trying to break rust; would you like some ICE?",
4892 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
4893 handler.note_without_error(
4894 "we would appreciate a joke overview: \
4895 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
4897 handler.note_without_error(&format!("rustc {} running on {}",
4898 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
4899 crate::session::config::host_triple(),
4903 fn potentially_plural_count(count: usize, word: &str) -> String {
4904 format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })