5 Within the check phase of type check, we check each item one at a time
6 (bodies of function expressions are checked as part of the containing
7 function). Inference is used to supply types wherever they are unknown.
9 By far the most complex case is checking the body of a function. This
10 can be broken down into several distinct phases:
12 - gather: creates type variables to represent the type of each local
13 variable and pattern binding.
15 - main: the main pass does the lion's share of the work: it
16 determines the types of all expressions, resolves
17 methods, checks for most invalid conditions, and so forth. In
18 some cases, where a type is unknown, it may create a type or region
19 variable and use that as the type of an expression.
21 In the process of checking, various constraints will be placed on
22 these type variables through the subtyping relationships requested
23 through the `demand` module. The `infer` module is in charge
24 of resolving those constraints.
26 - regionck: after main is complete, the regionck pass goes over all
27 types looking for regions and making sure that they did not escape
28 into places they are not in scope. This may also influence the
29 final assignments of the various region variables if there is some
32 - vtable: find and records the impls to use for each trait bound that
33 appears on a type parameter.
35 - writeback: writes the final types within a function body, replacing
36 type variables with their final inferred types. These final types
37 are written into the `tcx.node_types` table, which should *never* contain
38 any reference to a type variable.
42 While type checking a function, the intermediate types for the
43 expressions, blocks, and so forth contained within the function are
44 stored in `fcx.node_types` and `fcx.node_substs`. These types
45 may contain unresolved type variables. After type checking is
46 complete, the functions in the writeback module are used to take the
47 types from this table, resolve them, and then write them into their
48 permanent home in the type context `tcx`.
50 This means that during inferencing you should use `fcx.write_ty()`
51 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
52 nodes within the function.
54 The types of top-level items, which never contain unbound type
55 variables, are stored directly into the `tcx` tables.
57 N.B., a type variable is not the same thing as a type parameter. A
58 type variable is rather an "instance" of a type parameter: that is,
59 given a generic function `fn foo<T>(t: T)`: while checking the
60 function `foo`, the type `ty_param(0)` refers to the type `T`, which
61 is treated in abstract. When `foo()` is called, however, `T` will be
62 substituted for a fresh type variable `N`. This variable will
63 eventually be resolved to some concrete type (which might itself be
82 mod generator_interior;
86 use astconv::{AstConv, PathSeg};
87 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
88 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
89 use rustc::hir::def::{CtorKind, Def};
90 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
91 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
92 use rustc::hir::itemlikevisit::ItemLikeVisitor;
93 use middle::lang_items;
94 use namespace::Namespace;
95 use rustc::infer::{self, InferCtxt, InferOk, InferResult, RegionVariableOrigin};
96 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
97 use rustc_data_structures::indexed_vec::Idx;
98 use rustc_data_structures::sync::Lrc;
99 use rustc_target::spec::abi::Abi;
100 use rustc::infer::opaque_types::OpaqueTypeDecl;
101 use rustc::infer::type_variable::{TypeVariableOrigin};
102 use rustc::middle::region;
103 use rustc::mir::interpret::{ConstValue, GlobalId};
104 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
105 use rustc::ty::{self, AdtKind, Ty, TyCtxt, GenericParamDefKind, RegionKind, Visibility,
106 ToPolyTraitRef, ToPredicate};
107 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
108 use rustc::ty::fold::TypeFoldable;
109 use rustc::ty::query::Providers;
110 use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs,
111 UserSelfTy, UserSubsts};
112 use rustc::ty::util::{Representability, IntTypeExt, Discr};
113 use rustc::ty::layout::VariantIdx;
114 use syntax_pos::{self, BytePos, Span, MultiSpan};
117 use syntax::feature_gate::{GateIssue, emit_feature_err};
119 use syntax::source_map::{DUMMY_SP, original_sp};
120 use syntax::symbol::{Symbol, LocalInternedString, keywords};
121 use syntax::util::lev_distance::find_best_match_for_name;
123 use std::cell::{Cell, RefCell, Ref, RefMut};
124 use std::collections::hash_map::Entry;
126 use std::fmt::Display;
128 use std::mem::replace;
129 use std::ops::{self, Deref};
132 use require_c_abi_if_variadic;
133 use session::{CompileIncomplete, config, Session};
136 use util::captures::Captures;
137 use util::common::{ErrorReported, indenter};
138 use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap};
140 pub use self::Expectation::*;
141 use self::autoderef::Autoderef;
142 use self::callee::DeferredCallResolution;
143 use self::coercion::{CoerceMany, DynamicCoerceMany};
144 pub use self::compare_method::{compare_impl_method, compare_const_impl};
145 use self::method::{MethodCallee, SelfSource};
146 use self::TupleArgumentsFlag::*;
148 /// The type of a local binding, including the revealed type for anon types.
149 #[derive(Copy, Clone)]
150 pub struct LocalTy<'tcx> {
152 revealed_ty: Ty<'tcx>
155 /// A wrapper for InferCtxt's `in_progress_tables` field.
156 #[derive(Copy, Clone)]
157 struct MaybeInProgressTables<'a, 'tcx: 'a> {
158 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
161 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
162 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
163 match self.maybe_tables {
164 Some(tables) => tables.borrow(),
166 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
171 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
172 match self.maybe_tables {
173 Some(tables) => tables.borrow_mut(),
175 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
181 /// closures defined within the function. For example:
184 /// bar(move|| { ... })
187 /// Here, the function `foo()` and the closure passed to
188 /// `bar()` will each have their own `FnCtxt`, but they will
189 /// share the inherited fields.
190 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
191 infcx: InferCtxt<'a, 'gcx, 'tcx>,
193 tables: MaybeInProgressTables<'a, 'tcx>,
195 locals: RefCell<NodeMap<LocalTy<'tcx>>>,
197 fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
199 // Some additional `Sized` obligations badly affect type inference.
200 // These obligations are added in a later stage of typeck.
201 deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
203 // When we process a call like `c()` where `c` is a closure type,
204 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
205 // `FnOnce` closure. In that case, we defer full resolution of the
206 // call until upvar inference can kick in and make the
207 // decision. We keep these deferred resolutions grouped by the
208 // def-id of the closure, so that once we decide, we can easily go
209 // back and process them.
210 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
212 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
214 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
216 // Opaque types found in explicit return types and their
217 // associated fresh inference variable. Writeback resolves these
218 // variables to get the concrete type, which can be used to
219 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
220 opaque_types: RefCell<DefIdMap<OpaqueTypeDecl<'tcx>>>,
222 /// Each type parameter has an implicit region bound that
223 /// indicates it must outlive at least the function body (the user
224 /// may specify stronger requirements). This field indicates the
225 /// region of the callee. If it is `None`, then the parameter
226 /// environment is for an item or something where the "callee" is
228 implicit_region_bound: Option<ty::Region<'tcx>>,
230 body_id: Option<hir::BodyId>,
233 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
234 type Target = InferCtxt<'a, 'gcx, 'tcx>;
235 fn deref(&self) -> &Self::Target {
240 /// When type-checking an expression, we propagate downward
241 /// whatever type hint we are able in the form of an `Expectation`.
242 #[derive(Copy, Clone, Debug)]
243 pub enum Expectation<'tcx> {
244 /// We know nothing about what type this expression should have.
247 /// This expression is an `if` condition, it must resolve to `bool`.
250 /// This expression should have the type given (or some subtype)
251 ExpectHasType(Ty<'tcx>),
253 /// This expression will be cast to the `Ty`
254 ExpectCastableToType(Ty<'tcx>),
256 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
257 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
258 ExpectRvalueLikeUnsized(Ty<'tcx>),
261 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
262 // Disregard "castable to" expectations because they
263 // can lead us astray. Consider for example `if cond
264 // {22} else {c} as u8` -- if we propagate the
265 // "castable to u8" constraint to 22, it will pick the
266 // type 22u8, which is overly constrained (c might not
267 // be a u8). In effect, the problem is that the
268 // "castable to" expectation is not the tightest thing
269 // we can say, so we want to drop it in this case.
270 // The tightest thing we can say is "must unify with
271 // else branch". Note that in the case of a "has type"
272 // constraint, this limitation does not hold.
274 // If the expected type is just a type variable, then don't use
275 // an expected type. Otherwise, we might write parts of the type
276 // when checking the 'then' block which are incompatible with the
278 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
280 ExpectHasType(ety) => {
281 let ety = fcx.shallow_resolve(ety);
282 if !ety.is_ty_var() {
288 ExpectRvalueLikeUnsized(ety) => {
289 ExpectRvalueLikeUnsized(ety)
295 /// Provide an expectation for an rvalue expression given an *optional*
296 /// hint, which is not required for type safety (the resulting type might
297 /// be checked higher up, as is the case with `&expr` and `box expr`), but
298 /// is useful in determining the concrete type.
300 /// The primary use case is where the expected type is a fat pointer,
301 /// like `&[isize]`. For example, consider the following statement:
303 /// let x: &[isize] = &[1, 2, 3];
305 /// In this case, the expected type for the `&[1, 2, 3]` expression is
306 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
307 /// expectation `ExpectHasType([isize])`, that would be too strong --
308 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
309 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
310 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
311 /// which still is useful, because it informs integer literals and the like.
312 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
313 /// for examples of where this comes up,.
314 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
315 match fcx.tcx.struct_tail(ty).sty {
316 ty::Slice(_) | ty::Str | ty::Dynamic(..) => {
317 ExpectRvalueLikeUnsized(ty)
319 _ => ExpectHasType(ty)
323 // Resolves `expected` by a single level if it is a variable. If
324 // there is no expected type or resolution is not possible (e.g.,
325 // no constraints yet present), just returns `None`.
326 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
328 NoExpectation => NoExpectation,
329 ExpectIfCondition => ExpectIfCondition,
330 ExpectCastableToType(t) => {
331 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
333 ExpectHasType(t) => {
334 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
336 ExpectRvalueLikeUnsized(t) => {
337 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
342 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
343 match self.resolve(fcx) {
344 NoExpectation => None,
345 ExpectIfCondition => Some(fcx.tcx.types.bool),
346 ExpectCastableToType(ty) |
348 ExpectRvalueLikeUnsized(ty) => Some(ty),
352 /// It sometimes happens that we want to turn an expectation into
353 /// a **hard constraint** (i.e., something that must be satisfied
354 /// for the program to type-check). `only_has_type` will return
355 /// such a constraint, if it exists.
356 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
357 match self.resolve(fcx) {
358 ExpectHasType(ty) => Some(ty),
359 ExpectIfCondition => Some(fcx.tcx.types.bool),
360 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
364 /// Like `only_has_type`, but instead of returning `None` if no
365 /// hard constraint exists, creates a fresh type variable.
366 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
367 self.only_has_type(fcx)
368 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
372 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
379 fn maybe_mut_place(m: hir::Mutability) -> Self {
381 hir::MutMutable => Needs::MutPlace,
382 hir::MutImmutable => Needs::None,
387 #[derive(Copy, Clone)]
388 pub struct UnsafetyState {
389 pub def: ast::NodeId,
390 pub unsafety: hir::Unsafety,
391 pub unsafe_push_count: u32,
396 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
397 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
400 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
401 match self.unsafety {
402 // If this unsafe, then if the outer function was already marked as
403 // unsafe we shouldn't attribute the unsafe'ness to the block. This
404 // way the block can be warned about instead of ignoring this
405 // extraneous block (functions are never warned about).
406 hir::Unsafety::Unsafe if self.from_fn => *self,
409 let (unsafety, def, count) = match blk.rules {
410 hir::PushUnsafeBlock(..) =>
411 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
412 hir::PopUnsafeBlock(..) =>
413 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
414 hir::UnsafeBlock(..) =>
415 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
417 (unsafety, self.def, self.unsafe_push_count),
421 unsafe_push_count: count,
428 #[derive(Debug, Copy, Clone)]
434 /// Tracks whether executing a node may exit normally (versus
435 /// return/break/panic, which "diverge", leaving dead code in their
436 /// wake). Tracked semi-automatically (through type variables marked
437 /// as diverging), with some manual adjustments for control-flow
438 /// primitives (approximating a CFG).
439 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
441 /// Potentially unknown, some cases converge,
442 /// others require a CFG to determine them.
445 /// Definitely known to diverge and therefore
446 /// not reach the next sibling or its parent.
449 /// Same as `Always` but with a reachability
450 /// warning already emitted
454 // Convenience impls for combinig `Diverges`.
456 impl ops::BitAnd for Diverges {
458 fn bitand(self, other: Self) -> Self {
459 cmp::min(self, other)
463 impl ops::BitOr for Diverges {
465 fn bitor(self, other: Self) -> Self {
466 cmp::max(self, other)
470 impl ops::BitAndAssign for Diverges {
471 fn bitand_assign(&mut self, other: Self) {
472 *self = *self & other;
476 impl ops::BitOrAssign for Diverges {
477 fn bitor_assign(&mut self, other: Self) {
478 *self = *self | other;
483 fn always(self) -> bool {
484 self >= Diverges::Always
488 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
491 // this is `null` for loops where break with a value is illegal,
492 // such as `while`, `for`, and `while let`
493 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
496 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
497 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
498 by_id: NodeMap<usize>,
501 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
502 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
503 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
504 bug!("could not find enclosing breakable with id {}", target_id);
510 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
511 body_id: ast::NodeId,
513 /// The parameter environment used for proving trait obligations
514 /// in this function. This can change when we descend into
515 /// closures (as they bring new things into scope), hence it is
516 /// not part of `Inherited` (as of the time of this writing,
517 /// closures do not yet change the environment, but they will
519 param_env: ty::ParamEnv<'tcx>,
521 // Number of errors that had been reported when we started
522 // checking this function. On exit, if we find that *more* errors
523 // have been reported, we will skip regionck and other work that
524 // expects the types within the function to be consistent.
525 err_count_on_creation: usize,
527 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
528 ret_coercion_span: RefCell<Option<Span>>,
530 yield_ty: Option<Ty<'tcx>>,
532 ps: RefCell<UnsafetyState>,
534 /// Whether the last checked node generates a divergence (e.g.,
535 /// `return` will set this to Always). In general, when entering
536 /// an expression or other node in the tree, the initial value
537 /// indicates whether prior parts of the containing expression may
538 /// have diverged. It is then typically set to `Maybe` (and the
539 /// old value remembered) for processing the subparts of the
540 /// current expression. As each subpart is processed, they may set
541 /// the flag to `Always` etc. Finally, at the end, we take the
542 /// result and "union" it with the original value, so that when we
543 /// return the flag indicates if any subpart of the parent
544 /// expression (up to and including this part) has diverged. So,
545 /// if you read it after evaluating a subexpression `X`, the value
546 /// you get indicates whether any subexpression that was
547 /// evaluating up to and including `X` diverged.
549 /// We currently use this flag only for diagnostic purposes:
551 /// - To warn about unreachable code: if, after processing a
552 /// sub-expression but before we have applied the effects of the
553 /// current node, we see that the flag is set to `Always`, we
554 /// can issue a warning. This corresponds to something like
555 /// `foo(return)`; we warn on the `foo()` expression. (We then
556 /// update the flag to `WarnedAlways` to suppress duplicate
557 /// reports.) Similarly, if we traverse to a fresh statement (or
558 /// tail expression) from a `Always` setting, we will issue a
559 /// warning. This corresponds to something like `{return;
560 /// foo();}` or `{return; 22}`, where we would warn on the
563 /// An expression represents dead-code if, after checking it,
564 /// the diverges flag is set to something other than `Maybe`.
565 diverges: Cell<Diverges>,
567 /// Whether any child nodes have any type errors.
568 has_errors: Cell<bool>,
570 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
572 inh: &'a Inherited<'a, 'gcx, 'tcx>,
575 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
576 type Target = Inherited<'a, 'gcx, 'tcx>;
577 fn deref(&self) -> &Self::Target {
582 /// Helper type of a temporary returned by Inherited::build(...).
583 /// Necessary because we can't write the following bound:
584 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
585 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
586 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
590 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
591 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
592 -> InheritedBuilder<'a, 'gcx, 'tcx> {
593 let hir_id_root = if def_id.is_local() {
594 let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
595 let hir_id = tcx.hir().definitions().node_to_hir_id(node_id);
596 DefId::local(hir_id.owner)
602 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
608 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
609 fn enter<F, R>(&'tcx mut self, f: F) -> R
610 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
612 let def_id = self.def_id;
613 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
617 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
618 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
620 let item_id = tcx.hir().as_local_node_id(def_id);
621 let body_id = item_id.and_then(|id| tcx.hir().maybe_body_owned_by(id));
622 let implicit_region_bound = body_id.map(|body_id| {
623 let body = tcx.hir().body(body_id);
624 tcx.mk_region(ty::ReScope(region::Scope {
625 id: body.value.hir_id.local_id,
626 data: region::ScopeData::CallSite
631 tables: MaybeInProgressTables {
632 maybe_tables: infcx.in_progress_tables,
635 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
636 locals: RefCell::new(Default::default()),
637 deferred_sized_obligations: RefCell::new(Vec::new()),
638 deferred_call_resolutions: RefCell::new(Default::default()),
639 deferred_cast_checks: RefCell::new(Vec::new()),
640 deferred_generator_interiors: RefCell::new(Vec::new()),
641 opaque_types: RefCell::new(Default::default()),
642 implicit_region_bound,
647 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
648 debug!("register_predicate({:?})", obligation);
649 if obligation.has_escaping_bound_vars() {
650 span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
655 .register_predicate_obligation(self, obligation);
658 fn register_predicates<I>(&self, obligations: I)
659 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>>
661 for obligation in obligations {
662 self.register_predicate(obligation);
666 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
667 self.register_predicates(infer_ok.obligations);
671 fn normalize_associated_types_in<T>(&self,
673 body_id: ast::NodeId,
674 param_env: ty::ParamEnv<'tcx>,
676 where T : TypeFoldable<'tcx>
678 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
679 self.register_infer_ok_obligations(ok)
683 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
685 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
686 fn visit_item(&mut self, i: &'tcx hir::Item) {
687 check_item_type(self.tcx, i);
689 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
690 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
693 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
694 tcx.sess.track_errors(|| {
695 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
696 tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor());
700 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
701 tcx.sess.track_errors(|| {
702 tcx.hir().krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
706 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
707 tcx.typeck_item_bodies(LOCAL_CRATE)
710 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
711 -> Result<(), CompileIncomplete>
713 debug_assert!(crate_num == LOCAL_CRATE);
714 Ok(tcx.sess.track_errors(|| {
715 tcx.par_body_owners(|body_owner_def_id| {
716 ty::query::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
721 fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
722 wfcheck::check_item_well_formed(tcx, def_id);
725 fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
726 wfcheck::check_trait_item(tcx, def_id);
729 fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
730 wfcheck::check_impl_item(tcx, def_id);
733 pub fn provide(providers: &mut Providers) {
734 method::provide(providers);
735 *providers = Providers {
741 check_item_well_formed,
742 check_trait_item_well_formed,
743 check_impl_item_well_formed,
748 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
750 -> Option<ty::Destructor> {
751 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
754 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
755 /// with information about it's body-id and fn-decl (if any). Otherwise,
758 /// If this function returns "some", then `typeck_tables(def_id)` will
759 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
760 /// may not succeed. In some cases where this function returns `None`
761 /// (notably closures), `typeck_tables(def_id)` would wind up
762 /// redirecting to the owning function.
763 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
765 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
767 match tcx.hir().get(id) {
768 Node::Item(item) => {
770 hir::ItemKind::Const(_, body) |
771 hir::ItemKind::Static(_, _, body) =>
773 hir::ItemKind::Fn(ref decl, .., body) =>
774 Some((body, Some(decl))),
779 Node::TraitItem(item) => {
781 hir::TraitItemKind::Const(_, Some(body)) =>
783 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
784 Some((body, Some(&sig.decl))),
789 Node::ImplItem(item) => {
791 hir::ImplItemKind::Const(_, body) =>
793 hir::ImplItemKind::Method(ref sig, body) =>
794 Some((body, Some(&sig.decl))),
799 Node::AnonConst(constant) => Some((constant.body, None)),
804 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
807 // Closures' tables come from their outermost function,
808 // as they are part of the same "inference environment".
809 let outer_def_id = tcx.closure_base_def_id(def_id);
810 if outer_def_id != def_id {
811 return tcx.has_typeck_tables(outer_def_id);
814 let id = tcx.hir().as_local_node_id(def_id).unwrap();
815 primary_body_of(tcx, id).is_some()
818 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
821 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
824 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
826 -> &'tcx ty::TypeckTables<'tcx> {
827 // Closures' tables come from their outermost function,
828 // as they are part of the same "inference environment".
829 let outer_def_id = tcx.closure_base_def_id(def_id);
830 if outer_def_id != def_id {
831 return tcx.typeck_tables_of(outer_def_id);
834 let id = tcx.hir().as_local_node_id(def_id).unwrap();
835 let span = tcx.hir().span(id);
837 // Figure out what primary body this item has.
838 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
839 span_bug!(span, "can't type-check body of {:?}", def_id);
841 let body = tcx.hir().body(body_id);
843 let tables = Inherited::build(tcx, def_id).enter(|inh| {
844 let param_env = tcx.param_env(def_id);
845 let fcx = if let Some(decl) = fn_decl {
846 let fn_sig = tcx.fn_sig(def_id);
848 check_abi(tcx, span, fn_sig.abi());
850 // Compute the fty from point of view of inside the fn.
852 tcx.liberate_late_bound_regions(def_id, &fn_sig);
854 inh.normalize_associated_types_in(body.value.span,
859 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
862 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
863 let expected_type = 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(
876 // Gather locals in statics (because of block expressions).
877 GatherLocalsVisitor { fcx: &fcx, parent_id: id, }.visit_body(body);
879 fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
884 // All type checking constraints were added, try to fallback unsolved variables.
885 fcx.select_obligations_where_possible(false);
886 let mut fallback_has_occurred = false;
887 for ty in &fcx.unsolved_variables() {
888 fallback_has_occurred |= fcx.fallback_if_possible(ty);
890 fcx.select_obligations_where_possible(fallback_has_occurred);
892 // Even though coercion casts provide type hints, we check casts after fallback for
893 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
896 // Closure and generator analysis may run after fallback
897 // because they don't constrain other type variables.
898 fcx.closure_analyze(body);
899 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
900 fcx.resolve_generator_interiors(def_id);
902 for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
903 let ty = fcx.normalize_ty(span, ty);
904 fcx.require_type_is_sized(ty, span, code);
906 fcx.select_all_obligations_or_error();
908 if fn_decl.is_some() {
909 fcx.regionck_fn(id, body);
911 fcx.regionck_expr(body);
914 fcx.resolve_type_vars_in_body(body)
917 // Consistency check our TypeckTables instance can hold all ItemLocalIds
918 // it will need to hold.
919 assert_eq!(tables.local_id_root,
920 Some(DefId::local(tcx.hir().definitions().node_to_hir_id(id).owner)));
924 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
925 if !tcx.sess.target.target.is_abi_supported(abi) {
926 struct_span_err!(tcx.sess, span, E0570,
927 "The ABI `{}` is not supported for the current target", abi).emit()
931 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
932 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
933 parent_id: ast::NodeId,
936 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
937 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
940 // infer the variable's type
941 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
942 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
949 // take type that the user specified
950 self.fcx.locals.borrow_mut().insert(nid, typ);
957 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
958 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
959 NestedVisitorMap::None
962 // Add explicitly-declared locals.
963 fn visit_local(&mut self, local: &'gcx hir::Local) {
964 let local_ty = match local.ty {
966 let o_ty = self.fcx.to_ty(&ty);
968 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
969 self.fcx.instantiate_opaque_types_from_value(
977 let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(&revealed_ty);
978 debug!("visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
979 ty.hir_id, o_ty, revealed_ty, c_ty);
980 self.fcx.tables.borrow_mut().user_provided_tys_mut().insert(ty.hir_id, c_ty);
982 Some(LocalTy { decl_ty: o_ty, revealed_ty })
986 self.assign(local.span, local.id, local_ty);
988 debug!("Local variable {:?} is assigned type {}",
990 self.fcx.ty_to_string(
991 self.fcx.locals.borrow().get(&local.id).unwrap().clone().decl_ty));
992 intravisit::walk_local(self, local);
995 // Add pattern bindings.
996 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
997 if let PatKind::Binding(_, _, ident, _) = p.node {
998 let var_ty = self.assign(p.span, p.id, None);
1000 if !self.fcx.tcx.features().unsized_locals {
1001 self.fcx.require_type_is_sized(var_ty, p.span,
1002 traits::VariableType(p.id));
1005 debug!("Pattern binding {} is assigned to {} with type {:?}",
1007 self.fcx.ty_to_string(
1008 self.fcx.locals.borrow().get(&p.id).unwrap().clone().decl_ty),
1011 intravisit::walk_pat(self, p);
1014 // Don't descend into the bodies of nested closures
1015 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
1016 _: hir::BodyId, _: Span, _: ast::NodeId) { }
1019 /// When `check_fn` is invoked on a generator (i.e., a body that
1020 /// includes yield), it returns back some information about the yield
1022 struct GeneratorTypes<'tcx> {
1023 /// Type of value that is yielded.
1024 yield_ty: ty::Ty<'tcx>,
1026 /// Types that are captured (see `GeneratorInterior` for more).
1027 interior: ty::Ty<'tcx>,
1029 /// Indicates if the generator is movable or static (immovable)
1030 movability: hir::GeneratorMovability,
1033 /// Helper used for fns and closures. Does the grungy work of checking a function
1034 /// body and returns the function context used for that purpose, since in the case of a fn item
1035 /// there is still a bit more to do.
1038 /// * inherited: other fields inherited from the enclosing fn (if any)
1039 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1040 param_env: ty::ParamEnv<'tcx>,
1041 fn_sig: ty::FnSig<'tcx>,
1042 decl: &'gcx hir::FnDecl,
1044 body: &'gcx hir::Body,
1045 can_be_generator: Option<hir::GeneratorMovability>)
1046 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<GeneratorTypes<'tcx>>)
1048 let mut fn_sig = fn_sig.clone();
1050 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1052 // Create the function context. This is either derived from scratch or,
1053 // in the case of closures, based on the outer context.
1054 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
1055 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1057 let declared_ret_ty = fn_sig.output();
1058 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1059 let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty);
1060 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1061 fn_sig = fcx.tcx.mk_fn_sig(
1062 fn_sig.inputs().iter().cloned(),
1069 let span = body.value.span;
1071 if body.is_generator && can_be_generator.is_some() {
1072 let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
1073 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1074 fcx.yield_ty = Some(yield_ty);
1077 let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
1078 let outer_node_id = fcx.tcx.hir().as_local_node_id(outer_def_id).unwrap();
1079 GatherLocalsVisitor { fcx: &fcx, parent_id: outer_node_id, }.visit_body(body);
1081 // Add formal parameters.
1082 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1083 // Check the pattern.
1084 fcx.check_pat_walk(&arg.pat, arg_ty,
1085 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
1087 // Check that argument is Sized.
1088 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1089 // for simple cases like `fn foo(x: Trait)`,
1090 // where we would error once on the parameter as a whole, and once on the binding `x`.
1091 if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
1092 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
1095 fcx.write_ty(arg.hir_id, arg_ty);
1098 let fn_hir_id = fcx.tcx.hir().node_to_hir_id(fn_id);
1099 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
1101 fcx.check_return_expr(&body.value);
1103 // We insert the deferred_generator_interiors entry after visiting the body.
1104 // This ensures that all nested generators appear before the entry of this generator.
1105 // resolve_generator_interiors relies on this property.
1106 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1107 let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
1108 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1109 Some(GeneratorTypes {
1110 yield_ty: fcx.yield_ty.unwrap(),
1112 movability: can_be_generator.unwrap(),
1118 // Finalize the return check by taking the LUB of the return types
1119 // we saw and assigning it to the expected return type. This isn't
1120 // really expected to fail, since the coercions would have failed
1121 // earlier when trying to find a LUB.
1123 // However, the behavior around `!` is sort of complex. In the
1124 // event that the `actual_return_ty` comes back as `!`, that
1125 // indicates that the fn either does not return or "returns" only
1126 // values of type `!`. In this case, if there is an expected
1127 // return type that is *not* `!`, that should be ok. But if the
1128 // return type is being inferred, we want to "fallback" to `!`:
1130 // let x = move || panic!();
1132 // To allow for that, I am creating a type variable with diverging
1133 // fallback. This was deemed ever so slightly better than unifying
1134 // the return value with `!` because it allows for the caller to
1135 // make more assumptions about the return type (e.g., they could do
1137 // let y: Option<u32> = Some(x());
1139 // which would then cause this return type to become `u32`, not
1141 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1142 let mut actual_return_ty = coercion.complete(&fcx);
1143 if actual_return_ty.is_never() {
1144 actual_return_ty = fcx.next_diverging_ty_var(
1145 TypeVariableOrigin::DivergingFn(span));
1147 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1149 // Check that the main return type implements the termination trait.
1150 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1151 if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
1153 if let config::EntryFnType::Main = entry_type {
1154 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1155 let trait_ref = ty::TraitRef::new(term_id, substs);
1156 let return_ty_span = decl.output.span();
1157 let cause = traits::ObligationCause::new(
1158 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1160 inherited.register_predicate(
1161 traits::Obligation::new(
1162 cause, param_env, trait_ref.to_predicate()));
1168 // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
1169 if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
1170 if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
1171 if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
1172 // at this point we don't care if there are duplicate handlers or if the handler has
1173 // the wrong signature as this value we'll be used when writing metadata and that
1174 // only happens if compilation succeeded
1175 fcx.tcx.sess.has_panic_handler.try_set_same(true);
1177 if declared_ret_ty.sty != ty::Never {
1178 fcx.tcx.sess.span_err(
1180 "return type should be `!`",
1184 let inputs = fn_sig.inputs();
1185 let span = fcx.tcx.hir().span(fn_id);
1186 if inputs.len() == 1 {
1187 let arg_is_panic_info = match inputs[0].sty {
1188 ty::Ref(region, ty, mutbl) => match ty.sty {
1189 ty::Adt(ref adt, _) => {
1190 adt.did == panic_info_did &&
1191 mutbl == hir::Mutability::MutImmutable &&
1192 *region != RegionKind::ReStatic
1199 if !arg_is_panic_info {
1200 fcx.tcx.sess.span_err(
1201 decl.inputs[0].span,
1202 "argument should be `&PanicInfo`",
1206 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1207 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1208 if !generics.params.is_empty() {
1209 fcx.tcx.sess.span_err(
1211 "should have no type parameters",
1217 let span = fcx.tcx.sess.source_map().def_span(span);
1218 fcx.tcx.sess.span_err(span, "function should have one argument");
1221 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
1226 // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
1227 if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
1228 if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
1229 if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
1230 if declared_ret_ty.sty != ty::Never {
1231 fcx.tcx.sess.span_err(
1233 "return type should be `!`",
1237 let inputs = fn_sig.inputs();
1238 let span = fcx.tcx.hir().span(fn_id);
1239 if inputs.len() == 1 {
1240 let arg_is_alloc_layout = match inputs[0].sty {
1241 ty::Adt(ref adt, _) => {
1242 adt.did == alloc_layout_did
1247 if !arg_is_alloc_layout {
1248 fcx.tcx.sess.span_err(
1249 decl.inputs[0].span,
1250 "argument should be `Layout`",
1254 if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
1255 if let ItemKind::Fn(_, _, ref generics, _) = item.node {
1256 if !generics.params.is_empty() {
1257 fcx.tcx.sess.span_err(
1259 "`#[alloc_error_handler]` function should have no type \
1266 let span = fcx.tcx.sess.source_map().def_span(span);
1267 fcx.tcx.sess.span_err(span, "function should have one argument");
1270 fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
1278 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1281 let def_id = tcx.hir().local_def_id(id);
1282 let def = tcx.adt_def(def_id);
1283 def.destructor(tcx); // force the destructor to be evaluated
1284 check_representable(tcx, span, def_id);
1286 if def.repr.simd() {
1287 check_simd(tcx, span, def_id);
1290 check_transparent(tcx, span, def_id);
1291 check_packed(tcx, span, def_id);
1294 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1297 let def_id = tcx.hir().local_def_id(id);
1298 let def = tcx.adt_def(def_id);
1299 def.destructor(tcx); // force the destructor to be evaluated
1300 check_representable(tcx, span, def_id);
1302 check_packed(tcx, span, def_id);
1305 pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1307 "check_item_type(it.id={}, it.name={})",
1309 tcx.item_path_str(tcx.hir().local_def_id(it.id))
1311 let _indenter = indenter();
1313 // Consts can play a role in type-checking, so they are included here.
1314 hir::ItemKind::Static(..) => {
1315 let def_id = tcx.hir().local_def_id(it.id);
1316 tcx.typeck_tables_of(def_id);
1317 maybe_check_static_with_link_section(tcx, def_id, it.span);
1319 hir::ItemKind::Const(..) => {
1320 tcx.typeck_tables_of(tcx.hir().local_def_id(it.id));
1322 hir::ItemKind::Enum(ref enum_definition, _) => {
1323 check_enum(tcx, it.span, &enum_definition.variants, it.id);
1325 hir::ItemKind::Fn(..) => {} // entirely within check_item_body
1326 hir::ItemKind::Impl(.., ref impl_item_refs) => {
1327 debug!("ItemKind::Impl {} with id {}", it.ident, it.id);
1328 let impl_def_id = tcx.hir().local_def_id(it.id);
1329 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1330 check_impl_items_against_trait(
1337 let trait_def_id = impl_trait_ref.def_id;
1338 check_on_unimplemented(tcx, trait_def_id, it);
1341 hir::ItemKind::Trait(..) => {
1342 let def_id = tcx.hir().local_def_id(it.id);
1343 check_on_unimplemented(tcx, def_id, it);
1345 hir::ItemKind::Struct(..) => {
1346 check_struct(tcx, it.id, it.span);
1348 hir::ItemKind::Union(..) => {
1349 check_union(tcx, it.id, it.span);
1351 hir::ItemKind::Existential(..) | hir::ItemKind::Ty(..) => {
1352 let def_id = tcx.hir().local_def_id(it.id);
1353 let pty_ty = tcx.type_of(def_id);
1354 let generics = tcx.generics_of(def_id);
1355 check_bounds_are_used(tcx, &generics, pty_ty);
1357 hir::ItemKind::ForeignMod(ref m) => {
1358 check_abi(tcx, it.span, m.abi);
1360 if m.abi == Abi::RustIntrinsic {
1361 for item in &m.items {
1362 intrinsic::check_intrinsic_type(tcx, item);
1364 } else if m.abi == Abi::PlatformIntrinsic {
1365 for item in &m.items {
1366 intrinsic::check_platform_intrinsic_type(tcx, item);
1369 for item in &m.items {
1370 let generics = tcx.generics_of(tcx.hir().local_def_id(item.id));
1371 if generics.params.len() - generics.own_counts().lifetimes != 0 {
1372 let mut err = struct_span_err!(
1376 "foreign items may not have type parameters"
1378 err.span_label(item.span, "can't have type parameters");
1379 // FIXME: once we start storing spans for type arguments, turn this into a
1382 "use specialization instead of type parameters by replacing them \
1383 with concrete types like `u32`",
1388 if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
1389 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1394 _ => { /* nothing to do */ }
1398 fn maybe_check_static_with_link_section(tcx: TyCtxt, id: DefId, span: Span) {
1399 // Only restricted on wasm32 target for now
1400 if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1404 // If `#[link_section]` is missing, then nothing to verify
1405 let attrs = tcx.codegen_fn_attrs(id);
1406 if attrs.link_section.is_none() {
1410 // For the wasm32 target statics with #[link_section] are placed into custom
1411 // sections of the final output file, but this isn't link custom sections of
1412 // other executable formats. Namely we can only embed a list of bytes,
1413 // nothing with pointers to anything else or relocations. If any relocation
1414 // show up, reject them here.
1415 let instance = ty::Instance::mono(tcx, id);
1416 let cid = GlobalId {
1420 let param_env = ty::ParamEnv::reveal_all();
1421 if let Ok(static_) = tcx.const_eval(param_env.and(cid)) {
1422 let alloc = if let ConstValue::ByRef(_, allocation, _) = static_.val {
1425 bug!("Matching on non-ByRef static")
1427 if alloc.relocations.len() != 0 {
1428 let msg = "statics with a custom `#[link_section]` must be a \
1429 simple list of bytes on the wasm target with no \
1430 extra levels of indirection such as references";
1431 tcx.sess.span_err(span, msg);
1436 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1437 trait_def_id: DefId,
1439 let item_def_id = tcx.hir().local_def_id(item.id);
1440 // an error would be reported if this fails.
1441 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1444 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1445 impl_item: &hir::ImplItem,
1448 let mut err = struct_span_err!(
1449 tcx.sess, impl_item.span, E0520,
1450 "`{}` specializes an item from a parent `impl`, but \
1451 that item is not marked `default`",
1453 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1456 match tcx.span_of_impl(parent_impl) {
1458 err.span_label(span, "parent `impl` is here");
1459 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1463 err.note(&format!("parent implementation is in crate `{}`", cname));
1470 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1471 trait_def: &ty::TraitDef,
1472 trait_item: &ty::AssociatedItem,
1474 impl_item: &hir::ImplItem)
1476 let ancestors = trait_def.ancestors(tcx, impl_id);
1478 let kind = match impl_item.node {
1479 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1480 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1481 hir::ImplItemKind::Existential(..) => ty::AssociatedKind::Existential,
1482 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1485 let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
1486 .map(|node_item| node_item.map(|parent| parent.defaultness));
1488 if let Some(parent) = parent {
1489 if tcx.impl_item_is_final(&parent) {
1490 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1496 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1499 impl_trait_ref: ty::TraitRef<'tcx>,
1500 impl_item_refs: &[hir::ImplItemRef]) {
1501 let impl_span = tcx.sess.source_map().def_span(impl_span);
1503 // If the trait reference itself is erroneous (so the compilation is going
1504 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1505 // isn't populated for such impls.
1506 if impl_trait_ref.references_error() { return; }
1508 // Locate trait definition and items
1509 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1510 let mut overridden_associated_type = None;
1512 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
1514 // Check existing impl methods to see if they are both present in trait
1515 // and compatible with trait signature
1516 for impl_item in impl_items() {
1517 let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.id));
1518 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1519 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1520 tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1522 // Not compatible, but needed for the error message
1523 tcx.associated_items(impl_trait_ref.def_id)
1524 .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
1527 // Check that impl definition matches trait definition
1528 if let Some(ty_trait_item) = ty_trait_item {
1529 match impl_item.node {
1530 hir::ImplItemKind::Const(..) => {
1531 // Find associated const definition.
1532 if ty_trait_item.kind == ty::AssociatedKind::Const {
1533 compare_const_impl(tcx,
1539 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1540 "item `{}` is an associated const, \
1541 which doesn't match its trait `{}`",
1544 err.span_label(impl_item.span, "does not match trait");
1545 // We can only get the spans from local trait definition
1546 // Same for E0324 and E0325
1547 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1548 err.span_label(trait_span, "item in trait");
1553 hir::ImplItemKind::Method(..) => {
1554 let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
1555 if ty_trait_item.kind == ty::AssociatedKind::Method {
1556 compare_impl_method(tcx,
1563 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1564 "item `{}` is an associated method, \
1565 which doesn't match its trait `{}`",
1568 err.span_label(impl_item.span, "does not match trait");
1569 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1570 err.span_label(trait_span, "item in trait");
1575 hir::ImplItemKind::Existential(..) |
1576 hir::ImplItemKind::Type(_) => {
1577 if ty_trait_item.kind == ty::AssociatedKind::Type {
1578 if ty_trait_item.defaultness.has_value() {
1579 overridden_associated_type = Some(impl_item);
1582 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1583 "item `{}` is an associated type, \
1584 which doesn't match its trait `{}`",
1587 err.span_label(impl_item.span, "does not match trait");
1588 if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
1589 err.span_label(trait_span, "item in trait");
1596 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1600 // Check for missing items from trait
1601 let mut missing_items = Vec::new();
1602 let mut invalidated_items = Vec::new();
1603 let associated_type_overridden = overridden_associated_type.is_some();
1604 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1605 let is_implemented = trait_def.ancestors(tcx, impl_id)
1606 .defs(tcx, trait_item.ident, trait_item.kind, impl_trait_ref.def_id)
1608 .map(|node_item| !node_item.node.is_from_trait())
1611 if !is_implemented && !tcx.impl_is_default(impl_id) {
1612 if !trait_item.defaultness.has_value() {
1613 missing_items.push(trait_item);
1614 } else if associated_type_overridden {
1615 invalidated_items.push(trait_item.ident);
1620 if !missing_items.is_empty() {
1621 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1622 "not all trait items implemented, missing: `{}`",
1623 missing_items.iter()
1624 .map(|trait_item| trait_item.ident.to_string())
1625 .collect::<Vec<_>>().join("`, `"));
1626 err.span_label(impl_span, format!("missing `{}` in implementation",
1627 missing_items.iter()
1628 .map(|trait_item| trait_item.ident.to_string())
1629 .collect::<Vec<_>>().join("`, `")));
1630 for trait_item in missing_items {
1631 if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
1632 err.span_label(span, format!("`{}` from trait", trait_item.ident));
1634 err.note_trait_signature(trait_item.ident.to_string(),
1635 trait_item.signature(&tcx));
1641 if !invalidated_items.is_empty() {
1642 let invalidator = overridden_associated_type.unwrap();
1643 span_err!(tcx.sess, invalidator.span, E0399,
1644 "the following trait items need to be reimplemented \
1645 as `{}` was overridden: `{}`",
1647 invalidated_items.iter()
1648 .map(|name| name.to_string())
1649 .collect::<Vec<_>>().join("`, `"))
1653 /// Checks whether a type can be represented in memory. In particular, it
1654 /// identifies types that contain themselves without indirection through a
1655 /// pointer, which would mean their size is unbounded.
1656 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1660 let rty = tcx.type_of(item_def_id);
1662 // Check that it is possible to represent this type. This call identifies
1663 // (1) types that contain themselves and (2) types that contain a different
1664 // recursive type. It is only necessary to throw an error on those that
1665 // contain themselves. For case 2, there must be an inner type that will be
1666 // caught by case 1.
1667 match rty.is_representable(tcx, sp) {
1668 Representability::SelfRecursive(spans) => {
1669 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1671 err.span_label(span, "recursive without indirection");
1676 Representability::Representable | Representability::ContainsRecursive => (),
1681 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1682 let t = tcx.type_of(def_id);
1683 if let ty::Adt(def, substs) = t.sty {
1684 if def.is_struct() {
1685 let fields = &def.non_enum_variant().fields;
1686 if fields.is_empty() {
1687 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1690 let e = fields[0].ty(tcx, substs);
1691 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1692 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1693 .span_label(sp, "SIMD elements must have the same type")
1698 ty::Param(_) => { /* struct<T>(T, T, T, T) is ok */ }
1699 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1701 span_err!(tcx.sess, sp, E0077,
1702 "SIMD vector element type should be machine type");
1710 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1711 let repr = tcx.adt_def(def_id).repr;
1713 for attr in tcx.get_attrs(def_id).iter() {
1714 for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
1715 if let attr::ReprPacked(pack) = r {
1716 if pack != repr.pack {
1717 struct_span_err!(tcx.sess, sp, E0634,
1718 "type has conflicting packed representation hints").emit();
1724 struct_span_err!(tcx.sess, sp, E0587,
1725 "type has conflicting packed and align representation hints").emit();
1727 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1728 struct_span_err!(tcx.sess, sp, E0588,
1729 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1734 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1736 stack: &mut Vec<DefId>) -> bool {
1737 let t = tcx.type_of(def_id);
1738 if stack.contains(&def_id) {
1739 debug!("check_packed_inner: {:?} is recursive", t);
1742 if let ty::Adt(def, substs) = t.sty {
1743 if def.is_struct() || def.is_union() {
1744 if tcx.adt_def(def.did).repr.align > 0 {
1747 // push struct def_id before checking fields
1749 for field in &def.non_enum_variant().fields {
1750 let f = field.ty(tcx, substs);
1751 if let ty::Adt(def, _) = f.sty {
1752 if check_packed_inner(tcx, def.did, stack) {
1757 // only need to pop if not early out
1764 fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1765 let adt = tcx.adt_def(def_id);
1766 if !adt.repr.transparent() {
1770 // For each field, figure out if it's known to be a ZST and align(1)
1771 let field_infos = adt.non_enum_variant().fields.iter().map(|field| {
1772 let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
1773 let param_env = tcx.param_env(field.did);
1774 let layout = tcx.layout_of(param_env.and(ty));
1775 // We are currently checking the type this field came from, so it must be local
1776 let span = tcx.hir().span_if_local(field.did).unwrap();
1777 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1778 let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false);
1782 let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
1783 let non_zst_count = non_zst_fields.clone().count();
1784 if non_zst_count != 1 {
1785 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
1786 struct_span_err!(tcx.sess, sp, E0690,
1787 "transparent struct needs exactly one non-zero-sized field, but has {}",
1789 .span_note(field_spans, "non-zero-sized field")
1792 for (span, zst, align1) in field_infos {
1794 span_err!(tcx.sess, span, E0691,
1795 "zero-sized field in transparent struct has alignment larger than 1");
1800 #[allow(trivial_numeric_casts)]
1801 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1803 vs: &'tcx [hir::Variant],
1805 let def_id = tcx.hir().local_def_id(id);
1806 let def = tcx.adt_def(def_id);
1807 def.destructor(tcx); // force the destructor to be evaluated
1810 let attributes = tcx.get_attrs(def_id);
1811 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1813 tcx.sess, attr.span, E0084,
1814 "unsupported representation for zero-variant enum")
1815 .span_label(sp, "zero-variant enum")
1820 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1821 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1822 if !tcx.features().repr128 {
1823 emit_feature_err(&tcx.sess.parse_sess,
1826 GateIssue::Language,
1827 "repr with 128-bit type is unstable");
1832 if let Some(ref e) = v.node.disr_expr {
1833 tcx.typeck_tables_of(tcx.hir().local_def_id(e.id));
1837 let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
1838 for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
1839 // Check for duplicate discriminant values
1840 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1841 let variant_did = def.variants[VariantIdx::new(i)].did;
1842 let variant_i_node_id = tcx.hir().as_local_node_id(variant_did).unwrap();
1843 let variant_i = tcx.hir().expect_variant(variant_i_node_id);
1844 let i_span = match variant_i.node.disr_expr {
1845 Some(ref expr) => tcx.hir().span(expr.id),
1846 None => tcx.hir().span(variant_i_node_id)
1848 let span = match v.node.disr_expr {
1849 Some(ref expr) => tcx.hir().span(expr.id),
1852 struct_span_err!(tcx.sess, span, E0081,
1853 "discriminant value `{}` already exists", disr_vals[i])
1854 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1855 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1858 disr_vals.push(discr);
1861 check_representable(tcx, sp, def_id);
1864 fn report_unexpected_variant_def<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1868 span_err!(tcx.sess, span, E0533,
1869 "expected unit struct/variant or constant, found {} `{}`",
1871 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1874 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1875 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1877 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1878 -> Lrc<ty::GenericPredicates<'tcx>>
1881 let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
1882 let item_id = tcx.hir().ty_param_owner(node_id);
1883 let item_def_id = tcx.hir().local_def_id(item_id);
1884 let generics = tcx.generics_of(item_def_id);
1885 let index = generics.param_def_id_to_index[&def_id];
1886 Lrc::new(ty::GenericPredicates {
1888 predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
1890 ty::Predicate::Trait(ref data)
1891 if data.skip_binder().self_ty().is_param(index) => {
1892 // HACK(eddyb) should get the original `Span`.
1893 let span = tcx.def_span(def_id);
1894 Some((predicate, span))
1902 fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
1903 -> Option<ty::Region<'tcx>> {
1905 Some(def) => infer::EarlyBoundRegion(span, def.name),
1906 None => infer::MiscVariable(span)
1908 Some(self.next_region_var(v))
1911 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1912 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1915 fn ty_infer_for_def(&self,
1916 ty_param_def: &ty::GenericParamDef,
1917 span: Span) -> Ty<'tcx> {
1918 if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
1924 fn projected_ty_from_poly_trait_ref(&self,
1927 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1930 let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
1932 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1936 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1939 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1940 if ty.has_escaping_bound_vars() {
1941 ty // FIXME: normalization and escaping regions
1943 self.normalize_associated_types_in(span, &ty)
1947 fn set_tainted_by_errors(&self) {
1948 self.infcx.set_tainted_by_errors()
1951 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1952 self.write_ty(hir_id, ty)
1956 /// Controls whether the arguments are tupled. This is used for the call
1959 /// Tupling means that all call-side arguments are packed into a tuple and
1960 /// passed as a single parameter. For example, if tupling is enabled, this
1963 /// fn f(x: (isize, isize))
1965 /// Can be called as:
1972 #[derive(Clone, Eq, PartialEq)]
1973 enum TupleArgumentsFlag {
1978 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1979 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1980 param_env: ty::ParamEnv<'tcx>,
1981 body_id: ast::NodeId)
1982 -> FnCtxt<'a, 'gcx, 'tcx> {
1986 err_count_on_creation: inh.tcx.sess.err_count(),
1988 ret_coercion_span: RefCell::new(None),
1990 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1991 ast::CRATE_NODE_ID)),
1992 diverges: Cell::new(Diverges::Maybe),
1993 has_errors: Cell::new(false),
1994 enclosing_breakables: RefCell::new(EnclosingBreakables {
1996 by_id: Default::default(),
2002 pub fn sess(&self) -> &Session {
2006 pub fn err_count_since_creation(&self) -> usize {
2007 self.tcx.sess.err_count() - self.err_count_on_creation
2010 /// Produce warning on the given node, if the current point in the
2011 /// function is unreachable, and there hasn't been another warning.
2012 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
2013 if self.diverges.get() == Diverges::Always {
2014 self.diverges.set(Diverges::WarnedAlways);
2016 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
2018 self.tcx().lint_node(
2019 lint::builtin::UNREACHABLE_CODE,
2021 &format!("unreachable {}", kind));
2027 code: ObligationCauseCode<'tcx>)
2028 -> ObligationCause<'tcx> {
2029 ObligationCause::new(span, self.body_id, code)
2032 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
2033 self.cause(span, ObligationCauseCode::MiscObligation)
2036 /// Resolves type variables in `ty` if possible. Unlike the infcx
2037 /// version (resolve_type_vars_if_possible), this version will
2038 /// also select obligations if it seems useful, in an effort
2039 /// to get more type information.
2040 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
2041 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
2043 // No Infer()? Nothing needs doing.
2044 if !ty.has_infer_types() {
2045 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2049 // If `ty` is a type variable, see whether we already know what it is.
2050 ty = self.resolve_type_vars_if_possible(&ty);
2051 if !ty.has_infer_types() {
2052 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2056 // If not, try resolving pending obligations as much as
2057 // possible. This can help substantially when there are
2058 // indirect dependencies that don't seem worth tracking
2060 self.select_obligations_where_possible(false);
2061 ty = self.resolve_type_vars_if_possible(&ty);
2063 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
2067 fn record_deferred_call_resolution(&self,
2068 closure_def_id: DefId,
2069 r: DeferredCallResolution<'gcx, 'tcx>) {
2070 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2071 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
2074 fn remove_deferred_call_resolutions(&self,
2075 closure_def_id: DefId)
2076 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
2078 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
2079 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
2082 pub fn tag(&self) -> String {
2083 let self_ptr: *const FnCtxt = self;
2084 format!("{:?}", self_ptr)
2087 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> LocalTy<'tcx> {
2088 self.locals.borrow().get(&nid).cloned().unwrap_or_else(||
2089 span_bug!(span, "no type for local variable {}",
2090 self.tcx.hir().node_to_string(nid))
2095 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
2096 debug!("write_ty({:?}, {:?}) in fcx {}",
2097 id, self.resolve_type_vars_if_possible(&ty), self.tag());
2098 self.tables.borrow_mut().node_types_mut().insert(id, ty);
2100 if ty.references_error() {
2101 self.has_errors.set(true);
2102 self.set_tainted_by_errors();
2106 pub fn write_field_index(&self, node_id: ast::NodeId, index: usize) {
2107 let hir_id = self.tcx.hir().node_to_hir_id(node_id);
2108 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
2111 // The NodeId and the ItemLocalId must identify the same item. We just pass
2112 // both of them for consistency checking.
2113 pub fn write_method_call(&self,
2115 method: MethodCallee<'tcx>) {
2116 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
2119 .type_dependent_defs_mut()
2120 .insert(hir_id, Def::Method(method.def_id));
2122 self.write_substs(hir_id, method.substs);
2124 // When the method is confirmed, the `method.substs` includes
2125 // parameters from not just the method, but also the impl of
2126 // the method -- in particular, the `Self` type will be fully
2127 // resolved. However, those are not something that the "user
2128 // specified" -- i.e., those types come from the inferred type
2129 // of the receiver, not something the user wrote. So when we
2130 // create the user-substs, we want to replace those earlier
2131 // types with just the types that the user actually wrote --
2132 // that is, those that appear on the *method itself*.
2134 // As an example, if the user wrote something like
2135 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
2136 // type of `foo` (possibly adjusted), but we don't want to
2137 // include that. We want just the `[_, u32]` part.
2138 if !method.substs.is_noop() {
2139 let method_generics = self.tcx.generics_of(method.def_id);
2140 if !method_generics.params.is_empty() {
2141 let user_substs = self.infcx.probe(|_| {
2142 let just_method_substs = Substs::for_item(self.tcx, method.def_id, |param, _| {
2143 let i = param.index as usize;
2144 if i < method_generics.parent_count {
2145 self.infcx.var_for_def(DUMMY_SP, param)
2150 self.infcx.canonicalize_user_type_annotation(&UserSubsts {
2151 substs: just_method_substs,
2152 user_self_ty: None, // not relevant here
2156 debug!("write_method_call: user_substs = {:?}", user_substs);
2157 self.write_user_substs(hir_id, user_substs);
2162 pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
2163 if !substs.is_noop() {
2164 debug!("write_substs({:?}, {:?}) in fcx {}",
2169 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
2173 /// Given the substs that we just converted from the HIR, try to
2174 /// canonicalize them and store them as user-given substitutions
2175 /// (i.e., substitutions that must be respected by the NLL check).
2177 /// This should be invoked **before any unifications have
2178 /// occurred**, so that annotations like `Vec<_>` are preserved
2180 pub fn write_user_substs_from_substs(
2183 substs: &'tcx Substs<'tcx>,
2184 user_self_ty: Option<UserSelfTy<'tcx>>,
2187 "write_user_substs_from_substs({:?}, {:?}) in fcx {}",
2193 if !substs.is_noop() {
2194 let user_substs = self.infcx.canonicalize_user_type_annotation(&UserSubsts {
2198 debug!("instantiate_value_path: user_substs = {:?}", user_substs);
2199 self.write_user_substs(hir_id, user_substs);
2203 pub fn write_user_substs(&self, hir_id: hir::HirId, substs: CanonicalUserSubsts<'tcx>) {
2205 "write_user_substs({:?}, {:?}) in fcx {}",
2211 if !substs.is_identity() {
2212 self.tables.borrow_mut().user_substs_mut().insert(hir_id, substs);
2214 debug!("write_user_substs: skipping identity substs");
2218 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
2219 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
2225 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
2226 Entry::Vacant(entry) => { entry.insert(adj); },
2227 Entry::Occupied(mut entry) => {
2228 debug!(" - composing on top of {:?}", entry.get());
2229 match (&entry.get()[..], &adj[..]) {
2230 // Applying any adjustment on top of a NeverToAny
2231 // is a valid NeverToAny adjustment, because it can't
2233 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
2235 Adjustment { kind: Adjust::Deref(_), .. },
2236 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
2238 Adjustment { kind: Adjust::Deref(_), .. },
2239 .. // Any following adjustments are allowed.
2241 // A reborrow has no effect before a dereference.
2243 // FIXME: currently we never try to compose autoderefs
2244 // and ReifyFnPointer/UnsafeFnPointer, but we could.
2246 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
2247 expr, entry.get(), adj)
2249 *entry.get_mut() = adj;
2254 /// Basically whenever we are converting from a type scheme into
2255 /// the fn body space, we always want to normalize associated
2256 /// types as well. This function combines the two.
2257 fn instantiate_type_scheme<T>(&self,
2259 substs: &Substs<'tcx>,
2262 where T : TypeFoldable<'tcx>
2264 let value = value.subst(self.tcx, substs);
2265 let result = self.normalize_associated_types_in(span, &value);
2266 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2273 /// As `instantiate_type_scheme`, but for the bounds found in a
2274 /// generic type scheme.
2275 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
2276 -> ty::InstantiatedPredicates<'tcx> {
2277 let bounds = self.tcx.predicates_of(def_id);
2278 let result = bounds.instantiate(self.tcx, substs);
2279 let result = self.normalize_associated_types_in(span, &result);
2280 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2287 /// Replace the opaque types from the given value with type variables,
2288 /// and records the `OpaqueTypeMap` for later use during writeback. See
2289 /// `InferCtxt::instantiate_opaque_types` for more details.
2290 fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
2292 parent_id: ast::NodeId,
2295 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
2296 debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
2300 let (value, opaque_type_map) = self.register_infer_ok_obligations(
2301 self.instantiate_opaque_types(
2309 let mut opaque_types = self.opaque_types.borrow_mut();
2310 for (ty, decl) in opaque_type_map {
2311 let old_value = opaque_types.insert(ty, decl);
2312 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2318 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2319 where T : TypeFoldable<'tcx>
2321 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2324 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2326 where T : TypeFoldable<'tcx>
2328 self.inh.partially_normalize_associated_types_in(span,
2334 pub fn require_type_meets(&self,
2337 code: traits::ObligationCauseCode<'tcx>,
2340 self.register_bound(
2343 traits::ObligationCause::new(span, self.body_id, code));
2346 pub fn require_type_is_sized(&self,
2349 code: traits::ObligationCauseCode<'tcx>)
2351 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2352 self.require_type_meets(ty, span, code, lang_item);
2355 pub fn require_type_is_sized_deferred(&self,
2358 code: traits::ObligationCauseCode<'tcx>)
2360 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2363 pub fn register_bound(&self,
2366 cause: traits::ObligationCause<'tcx>)
2368 self.fulfillment_cx.borrow_mut()
2369 .register_bound(self, self.param_env, ty, def_id, cause);
2372 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2373 let t = AstConv::ast_ty_to_ty(self, ast_t);
2374 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2378 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
2379 let ty = self.to_ty(ast_ty);
2381 // If the type given by the user has free regions, save it for
2382 // later, since NLL would like to enforce those. Also pass in
2383 // types that involve projections, since those can resolve to
2384 // `'static` bounds (modulo #54940, which hopefully will be
2385 // fixed by the time you see this comment, dear reader,
2386 // although I have my doubts). Other sorts of things are
2387 // already sufficiently enforced with erased regions. =)
2388 if ty.has_free_regions() || ty.has_projections() {
2389 let c_ty = self.infcx.canonicalize_response(&ty);
2390 self.tables.borrow_mut().user_provided_tys_mut().insert(ast_ty.hir_id, c_ty);
2396 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2397 match self.tables.borrow().node_types().get(id) {
2399 None if self.is_tainted_by_errors() => self.tcx.types.err,
2401 let node_id = self.tcx.hir().hir_to_node_id(id);
2402 bug!("no type for node {}: {} in fcx {}",
2403 node_id, self.tcx.hir().node_to_string(node_id),
2409 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2410 /// outlive the region `r`.
2411 pub fn register_wf_obligation(&self,
2414 code: traits::ObligationCauseCode<'tcx>)
2416 // WF obligations never themselves fail, so no real need to give a detailed cause:
2417 let cause = traits::ObligationCause::new(span, self.body_id, code);
2418 self.register_predicate(traits::Obligation::new(cause,
2420 ty::Predicate::WellFormed(ty)));
2423 /// Registers obligations that all types appearing in `substs` are well-formed.
2424 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr) {
2425 for ty in substs.types() {
2426 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2430 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2431 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2432 /// trait/region obligations.
2434 /// For example, if there is a function:
2437 /// fn foo<'a,T:'a>(...)
2440 /// and a reference:
2446 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2447 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2448 pub fn add_obligations_for_parameters(&self,
2449 cause: traits::ObligationCause<'tcx>,
2450 predicates: &ty::InstantiatedPredicates<'tcx>)
2452 assert!(!predicates.has_escaping_bound_vars());
2454 debug!("add_obligations_for_parameters(predicates={:?})",
2457 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2458 self.register_predicate(obligation);
2462 // FIXME(arielb1): use this instead of field.ty everywhere
2463 // Only for fields! Returns <none> for methods>
2464 // Indifferent to privacy flags
2465 pub fn field_ty(&self,
2467 field: &'tcx ty::FieldDef,
2468 substs: &Substs<'tcx>)
2471 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
2474 fn check_casts(&self) {
2475 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2476 for cast in deferred_cast_checks.drain(..) {
2481 fn resolve_generator_interiors(&self, def_id: DefId) {
2482 let mut generators = self.deferred_generator_interiors.borrow_mut();
2483 for (body_id, interior) in generators.drain(..) {
2484 self.select_obligations_where_possible(false);
2485 generator_interior::resolve_interior(self, def_id, body_id, interior);
2489 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2490 // Non-numerics get replaced with ! or () (depending on whether
2491 // feature(never_type) is enabled, unconstrained ints with i32,
2492 // unconstrained floats with f64.
2493 // Fallback becomes very dubious if we have encountered type-checking errors.
2494 // In that case, fallback to Error.
2495 // The return value indicates whether fallback has occurred.
2496 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2497 use rustc::ty::error::UnconstrainedNumeric::Neither;
2498 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2500 assert!(ty.is_ty_infer());
2501 let fallback = match self.type_is_unconstrained_numeric(ty) {
2502 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2503 UnconstrainedInt => self.tcx.types.i32,
2504 UnconstrainedFloat => self.tcx.types.f64,
2505 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2506 Neither => return false,
2508 debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
2509 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2513 fn select_all_obligations_or_error(&self) {
2514 debug!("select_all_obligations_or_error");
2515 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2516 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2520 /// Select as many obligations as we can at present.
2521 fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2522 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2523 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2527 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2528 /// returns a type of `&T`, but the actual type we assign to the
2529 /// *expression* is `T`. So this function just peels off the return
2530 /// type by one layer to yield `T`.
2531 fn make_overloaded_place_return_type(&self,
2532 method: MethodCallee<'tcx>)
2533 -> ty::TypeAndMut<'tcx>
2535 // extract method return type, which will be &T;
2536 let ret_ty = method.sig.output();
2538 // method returns &T, but the type as visible to user is T, so deref
2539 ret_ty.builtin_deref(true).unwrap()
2542 fn lookup_indexing(&self,
2544 base_expr: &'gcx hir::Expr,
2548 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2550 // FIXME(#18741) -- this is almost but not quite the same as the
2551 // autoderef that normal method probing does. They could likely be
2554 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2555 let mut result = None;
2556 while result.is_none() && autoderef.next().is_some() {
2557 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2559 autoderef.finalize(self);
2563 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2564 /// (and otherwise adjust) `base_expr`, looking for a type which either
2565 /// supports builtin indexing or overloaded indexing.
2566 /// This loop implements one step in that search; the autoderef loop
2567 /// is implemented by `lookup_indexing`.
2568 fn try_index_step(&self,
2570 base_expr: &hir::Expr,
2571 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2574 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2576 let adjusted_ty = autoderef.unambiguous_final_ty(self);
2577 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2584 for &unsize in &[false, true] {
2585 let mut self_ty = adjusted_ty;
2587 // We only unsize arrays here.
2588 if let ty::Array(element_ty, _) = adjusted_ty.sty {
2589 self_ty = self.tcx.mk_slice(element_ty);
2595 // If some lookup succeeds, write callee into table and extract index/element
2596 // type from the method signature.
2597 // If some lookup succeeded, install method in table
2598 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2599 let method = self.try_overloaded_place_op(
2600 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2602 let result = method.map(|ok| {
2603 debug!("try_index_step: success, using overloaded indexing");
2604 let method = self.register_infer_ok_obligations(ok);
2606 let mut adjustments = autoderef.adjust_steps(self, needs);
2607 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2608 let mutbl = match r_mutbl {
2609 hir::MutImmutable => AutoBorrowMutability::Immutable,
2610 hir::MutMutable => AutoBorrowMutability::Mutable {
2611 // Indexing can be desugared to a method call,
2612 // so maybe we could use two-phase here.
2613 // See the documentation of AllowTwoPhase for why that's
2614 // not the case today.
2615 allow_two_phase_borrow: AllowTwoPhase::No,
2618 adjustments.push(Adjustment {
2619 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2620 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2627 adjustments.push(Adjustment {
2628 kind: Adjust::Unsize,
2629 target: method.sig.inputs()[0]
2632 self.apply_adjustments(base_expr, adjustments);
2634 self.write_method_call(expr.hir_id, method);
2635 (input_ty, self.make_overloaded_place_return_type(method).ty)
2637 if result.is_some() {
2645 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
2646 let (tr, name) = match (op, is_mut) {
2647 (PlaceOp::Deref, false) =>
2648 (self.tcx.lang_items().deref_trait(), "deref"),
2649 (PlaceOp::Deref, true) =>
2650 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2651 (PlaceOp::Index, false) =>
2652 (self.tcx.lang_items().index_trait(), "index"),
2653 (PlaceOp::Index, true) =>
2654 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2656 (tr, ast::Ident::from_str(name))
2659 fn try_overloaded_place_op(&self,
2662 arg_tys: &[Ty<'tcx>],
2665 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2667 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2673 // Try Mut first, if needed.
2674 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2675 let method = match (needs, mut_tr) {
2676 (Needs::MutPlace, Some(trait_did)) => {
2677 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2682 // Otherwise, fall back to the immutable version.
2683 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2684 let method = match (method, imm_tr) {
2685 (None, Some(trait_did)) => {
2686 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2688 (method, _) => method,
2694 fn check_method_argument_types(&self,
2697 method: Result<MethodCallee<'tcx>, ()>,
2698 args_no_rcvr: &'gcx [hir::Expr],
2699 tuple_arguments: TupleArgumentsFlag,
2700 expected: Expectation<'tcx>)
2702 let has_error = match method {
2704 method.substs.references_error() || method.sig.references_error()
2709 let err_inputs = self.err_args(args_no_rcvr.len());
2711 let err_inputs = match tuple_arguments {
2712 DontTupleArguments => err_inputs,
2713 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
2716 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2717 false, tuple_arguments, None);
2718 return self.tcx.types.err;
2721 let method = method.unwrap();
2722 // HACK(eddyb) ignore self in the definition (see above).
2723 let expected_arg_tys = self.expected_inputs_for_expected_output(
2726 method.sig.output(),
2727 &method.sig.inputs()[1..]
2729 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2730 args_no_rcvr, method.sig.variadic, tuple_arguments,
2731 self.tcx.hir().span_if_local(method.def_id));
2735 fn self_type_matches_expected_vid(
2737 trait_ref: ty::PolyTraitRef<'tcx>,
2738 expected_vid: ty::TyVid,
2740 let self_ty = self.shallow_resolve(trait_ref.self_ty());
2742 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
2743 trait_ref, self_ty, expected_vid
2746 ty::Infer(ty::TyVar(found_vid)) => {
2747 // FIXME: consider using `sub_root_var` here so we
2748 // can see through subtyping.
2749 let found_vid = self.root_var(found_vid);
2750 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
2751 expected_vid == found_vid
2757 fn obligations_for_self_ty<'b>(&'b self, self_ty: ty::TyVid)
2758 -> impl Iterator<Item=(ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
2759 + Captures<'gcx> + 'b
2761 // FIXME: consider using `sub_root_var` here so we
2762 // can see through subtyping.
2763 let ty_var_root = self.root_var(self_ty);
2764 debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
2765 self_ty, ty_var_root,
2766 self.fulfillment_cx.borrow().pending_obligations());
2770 .pending_obligations()
2772 .filter_map(move |obligation| match obligation.predicate {
2773 ty::Predicate::Projection(ref data) =>
2774 Some((data.to_poly_trait_ref(self.tcx), obligation)),
2775 ty::Predicate::Trait(ref data) =>
2776 Some((data.to_poly_trait_ref(), obligation)),
2777 ty::Predicate::Subtype(..) => None,
2778 ty::Predicate::RegionOutlives(..) => None,
2779 ty::Predicate::TypeOutlives(..) => None,
2780 ty::Predicate::WellFormed(..) => None,
2781 ty::Predicate::ObjectSafe(..) => None,
2782 ty::Predicate::ConstEvaluatable(..) => None,
2783 // N.B., this predicate is created by breaking down a
2784 // `ClosureType: FnFoo()` predicate, where
2785 // `ClosureType` represents some `Closure`. It can't
2786 // possibly be referring to the current closure,
2787 // because we haven't produced the `Closure` for
2788 // this closure yet; this is exactly why the other
2789 // code is looking for a self type of a unresolved
2790 // inference variable.
2791 ty::Predicate::ClosureKind(..) => None,
2792 }).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
2795 fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
2796 self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
2797 Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
2801 /// Generic function that factors out common logic from function calls,
2802 /// method calls and overloaded operators.
2803 fn check_argument_types(&self,
2806 fn_inputs: &[Ty<'tcx>],
2807 mut expected_arg_tys: &[Ty<'tcx>],
2808 args: &'gcx [hir::Expr],
2810 tuple_arguments: TupleArgumentsFlag,
2811 def_span: Option<Span>) {
2814 // Grab the argument types, supplying fresh type variables
2815 // if the wrong number of arguments were supplied
2816 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2822 // All the input types from the fn signature must outlive the call
2823 // so as to validate implied bounds.
2824 for &fn_input_ty in fn_inputs {
2825 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2828 let expected_arg_count = fn_inputs.len();
2830 let param_count_error = |expected_count: usize,
2835 let mut err = tcx.sess.struct_span_err_with_code(sp,
2836 &format!("this function takes {}{} but {} {} supplied",
2837 if variadic {"at least "} else {""},
2838 potentially_plural_count(expected_count, "parameter"),
2839 potentially_plural_count(arg_count, "parameter"),
2840 if arg_count == 1 {"was"} else {"were"}),
2841 DiagnosticId::Error(error_code.to_owned()));
2843 if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
2844 err.span_label(def_s, "defined here");
2847 let sugg_span = tcx.sess.source_map().end_point(expr_sp);
2848 // remove closing `)` from the span
2849 let sugg_span = sugg_span.shrink_to_lo();
2850 err.span_suggestion_with_applicability(
2852 "expected the unit value `()`; create it with empty parentheses",
2854 Applicability::MachineApplicable);
2856 err.span_label(sp, format!("expected {}{}",
2857 if variadic {"at least "} else {""},
2858 potentially_plural_count(expected_count, "parameter")));
2863 let formal_tys = if tuple_arguments == TupleArguments {
2864 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2865 match tuple_type.sty {
2866 ty::Tuple(arg_types) if arg_types.len() != args.len() => {
2867 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
2868 expected_arg_tys = &[];
2869 self.err_args(args.len())
2871 ty::Tuple(arg_types) => {
2872 expected_arg_tys = match expected_arg_tys.get(0) {
2873 Some(&ty) => match ty.sty {
2874 ty::Tuple(ref tys) => &tys,
2882 span_err!(tcx.sess, sp, E0059,
2883 "cannot use call notation; the first type parameter \
2884 for the function trait is neither a tuple nor unit");
2885 expected_arg_tys = &[];
2886 self.err_args(args.len())
2889 } else if expected_arg_count == supplied_arg_count {
2891 } else if variadic {
2892 if supplied_arg_count >= expected_arg_count {
2895 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
2896 expected_arg_tys = &[];
2897 self.err_args(supplied_arg_count)
2900 // is the missing argument of type `()`?
2901 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2902 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_unit()
2903 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2904 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_unit()
2908 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
2910 expected_arg_tys = &[];
2911 self.err_args(supplied_arg_count)
2913 // If there is no expectation, expect formal_tys.
2914 let expected_arg_tys = if !expected_arg_tys.is_empty() {
2920 debug!("check_argument_types: formal_tys={:?}",
2921 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2923 // Check the arguments.
2924 // We do this in a pretty awful way: first we type-check any arguments
2925 // that are not closures, then we type-check the closures. This is so
2926 // that we have more information about the types of arguments when we
2927 // type-check the functions. This isn't really the right way to do this.
2928 for &check_closures in &[false, true] {
2929 debug!("check_closures={}", check_closures);
2931 // More awful hacks: before we check argument types, try to do
2932 // an "opportunistic" vtable resolution of any trait bounds on
2933 // the call. This helps coercions.
2935 self.select_obligations_where_possible(false);
2938 // For variadic functions, we don't have a declared type for all of
2939 // the arguments hence we only do our usual type checking with
2940 // the arguments who's types we do know.
2941 let t = if variadic {
2943 } else if tuple_arguments == TupleArguments {
2948 for (i, arg) in args.iter().take(t).enumerate() {
2949 // Warn only for the first loop (the "no closures" one).
2950 // Closure arguments themselves can't be diverging, but
2951 // a previous argument can, e.g., `foo(panic!(), || {})`.
2952 if !check_closures {
2953 self.warn_if_unreachable(arg.id, arg.span, "expression");
2956 let is_closure = match arg.node {
2957 ExprKind::Closure(..) => true,
2961 if is_closure != check_closures {
2965 debug!("checking the argument");
2966 let formal_ty = formal_tys[i];
2968 // The special-cased logic below has three functions:
2969 // 1. Provide as good of an expected type as possible.
2970 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
2972 let checked_ty = self.check_expr_with_expectation(&arg, expected);
2974 // 2. Coerce to the most detailed type that could be coerced
2975 // to, which is `expected_ty` if `rvalue_hint` returns an
2976 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2977 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
2978 // We're processing function arguments so we definitely want to use
2979 // two-phase borrows.
2980 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
2982 // 3. Relate the expected type and the formal one,
2983 // if the expected type was used for the coercion.
2984 self.demand_suptype(arg.span, formal_ty, coerce_ty);
2988 // We also need to make sure we at least write the ty of the other
2989 // arguments which we skipped above.
2991 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
2992 use structured_errors::{VariadicError, StructuredDiagnostic};
2993 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
2996 for arg in args.iter().skip(expected_arg_count) {
2997 let arg_ty = self.check_expr(&arg);
2999 // There are a few types which get autopromoted when passed via varargs
3000 // in C but we just error out instead and require explicit casts.
3001 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
3003 ty::Float(ast::FloatTy::F32) => {
3004 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
3006 ty::Int(ast::IntTy::I8) | ty::Int(ast::IntTy::I16) | ty::Bool => {
3007 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
3009 ty::Uint(ast::UintTy::U8) | ty::Uint(ast::UintTy::U16) => {
3010 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
3013 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
3014 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
3015 variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
3023 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
3024 vec![self.tcx.types.err; len]
3027 // AST fragment checking
3030 expected: Expectation<'tcx>)
3036 ast::LitKind::Str(..) => tcx.mk_static_str(),
3037 ast::LitKind::ByteStr(ref v) => {
3038 tcx.mk_imm_ref(tcx.types.re_static,
3039 tcx.mk_array(tcx.types.u8, v.len() as u64))
3041 ast::LitKind::Byte(_) => tcx.types.u8,
3042 ast::LitKind::Char(_) => tcx.types.char,
3043 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
3044 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
3045 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
3046 let opt_ty = expected.to_option(self).and_then(|ty| {
3048 ty::Int(_) | ty::Uint(_) => Some(ty),
3049 ty::Char => Some(tcx.types.u8),
3050 ty::RawPtr(..) => Some(tcx.types.usize),
3051 ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
3055 opt_ty.unwrap_or_else(
3056 || tcx.mk_int_var(self.next_int_var_id()))
3058 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
3059 ast::LitKind::FloatUnsuffixed(_) => {
3060 let opt_ty = expected.to_option(self).and_then(|ty| {
3062 ty::Float(_) => Some(ty),
3066 opt_ty.unwrap_or_else(
3067 || tcx.mk_float_var(self.next_float_var_id()))
3069 ast::LitKind::Bool(_) => tcx.types.bool
3073 fn check_expr_eq_type(&self,
3074 expr: &'gcx hir::Expr,
3075 expected: Ty<'tcx>) {
3076 let ty = self.check_expr_with_hint(expr, expected);
3077 self.demand_eqtype(expr.span, expected, ty);
3080 pub fn check_expr_has_type_or_error(&self,
3081 expr: &'gcx hir::Expr,
3082 expected: Ty<'tcx>) -> Ty<'tcx> {
3083 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
3086 fn check_expr_meets_expectation_or_error(&self,
3087 expr: &'gcx hir::Expr,
3088 expected: Expectation<'tcx>) -> Ty<'tcx> {
3089 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
3090 let mut ty = self.check_expr_with_expectation(expr, expected);
3092 // While we don't allow *arbitrary* coercions here, we *do* allow
3093 // coercions from ! to `expected`.
3095 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
3096 "expression with never type wound up being adjusted");
3097 let adj_ty = self.next_diverging_ty_var(
3098 TypeVariableOrigin::AdjustmentType(expr.span));
3099 self.apply_adjustments(expr, vec![Adjustment {
3100 kind: Adjust::NeverToAny,
3106 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
3107 // Add help to type error if this is an `if` condition with an assignment.
3108 if let (ExpectIfCondition, &ExprKind::Assign(ref lhs, ref rhs))
3109 = (expected, &expr.node)
3111 let msg = "try comparing for equality";
3112 if let (Ok(left), Ok(right)) = (
3113 self.tcx.sess.source_map().span_to_snippet(lhs.span),
3114 self.tcx.sess.source_map().span_to_snippet(rhs.span))
3116 err.span_suggestion_with_applicability(
3119 format!("{} == {}", left, right),
3120 Applicability::MaybeIncorrect);
3130 fn check_expr_coercable_to_type(&self,
3131 expr: &'gcx hir::Expr,
3132 expected: Ty<'tcx>) -> Ty<'tcx> {
3133 let ty = self.check_expr_with_hint(expr, expected);
3134 // checks don't need two phase
3135 self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
3138 fn check_expr_with_hint(&self,
3139 expr: &'gcx hir::Expr,
3140 expected: Ty<'tcx>) -> Ty<'tcx> {
3141 self.check_expr_with_expectation(expr, ExpectHasType(expected))
3144 fn check_expr_with_expectation(&self,
3145 expr: &'gcx hir::Expr,
3146 expected: Expectation<'tcx>) -> Ty<'tcx> {
3147 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
3150 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
3151 self.check_expr_with_expectation(expr, NoExpectation)
3154 fn check_expr_with_needs(&self, expr: &'gcx hir::Expr, needs: Needs) -> Ty<'tcx> {
3155 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
3158 // Determine the `Self` type, using fresh variables for all variables
3159 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
3160 // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
3162 pub fn impl_self_ty(&self,
3163 span: Span, // (potential) receiver for this impl
3165 -> TypeAndSubsts<'tcx> {
3166 let ity = self.tcx.type_of(did);
3167 debug!("impl_self_ty: ity={:?}", ity);
3169 let substs = self.fresh_substs_for_item(span, did);
3170 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
3172 TypeAndSubsts { substs: substs, ty: substd_ty }
3175 /// Unifies the output type with the expected type early, for more coercions
3176 /// and forward type information on the input expressions.
3177 fn expected_inputs_for_expected_output(&self,
3179 expected_ret: Expectation<'tcx>,
3180 formal_ret: Ty<'tcx>,
3181 formal_args: &[Ty<'tcx>])
3183 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
3184 let ret_ty = match expected_ret.only_has_type(self) {
3186 None => return Vec::new()
3188 let expect_args = self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
3189 // Attempt to apply a subtyping relationship between the formal
3190 // return type (likely containing type variables if the function
3191 // is polymorphic) and the expected return type.
3192 // No argument expectations are produced if unification fails.
3193 let origin = self.misc(call_span);
3194 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
3196 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
3197 // to identity so the resulting type is not constrained.
3200 // Process any obligations locally as much as
3201 // we can. We don't care if some things turn
3202 // out unconstrained or ambiguous, as we're
3203 // just trying to get hints here.
3204 self.save_and_restore_in_snapshot_flag(|_| {
3205 let mut fulfill = TraitEngine::new(self.tcx);
3206 for obligation in ok.obligations {
3207 fulfill.register_predicate_obligation(self, obligation);
3209 fulfill.select_where_possible(self)
3210 }).map_err(|_| ())?;
3212 Err(_) => return Err(()),
3215 // Record all the argument types, with the substitutions
3216 // produced from the above subtyping unification.
3217 Ok(formal_args.iter().map(|ty| {
3218 self.resolve_type_vars_if_possible(ty)
3220 }).unwrap_or_default();
3221 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
3222 formal_args, formal_ret,
3223 expect_args, expected_ret);
3227 // Checks a method call.
3228 fn check_method_call(&self,
3229 expr: &'gcx hir::Expr,
3230 segment: &hir::PathSegment,
3232 args: &'gcx [hir::Expr],
3233 expected: Expectation<'tcx>,
3234 needs: Needs) -> Ty<'tcx> {
3235 let rcvr = &args[0];
3236 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
3237 // no need to check for bot/err -- callee does that
3238 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
3240 let method = match self.lookup_method(rcvr_t,
3246 self.write_method_call(expr.hir_id, method);
3250 if segment.ident.name != keywords::Invalid.name() {
3251 self.report_method_error(span,
3254 SelfSource::MethodCall(rcvr),
3262 // Call the generic checker.
3263 self.check_method_argument_types(span,
3271 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
3275 .unwrap_or_else(|| span_bug!(return_expr.span,
3276 "check_return_expr called outside fn body"));
3278 let ret_ty = ret_coercion.borrow().expected_ty();
3279 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
3280 ret_coercion.borrow_mut()
3282 &self.cause(return_expr.span,
3283 ObligationCauseCode::ReturnType(return_expr.id)),
3288 // A generic function for checking the 'then' and 'else' clauses in an 'if'
3289 // or 'if-else' expression.
3290 fn check_then_else(&self,
3291 cond_expr: &'gcx hir::Expr,
3292 then_expr: &'gcx hir::Expr,
3293 opt_else_expr: Option<&'gcx hir::Expr>,
3295 expected: Expectation<'tcx>) -> Ty<'tcx> {
3296 let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
3297 let cond_diverges = self.diverges.get();
3298 self.diverges.set(Diverges::Maybe);
3300 let expected = expected.adjust_for_branches(self);
3301 let then_ty = self.check_expr_with_expectation(then_expr, expected);
3302 let then_diverges = self.diverges.get();
3303 self.diverges.set(Diverges::Maybe);
3305 // We've already taken the expected type's preferences
3306 // into account when typing the `then` branch. To figure
3307 // out the initial shot at a LUB, we thus only consider
3308 // `expected` if it represents a *hard* constraint
3309 // (`only_has_type`); otherwise, we just go with a
3310 // fresh type variable.
3311 let coerce_to_ty = expected.coercion_target_type(self, sp);
3312 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
3314 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
3315 coerce.coerce(self, &if_cause, then_expr, then_ty);
3317 if let Some(else_expr) = opt_else_expr {
3318 let else_ty = self.check_expr_with_expectation(else_expr, expected);
3319 let else_diverges = self.diverges.get();
3321 coerce.coerce(self, &if_cause, else_expr, else_ty);
3323 // We won't diverge unless both branches do (or the condition does).
3324 self.diverges.set(cond_diverges | then_diverges & else_diverges);
3326 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
3327 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
3329 // If the condition is false we can't diverge.
3330 self.diverges.set(cond_diverges);
3333 let result_ty = coerce.complete(self);
3334 if cond_ty.references_error() {
3341 // Check field access expressions
3342 fn check_field(&self,
3343 expr: &'gcx hir::Expr,
3345 base: &'gcx hir::Expr,
3346 field: ast::Ident) -> Ty<'tcx> {
3347 let expr_t = self.check_expr_with_needs(base, needs);
3348 let expr_t = self.structurally_resolved_type(base.span,
3350 let mut private_candidate = None;
3351 let mut autoderef = self.autoderef(expr.span, expr_t);
3352 while let Some((base_t, _)) = autoderef.next() {
3354 ty::Adt(base_def, substs) if !base_def.is_enum() => {
3355 debug!("struct named {:?}", base_t);
3356 let (ident, def_scope) =
3357 self.tcx.adjust_ident(field, base_def.did, self.body_id);
3358 let fields = &base_def.non_enum_variant().fields;
3359 if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
3360 let field = &fields[index];
3361 let field_ty = self.field_ty(expr.span, field, substs);
3362 // Save the index of all fields regardless of their visibility in case
3363 // of error recovery.
3364 self.write_field_index(expr.id, index);
3365 if field.vis.is_accessible_from(def_scope, self.tcx) {
3366 let adjustments = autoderef.adjust_steps(self, needs);
3367 self.apply_adjustments(base, adjustments);
3368 autoderef.finalize(self);
3370 self.tcx.check_stability(field.did, Some(expr.id), expr.span);
3373 private_candidate = Some((base_def.did, field_ty));
3376 ty::Tuple(ref tys) => {
3377 let fstr = field.as_str();
3378 if let Ok(index) = fstr.parse::<usize>() {
3379 if fstr == index.to_string() {
3380 if let Some(field_ty) = tys.get(index) {
3381 let adjustments = autoderef.adjust_steps(self, needs);
3382 self.apply_adjustments(base, adjustments);
3383 autoderef.finalize(self);
3385 self.write_field_index(expr.id, index);
3394 autoderef.unambiguous_final_ty(self);
3396 if let Some((did, field_ty)) = private_candidate {
3397 let struct_path = self.tcx().item_path_str(did);
3398 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3399 "field `{}` of struct `{}` is private",
3400 field, struct_path);
3401 // Also check if an accessible method exists, which is often what is meant.
3402 if self.method_exists(field, expr_t, expr.id, false) {
3403 err.note(&format!("a method `{}` also exists, perhaps you wish to call it", field));
3407 } else if field.name == keywords::Invalid.name() {
3408 self.tcx().types.err
3409 } else if self.method_exists(field, expr_t, expr.id, true) {
3410 type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3411 "attempted to take value of method `{}` on type `{}`",
3413 .help("maybe a `()` to call it is missing?")
3415 self.tcx().types.err
3417 if !expr_t.is_primitive_ty() {
3418 let mut err = self.no_such_field_err(field.span, field, expr_t);
3421 ty::Adt(def, _) if !def.is_enum() => {
3422 if let Some(suggested_field_name) =
3423 Self::suggest_field_name(def.non_enum_variant(),
3424 &field.as_str(), vec![]) {
3425 err.span_suggestion_with_applicability(
3427 "a field with a similar name exists",
3428 suggested_field_name.to_string(),
3429 Applicability::MaybeIncorrect,
3432 err.span_label(field.span, "unknown field");
3433 let struct_variant_def = def.non_enum_variant();
3434 let field_names = self.available_field_names(struct_variant_def);
3435 if !field_names.is_empty() {
3436 err.note(&format!("available fields are: {}",
3437 self.name_series_display(field_names)));
3441 ty::Array(_, len) => {
3442 if let (Some(len), Ok(user_index)) = (
3443 len.assert_usize(self.tcx),
3444 field.as_str().parse::<u64>()
3446 let base = self.tcx.sess.source_map()
3447 .span_to_snippet(base.span)
3448 .unwrap_or_else(|_| self.tcx.hir().node_to_pretty_string(base.id));
3449 let help = "instead of using tuple indexing, use array indexing";
3450 let suggestion = format!("{}[{}]", base, field);
3451 let applicability = if len < user_index {
3452 Applicability::MachineApplicable
3454 Applicability::MaybeIncorrect
3456 err.span_suggestion_with_applicability(
3457 expr.span, help, suggestion, applicability
3462 let base = self.tcx.sess.source_map()
3463 .span_to_snippet(base.span)
3464 .unwrap_or_else(|_| self.tcx.hir().node_to_pretty_string(base.id));
3465 let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
3466 let suggestion = format!("(*{}).{}", base, field);
3467 err.span_suggestion_with_applicability(
3471 Applicability::MaybeIncorrect,
3478 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3479 "`{}` is a primitive type and therefore doesn't have fields",
3482 self.tcx().types.err
3486 // Return an hint about the closest match in field names
3487 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3489 skip: Vec<LocalInternedString>)
3491 let names = variant.fields.iter().filter_map(|field| {
3492 // ignore already set fields and private fields from non-local crates
3493 if skip.iter().any(|x| *x == field.ident.as_str()) ||
3494 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3497 Some(&field.ident.name)
3501 find_best_match_for_name(names, field, None)
3504 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3505 variant.fields.iter().filter(|field| {
3506 let def_scope = self.tcx.adjust_ident(field.ident, variant.did, self.body_id).1;
3507 field.vis.is_accessible_from(def_scope, self.tcx)
3509 .map(|field| field.ident.name)
3513 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3514 // dynamic limit, to never omit just one field
3515 let limit = if names.len() == 6 { 6 } else { 5 };
3516 let mut display = names.iter().take(limit)
3517 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3518 if names.len() > limit {
3519 display = format!("{} ... and {} others", display, names.len() - limit);
3524 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
3525 -> DiagnosticBuilder {
3526 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3527 "no field `{}` on type `{}`",
3531 fn report_unknown_field(&self,
3533 variant: &'tcx ty::VariantDef,
3535 skip_fields: &[hir::Field],
3537 let mut err = self.type_error_struct_with_diag(
3539 |actual| match ty.sty {
3540 ty::Adt(adt, ..) if adt.is_enum() => {
3541 struct_span_err!(self.tcx.sess, field.ident.span, E0559,
3542 "{} `{}::{}` has no field named `{}`",
3543 kind_name, actual, variant.ident, field.ident)
3546 struct_span_err!(self.tcx.sess, field.ident.span, E0560,
3547 "{} `{}` has no field named `{}`",
3548 kind_name, actual, field.ident)
3552 // prevent all specified fields from being suggested
3553 let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
3554 if let Some(field_name) = Self::suggest_field_name(variant,
3555 &field.ident.as_str(),
3556 skip_fields.collect()) {
3557 err.span_suggestion_with_applicability(
3559 "a field with a similar name exists",
3560 field_name.to_string(),
3561 Applicability::MaybeIncorrect,
3565 ty::Adt(adt, ..) => {
3567 err.span_label(field.ident.span,
3568 format!("`{}::{}` does not have this field",
3569 ty, variant.ident));
3571 err.span_label(field.ident.span,
3572 format!("`{}` does not have this field", ty));
3574 let available_field_names = self.available_field_names(variant);
3575 if !available_field_names.is_empty() {
3576 err.note(&format!("available fields are: {}",
3577 self.name_series_display(available_field_names)));
3580 _ => bug!("non-ADT passed to report_unknown_field")
3586 fn check_expr_struct_fields(&self,
3588 expected: Expectation<'tcx>,
3589 expr_id: ast::NodeId,
3591 variant: &'tcx ty::VariantDef,
3592 ast_fields: &'gcx [hir::Field],
3593 check_completeness: bool) -> bool {
3597 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3598 .get(0).cloned().unwrap_or(adt_ty);
3599 // re-link the regions that EIfEO can erase.
3600 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3602 let (substs, adt_kind, kind_name) = match &adt_ty.sty {
3603 &ty::Adt(adt, substs) => {
3604 (substs, adt.adt_kind(), adt.variant_descr())
3606 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3609 let mut remaining_fields = variant.fields.iter().enumerate().map(|(i, field)|
3610 (field.ident.modern(), (i, field))
3611 ).collect::<FxHashMap<_, _>>();
3613 let mut seen_fields = FxHashMap::default();
3615 let mut error_happened = false;
3617 // Type-check each field.
3618 for field in ast_fields {
3619 let ident = tcx.adjust_ident(field.ident, variant.did, self.body_id).0;
3620 let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
3621 seen_fields.insert(ident, field.span);
3622 self.write_field_index(field.id, i);
3624 // We don't look at stability attributes on
3625 // struct-like enums (yet...), but it's definitely not
3626 // a bug to have constructed one.
3627 if adt_kind != AdtKind::Enum {
3628 tcx.check_stability(v_field.did, Some(expr_id), field.span);
3631 self.field_ty(field.span, v_field, substs)
3633 error_happened = true;
3634 if let Some(prev_span) = seen_fields.get(&ident) {
3635 let mut err = struct_span_err!(self.tcx.sess,
3638 "field `{}` specified more than once",
3641 err.span_label(field.ident.span, "used more than once");
3642 err.span_label(*prev_span, format!("first use of `{}`", ident));
3646 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3652 // Make sure to give a type to the field even if there's
3653 // an error, so we can continue type-checking.
3654 self.check_expr_coercable_to_type(&field.expr, field_type);
3657 // Make sure the programmer specified correct number of fields.
3658 if kind_name == "union" {
3659 if ast_fields.len() != 1 {
3660 tcx.sess.span_err(span, "union expressions should have exactly one field");
3662 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3663 let len = remaining_fields.len();
3665 let mut displayable_field_names = remaining_fields
3667 .map(|ident| ident.as_str())
3668 .collect::<Vec<_>>();
3670 displayable_field_names.sort();
3672 let truncated_fields_error = if len <= 3 {
3675 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3678 let remaining_fields_names = displayable_field_names.iter().take(3)
3679 .map(|n| format!("`{}`", n))
3680 .collect::<Vec<_>>()
3683 struct_span_err!(tcx.sess, span, E0063,
3684 "missing field{} {}{} in initializer of `{}`",
3685 if remaining_fields.len() == 1 { "" } else { "s" },
3686 remaining_fields_names,
3687 truncated_fields_error,
3689 .span_label(span, format!("missing {}{}",
3690 remaining_fields_names,
3691 truncated_fields_error))
3697 fn check_struct_fields_on_error(&self,
3698 fields: &'gcx [hir::Field],
3699 base_expr: &'gcx Option<P<hir::Expr>>) {
3700 for field in fields {
3701 self.check_expr(&field.expr);
3703 if let Some(ref base) = *base_expr {
3704 self.check_expr(&base);
3708 pub fn check_struct_path(&self,
3710 node_id: ast::NodeId)
3711 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3712 let path_span = match *qpath {
3713 QPath::Resolved(_, ref path) => path.span,
3714 QPath::TypeRelative(ref qself, _) => qself.span
3716 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3717 let variant = match def {
3719 self.set_tainted_by_errors();
3722 Def::Variant(..) => {
3724 ty::Adt(adt, substs) => {
3725 Some((adt.variant_of_def(def), adt.did, substs))
3727 _ => bug!("unexpected type: {:?}", ty.sty)
3730 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3731 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3733 ty::Adt(adt, substs) if !adt.is_enum() => {
3734 Some((adt.non_enum_variant(), adt.did, substs))
3739 _ => bug!("unexpected definition: {:?}", def)
3742 if let Some((variant, did, substs)) = variant {
3743 debug!("check_struct_path: did={:?} substs={:?}", did, substs);
3744 let hir_id = self.tcx.hir().node_to_hir_id(node_id);
3745 self.write_user_substs_from_substs(hir_id, substs, None);
3747 // Check bounds on type arguments used in the path.
3748 let bounds = self.instantiate_bounds(path_span, did, substs);
3749 let cause = traits::ObligationCause::new(path_span, self.body_id,
3750 traits::ItemObligation(did));
3751 self.add_obligations_for_parameters(cause, &bounds);
3755 struct_span_err!(self.tcx.sess, path_span, E0071,
3756 "expected struct, variant or union type, found {}",
3757 ty.sort_string(self.tcx))
3758 .span_label(path_span, "not a struct")
3764 fn check_expr_struct(&self,
3766 expected: Expectation<'tcx>,
3768 fields: &'gcx [hir::Field],
3769 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3771 // Find the relevant variant
3772 let (variant, adt_ty) =
3773 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3776 self.check_struct_fields_on_error(fields, base_expr);
3777 return self.tcx.types.err;
3780 let path_span = match *qpath {
3781 QPath::Resolved(_, ref path) => path.span,
3782 QPath::TypeRelative(ref qself, _) => qself.span
3785 // Prohibit struct expressions when non-exhaustive flag is set.
3786 let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
3787 if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
3788 span_err!(self.tcx.sess, expr.span, E0639,
3789 "cannot create non-exhaustive {} using struct expression",
3790 adt.variant_descr());
3793 let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.id, path_span,
3794 variant, fields, base_expr.is_none());
3795 if let &Some(ref base_expr) = base_expr {
3796 // If check_expr_struct_fields hit an error, do not attempt to populate
3797 // the fields with the base_expr. This could cause us to hit errors later
3798 // when certain fields are assumed to exist that in fact do not.
3799 if !error_happened {
3800 self.check_expr_has_type_or_error(base_expr, adt_ty);
3802 ty::Adt(adt, substs) if adt.is_struct() => {
3803 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3804 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3809 .fru_field_types_mut()
3810 .insert(expr.hir_id, fru_field_types);
3813 span_err!(self.tcx.sess, base_expr.span, E0436,
3814 "functional record update syntax requires a struct");
3819 self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
3825 /// If an expression has any sub-expressions that result in a type error,
3826 /// inspecting that expression's type with `ty.references_error()` will return
3827 /// true. Likewise, if an expression is known to diverge, inspecting its
3828 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3829 /// strict, _|_ can appear in the type of an expression that does not,
3830 /// itself, diverge: for example, fn() -> _|_.)
3831 /// Note that inspecting a type's structure *directly* may expose the fact
3832 /// that there are actually multiple representations for `Error`, so avoid
3833 /// that when err needs to be handled differently.
3834 fn check_expr_with_expectation_and_needs(&self,
3835 expr: &'gcx hir::Expr,
3836 expected: Expectation<'tcx>,
3837 needs: Needs) -> Ty<'tcx> {
3838 debug!(">> type-checking: expr={:?} expected={:?}",
3841 // Warn for expressions after diverging siblings.
3842 self.warn_if_unreachable(expr.id, expr.span, "expression");
3844 // Hide the outer diverging and has_errors flags.
3845 let old_diverges = self.diverges.get();
3846 let old_has_errors = self.has_errors.get();
3847 self.diverges.set(Diverges::Maybe);
3848 self.has_errors.set(false);
3850 let ty = self.check_expr_kind(expr, expected, needs);
3852 // Warn for non-block expressions with diverging children.
3854 ExprKind::Block(..) |
3855 ExprKind::Loop(..) | ExprKind::While(..) |
3856 ExprKind::If(..) | ExprKind::Match(..) => {}
3858 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3861 // Any expression that produces a value of type `!` must have diverged
3863 self.diverges.set(self.diverges.get() | Diverges::Always);
3866 // Record the type, which applies it effects.
3867 // We need to do this after the warning above, so that
3868 // we don't warn for the diverging expression itself.
3869 self.write_ty(expr.hir_id, ty);
3871 // Combine the diverging and has_error flags.
3872 self.diverges.set(self.diverges.get() | old_diverges);
3873 self.has_errors.set(self.has_errors.get() | old_has_errors);
3875 debug!("type of {} is...", self.tcx.hir().node_to_string(expr.id));
3876 debug!("... {:?}, expected is {:?}", ty, expected);
3883 expr: &'gcx hir::Expr,
3884 expected: Expectation<'tcx>,
3888 "check_expr_kind(expr={:?}, expected={:?}, needs={:?})",
3897 ExprKind::Box(ref subexpr) => {
3898 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3900 ty::Adt(def, _) if def.is_box()
3901 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3905 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3906 tcx.mk_box(referent_ty)
3909 ExprKind::Lit(ref lit) => {
3910 self.check_lit(&lit, expected)
3912 ExprKind::Binary(op, ref lhs, ref rhs) => {
3913 self.check_binop(expr, op, lhs, rhs)
3915 ExprKind::AssignOp(op, ref lhs, ref rhs) => {
3916 self.check_binop_assign(expr, op, lhs, rhs)
3918 ExprKind::Unary(unop, ref oprnd) => {
3919 let expected_inner = match unop {
3920 hir::UnNot | hir::UnNeg => {
3927 let needs = match unop {
3928 hir::UnDeref => needs,
3931 let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
3935 if !oprnd_t.references_error() {
3936 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3939 if let Some(mt) = oprnd_t.builtin_deref(true) {
3941 } else if let Some(ok) = self.try_overloaded_deref(
3942 expr.span, oprnd_t, needs) {
3943 let method = self.register_infer_ok_obligations(ok);
3944 if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
3945 let mutbl = match mutbl {
3946 hir::MutImmutable => AutoBorrowMutability::Immutable,
3947 hir::MutMutable => AutoBorrowMutability::Mutable {
3948 // (It shouldn't actually matter for unary ops whether
3949 // we enable two-phase borrows or not, since a unary
3950 // op has no additional operands.)
3951 allow_two_phase_borrow: AllowTwoPhase::No,
3954 self.apply_adjustments(oprnd, vec![Adjustment {
3955 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3956 target: method.sig.inputs()[0]
3959 oprnd_t = self.make_overloaded_place_return_type(method).ty;
3960 self.write_method_call(expr.hir_id, method);
3962 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3963 "type `{}` cannot be dereferenced",
3965 oprnd_t = tcx.types.err;
3969 let result = self.check_user_unop(expr, oprnd_t, unop);
3970 // If it's builtin, we can reuse the type, this helps inference.
3971 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::Bool) {
3976 let result = self.check_user_unop(expr, oprnd_t, unop);
3977 // If it's builtin, we can reuse the type, this helps inference.
3978 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3986 ExprKind::AddrOf(mutbl, ref oprnd) => {
3987 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3989 ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
3990 if oprnd.is_place_expr() {
3991 // Places may legitimately have unsized types.
3992 // For example, dereferences of a fat pointer and
3993 // the last field of a struct can be unsized.
3996 Expectation::rvalue_hint(self, ty)
4002 let needs = Needs::maybe_mut_place(mutbl);
4003 let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
4005 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
4006 if tm.ty.references_error() {
4009 // Note: at this point, we cannot say what the best lifetime
4010 // is to use for resulting pointer. We want to use the
4011 // shortest lifetime possible so as to avoid spurious borrowck
4012 // errors. Moreover, the longest lifetime will depend on the
4013 // precise details of the value whose address is being taken
4014 // (and how long it is valid), which we don't know yet until type
4015 // inference is complete.
4017 // Therefore, here we simply generate a region variable. The
4018 // region inferencer will then select the ultimate value.
4019 // Finally, borrowck is charged with guaranteeing that the
4020 // value whose address was taken can actually be made to live
4021 // as long as it needs to live.
4022 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
4023 tcx.mk_ref(region, tm)
4026 ExprKind::Path(ref qpath) => {
4027 let (def, opt_ty, segs) = self.resolve_ty_and_def_ufcs(qpath, expr.id, expr.span);
4028 let ty = match def {
4030 self.set_tainted_by_errors();
4033 Def::VariantCtor(_, CtorKind::Fictive) => {
4034 report_unexpected_variant_def(tcx, &def, expr.span, qpath);
4037 _ => self.instantiate_value_path(segs, opt_ty, def, expr.span, id).0,
4040 if let ty::FnDef(..) = ty.sty {
4041 let fn_sig = ty.fn_sig(tcx);
4042 if !tcx.features().unsized_locals {
4043 // We want to remove some Sized bounds from std functions,
4044 // but don't want to expose the removal to stable Rust.
4045 // i.e., we don't want to allow
4051 // to work in stable even if the Sized bound on `drop` is relaxed.
4052 for i in 0..fn_sig.inputs().skip_binder().len() {
4053 // We just want to check sizedness, so instead of introducing
4054 // placeholder lifetimes with probing, we just replace higher lifetimes
4056 let input = self.replace_bound_vars_with_fresh_vars(
4058 infer::LateBoundRegionConversionTime::FnCall,
4059 &fn_sig.input(i)).0;
4060 self.require_type_is_sized_deferred(input, expr.span,
4061 traits::SizedArgumentType);
4064 // Here we want to prevent struct constructors from returning unsized types.
4065 // There were two cases this happened: fn pointer coercion in stable
4066 // and usual function call in presense of unsized_locals.
4067 // Also, as we just want to check sizedness, instead of introducing
4068 // placeholder lifetimes with probing, we just replace higher lifetimes
4070 let output = self.replace_bound_vars_with_fresh_vars(
4072 infer::LateBoundRegionConversionTime::FnCall,
4073 &fn_sig.output()).0;
4074 self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
4077 // We always require that the type provided as the value for
4078 // a type parameter outlives the moment of instantiation.
4079 let substs = self.tables.borrow().node_substs(expr.hir_id);
4080 self.add_wf_bounds(substs, expr);
4084 ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
4085 for expr in outputs.iter().chain(inputs.iter()) {
4086 self.check_expr(expr);
4090 ExprKind::Break(destination, ref expr_opt) => {
4091 if let Ok(target_id) = destination.target_id {
4093 if let Some(ref e) = *expr_opt {
4094 // If this is a break with a value, we need to type-check
4095 // the expression. Get an expected type from the loop context.
4096 let opt_coerce_to = {
4097 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4098 enclosing_breakables.find_breakable(target_id)
4101 .map(|coerce| coerce.expected_ty())
4104 // If the loop context is not a `loop { }`, then break with
4105 // a value is illegal, and `opt_coerce_to` will be `None`.
4106 // Just set expectation to error in that case.
4107 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
4109 // Recurse without `enclosing_breakables` borrowed.
4110 e_ty = self.check_expr_with_hint(e, coerce_to);
4111 cause = self.misc(e.span);
4113 // Otherwise, this is a break *without* a value. That's
4114 // always legal, and is equivalent to `break ()`.
4115 e_ty = tcx.mk_unit();
4116 cause = self.misc(expr.span);
4119 // Now that we have type-checked `expr_opt`, borrow
4120 // the `enclosing_loops` field and let's coerce the
4121 // type of `expr_opt` into what is expected.
4122 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4123 let ctxt = enclosing_breakables.find_breakable(target_id);
4124 if let Some(ref mut coerce) = ctxt.coerce {
4125 if let Some(ref e) = *expr_opt {
4126 coerce.coerce(self, &cause, e, e_ty);
4128 assert!(e_ty.is_unit());
4129 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
4132 // If `ctxt.coerce` is `None`, we can just ignore
4133 // the type of the expresison. This is because
4134 // either this was a break *without* a value, in
4135 // which case it is always a legal type (`()`), or
4136 // else an error would have been flagged by the
4137 // `loops` pass for using break with an expression
4138 // where you are not supposed to.
4139 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
4142 ctxt.may_break = true;
4144 // the type of a `break` is always `!`, since it diverges
4147 // Otherwise, we failed to find the enclosing loop;
4148 // this can only happen if the `break` was not
4149 // inside a loop at all, which is caught by the
4150 // loop-checking pass.
4151 if self.tcx.sess.err_count() == 0 {
4152 self.tcx.sess.delay_span_bug(expr.span,
4153 "break was outside loop, but no error was emitted");
4156 // We still need to assign a type to the inner expression to
4157 // prevent the ICE in #43162.
4158 if let Some(ref e) = *expr_opt {
4159 self.check_expr_with_hint(e, tcx.types.err);
4161 // ... except when we try to 'break rust;'.
4162 // ICE this expression in particular (see #43162).
4163 if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
4164 if path.segments.len() == 1 && path.segments[0].ident.name == "rust" {
4165 fatally_break_rust(self.tcx.sess);
4169 // There was an error; make type-check fail.
4174 ExprKind::Continue(destination) => {
4175 if destination.target_id.is_ok() {
4178 // There was an error; make type-check fail.
4182 ExprKind::Ret(ref expr_opt) => {
4183 if self.ret_coercion.is_none() {
4184 struct_span_err!(self.tcx.sess, expr.span, E0572,
4185 "return statement outside of function body").emit();
4186 } else if let Some(ref e) = *expr_opt {
4187 *self.ret_coercion_span.borrow_mut() = Some(e.span);
4188 self.check_return_expr(e);
4190 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
4191 *self.ret_coercion_span.borrow_mut() = Some(expr.span);
4192 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
4193 if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) {
4194 coercion.coerce_forced_unit(
4199 fn_decl.output.span(),
4201 "expected `{}` because of this return type",
4209 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
4214 ExprKind::Assign(ref lhs, ref rhs) => {
4215 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
4217 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
4220 ExpectIfCondition => {
4221 self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
4222 expected error elsehwere");
4225 // Only check this if not in an `if` condition, as the
4226 // mistyped comparison help is more appropriate.
4227 if !lhs.is_place_expr() {
4228 struct_span_err!(self.tcx.sess, expr.span, E0070,
4229 "invalid left-hand side expression")
4230 .span_label(expr.span, "left-hand of expression not valid")
4236 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
4238 if lhs_ty.references_error() || rhs_ty.references_error() {
4244 ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => {
4245 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
4246 expr.span, expected)
4248 ExprKind::While(ref cond, ref body, _) => {
4249 let ctxt = BreakableCtxt {
4250 // cannot use break with a value from a while loop
4252 may_break: false, // Will get updated if/when we find a `break`.
4255 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
4256 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
4257 let cond_diverging = self.diverges.get();
4258 self.check_block_no_value(&body);
4260 // We may never reach the body so it diverging means nothing.
4261 self.diverges.set(cond_diverging);
4265 // No way to know whether it's diverging because
4266 // of a `break` or an outer `break` or `return`.
4267 self.diverges.set(Diverges::Maybe);
4272 ExprKind::Loop(ref body, _, source) => {
4273 let coerce = match source {
4274 // you can only use break with a value from a normal `loop { }`
4275 hir::LoopSource::Loop => {
4276 let coerce_to = expected.coercion_target_type(self, body.span);
4277 Some(CoerceMany::new(coerce_to))
4280 hir::LoopSource::WhileLet |
4281 hir::LoopSource::ForLoop => {
4286 let ctxt = BreakableCtxt {
4288 may_break: false, // Will get updated if/when we find a `break`.
4291 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
4292 self.check_block_no_value(&body);
4296 // No way to know whether it's diverging because
4297 // of a `break` or an outer `break` or `return`.
4298 self.diverges.set(Diverges::Maybe);
4301 // If we permit break with a value, then result type is
4302 // the LUB of the breaks (possibly ! if none); else, it
4303 // is nil. This makes sense because infinite loops
4304 // (which would have type !) are only possible iff we
4305 // permit break with a value [1].
4306 if ctxt.coerce.is_none() && !ctxt.may_break {
4308 self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
4310 ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
4312 ExprKind::Match(ref discrim, ref arms, match_src) => {
4313 self.check_match(expr, &discrim, arms, expected, match_src)
4315 ExprKind::Closure(capture, ref decl, body_id, _, gen) => {
4316 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
4318 ExprKind::Block(ref body, _) => {
4319 self.check_block_with_expected(&body, expected)
4321 ExprKind::Call(ref callee, ref args) => {
4322 self.check_call(expr, &callee, args, expected)
4324 ExprKind::MethodCall(ref segment, span, ref args) => {
4325 self.check_method_call(expr, segment, span, args, expected, needs)
4327 ExprKind::Cast(ref e, ref t) => {
4328 // Find the type of `e`. Supply hints based on the type we are casting to,
4330 let t_cast = self.to_ty_saving_user_provided_ty(t);
4331 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
4332 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
4333 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
4335 // Eagerly check for some obvious errors.
4336 if t_expr.references_error() || t_cast.references_error() {
4339 // Defer other checks until we're done type checking.
4340 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
4341 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
4343 deferred_cast_checks.push(cast_check);
4346 Err(ErrorReported) => {
4352 ExprKind::Type(ref e, ref t) => {
4353 let ty = self.to_ty_saving_user_provided_ty(&t);
4354 self.check_expr_eq_type(&e, ty);
4357 ExprKind::Array(ref args) => {
4358 let uty = expected.to_option(self).and_then(|uty| {
4360 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4365 let element_ty = if !args.is_empty() {
4366 let coerce_to = uty.unwrap_or_else(
4367 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
4368 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
4369 assert_eq!(self.diverges.get(), Diverges::Maybe);
4371 let e_ty = self.check_expr_with_hint(e, coerce_to);
4372 let cause = self.misc(e.span);
4373 coerce.coerce(self, &cause, e, e_ty);
4375 coerce.complete(self)
4377 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
4379 tcx.mk_array(element_ty, args.len() as u64)
4381 ExprKind::Repeat(ref element, ref count) => {
4382 let count_def_id = tcx.hir().local_def_id(count.id);
4383 let param_env = ty::ParamEnv::empty();
4384 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
4385 let instance = ty::Instance::resolve(
4391 let global_id = GlobalId {
4395 let count = tcx.const_eval(param_env.and(global_id));
4397 let uty = match expected {
4398 ExpectHasType(uty) => {
4400 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
4407 let (element_ty, t) = match uty {
4409 self.check_expr_coercable_to_type(&element, uty);
4413 let ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
4414 let element_ty = self.check_expr_has_type_or_error(&element, ty);
4419 if let Ok(count) = count {
4420 let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
4422 // For [foo, ..n] where n > 1, `foo` must have
4424 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4425 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4429 if element_ty.references_error() {
4431 } else if let Ok(count) = count {
4432 tcx.mk_ty(ty::Array(t, count))
4437 ExprKind::Tup(ref elts) => {
4438 let flds = expected.only_has_type(self).and_then(|ty| {
4439 let ty = self.resolve_type_vars_with_obligations(ty);
4441 ty::Tuple(ref flds) => Some(&flds[..]),
4446 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4447 let t = match flds {
4448 Some(ref fs) if i < fs.len() => {
4450 self.check_expr_coercable_to_type(&e, ety);
4454 self.check_expr_with_expectation(&e, NoExpectation)
4459 let tuple = tcx.mk_tup(elt_ts_iter);
4460 if tuple.references_error() {
4463 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4467 ExprKind::Struct(ref qpath, ref fields, ref base_expr) => {
4468 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4470 ExprKind::Field(ref base, field) => {
4471 self.check_field(expr, needs, &base, field)
4473 ExprKind::Index(ref base, ref idx) => {
4474 let base_t = self.check_expr_with_needs(&base, needs);
4475 let idx_t = self.check_expr(&idx);
4477 if base_t.references_error() {
4479 } else if idx_t.references_error() {
4482 let base_t = self.structurally_resolved_type(base.span, base_t);
4483 match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
4484 Some((index_ty, element_ty)) => {
4485 // two-phase not needed because index_ty is never mutable
4486 self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
4491 type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4492 "cannot index into a value of type `{}`",
4494 // Try to give some advice about indexing tuples.
4495 if let ty::Tuple(..) = base_t.sty {
4496 let mut needs_note = true;
4497 // If the index is an integer, we can show the actual
4498 // fixed expression:
4499 if let ExprKind::Lit(ref lit) = idx.node {
4500 if let ast::LitKind::Int(i,
4501 ast::LitIntType::Unsuffixed) = lit.node {
4502 let snip = tcx.sess.source_map().span_to_snippet(base.span);
4503 if let Ok(snip) = snip {
4504 err.span_suggestion_with_applicability(
4506 "to access tuple elements, use",
4507 format!("{}.{}", snip, i),
4508 Applicability::MachineApplicable);
4514 err.help("to access tuple elements, use tuple indexing \
4515 syntax (e.g., `tuple.0`)");
4524 ExprKind::Yield(ref value) => {
4525 match self.yield_ty {
4527 self.check_expr_coercable_to_type(&value, ty);
4530 struct_span_err!(self.tcx.sess, expr.span, E0627,
4531 "yield statement outside of generator literal").emit();
4536 hir::ExprKind::Err => {
4542 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4543 // The newly resolved definition is written into `type_dependent_defs`.
4544 fn finish_resolving_struct_path(&self,
4547 node_id: ast::NodeId)
4551 QPath::Resolved(ref maybe_qself, ref path) => {
4552 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4553 let ty = AstConv::def_to_ty(self, self_ty, path, true);
4556 QPath::TypeRelative(ref qself, ref segment) => {
4557 let ty = self.to_ty(qself);
4559 let def = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
4564 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4567 // Write back the new resolution.
4568 let hir_id = self.tcx.hir().node_to_hir_id(node_id);
4569 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4576 // Resolve associated value path into a base type and associated constant or method definition.
4577 // The newly resolved definition is written into `type_dependent_defs`.
4578 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4580 node_id: ast::NodeId,
4582 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4584 let (ty, qself, item_segment) = match *qpath {
4585 QPath::Resolved(ref opt_qself, ref path) => {
4587 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4588 &path.segments[..]);
4590 QPath::TypeRelative(ref qself, ref segment) => {
4591 (self.to_ty(qself), qself, segment)
4594 let hir_id = self.tcx.hir().node_to_hir_id(node_id);
4595 if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4596 // Return directly on cache hit. This is useful to avoid doubly reporting
4597 // errors with default match binding modes. See #44614.
4598 return (*cached_def, Some(ty), slice::from_ref(&**item_segment))
4600 let item_name = item_segment.ident;
4601 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
4604 let def = match error {
4605 method::MethodError::PrivateMatch(def, _) => def,
4608 if item_name.name != keywords::Invalid.name() {
4609 self.report_method_error(span,
4612 SelfSource::QPath(qself),
4620 // Write back the new resolution.
4621 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4622 (def, Some(ty), slice::from_ref(&**item_segment))
4625 pub fn check_decl_initializer(&self,
4626 local: &'gcx hir::Local,
4627 init: &'gcx hir::Expr) -> Ty<'tcx>
4629 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
4630 // for #42640 (default match binding modes).
4633 let ref_bindings = local.pat.contains_explicit_ref_binding();
4635 let local_ty = self.local_ty(init.span, local.id).revealed_ty;
4636 if let Some(m) = ref_bindings {
4637 // Somewhat subtle: if we have a `ref` binding in the pattern,
4638 // we want to avoid introducing coercions for the RHS. This is
4639 // both because it helps preserve sanity and, in the case of
4640 // ref mut, for soundness (issue #23116). In particular, in
4641 // the latter case, we need to be clear that the type of the
4642 // referent for the reference that results is *equal to* the
4643 // type of the place it is referencing, and not some
4644 // supertype thereof.
4645 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4646 self.demand_eqtype(init.span, local_ty, init_ty);
4649 self.check_expr_coercable_to_type(init, local_ty)
4653 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4654 let t = self.local_ty(local.span, local.id).decl_ty;
4655 self.write_ty(local.hir_id, t);
4657 if let Some(ref init) = local.init {
4658 let init_ty = self.check_decl_initializer(local, &init);
4659 if init_ty.references_error() {
4660 self.write_ty(local.hir_id, init_ty);
4664 self.check_pat_walk(&local.pat, t,
4665 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4667 let pat_ty = self.node_ty(local.pat.hir_id);
4668 if pat_ty.references_error() {
4669 self.write_ty(local.hir_id, pat_ty);
4673 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4674 // Don't do all the complex logic below for `DeclItem`.
4676 hir::StmtKind::Decl(ref decl, _) => {
4677 if let hir::DeclKind::Item(_) = decl.node {
4681 hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4684 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4686 // Hide the outer diverging and `has_errors` flags.
4687 let old_diverges = self.diverges.get();
4688 let old_has_errors = self.has_errors.get();
4689 self.diverges.set(Diverges::Maybe);
4690 self.has_errors.set(false);
4693 hir::StmtKind::Decl(ref decl, _) => {
4695 hir::DeclKind::Local(ref l) => {
4696 self.check_decl_local(&l);
4699 hir::DeclKind::Item(_) => ()
4702 hir::StmtKind::Expr(ref expr, _) => {
4703 // Check with expected type of `()`.
4704 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
4706 hir::StmtKind::Semi(ref expr, _) => {
4707 self.check_expr(&expr);
4711 // Combine the diverging and `has_error` flags.
4712 self.diverges.set(self.diverges.get() | old_diverges);
4713 self.has_errors.set(self.has_errors.get() | old_has_errors);
4716 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4717 let unit = self.tcx.mk_unit();
4718 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4720 // if the block produces a `!` value, that can always be
4721 // (effectively) coerced to unit.
4723 self.demand_suptype(blk.span, unit, ty);
4727 fn check_block_with_expected(&self,
4728 blk: &'gcx hir::Block,
4729 expected: Expectation<'tcx>) -> Ty<'tcx> {
4731 let mut fcx_ps = self.ps.borrow_mut();
4732 let unsafety_state = fcx_ps.recurse(blk);
4733 replace(&mut *fcx_ps, unsafety_state)
4736 // In some cases, blocks have just one exit, but other blocks
4737 // can be targeted by multiple breaks. This can happen both
4738 // with labeled blocks as well as when we desugar
4739 // a `try { ... }` expression.
4743 // 'a: { if true { break 'a Err(()); } Ok(()) }
4745 // Here we would wind up with two coercions, one from
4746 // `Err(())` and the other from the tail expression
4747 // `Ok(())`. If the tail expression is omitted, that's a
4748 // "forced unit" -- unless the block diverges, in which
4749 // case we can ignore the tail expression (e.g., `'a: {
4750 // break 'a 22; }` would not force the type of the block
4752 let tail_expr = blk.expr.as_ref();
4753 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4754 let coerce = if blk.targeted_by_break {
4755 CoerceMany::new(coerce_to_ty)
4757 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4758 Some(e) => slice::from_ref(e),
4761 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4764 let prev_diverges = self.diverges.get();
4765 let ctxt = BreakableCtxt {
4766 coerce: Some(coerce),
4770 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4771 for s in &blk.stmts {
4775 // check the tail expression **without** holding the
4776 // `enclosing_breakables` lock below.
4777 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4779 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4780 let ctxt = enclosing_breakables.find_breakable(blk.id);
4781 let coerce = ctxt.coerce.as_mut().unwrap();
4782 if let Some(tail_expr_ty) = tail_expr_ty {
4783 let tail_expr = tail_expr.unwrap();
4784 let cause = self.cause(tail_expr.span,
4785 ObligationCauseCode::BlockTailExpression(blk.id));
4791 // Subtle: if there is no explicit tail expression,
4792 // that is typically equivalent to a tail expression
4793 // of `()` -- except if the block diverges. In that
4794 // case, there is no value supplied from the tail
4795 // expression (assuming there are no other breaks,
4796 // this implies that the type of the block will be
4799 // #41425 -- label the implicit `()` as being the
4800 // "found type" here, rather than the "expected type".
4801 if !self.diverges.get().always() {
4802 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4803 if let Some(expected_ty) = expected.only_has_type(self) {
4804 self.consider_hint_about_removing_semicolon(blk,
4814 // If we can break from the block, then the block's exit is always reachable
4815 // (... as long as the entry is reachable) - regardless of the tail of the block.
4816 self.diverges.set(prev_diverges);
4819 let mut ty = ctxt.coerce.unwrap().complete(self);
4821 if self.has_errors.get() || ty.references_error() {
4822 ty = self.tcx.types.err
4825 self.write_ty(blk.hir_id, ty);
4827 *self.ps.borrow_mut() = prev;
4831 /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
4832 /// suggestion can be made, `None` otherwise.
4833 pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
4834 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4835 // `while` before reaching it, as block tail returns are not available in them.
4836 if let Some(fn_id) = self.tcx.hir().get_return_block(blk_id) {
4837 let parent = self.tcx.hir().get(fn_id);
4839 if let Node::Item(&hir::Item {
4840 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4842 decl.clone().and_then(|decl| {
4843 // This is less than ideal, it will not suggest a return type span on any
4844 // method called `main`, regardless of whether it is actually the entry point,
4845 // but it will still present it as the reason for the expected type.
4846 Some((decl, ident.name != Symbol::intern("main")))
4848 } else if let Node::TraitItem(&hir::TraitItem {
4849 node: hir::TraitItemKind::Method(hir::MethodSig {
4853 decl.clone().and_then(|decl| {
4856 } else if let Node::ImplItem(&hir::ImplItem {
4857 node: hir::ImplItemKind::Method(hir::MethodSig {
4861 decl.clone().and_then(|decl| {
4872 /// On implicit return expressions with mismatched types, provide the following suggestions:
4874 /// - Point out the method's return type as the reason for the expected type
4875 /// - Possible missing semicolon
4876 /// - Possible missing return type if the return type is the default, and not `fn main()`
4877 pub fn suggest_mismatched_types_on_tail(&self,
4878 err: &mut DiagnosticBuilder<'tcx>,
4879 expression: &'gcx hir::Expr,
4883 blk_id: ast::NodeId) {
4884 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4885 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4886 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4888 self.suggest_ref_or_into(err, expression, expected, found);
4891 pub fn suggest_ref_or_into(
4893 err: &mut DiagnosticBuilder<'tcx>,
4898 if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
4899 err.span_suggestion_with_applicability(
4903 Applicability::MachineApplicable,
4905 } else if !self.check_for_cast(err, expr, found, expected) {
4906 let methods = self.get_conversion_methods(expr.span, expected, found);
4907 if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
4908 let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
4909 .filter_map(|(receiver, method)| {
4910 let method_call = format!(".{}()", method.ident);
4911 if receiver.ends_with(&method_call) {
4912 None // do not suggest code that is already there (#53348)
4914 let method_call_list = [".to_vec()", ".to_string()"];
4915 if receiver.ends_with(".clone()")
4916 && method_call_list.contains(&method_call.as_str()) {
4917 let max_len = receiver.rfind(".").unwrap();
4918 Some(format!("{}{}", &receiver[..max_len], method_call))
4921 Some(format!("{}{}", receiver, method_call))
4925 if suggestions.peek().is_some() {
4926 err.span_suggestions_with_applicability(
4928 "try using a conversion method",
4930 Applicability::MaybeIncorrect,
4937 /// A common error is to forget to add a semicolon at the end of a block:
4941 /// bar_that_returns_u32()
4945 /// This routine checks if the return expression in a block would make sense on its own as a
4946 /// statement and the return type has been left as default or has been specified as `()`. If so,
4947 /// it suggests adding a semicolon.
4948 fn suggest_missing_semicolon(&self,
4949 err: &mut DiagnosticBuilder<'tcx>,
4950 expression: &'gcx hir::Expr,
4953 if expected.is_unit() {
4954 // `BlockTailExpression` only relevant if the tail expr would be
4955 // useful on its own.
4956 match expression.node {
4957 ExprKind::Call(..) |
4958 ExprKind::MethodCall(..) |
4960 ExprKind::While(..) |
4961 ExprKind::Loop(..) |
4962 ExprKind::Match(..) |
4963 ExprKind::Block(..) => {
4964 let sp = self.tcx.sess.source_map().next_point(cause_span);
4965 err.span_suggestion_with_applicability(
4967 "try adding a semicolon",
4969 Applicability::MachineApplicable);
4976 /// A possible error is to forget to add a return type that is needed:
4980 /// bar_that_returns_u32()
4984 /// This routine checks if the return type is left as default, the method is not part of an
4985 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4987 fn suggest_missing_return_type(&self,
4988 err: &mut DiagnosticBuilder<'tcx>,
4989 fn_decl: &hir::FnDecl,
4992 can_suggest: bool) {
4993 // Only suggest changing the return type for methods that
4994 // haven't set a return type at all (and aren't `fn main()` or an impl).
4995 match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
4996 (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
4997 err.span_suggestion_with_applicability(
4999 "try adding a return type",
5000 format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
5001 Applicability::MachineApplicable);
5003 (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
5004 err.span_label(span, "possibly return type missing here?");
5006 (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
5007 // `fn main()` must return `()`, do not suggest changing return type
5008 err.span_label(span, "expected `()` because of default return type");
5010 // expectation was caused by something else, not the default return
5011 (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => {}
5012 (&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
5013 // Only point to return type if the expected type is the return type, as if they
5014 // are not, the expectation must have been caused by something else.
5015 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
5017 let ty = AstConv::ast_ty_to_ty(self, ty);
5018 debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
5019 debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
5020 if ty.sty == expected.sty {
5021 err.span_label(sp, format!("expected `{}` because of return type",
5029 /// A common error is to add an extra semicolon:
5032 /// fn foo() -> usize {
5037 /// This routine checks if the final statement in a block is an
5038 /// expression with an explicit semicolon whose type is compatible
5039 /// with `expected_ty`. If so, it suggests removing the semicolon.
5040 fn consider_hint_about_removing_semicolon(&self,
5041 blk: &'gcx hir::Block,
5042 expected_ty: Ty<'tcx>,
5043 err: &mut DiagnosticBuilder) {
5044 // Be helpful when the user wrote `{... expr;}` and
5045 // taking the `;` off is enough to fix the error.
5046 let last_stmt = match blk.stmts.last() {
5050 let last_expr = match last_stmt.node {
5051 hir::StmtKind::Semi(ref e, _) => e,
5054 let last_expr_ty = self.node_ty(last_expr.hir_id);
5055 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
5058 let original_span = original_sp(last_stmt.span, blk.span);
5059 let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
5060 err.span_suggestion_with_applicability(
5062 "consider removing this semicolon",
5064 Applicability::MachineApplicable);
5067 // Instantiates the given path, which must refer to an item with the given
5068 // number of type parameters and type.
5069 pub fn instantiate_value_path(&self,
5070 segments: &[hir::PathSegment],
5071 self_ty: Option<Ty<'tcx>>,
5074 node_id: ast::NodeId)
5075 -> (Ty<'tcx>, Def) {
5077 "instantiate_value_path(segments={:?}, self_ty={:?}, def={:?}, node_id={})",
5086 let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
5088 let mut user_self_ty = None;
5089 let mut is_alias_variant_ctor = false;
5091 Def::VariantCtor(_, _) => {
5092 if let Some(self_ty) = self_ty {
5093 let adt_def = self_ty.ty_adt_def().unwrap();
5094 user_self_ty = Some(UserSelfTy {
5095 impl_def_id: adt_def.did,
5098 is_alias_variant_ctor = true;
5101 Def::Method(def_id) |
5102 Def::AssociatedConst(def_id) => {
5103 let container = tcx.associated_item(def_id).container;
5105 ty::TraitContainer(trait_did) => {
5106 callee::check_legal_trait_for_method_call(tcx, span, trait_did)
5108 ty::ImplContainer(impl_def_id) => {
5109 if segments.len() == 1 {
5110 // `<T>::assoc` will end up here, and so
5111 // can `T::assoc`. It this came from an
5112 // inherent impl, we need to record the
5113 // `T` for posterity (see `UserSelfTy` for
5115 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
5116 user_self_ty = Some(UserSelfTy {
5127 // Now that we have categorized what space the parameters for each
5128 // segment belong to, let's sort out the parameters that the user
5129 // provided (if any) into their appropriate spaces. We'll also report
5130 // errors if type parameters are provided in an inappropriate place.
5132 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
5133 let generics_has_err = AstConv::prohibit_generics(
5134 self, segments.iter().enumerate().filter_map(|(index, seg)| {
5135 if !generic_segs.contains(&index) || is_alias_variant_ctor {
5141 if generics_has_err {
5142 // Don't try to infer type parameters when prohibited generic arguments were given.
5143 user_self_ty = None;
5147 Def::Local(nid) | Def::Upvar(nid, ..) => {
5148 let ty = self.local_ty(span, nid).decl_ty;
5149 let ty = self.normalize_associated_types_in(span, &ty);
5150 self.write_ty(tcx.hir().node_to_hir_id(node_id), ty);
5156 // Now we have to compare the types that the user *actually*
5157 // provided against the types that were *expected*. If the user
5158 // did not provide any types, then we want to substitute inference
5159 // variables. If the user provided some types, we may still need
5160 // to add defaults. If the user provided *too many* types, that's
5163 let mut infer_args_for_err = FxHashSet::default();
5164 for &PathSeg(def_id, index) in &path_segs {
5165 let seg = &segments[index];
5166 let generics = tcx.generics_of(def_id);
5167 // Argument-position `impl Trait` is treated as a normal generic
5168 // parameter internally, but we don't allow users to specify the
5169 // parameter's value explicitly, so we have to do some error-
5171 let suppress_errors = AstConv::check_generic_arg_count_for_call(
5176 false, // `is_method_call`
5178 if suppress_errors {
5179 infer_args_for_err.insert(index);
5180 self.set_tainted_by_errors(); // See issue #53251.
5184 let has_self = path_segs.last().map(|PathSeg(def_id, _)| {
5185 tcx.generics_of(*def_id).has_self
5186 }).unwrap_or(false);
5188 let mut new_def = def;
5189 let (def_id, ty) = match def {
5190 Def::SelfCtor(impl_def_id) => {
5191 let ty = self.impl_self_ty(span, impl_def_id).ty;
5192 let adt_def = ty.ty_adt_def();
5195 Some(adt_def) if adt_def.has_ctor() => {
5196 let variant = adt_def.non_enum_variant();
5197 new_def = Def::StructCtor(variant.did, variant.ctor_kind);
5198 (variant.did, tcx.type_of(variant.did))
5201 let mut err = tcx.sess.struct_span_err(span,
5202 "the `Self` constructor can only be used with tuple or unit structs");
5203 if let Some(adt_def) = adt_def {
5204 match adt_def.adt_kind() {
5206 err.help("did you mean to use one of the enum's variants?");
5210 err.span_suggestion_with_applicability(
5212 "use curly brackets",
5213 String::from("Self { /* fields */ }"),
5214 Applicability::HasPlaceholders,
5221 (impl_def_id, tcx.types.err)
5226 let def_id = def.def_id();
5228 // The things we are substituting into the type should not contain
5229 // escaping late-bound regions, and nor should the base type scheme.
5230 let ty = tcx.type_of(def_id);
5235 let substs = AstConv::create_substs_for_generic_args(
5241 // Provide the generic args, and whether types should be inferred.
5243 if let Some(&PathSeg(_, index)) = path_segs.iter().find(|&PathSeg(did, _)| {
5246 // If we've encountered an `impl Trait`-related error, we're just
5247 // going to infer the arguments for better error messages.
5248 if !infer_args_for_err.contains(&index) {
5249 // Check whether the user has provided generic arguments.
5250 if let Some(ref data) = segments[index].args {
5251 return (Some(data), segments[index].infer_types);
5254 return (None, segments[index].infer_types);
5259 // Provide substitutions for parameters for which (valid) arguments have been provided.
5261 match (¶m.kind, arg) {
5262 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
5263 AstConv::ast_region_to_region(self, lt, Some(param)).into()
5265 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
5266 self.to_ty(ty).into()
5268 _ => unreachable!(),
5271 // Provide substitutions for parameters for which arguments are inferred.
5272 |substs, param, infer_types| {
5274 GenericParamDefKind::Lifetime => {
5275 self.re_infer(span, Some(param)).unwrap().into()
5277 GenericParamDefKind::Type { has_default, .. } => {
5278 if !infer_types && has_default {
5279 // If we have a default, then we it doesn't matter that we're not
5280 // inferring the type arguments: we provide the default where any
5282 let default = tcx.type_of(param.def_id);
5285 default.subst_spanned(tcx, substs.unwrap(), Some(span))
5288 // If no type arguments were provided, we have to infer them.
5289 // This case also occurs as a result of some malformed input, e.g.
5290 // a lifetime argument being given instead of a type parameter.
5291 // Using inference instead of `Error` gives better error messages.
5292 self.var_for_def(span, param)
5298 assert!(!substs.has_escaping_bound_vars());
5299 assert!(!ty.has_escaping_bound_vars());
5301 // First, store the "user substs" for later.
5302 let hir_id = tcx.hir().node_to_hir_id(node_id);
5303 self.write_user_substs_from_substs(hir_id, substs, user_self_ty);
5305 // Add all the obligations that are required, substituting and
5306 // normalized appropriately.
5307 let bounds = self.instantiate_bounds(span, def_id, &substs);
5308 self.add_obligations_for_parameters(
5309 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
5312 // Substitute the values for the type parameters into the type of
5313 // the referenced item.
5314 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
5316 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
5317 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5318 // is inherent, there is no `Self` parameter; instead, the impl needs
5319 // type parameters, which we can infer by unifying the provided `Self`
5320 // with the substituted impl type.
5321 // This also occurs for an enum variant on a type alias.
5322 let ty = tcx.type_of(impl_def_id);
5324 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
5325 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
5326 Ok(ok) => self.register_infer_ok_obligations(ok),
5329 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
5336 self.check_rustc_args_require_const(def_id, node_id, span);
5338 debug!("instantiate_value_path: type of {:?} is {:?}",
5341 self.write_substs(hir_id, substs);
5343 (ty_substituted, new_def)
5346 fn check_rustc_args_require_const(&self,
5348 node_id: ast::NodeId,
5350 // We're only interested in functions tagged with
5351 // #[rustc_args_required_const], so ignore anything that's not.
5352 if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
5356 // If our calling expression is indeed the function itself, we're good!
5357 // If not, generate an error that this can only be called directly.
5358 if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(node_id)) {
5359 if let ExprKind::Call(ref callee, ..) = expr.node {
5360 if callee.id == node_id {
5366 self.tcx.sess.span_err(span, "this function can only be invoked \
5367 directly, not through a function pointer");
5370 // Resolves `typ` by a single level if `typ` is a type variable.
5371 // If no resolution is possible, then an error is reported.
5372 // Numeric inference variables may be left unresolved.
5373 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5374 let ty = self.resolve_type_vars_with_obligations(ty);
5375 if !ty.is_ty_var() {
5378 if !self.is_tainted_by_errors() {
5379 self.need_type_info_err((**self).body_id, sp, ty)
5380 .note("type must be known at this point")
5383 self.demand_suptype(sp, self.tcx.types.err, ty);
5388 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
5389 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5390 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5393 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5394 index = enclosing_breakables.stack.len();
5395 enclosing_breakables.by_id.insert(id, index);
5396 enclosing_breakables.stack.push(ctxt);
5400 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5401 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5402 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5403 enclosing_breakables.stack.pop().expect("missing breakable context")
5408 /// Instantiate a QueryResponse in a probe context, without a
5409 /// good ObligationCause.
5410 fn probe_instantiate_query_response(
5413 original_values: &OriginalQueryValues<'tcx>,
5414 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
5415 ) -> InferResult<'tcx, Ty<'tcx>>
5417 self.instantiate_query_response_and_region_obligations(
5418 &traits::ObligationCause::misc(span, self.body_id),
5425 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5426 generics: &ty::Generics,
5428 let own_counts = generics.own_counts();
5429 debug!("check_bounds_are_used(n_tps={}, ty={:?})", own_counts.types, ty);
5431 if own_counts.types == 0 {
5434 // Make a vector of booleans initially false, set to true when used.
5435 let mut types_used = vec![false; own_counts.types];
5437 for leaf_ty in ty.walk() {
5438 if let ty::Param(ty::ParamTy { idx, .. }) = leaf_ty.sty {
5439 debug!("Found use of ty param num {}", idx);
5440 types_used[idx as usize - own_counts.lifetimes] = true;
5441 } else if let ty::Error = leaf_ty.sty {
5442 // If there is already another error, do not emit
5443 // an error for not using a type Parameter.
5444 assert!(tcx.sess.err_count() > 0);
5449 let types = generics.params.iter().filter(|param| match param.kind {
5450 ty::GenericParamDefKind::Type { .. } => true,
5453 for (&used, param) in types_used.iter().zip(types) {
5455 let id = tcx.hir().as_local_node_id(param.def_id).unwrap();
5456 let span = tcx.hir().span(id);
5457 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name)
5458 .span_label(span, "unused type parameter")
5464 fn fatally_break_rust(sess: &Session) {
5465 let handler = sess.diagnostic();
5466 handler.span_bug_no_panic(
5468 "It looks like you're trying to break rust; would you like some ICE?",
5470 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5471 handler.note_without_error(
5472 "we would appreciate a joke overview: \
5473 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5475 handler.note_without_error(&format!("rustc {} running on {}",
5476 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5477 ::session::config::host_triple(),
5481 fn potentially_plural_count(count: usize, word: &str) -> String {
5482 format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })