1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function). Inference is used to supply types wherever they are
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
26 - main: the main pass does the lion's share of the work: it
27 determines the types of all expressions, resolves
28 methods, checks for most invalid conditions, and so forth. In
29 some cases, where a type is unknown, it may create a type or region
30 variable and use that as the type of an expression.
32 In the process of checking, various constraints will be placed on
33 these type variables through the subtyping relationships requested
34 through the `demand` module. The `infer` module is in charge
35 of resolving those constraints.
37 - regionck: after main is complete, the regionck pass goes over all
38 types looking for regions and making sure that they did not escape
39 into places they are not in scope. This may also influence the
40 final assignments of the various region variables if there is some
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
46 - writeback: writes the final types within a function body, replacing
47 type variables with their final inferred types. These final types
48 are written into the `tcx.node_types` table, which should *never* contain
49 any reference to a type variable.
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.node_substs`. These types
56 may contain unresolved type variables. After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `tcx`.
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
68 n.b.: A type variable is not the same thing as a type parameter. A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract. When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`. This variable will
74 eventually be resolved to some concrete type (which might itself be
79 pub use self::Expectation::*;
80 use self::autoderef::Autoderef;
81 use self::callee::DeferredCallResolution;
82 use self::coercion::{CoerceMany, DynamicCoerceMany};
83 pub use self::compare_method::{compare_impl_method, compare_const_impl};
84 use self::method::MethodCallee;
85 use self::TupleArgumentsFlag::*;
88 use hir::def::{Def, CtorKind};
89 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
91 use namespace::Namespace;
92 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
93 use rustc::infer::anon_types::AnonTypeDecl;
94 use rustc::infer::type_variable::{TypeVariableOrigin};
95 use rustc::middle::region;
96 use rustc::mir::interpret::{GlobalId};
97 use rustc::ty::subst::{Kind, Subst, Substs};
98 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
99 use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
100 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
101 use rustc::ty::fold::TypeFoldable;
102 use rustc::ty::maps::Providers;
103 use rustc::ty::util::{Representability, IntTypeExt};
104 use errors::{DiagnosticBuilder, DiagnosticId};
106 use require_c_abi_if_variadic;
107 use session::{CompileIncomplete, config, Session};
110 use util::common::{ErrorReported, indenter};
111 use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, NodeMap};
113 use std::cell::{Cell, RefCell, Ref, RefMut};
114 use rustc_data_structures::sync::Lrc;
115 use std::collections::hash_map::Entry;
117 use std::fmt::Display;
118 use std::mem::replace;
120 use std::ops::{self, Deref};
121 use syntax::abi::Abi;
124 use syntax::codemap::{self, original_sp, Spanned};
125 use syntax::feature_gate::{GateIssue, emit_feature_err};
127 use syntax::symbol::{Symbol, InternedString, keywords};
128 use syntax::util::lev_distance::find_best_match_for_name;
129 use syntax_pos::{self, BytePos, Span, MultiSpan};
131 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
132 use rustc::hir::itemlikevisit::ItemLikeVisitor;
133 use rustc::hir::map::Node;
134 use rustc::hir::{self, PatKind};
135 use rustc::middle::lang_items;
136 use rustc_const_math::ConstInt;
152 mod generator_interior;
156 /// A wrapper for InferCtxt's `in_progress_tables` field.
157 #[derive(Copy, Clone)]
158 struct MaybeInProgressTables<'a, 'tcx: 'a> {
159 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
162 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
163 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
164 match self.maybe_tables {
165 Some(tables) => tables.borrow(),
167 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
172 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
173 match self.maybe_tables {
174 Some(tables) => tables.borrow_mut(),
176 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
183 /// closures defined within the function. For example:
186 /// bar(move|| { ... })
189 /// Here, the function `foo()` and the closure passed to
190 /// `bar()` will each have their own `FnCtxt`, but they will
191 /// share the inherited fields.
192 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
193 infcx: InferCtxt<'a, 'gcx, 'tcx>,
195 tables: MaybeInProgressTables<'a, 'tcx>,
197 locals: RefCell<NodeMap<Ty<'tcx>>>,
199 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
201 // When we process a call like `c()` where `c` is a closure type,
202 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
203 // `FnOnce` closure. In that case, we defer full resolution of the
204 // call until upvar inference can kick in and make the
205 // decision. We keep these deferred resolutions grouped by the
206 // def-id of the closure, so that once we decide, we can easily go
207 // back and process them.
208 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
210 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
212 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, ty::GeneratorInterior<'tcx>)>>,
214 // Anonymized types found in explicit return types and their
215 // associated fresh inference variable. Writeback resolves these
216 // variables to get the concrete type, which can be used to
217 // deanonymize TyAnon, after typeck is done with all functions.
218 anon_types: RefCell<DefIdMap<AnonTypeDecl<'tcx>>>,
220 /// Each type parameter has an implicit region bound that
221 /// indicates it must outlive at least the function body (the user
222 /// may specify stronger requirements). This field indicates the
223 /// region of the callee. If it is `None`, then the parameter
224 /// environment is for an item or something where the "callee" is
226 implicit_region_bound: Option<ty::Region<'tcx>>,
228 body_id: Option<hir::BodyId>,
231 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
232 type Target = InferCtxt<'a, 'gcx, 'tcx>;
233 fn deref(&self) -> &Self::Target {
238 /// When type-checking an expression, we propagate downward
239 /// whatever type hint we are able in the form of an `Expectation`.
240 #[derive(Copy, Clone, Debug)]
241 pub enum Expectation<'tcx> {
242 /// We know nothing about what type this expression should have.
245 /// This expression is an `if` condition, it must resolve to `bool`.
248 /// This expression should have the type given (or some subtype)
249 ExpectHasType(Ty<'tcx>),
251 /// This expression will be cast to the `Ty`
252 ExpectCastableToType(Ty<'tcx>),
254 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
255 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
256 ExpectRvalueLikeUnsized(Ty<'tcx>),
259 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
260 // Disregard "castable to" expectations because they
261 // can lead us astray. Consider for example `if cond
262 // {22} else {c} as u8` -- if we propagate the
263 // "castable to u8" constraint to 22, it will pick the
264 // type 22u8, which is overly constrained (c might not
265 // be a u8). In effect, the problem is that the
266 // "castable to" expectation is not the tightest thing
267 // we can say, so we want to drop it in this case.
268 // The tightest thing we can say is "must unify with
269 // else branch". Note that in the case of a "has type"
270 // constraint, this limitation does not hold.
272 // If the expected type is just a type variable, then don't use
273 // an expected type. Otherwise, we might write parts of the type
274 // when checking the 'then' block which are incompatible with the
276 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
278 ExpectHasType(ety) => {
279 let ety = fcx.shallow_resolve(ety);
280 if !ety.is_ty_var() {
286 ExpectRvalueLikeUnsized(ety) => {
287 ExpectRvalueLikeUnsized(ety)
293 /// Provide an expectation for an rvalue expression given an *optional*
294 /// hint, which is not required for type safety (the resulting type might
295 /// be checked higher up, as is the case with `&expr` and `box expr`), but
296 /// is useful in determining the concrete type.
298 /// The primary use case is where the expected type is a fat pointer,
299 /// like `&[isize]`. For example, consider the following statement:
301 /// let x: &[isize] = &[1, 2, 3];
303 /// In this case, the expected type for the `&[1, 2, 3]` expression is
304 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
305 /// expectation `ExpectHasType([isize])`, that would be too strong --
306 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
307 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
308 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
309 /// which still is useful, because it informs integer literals and the like.
310 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
311 /// for examples of where this comes up,.
312 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
313 match fcx.tcx.struct_tail(ty).sty {
314 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
315 ExpectRvalueLikeUnsized(ty)
317 _ => ExpectHasType(ty)
321 // Resolves `expected` by a single level if it is a variable. If
322 // there is no expected type or resolution is not possible (e.g.,
323 // no constraints yet present), just returns `None`.
324 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
326 NoExpectation => NoExpectation,
327 ExpectIfCondition => ExpectIfCondition,
328 ExpectCastableToType(t) => {
329 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
331 ExpectHasType(t) => {
332 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
334 ExpectRvalueLikeUnsized(t) => {
335 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
340 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
341 match self.resolve(fcx) {
342 NoExpectation => None,
343 ExpectIfCondition => Some(fcx.tcx.types.bool),
344 ExpectCastableToType(ty) |
346 ExpectRvalueLikeUnsized(ty) => Some(ty),
350 /// It sometimes happens that we want to turn an expectation into
351 /// a **hard constraint** (i.e., something that must be satisfied
352 /// for the program to type-check). `only_has_type` will return
353 /// such a constraint, if it exists.
354 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
355 match self.resolve(fcx) {
356 ExpectHasType(ty) => Some(ty),
357 ExpectIfCondition => Some(fcx.tcx.types.bool),
358 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
362 /// Like `only_has_type`, but instead of returning `None` if no
363 /// hard constraint exists, creates a fresh type variable.
364 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
365 self.only_has_type(fcx)
366 .unwrap_or_else(|| fcx.next_ty_var(ty::UniverseIndex::ROOT,
367 TypeVariableOrigin::MiscVariable(span)))
371 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
378 fn maybe_mut_place(m: hir::Mutability) -> Self {
380 hir::MutMutable => Needs::MutPlace,
381 hir::MutImmutable => Needs::None,
386 #[derive(Copy, Clone)]
387 pub struct UnsafetyState {
388 pub def: ast::NodeId,
389 pub unsafety: hir::Unsafety,
390 pub unsafe_push_count: u32,
395 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
396 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
399 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
400 match self.unsafety {
401 // If this unsafe, then if the outer function was already marked as
402 // unsafe we shouldn't attribute the unsafe'ness to the block. This
403 // way the block can be warned about instead of ignoring this
404 // extraneous block (functions are never warned about).
405 hir::Unsafety::Unsafe if self.from_fn => *self,
408 let (unsafety, def, count) = match blk.rules {
409 hir::PushUnsafeBlock(..) =>
410 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
411 hir::PopUnsafeBlock(..) =>
412 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
413 hir::UnsafeBlock(..) =>
414 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
416 (unsafety, self.def, self.unsafe_push_count),
420 unsafe_push_count: count,
427 #[derive(Debug, Copy, Clone)]
433 /// Tracks whether executing a node may exit normally (versus
434 /// return/break/panic, which "diverge", leaving dead code in their
435 /// wake). Tracked semi-automatically (through type variables marked
436 /// as diverging), with some manual adjustments for control-flow
437 /// primitives (approximating a CFG).
438 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
440 /// Potentially unknown, some cases converge,
441 /// others require a CFG to determine them.
444 /// Definitely known to diverge and therefore
445 /// not reach the next sibling or its parent.
448 /// Same as `Always` but with a reachability
449 /// warning already emitted
453 // Convenience impls for combinig `Diverges`.
455 impl ops::BitAnd for Diverges {
457 fn bitand(self, other: Self) -> Self {
458 cmp::min(self, other)
462 impl ops::BitOr for Diverges {
464 fn bitor(self, other: Self) -> Self {
465 cmp::max(self, other)
469 impl ops::BitAndAssign for Diverges {
470 fn bitand_assign(&mut self, other: Self) {
471 *self = *self & other;
475 impl ops::BitOrAssign for Diverges {
476 fn bitor_assign(&mut self, other: Self) {
477 *self = *self | other;
482 fn always(self) -> bool {
483 self >= Diverges::Always
487 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
490 // this is `null` for loops where break with a value is illegal,
491 // such as `while`, `for`, and `while let`
492 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
495 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
496 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
497 by_id: NodeMap<usize>,
500 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
501 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
502 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
503 bug!("could not find enclosing breakable with id {}", target_id);
509 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
510 body_id: ast::NodeId,
512 /// The parameter environment used for proving trait obligations
513 /// in this function. This can change when we descend into
514 /// closures (as they bring new things into scope), hence it is
515 /// not part of `Inherited` (as of the time of this writing,
516 /// closures do not yet change the environment, but they will
518 param_env: ty::ParamEnv<'tcx>,
520 // Number of errors that had been reported when we started
521 // checking this function. On exit, if we find that *more* errors
522 // have been reported, we will skip regionck and other work that
523 // expects the types within the function to be consistent.
524 err_count_on_creation: usize,
526 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
528 yield_ty: Option<Ty<'tcx>>,
530 ps: RefCell<UnsafetyState>,
532 /// Whether the last checked node generates a divergence (e.g.,
533 /// `return` will set this to Always). In general, when entering
534 /// an expression or other node in the tree, the initial value
535 /// indicates whether prior parts of the containing expression may
536 /// have diverged. It is then typically set to `Maybe` (and the
537 /// old value remembered) for processing the subparts of the
538 /// current expression. As each subpart is processed, they may set
539 /// the flag to `Always` etc. Finally, at the end, we take the
540 /// result and "union" it with the original value, so that when we
541 /// return the flag indicates if any subpart of the the parent
542 /// expression (up to and including this part) has diverged. So,
543 /// if you read it after evaluating a subexpression `X`, the value
544 /// you get indicates whether any subexpression that was
545 /// evaluating up to and including `X` diverged.
547 /// We use this flag for two purposes:
549 /// - To warn about unreachable code: if, after processing a
550 /// sub-expression but before we have applied the effects of the
551 /// current node, we see that the flag is set to `Always`, we
552 /// can issue a warning. This corresponds to something like
553 /// `foo(return)`; we warn on the `foo()` expression. (We then
554 /// update the flag to `WarnedAlways` to suppress duplicate
555 /// reports.) Similarly, if we traverse to a fresh statement (or
556 /// tail expression) from a `Always` setting, we will issue a
557 /// warning. This corresponds to something like `{return;
558 /// foo();}` or `{return; 22}`, where we would warn on the
561 /// - To permit assignment into a local variable or other place
562 /// (including the "return slot") of type `!`. This is allowed
563 /// if **either** the type of value being assigned is `!`, which
564 /// means the current code is dead, **or** the expression's
565 /// diverging flag is true, which means that a diverging value was
566 /// wrapped (e.g., `let x: ! = foo(return)`).
568 /// To repeat the last point: an expression represents dead-code
569 /// if, after checking it, **either** its type is `!` OR the
570 /// diverges flag is set to something other than `Maybe`.
571 diverges: Cell<Diverges>,
573 /// Whether any child nodes have any type errors.
574 has_errors: Cell<bool>,
576 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
578 inh: &'a Inherited<'a, 'gcx, 'tcx>,
581 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
582 type Target = Inherited<'a, 'gcx, 'tcx>;
583 fn deref(&self) -> &Self::Target {
588 /// Helper type of a temporary returned by Inherited::build(...).
589 /// Necessary because we can't write the following bound:
590 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
591 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
592 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
596 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
597 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
598 -> InheritedBuilder<'a, 'gcx, 'tcx> {
599 let hir_id_root = if def_id.is_local() {
600 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
601 let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
602 DefId::local(hir_id.owner)
608 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
614 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
615 fn enter<F, R>(&'tcx mut self, f: F) -> R
616 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
618 let def_id = self.def_id;
619 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
623 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
624 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
626 let item_id = tcx.hir.as_local_node_id(def_id);
627 let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
628 let implicit_region_bound = body_id.map(|body_id| {
629 let body = tcx.hir.body(body_id);
630 tcx.mk_region(ty::ReScope(region::Scope::CallSite(body.value.hir_id.local_id)))
634 tables: MaybeInProgressTables {
635 maybe_tables: infcx.in_progress_tables,
638 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
639 locals: RefCell::new(NodeMap()),
640 deferred_call_resolutions: RefCell::new(DefIdMap()),
641 deferred_cast_checks: RefCell::new(Vec::new()),
642 deferred_generator_interiors: RefCell::new(Vec::new()),
643 anon_types: RefCell::new(DefIdMap()),
644 implicit_region_bound,
649 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
650 debug!("register_predicate({:?})", obligation);
651 if obligation.has_escaping_regions() {
652 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
657 .register_predicate_obligation(self, obligation);
660 fn register_predicates<I>(&self, obligations: I)
661 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>> {
662 for obligation in obligations {
663 self.register_predicate(obligation);
667 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
668 self.register_predicates(infer_ok.obligations);
672 fn normalize_associated_types_in<T>(&self,
674 body_id: ast::NodeId,
675 param_env: ty::ParamEnv<'tcx>,
677 where T : TypeFoldable<'tcx>
679 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
680 self.register_infer_ok_obligations(ok)
684 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
686 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
687 fn visit_item(&mut self, i: &'tcx hir::Item) {
688 check_item_type(self.tcx, i);
690 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
691 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
694 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
695 tcx.sess.track_errors(|| {
696 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
697 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
701 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
702 tcx.sess.track_errors(|| {
703 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
707 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
708 tcx.typeck_item_bodies(LOCAL_CRATE)
711 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
712 -> Result<(), CompileIncomplete>
714 debug_assert!(crate_num == LOCAL_CRATE);
715 Ok(tcx.sess.track_errors(|| {
716 for body_owner_def_id in tcx.body_owners() {
717 ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
722 pub fn provide(providers: &mut Providers) {
723 *providers = Providers {
733 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
735 -> Option<ty::Destructor> {
736 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
739 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
740 /// with information about it's body-id and fn-decl (if any). Otherwise,
743 /// If this function returns "some", then `typeck_tables(def_id)` will
744 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
745 /// may not succeed. In some cases where this function returns `None`
746 /// (notably closures), `typeck_tables(def_id)` would wind up
747 /// redirecting to the owning function.
748 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
750 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
752 match tcx.hir.get(id) {
753 hir::map::NodeItem(item) => {
755 hir::ItemConst(_, body) |
756 hir::ItemStatic(_, _, body) =>
758 hir::ItemFn(ref decl, .., body) =>
759 Some((body, Some(decl))),
764 hir::map::NodeTraitItem(item) => {
766 hir::TraitItemKind::Const(_, Some(body)) =>
768 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
769 Some((body, Some(&sig.decl))),
774 hir::map::NodeImplItem(item) => {
776 hir::ImplItemKind::Const(_, body) =>
778 hir::ImplItemKind::Method(ref sig, body) =>
779 Some((body, Some(&sig.decl))),
784 hir::map::NodeExpr(expr) => {
785 // FIXME(eddyb) Closures should have separate
786 // function definition IDs and expression IDs.
787 // Type-checking should not let closures get
788 // this far in a constant position.
789 // Assume that everything other than closures
790 // is a constant "initializer" expression.
792 hir::ExprClosure(..) =>
795 Some((hir::BodyId { node_id: expr.id }, None)),
802 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
805 // Closures' tables come from their outermost function,
806 // as they are part of the same "inference environment".
807 let outer_def_id = tcx.closure_base_def_id(def_id);
808 if outer_def_id != def_id {
809 return tcx.has_typeck_tables(outer_def_id);
812 let id = tcx.hir.as_local_node_id(def_id).unwrap();
813 primary_body_of(tcx, id).is_some()
816 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
819 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
822 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
824 -> &'tcx ty::TypeckTables<'tcx> {
825 // Closures' tables come from their outermost function,
826 // as they are part of the same "inference environment".
827 let outer_def_id = tcx.closure_base_def_id(def_id);
828 if outer_def_id != def_id {
829 return tcx.typeck_tables_of(outer_def_id);
832 let id = tcx.hir.as_local_node_id(def_id).unwrap();
833 let span = tcx.hir.span(id);
835 // Figure out what primary body this item has.
836 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
837 span_bug!(span, "can't type-check body of {:?}", def_id);
839 let body = tcx.hir.body(body_id);
841 let tables = Inherited::build(tcx, def_id).enter(|inh| {
842 let param_env = tcx.param_env(def_id);
843 let fcx = if let Some(decl) = fn_decl {
844 let fn_sig = tcx.fn_sig(def_id);
846 check_abi(tcx, span, fn_sig.abi());
848 // Compute the fty from point of view of inside fn.
850 tcx.liberate_late_bound_regions(def_id, &fn_sig);
852 inh.normalize_associated_types_in(body.value.span,
857 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
860 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
861 let expected_type = tcx.type_of(def_id);
862 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
863 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
865 // Gather locals in statics (because of block expressions).
866 // This is technically unnecessary because locals in static items are forbidden,
867 // but prevents type checking from blowing up before const checking can properly
869 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
871 fcx.check_expr_coercable_to_type(&body.value, expected_type);
876 // All type checking constraints were added, try to fallback unsolved variables.
877 fcx.select_obligations_where_possible();
878 for ty in &fcx.unsolved_variables() {
879 fcx.fallback_if_possible(ty);
881 fcx.select_obligations_where_possible();
883 // Even though coercion casts provide type hints, we check casts after fallback for
884 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
887 // Closure and generater analysis may run after fallback
888 // because they don't constrain other type variables.
889 fcx.closure_analyze(body);
890 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
891 fcx.resolve_generator_interiors(def_id);
892 fcx.select_all_obligations_or_error();
894 if fn_decl.is_some() {
895 fcx.regionck_fn(id, body);
897 fcx.regionck_expr(body);
900 fcx.resolve_type_vars_in_body(body)
903 // Consistency check our TypeckTables instance can hold all ItemLocalIds
904 // it will need to hold.
905 assert_eq!(tables.local_id_root,
906 Some(DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner)));
910 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
911 if !tcx.sess.target.target.is_abi_supported(abi) {
912 struct_span_err!(tcx.sess, span, E0570,
913 "The ABI `{}` is not supported for the current target", abi).emit()
917 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
918 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
921 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
922 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
925 // infer the variable's type
926 let var_ty = self.fcx.next_ty_var(ty::UniverseIndex::ROOT,
927 TypeVariableOrigin::TypeInference(span));
928 self.fcx.locals.borrow_mut().insert(nid, var_ty);
932 // take type that the user specified
933 self.fcx.locals.borrow_mut().insert(nid, typ);
940 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
941 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
942 NestedVisitorMap::None
945 // Add explicitly-declared locals.
946 fn visit_local(&mut self, local: &'gcx hir::Local) {
947 let o_ty = match local.ty {
948 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
951 self.assign(local.span, local.id, o_ty);
952 debug!("Local variable {:?} is assigned type {}",
954 self.fcx.ty_to_string(
955 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
956 intravisit::walk_local(self, local);
959 // Add pattern bindings.
960 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
961 if let PatKind::Binding(_, _, ref path1, _) = p.node {
962 let var_ty = self.assign(p.span, p.id, None);
964 self.fcx.require_type_is_sized(var_ty, p.span,
965 traits::VariableType(p.id));
967 debug!("Pattern binding {} is assigned to {} with type {:?}",
969 self.fcx.ty_to_string(
970 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
973 intravisit::walk_pat(self, p);
976 // Don't descend into the bodies of nested closures
977 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
978 _: hir::BodyId, _: Span, _: ast::NodeId) { }
981 /// When `check_fn` is invoked on a generator (i.e., a body that
982 /// includes yield), it returns back some information about the yield
984 struct GeneratorTypes<'tcx> {
985 /// Type of value that is yielded.
986 yield_ty: ty::Ty<'tcx>,
988 /// Types that are captured (see `GeneratorInterior` for more).
989 interior: ty::GeneratorInterior<'tcx>
992 /// Helper used for fns and closures. Does the grungy work of checking a function
993 /// body and returns the function context used for that purpose, since in the case of a fn item
994 /// there is still a bit more to do.
997 /// * inherited: other fields inherited from the enclosing fn (if any)
998 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
999 param_env: ty::ParamEnv<'tcx>,
1000 fn_sig: ty::FnSig<'tcx>,
1001 decl: &'gcx hir::FnDecl,
1003 body: &'gcx hir::Body,
1004 can_be_generator: Option<hir::GeneratorMovability>)
1005 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<GeneratorTypes<'tcx>>)
1007 let mut fn_sig = fn_sig.clone();
1009 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1011 // Create the function context. This is either derived from scratch or,
1012 // in the case of function expressions, based on the outer context.
1013 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
1014 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1016 let ret_ty = fn_sig.output();
1017 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType);
1018 let ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &ret_ty);
1019 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
1020 fn_sig = fcx.tcx.mk_fn_sig(
1021 fn_sig.inputs().iter().cloned(),
1028 let span = body.value.span;
1030 if body.is_generator && can_be_generator.is_some() {
1031 let yield_ty = fcx.next_ty_var(ty::UniverseIndex::ROOT,
1032 TypeVariableOrigin::TypeInference(span));
1033 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1034 fcx.yield_ty = Some(yield_ty);
1037 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
1039 // Add formal parameters.
1040 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1041 // Check the pattern.
1042 fcx.check_pat_walk(&arg.pat, arg_ty,
1043 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
1045 // Check that argument is Sized.
1046 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1047 // for simple cases like `fn foo(x: Trait)`,
1048 // where we would error once on the parameter as a whole, and once on the binding `x`.
1049 if arg.pat.simple_name().is_none() {
1050 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
1053 fcx.write_ty(arg.hir_id, arg_ty);
1056 let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
1057 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
1059 fcx.check_return_expr(&body.value);
1061 // We insert the deferred_generator_interiors entry after visiting the body.
1062 // This ensures that all nested generators appear before the entry of this generator.
1063 // resolve_generator_interiors relies on this property.
1064 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1065 let witness = fcx.next_ty_var(ty::UniverseIndex::ROOT,
1066 TypeVariableOrigin::MiscVariable(span));
1067 let interior = ty::GeneratorInterior {
1069 movable: can_be_generator.unwrap() == hir::GeneratorMovability::Movable,
1071 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1072 Some(GeneratorTypes { yield_ty: fcx.yield_ty.unwrap(), interior: interior })
1077 // Finalize the return check by taking the LUB of the return types
1078 // we saw and assigning it to the expected return type. This isn't
1079 // really expected to fail, since the coercions would have failed
1080 // earlier when trying to find a LUB.
1082 // However, the behavior around `!` is sort of complex. In the
1083 // event that the `actual_return_ty` comes back as `!`, that
1084 // indicates that the fn either does not return or "returns" only
1085 // values of type `!`. In this case, if there is an expected
1086 // return type that is *not* `!`, that should be ok. But if the
1087 // return type is being inferred, we want to "fallback" to `!`:
1089 // let x = move || panic!();
1091 // To allow for that, I am creating a type variable with diverging
1092 // fallback. This was deemed ever so slightly better than unifying
1093 // the return value with `!` because it allows for the caller to
1094 // make more assumptions about the return type (e.g., they could do
1096 // let y: Option<u32> = Some(x());
1098 // which would then cause this return type to become `u32`, not
1100 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1101 let mut actual_return_ty = coercion.complete(&fcx);
1102 if actual_return_ty.is_never() {
1103 actual_return_ty = fcx.next_diverging_ty_var(
1104 ty::UniverseIndex::ROOT,
1105 TypeVariableOrigin::DivergingFn(span));
1107 fcx.demand_suptype(span, ret_ty, actual_return_ty);
1109 if fcx.tcx.features().termination_trait {
1110 // If the termination trait language item is activated, check that the main return type
1111 // implements the termination trait.
1112 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1113 if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
1115 match fcx.sess().entry_type.get() {
1116 Some(config::EntryMain) => {
1117 let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
1118 let trait_ref = ty::TraitRef::new(term_id, substs);
1119 let cause = traits::ObligationCause::new(
1120 span, fn_id, ObligationCauseCode::MainFunctionType);
1122 inherited.register_predicate(
1123 traits::Obligation::new(
1124 cause, param_env, trait_ref.to_predicate()));
1136 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1139 let def_id = tcx.hir.local_def_id(id);
1140 let def = tcx.adt_def(def_id);
1141 def.destructor(tcx); // force the destructor to be evaluated
1142 check_representable(tcx, span, def_id);
1144 if def.repr.simd() {
1145 check_simd(tcx, span, def_id);
1148 check_transparent(tcx, span, def_id);
1149 check_packed(tcx, span, def_id);
1152 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1155 let def_id = tcx.hir.local_def_id(id);
1156 let def = tcx.adt_def(def_id);
1157 def.destructor(tcx); // force the destructor to be evaluated
1158 check_representable(tcx, span, def_id);
1160 check_packed(tcx, span, def_id);
1163 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1164 debug!("check_item_type(it.id={}, it.name={})",
1166 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
1167 let _indenter = indenter();
1169 // Consts can play a role in type-checking, so they are included here.
1170 hir::ItemStatic(..) |
1171 hir::ItemConst(..) => {
1172 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1174 hir::ItemEnum(ref enum_definition, _) => {
1177 &enum_definition.variants,
1180 hir::ItemFn(..) => {} // entirely within check_item_body
1181 hir::ItemImpl(.., ref impl_item_refs) => {
1182 debug!("ItemImpl {} with id {}", it.name, it.id);
1183 let impl_def_id = tcx.hir.local_def_id(it.id);
1184 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1185 check_impl_items_against_trait(tcx,
1190 let trait_def_id = impl_trait_ref.def_id;
1191 check_on_unimplemented(tcx, trait_def_id, it);
1194 hir::ItemTrait(..) => {
1195 let def_id = tcx.hir.local_def_id(it.id);
1196 check_on_unimplemented(tcx, def_id, it);
1198 hir::ItemStruct(..) => {
1199 check_struct(tcx, it.id, it.span);
1201 hir::ItemUnion(..) => {
1202 check_union(tcx, it.id, it.span);
1204 hir::ItemTy(_, ref generics) => {
1205 let def_id = tcx.hir.local_def_id(it.id);
1206 let pty_ty = tcx.type_of(def_id);
1207 check_bounds_are_used(tcx, generics, pty_ty);
1209 hir::ItemForeignMod(ref m) => {
1210 check_abi(tcx, it.span, m.abi);
1212 if m.abi == Abi::RustIntrinsic {
1213 for item in &m.items {
1214 intrinsic::check_intrinsic_type(tcx, item);
1216 } else if m.abi == Abi::PlatformIntrinsic {
1217 for item in &m.items {
1218 intrinsic::check_platform_intrinsic_type(tcx, item);
1221 for item in &m.items {
1222 let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
1223 if !generics.types.is_empty() {
1224 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1225 "foreign items may not have type parameters");
1226 span_help!(&mut err, item.span,
1227 "consider using specialization instead of \
1232 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1233 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1238 _ => {/* nothing to do */ }
1242 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1243 trait_def_id: DefId,
1245 let item_def_id = tcx.hir.local_def_id(item.id);
1246 // an error would be reported if this fails.
1247 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1250 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1251 impl_item: &hir::ImplItem,
1254 let mut err = struct_span_err!(
1255 tcx.sess, impl_item.span, E0520,
1256 "`{}` specializes an item from a parent `impl`, but \
1257 that item is not marked `default`",
1259 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1262 match tcx.span_of_impl(parent_impl) {
1264 err.span_label(span, "parent `impl` is here");
1265 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1269 err.note(&format!("parent implementation is in crate `{}`", cname));
1276 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1277 trait_def: &ty::TraitDef,
1278 trait_item: &ty::AssociatedItem,
1280 impl_item: &hir::ImplItem)
1282 let ancestors = trait_def.ancestors(tcx, impl_id);
1284 let kind = match impl_item.node {
1285 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1286 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1287 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1290 let parent = ancestors.defs(tcx, trait_item.name, kind, trait_def.def_id).skip(1).next()
1291 .map(|node_item| node_item.map(|parent| parent.defaultness));
1293 if let Some(parent) = parent {
1294 if tcx.impl_item_is_final(&parent) {
1295 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1301 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1304 impl_trait_ref: ty::TraitRef<'tcx>,
1305 impl_item_refs: &[hir::ImplItemRef]) {
1306 let impl_span = tcx.sess.codemap().def_span(impl_span);
1308 // If the trait reference itself is erroneous (so the compilation is going
1309 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1310 // isn't populated for such impls.
1311 if impl_trait_ref.references_error() { return; }
1313 // Locate trait definition and items
1314 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1315 let mut overridden_associated_type = None;
1317 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1319 // Check existing impl methods to see if they are both present in trait
1320 // and compatible with trait signature
1321 for impl_item in impl_items() {
1322 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1323 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1324 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1325 tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1327 // Not compatible, but needed for the error message
1328 tcx.associated_items(impl_trait_ref.def_id)
1329 .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1332 // Check that impl definition matches trait definition
1333 if let Some(ty_trait_item) = ty_trait_item {
1334 match impl_item.node {
1335 hir::ImplItemKind::Const(..) => {
1336 // Find associated const definition.
1337 if ty_trait_item.kind == ty::AssociatedKind::Const {
1338 compare_const_impl(tcx,
1344 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1345 "item `{}` is an associated const, \
1346 which doesn't match its trait `{}`",
1349 err.span_label(impl_item.span, "does not match trait");
1350 // We can only get the spans from local trait definition
1351 // Same for E0324 and E0325
1352 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1353 err.span_label(trait_span, "item in trait");
1358 hir::ImplItemKind::Method(..) => {
1359 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1360 if ty_trait_item.kind == ty::AssociatedKind::Method {
1361 compare_impl_method(tcx,
1368 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1369 "item `{}` is an associated method, \
1370 which doesn't match its trait `{}`",
1373 err.span_label(impl_item.span, "does not match trait");
1374 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1375 err.span_label(trait_span, "item in trait");
1380 hir::ImplItemKind::Type(_) => {
1381 if ty_trait_item.kind == ty::AssociatedKind::Type {
1382 if ty_trait_item.defaultness.has_value() {
1383 overridden_associated_type = Some(impl_item);
1386 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1387 "item `{}` is an associated type, \
1388 which doesn't match its trait `{}`",
1391 err.span_label(impl_item.span, "does not match trait");
1392 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1393 err.span_label(trait_span, "item in trait");
1400 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1404 // Check for missing items from trait
1405 let mut missing_items = Vec::new();
1406 let mut invalidated_items = Vec::new();
1407 let associated_type_overridden = overridden_associated_type.is_some();
1408 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1409 let is_implemented = trait_def.ancestors(tcx, impl_id)
1410 .defs(tcx, trait_item.name, trait_item.kind, impl_trait_ref.def_id)
1412 .map(|node_item| !node_item.node.is_from_trait())
1415 if !is_implemented && !tcx.impl_is_default(impl_id) {
1416 if !trait_item.defaultness.has_value() {
1417 missing_items.push(trait_item);
1418 } else if associated_type_overridden {
1419 invalidated_items.push(trait_item.name);
1424 if !missing_items.is_empty() {
1425 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1426 "not all trait items implemented, missing: `{}`",
1427 missing_items.iter()
1428 .map(|trait_item| trait_item.name.to_string())
1429 .collect::<Vec<_>>().join("`, `"));
1430 err.span_label(impl_span, format!("missing `{}` in implementation",
1431 missing_items.iter()
1432 .map(|trait_item| trait_item.name.to_string())
1433 .collect::<Vec<_>>().join("`, `")));
1434 for trait_item in missing_items {
1435 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1436 err.span_label(span, format!("`{}` from trait", trait_item.name));
1438 err.note_trait_signature(trait_item.name.to_string(),
1439 trait_item.signature(&tcx));
1445 if !invalidated_items.is_empty() {
1446 let invalidator = overridden_associated_type.unwrap();
1447 span_err!(tcx.sess, invalidator.span, E0399,
1448 "the following trait items need to be reimplemented \
1449 as `{}` was overridden: `{}`",
1451 invalidated_items.iter()
1452 .map(|name| name.to_string())
1453 .collect::<Vec<_>>().join("`, `"))
1457 /// Checks whether a type can be represented in memory. In particular, it
1458 /// identifies types that contain themselves without indirection through a
1459 /// pointer, which would mean their size is unbounded.
1460 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1464 let rty = tcx.type_of(item_def_id);
1466 // Check that it is possible to represent this type. This call identifies
1467 // (1) types that contain themselves and (2) types that contain a different
1468 // recursive type. It is only necessary to throw an error on those that
1469 // contain themselves. For case 2, there must be an inner type that will be
1470 // caught by case 1.
1471 match rty.is_representable(tcx, sp) {
1472 Representability::SelfRecursive(spans) => {
1473 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1475 err.span_label(span, "recursive without indirection");
1480 Representability::Representable | Representability::ContainsRecursive => (),
1485 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1486 let t = tcx.type_of(def_id);
1488 ty::TyAdt(def, substs) if def.is_struct() => {
1489 let fields = &def.non_enum_variant().fields;
1490 if fields.is_empty() {
1491 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1494 let e = fields[0].ty(tcx, substs);
1495 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1496 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1497 .span_label(sp, "SIMD elements must have the same type")
1502 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1503 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1505 span_err!(tcx.sess, sp, E0077,
1506 "SIMD vector element type should be machine type");
1515 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1516 if tcx.adt_def(def_id).repr.packed() {
1517 if tcx.adt_def(def_id).repr.align > 0 {
1518 struct_span_err!(tcx.sess, sp, E0587,
1519 "type has conflicting packed and align representation hints").emit();
1521 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1522 struct_span_err!(tcx.sess, sp, E0588,
1523 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1528 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1530 stack: &mut Vec<DefId>) -> bool {
1531 let t = tcx.type_of(def_id);
1532 if stack.contains(&def_id) {
1533 debug!("check_packed_inner: {:?} is recursive", t);
1537 ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
1538 if tcx.adt_def(def.did).repr.align > 0 {
1541 // push struct def_id before checking fields
1543 for field in &def.non_enum_variant().fields {
1544 let f = field.ty(tcx, substs);
1546 ty::TyAdt(def, _) => {
1547 if check_packed_inner(tcx, def.did, stack) {
1554 // only need to pop if not early out
1562 fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1563 let adt = tcx.adt_def(def_id);
1564 if !adt.repr.transparent() {
1568 // For each field, figure out if it's known to be a ZST and align(1)
1569 let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| {
1570 let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
1571 let param_env = tcx.param_env(field.did);
1572 let layout = tcx.layout_of(param_env.and(ty));
1573 // We are currently checking the type this field came from, so it must be local
1574 let span = tcx.hir.span_if_local(field.did).unwrap();
1575 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1576 let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false);
1580 let non_zst_fields = field_infos.iter().filter(|(_span, zst, _align1)| !*zst);
1581 let non_zst_count = non_zst_fields.clone().count();
1582 if non_zst_count != 1 {
1583 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| *span).collect();
1584 struct_span_err!(tcx.sess, sp, E0690,
1585 "transparent struct needs exactly one non-zero-sized field, but has {}",
1587 .span_note(field_spans, "non-zero-sized field")
1590 for &(span, zst, align1) in &field_infos {
1592 span_err!(tcx.sess, span, E0691,
1593 "zero-sized field in transparent struct has alignment larger than 1");
1598 #[allow(trivial_numeric_casts)]
1599 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1601 vs: &'tcx [hir::Variant],
1603 let def_id = tcx.hir.local_def_id(id);
1604 let def = tcx.adt_def(def_id);
1605 def.destructor(tcx); // force the destructor to be evaluated
1608 let attributes = tcx.get_attrs(def_id);
1609 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1611 tcx.sess, attr.span, E0084,
1612 "unsupported representation for zero-variant enum")
1613 .span_label(sp, "zero-variant enum")
1618 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1619 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1620 if !tcx.features().repr128 {
1621 emit_feature_err(&tcx.sess.parse_sess,
1624 GateIssue::Language,
1625 "repr with 128-bit type is unstable");
1630 if let Some(e) = v.node.disr_expr {
1631 tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
1635 let mut disr_vals: Vec<ConstInt> = Vec::new();
1636 for (discr, v) in def.discriminants(tcx).zip(vs) {
1637 // Check for duplicate discriminant values
1638 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1639 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1640 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1641 let i_span = match variant_i.node.disr_expr {
1642 Some(expr) => tcx.hir.span(expr.node_id),
1643 None => tcx.hir.span(variant_i_node_id)
1645 let span = match v.node.disr_expr {
1646 Some(expr) => tcx.hir.span(expr.node_id),
1649 struct_span_err!(tcx.sess, span, E0081,
1650 "discriminant value `{}` already exists", disr_vals[i])
1651 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1652 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1655 disr_vals.push(discr);
1658 check_representable(tcx, sp, def_id);
1661 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1662 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1664 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1665 -> ty::GenericPredicates<'tcx>
1668 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1669 let item_id = tcx.hir.ty_param_owner(node_id);
1670 let item_def_id = tcx.hir.local_def_id(item_id);
1671 let generics = tcx.generics_of(item_def_id);
1672 let index = generics.type_param_to_index[&def_id];
1673 ty::GenericPredicates {
1675 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1677 ty::Predicate::Trait(ref data) => {
1678 data.0.self_ty().is_param(index)
1682 }).cloned().collect()
1686 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1687 -> Option<ty::Region<'tcx>> {
1689 Some(def) => infer::EarlyBoundRegion(span, def.name),
1690 None => infer::MiscVariable(span)
1692 Some(self.next_region_var(v))
1695 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1696 self.next_ty_var(ty::UniverseIndex::ROOT,
1697 TypeVariableOrigin::TypeInference(span))
1700 fn ty_infer_for_def(&self,
1701 ty_param_def: &ty::TypeParameterDef,
1702 span: Span) -> Ty<'tcx> {
1703 self.type_var_for_def(ty::UniverseIndex::ROOT, span, ty_param_def)
1706 fn projected_ty_from_poly_trait_ref(&self,
1709 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1712 let (trait_ref, _) =
1713 self.replace_late_bound_regions_with_fresh_var(
1715 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1718 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1721 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1722 if ty.has_escaping_regions() {
1723 ty // FIXME: normalization and escaping regions
1725 self.normalize_associated_types_in(span, &ty)
1729 fn set_tainted_by_errors(&self) {
1730 self.infcx.set_tainted_by_errors()
1733 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1734 self.write_ty(hir_id, ty)
1738 /// Controls whether the arguments are tupled. This is used for the call
1741 /// Tupling means that all call-side arguments are packed into a tuple and
1742 /// passed as a single parameter. For example, if tupling is enabled, this
1745 /// fn f(x: (isize, isize))
1747 /// Can be called as:
1754 #[derive(Clone, Eq, PartialEq)]
1755 enum TupleArgumentsFlag {
1760 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1761 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1762 param_env: ty::ParamEnv<'tcx>,
1763 body_id: ast::NodeId)
1764 -> FnCtxt<'a, 'gcx, 'tcx> {
1768 err_count_on_creation: inh.tcx.sess.err_count(),
1771 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1772 ast::CRATE_NODE_ID)),
1773 diverges: Cell::new(Diverges::Maybe),
1774 has_errors: Cell::new(false),
1775 enclosing_breakables: RefCell::new(EnclosingBreakables {
1783 pub fn sess(&self) -> &Session {
1787 pub fn err_count_since_creation(&self) -> usize {
1788 self.tcx.sess.err_count() - self.err_count_on_creation
1791 /// Produce warning on the given node, if the current point in the
1792 /// function is unreachable, and there hasn't been another warning.
1793 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1794 if self.diverges.get() == Diverges::Always {
1795 self.diverges.set(Diverges::WarnedAlways);
1797 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1799 self.tcx().lint_node(
1800 lint::builtin::UNREACHABLE_CODE,
1802 &format!("unreachable {}", kind));
1808 code: ObligationCauseCode<'tcx>)
1809 -> ObligationCause<'tcx> {
1810 ObligationCause::new(span, self.body_id, code)
1813 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1814 self.cause(span, ObligationCauseCode::MiscObligation)
1817 /// Resolves type variables in `ty` if possible. Unlike the infcx
1818 /// version (resolve_type_vars_if_possible), this version will
1819 /// also select obligations if it seems useful, in an effort
1820 /// to get more type information.
1821 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1822 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1824 // No TyInfer()? Nothing needs doing.
1825 if !ty.has_infer_types() {
1826 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1830 // If `ty` is a type variable, see whether we already know what it is.
1831 ty = self.resolve_type_vars_if_possible(&ty);
1832 if !ty.has_infer_types() {
1833 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1837 // If not, try resolving pending obligations as much as
1838 // possible. This can help substantially when there are
1839 // indirect dependencies that don't seem worth tracking
1841 self.select_obligations_where_possible();
1842 ty = self.resolve_type_vars_if_possible(&ty);
1844 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1848 fn record_deferred_call_resolution(&self,
1849 closure_def_id: DefId,
1850 r: DeferredCallResolution<'gcx, 'tcx>) {
1851 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1852 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1855 fn remove_deferred_call_resolutions(&self,
1856 closure_def_id: DefId)
1857 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1859 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1860 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1863 pub fn tag(&self) -> String {
1864 let self_ptr: *const FnCtxt = self;
1865 format!("{:?}", self_ptr)
1868 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1869 match self.locals.borrow().get(&nid) {
1872 span_bug!(span, "no type for local variable {}",
1873 self.tcx.hir.node_to_string(nid));
1879 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
1880 debug!("write_ty({:?}, {:?}) in fcx {}",
1881 id, self.resolve_type_vars_if_possible(&ty), self.tag());
1882 self.tables.borrow_mut().node_types_mut().insert(id, ty);
1884 if ty.references_error() {
1885 self.has_errors.set(true);
1886 self.set_tainted_by_errors();
1890 // The NodeId and the ItemLocalId must identify the same item. We just pass
1891 // both of them for consistency checking.
1892 pub fn write_method_call(&self,
1894 method: MethodCallee<'tcx>) {
1897 .type_dependent_defs_mut()
1898 .insert(hir_id, Def::Method(method.def_id));
1899 self.write_substs(hir_id, method.substs);
1902 pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
1903 if !substs.is_noop() {
1904 debug!("write_substs({:?}, {:?}) in fcx {}",
1909 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
1913 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1914 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1920 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
1921 Entry::Vacant(entry) => { entry.insert(adj); },
1922 Entry::Occupied(mut entry) => {
1923 debug!(" - composing on top of {:?}", entry.get());
1924 match (&entry.get()[..], &adj[..]) {
1925 // Applying any adjustment on top of a NeverToAny
1926 // is a valid NeverToAny adjustment, because it can't
1928 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1930 Adjustment { kind: Adjust::Deref(_), .. },
1931 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1933 Adjustment { kind: Adjust::Deref(_), .. },
1934 .. // Any following adjustments are allowed.
1936 // A reborrow has no effect before a dereference.
1938 // FIXME: currently we never try to compose autoderefs
1939 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1941 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1942 expr, entry.get(), adj)
1944 *entry.get_mut() = adj;
1949 /// Basically whenever we are converting from a type scheme into
1950 /// the fn body space, we always want to normalize associated
1951 /// types as well. This function combines the two.
1952 fn instantiate_type_scheme<T>(&self,
1954 substs: &Substs<'tcx>,
1957 where T : TypeFoldable<'tcx>
1959 let value = value.subst(self.tcx, substs);
1960 let result = self.normalize_associated_types_in(span, &value);
1961 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1968 /// As `instantiate_type_scheme`, but for the bounds found in a
1969 /// generic type scheme.
1970 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1971 -> ty::InstantiatedPredicates<'tcx> {
1972 let bounds = self.tcx.predicates_of(def_id);
1973 let result = bounds.instantiate(self.tcx, substs);
1974 let result = self.normalize_associated_types_in(span, &result);
1975 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1982 /// Replace the anonymized types from the return value of the
1983 /// function with type variables and records the `AnonTypeMap` for
1984 /// later use during writeback. See
1985 /// `InferCtxt::instantiate_anon_types` for more details.
1986 fn instantiate_anon_types_from_return_value<T: TypeFoldable<'tcx>>(
1991 let fn_def_id = self.tcx.hir.local_def_id(fn_id);
1993 "instantiate_anon_types_from_return_value(fn_def_id={:?}, value={:?})",
1998 let (value, anon_type_map) = self.register_infer_ok_obligations(
1999 self.instantiate_anon_types(
2007 let mut anon_types = self.anon_types.borrow_mut();
2008 for (ty, decl) in anon_type_map {
2009 let old_value = anon_types.insert(ty, decl);
2010 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2016 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2017 where T : TypeFoldable<'tcx>
2019 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2022 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2024 where T : TypeFoldable<'tcx>
2026 self.inh.partially_normalize_associated_types_in(span,
2032 pub fn require_type_meets(&self,
2035 code: traits::ObligationCauseCode<'tcx>,
2038 self.register_bound(
2041 traits::ObligationCause::new(span, self.body_id, code));
2044 pub fn require_type_is_sized(&self,
2047 code: traits::ObligationCauseCode<'tcx>)
2049 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2050 self.require_type_meets(ty, span, code, lang_item);
2053 pub fn register_bound(&self,
2056 cause: traits::ObligationCause<'tcx>)
2058 self.fulfillment_cx.borrow_mut()
2059 .register_bound(self, self.param_env, ty, def_id, cause);
2062 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2063 let t = AstConv::ast_ty_to_ty(self, ast_t);
2064 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2068 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2069 match self.tables.borrow().node_types().get(id) {
2071 None if self.is_tainted_by_errors() => self.tcx.types.err,
2073 let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id);
2074 bug!("no type for node {}: {} in fcx {}",
2075 node_id, self.tcx.hir.node_to_string(node_id),
2081 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2082 /// outlive the region `r`.
2083 pub fn register_wf_obligation(&self,
2086 code: traits::ObligationCauseCode<'tcx>)
2088 // WF obligations never themselves fail, so no real need to give a detailed cause:
2089 let cause = traits::ObligationCause::new(span, self.body_id, code);
2090 self.register_predicate(traits::Obligation::new(cause,
2092 ty::Predicate::WellFormed(ty)));
2095 /// Registers obligations that all types appearing in `substs` are well-formed.
2096 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
2098 for ty in substs.types() {
2099 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2103 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2104 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2105 /// trait/region obligations.
2107 /// For example, if there is a function:
2110 /// fn foo<'a,T:'a>(...)
2113 /// and a reference:
2119 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2120 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2121 pub fn add_obligations_for_parameters(&self,
2122 cause: traits::ObligationCause<'tcx>,
2123 predicates: &ty::InstantiatedPredicates<'tcx>)
2125 assert!(!predicates.has_escaping_regions());
2127 debug!("add_obligations_for_parameters(predicates={:?})",
2130 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2131 self.register_predicate(obligation);
2135 // FIXME(arielb1): use this instead of field.ty everywhere
2136 // Only for fields! Returns <none> for methods>
2137 // Indifferent to privacy flags
2138 pub fn field_ty(&self,
2140 field: &'tcx ty::FieldDef,
2141 substs: &Substs<'tcx>)
2144 self.normalize_associated_types_in(span,
2145 &field.ty(self.tcx, substs))
2148 fn check_casts(&self) {
2149 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2150 for cast in deferred_cast_checks.drain(..) {
2155 fn resolve_generator_interiors(&self, def_id: DefId) {
2156 let mut generators = self.deferred_generator_interiors.borrow_mut();
2157 for (body_id, interior) in generators.drain(..) {
2158 self.select_obligations_where_possible();
2159 generator_interior::resolve_interior(self, def_id, body_id, interior);
2163 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2164 // Non-numerics get replaced with ! or () (depending on whether
2165 // feature(never_type) is enabled), unconstrained ints with i32,
2166 // unconstrained floats with f64.
2167 // Fallback becomes very dubious if we have encountered type-checking errors.
2168 // In that case, fallback to TyError.
2169 fn fallback_if_possible(&self, ty: Ty<'tcx>) {
2170 use rustc::ty::error::UnconstrainedNumeric::Neither;
2171 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2173 assert!(ty.is_ty_infer());
2174 let fallback = match self.type_is_unconstrained_numeric(ty) {
2175 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2176 UnconstrainedInt => self.tcx.types.i32,
2177 UnconstrainedFloat => self.tcx.types.f64,
2178 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2181 debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
2182 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2185 fn select_all_obligations_or_error(&self) {
2186 debug!("select_all_obligations_or_error");
2187 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2188 self.report_fulfillment_errors(&errors, self.inh.body_id);
2192 /// Select as many obligations as we can at present.
2193 fn select_obligations_where_possible(&self) {
2194 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2196 Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2200 fn is_place_expr(&self, expr: &hir::Expr) -> bool {
2202 hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
2204 Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
2209 hir::ExprType(ref e, _) => {
2210 self.is_place_expr(e)
2213 hir::ExprUnary(hir::UnDeref, _) |
2214 hir::ExprField(..) |
2215 hir::ExprTupField(..) |
2216 hir::ExprIndex(..) => {
2220 // Partially qualified paths in expressions can only legally
2221 // refer to associated items which are always rvalues.
2222 hir::ExprPath(hir::QPath::TypeRelative(..)) |
2225 hir::ExprMethodCall(..) |
2226 hir::ExprStruct(..) |
2229 hir::ExprMatch(..) |
2230 hir::ExprClosure(..) |
2231 hir::ExprBlock(..) |
2232 hir::ExprRepeat(..) |
2233 hir::ExprArray(..) |
2234 hir::ExprBreak(..) |
2235 hir::ExprAgain(..) |
2237 hir::ExprWhile(..) |
2239 hir::ExprAssign(..) |
2240 hir::ExprInlineAsm(..) |
2241 hir::ExprAssignOp(..) |
2243 hir::ExprUnary(..) |
2245 hir::ExprAddrOf(..) |
2246 hir::ExprBinary(..) |
2247 hir::ExprYield(..) |
2248 hir::ExprCast(..) => {
2254 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2255 /// returns a type of `&T`, but the actual type we assign to the
2256 /// *expression* is `T`. So this function just peels off the return
2257 /// type by one layer to yield `T`.
2258 fn make_overloaded_place_return_type(&self,
2259 method: MethodCallee<'tcx>)
2260 -> ty::TypeAndMut<'tcx>
2262 // extract method return type, which will be &T;
2263 let ret_ty = method.sig.output();
2265 // method returns &T, but the type as visible to user is T, so deref
2266 ret_ty.builtin_deref(true).unwrap()
2269 fn lookup_indexing(&self,
2271 base_expr: &'gcx hir::Expr,
2275 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2277 // FIXME(#18741) -- this is almost but not quite the same as the
2278 // autoderef that normal method probing does. They could likely be
2281 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2282 let mut result = None;
2283 while result.is_none() && autoderef.next().is_some() {
2284 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2286 autoderef.finalize();
2290 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2291 /// (and otherwise adjust) `base_expr`, looking for a type which either
2292 /// supports builtin indexing or overloaded indexing.
2293 /// This loop implements one step in that search; the autoderef loop
2294 /// is implemented by `lookup_indexing`.
2295 fn try_index_step(&self,
2297 base_expr: &hir::Expr,
2298 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2301 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2303 let adjusted_ty = autoderef.unambiguous_final_ty();
2304 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2311 for &unsize in &[false, true] {
2312 let mut self_ty = adjusted_ty;
2314 // We only unsize arrays here.
2315 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2316 self_ty = self.tcx.mk_slice(element_ty);
2322 // If some lookup succeeds, write callee into table and extract index/element
2323 // type from the method signature.
2324 // If some lookup succeeded, install method in table
2325 let input_ty = self.next_ty_var(ty::UniverseIndex::ROOT,
2326 TypeVariableOrigin::AutoDeref(base_expr.span));
2327 let method = self.try_overloaded_place_op(
2328 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2330 let result = method.map(|ok| {
2331 debug!("try_index_step: success, using overloaded indexing");
2332 let method = self.register_infer_ok_obligations(ok);
2334 let mut adjustments = autoderef.adjust_steps(needs);
2335 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
2336 let mutbl = match mt.mutbl {
2337 hir::MutImmutable => AutoBorrowMutability::Immutable,
2338 hir::MutMutable => AutoBorrowMutability::Mutable {
2339 // FIXME (#46747): arguably indexing is
2340 // "just another kind of call"; perhaps it
2341 // would be more consistent to allow
2342 // two-phase borrows for .index()
2344 allow_two_phase_borrow: false,
2347 adjustments.push(Adjustment {
2348 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2349 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2356 adjustments.push(Adjustment {
2357 kind: Adjust::Unsize,
2358 target: method.sig.inputs()[0]
2361 self.apply_adjustments(base_expr, adjustments);
2363 self.write_method_call(expr.hir_id, method);
2364 (input_ty, self.make_overloaded_place_return_type(method).ty)
2366 if result.is_some() {
2374 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2375 let (tr, name) = match (op, is_mut) {
2376 (PlaceOp::Deref, false) =>
2377 (self.tcx.lang_items().deref_trait(), "deref"),
2378 (PlaceOp::Deref, true) =>
2379 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2380 (PlaceOp::Index, false) =>
2381 (self.tcx.lang_items().index_trait(), "index"),
2382 (PlaceOp::Index, true) =>
2383 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2385 (tr, Symbol::intern(name))
2388 fn try_overloaded_place_op(&self,
2391 arg_tys: &[Ty<'tcx>],
2394 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2396 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2402 // Try Mut first, if needed.
2403 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2404 let method = match (needs, mut_tr) {
2405 (Needs::MutPlace, Some(trait_did)) => {
2406 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2411 // Otherwise, fall back to the immutable version.
2412 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2413 let method = match (method, imm_tr) {
2414 (None, Some(trait_did)) => {
2415 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2417 (method, _) => method,
2423 fn check_method_argument_types(&self,
2426 method: Result<MethodCallee<'tcx>, ()>,
2427 args_no_rcvr: &'gcx [hir::Expr],
2428 tuple_arguments: TupleArgumentsFlag,
2429 expected: Expectation<'tcx>)
2431 let has_error = match method {
2433 method.substs.references_error() || method.sig.references_error()
2438 let err_inputs = self.err_args(args_no_rcvr.len());
2440 let err_inputs = match tuple_arguments {
2441 DontTupleArguments => err_inputs,
2442 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2445 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2446 false, tuple_arguments, None);
2447 return self.tcx.types.err;
2450 let method = method.unwrap();
2451 // HACK(eddyb) ignore self in the definition (see above).
2452 let expected_arg_tys = self.expected_inputs_for_expected_output(
2455 method.sig.output(),
2456 &method.sig.inputs()[1..]
2458 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2459 args_no_rcvr, method.sig.variadic, tuple_arguments,
2460 self.tcx.hir.span_if_local(method.def_id));
2464 /// Generic function that factors out common logic from function calls,
2465 /// method calls and overloaded operators.
2466 fn check_argument_types(&self,
2469 fn_inputs: &[Ty<'tcx>],
2470 expected_arg_tys: &[Ty<'tcx>],
2471 args: &'gcx [hir::Expr],
2473 tuple_arguments: TupleArgumentsFlag,
2474 def_span: Option<Span>) {
2477 // Grab the argument types, supplying fresh type variables
2478 // if the wrong number of arguments were supplied
2479 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2485 // All the input types from the fn signature must outlive the call
2486 // so as to validate implied bounds.
2487 for &fn_input_ty in fn_inputs {
2488 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2491 let mut expected_arg_tys = expected_arg_tys;
2492 let expected_arg_count = fn_inputs.len();
2494 fn parameter_count_error<'tcx>(sess: &Session,
2497 expected_count: usize,
2501 def_span: Option<Span>,
2503 let mut err = sess.struct_span_err_with_code(sp,
2504 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2505 if variadic {"at least "} else {""},
2507 if expected_count == 1 {""} else {"s"},
2509 if arg_count == 1 {" was"} else {"s were"}),
2510 DiagnosticId::Error(error_code.to_owned()));
2512 if let Some(def_s) = def_span.map(|sp| sess.codemap().def_span(sp)) {
2513 err.span_label(def_s, "defined here");
2516 let sugg_span = sess.codemap().end_point(expr_sp);
2517 // remove closing `)` from the span
2518 let sugg_span = sugg_span.with_hi(sugg_span.lo());
2519 err.span_suggestion(
2521 "expected the unit value `()`; create it with empty parentheses",
2522 String::from("()"));
2524 err.span_label(sp, format!("expected {}{} parameter{}",
2525 if variadic {"at least "} else {""},
2527 if expected_count == 1 {""} else {"s"}));
2532 let formal_tys = if tuple_arguments == TupleArguments {
2533 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2534 match tuple_type.sty {
2535 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2536 parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(),
2537 "E0057", false, def_span, false);
2538 expected_arg_tys = &[];
2539 self.err_args(args.len())
2541 ty::TyTuple(arg_types, _) => {
2542 expected_arg_tys = match expected_arg_tys.get(0) {
2543 Some(&ty) => match ty.sty {
2544 ty::TyTuple(ref tys, _) => &tys,
2552 span_err!(tcx.sess, sp, E0059,
2553 "cannot use call notation; the first type parameter \
2554 for the function trait is neither a tuple nor unit");
2555 expected_arg_tys = &[];
2556 self.err_args(args.len())
2559 } else if expected_arg_count == supplied_arg_count {
2561 } else if variadic {
2562 if supplied_arg_count >= expected_arg_count {
2565 parameter_count_error(tcx.sess, sp, expr_sp, expected_arg_count,
2566 supplied_arg_count, "E0060", true, def_span, false);
2567 expected_arg_tys = &[];
2568 self.err_args(supplied_arg_count)
2571 // is the missing argument of type `()`?
2572 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2573 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
2574 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2575 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
2579 parameter_count_error(tcx.sess, sp, expr_sp, expected_arg_count,
2580 supplied_arg_count, "E0061", false, def_span, sugg_unit);
2581 expected_arg_tys = &[];
2582 self.err_args(supplied_arg_count)
2585 debug!("check_argument_types: formal_tys={:?}",
2586 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2588 // Check the arguments.
2589 // We do this in a pretty awful way: first we typecheck any arguments
2590 // that are not closures, then we typecheck the closures. This is so
2591 // that we have more information about the types of arguments when we
2592 // typecheck the functions. This isn't really the right way to do this.
2593 for &check_closures in &[false, true] {
2594 debug!("check_closures={}", check_closures);
2596 // More awful hacks: before we check argument types, try to do
2597 // an "opportunistic" vtable resolution of any trait bounds on
2598 // the call. This helps coercions.
2600 self.select_obligations_where_possible();
2603 // For variadic functions, we don't have a declared type for all of
2604 // the arguments hence we only do our usual type checking with
2605 // the arguments who's types we do know.
2606 let t = if variadic {
2608 } else if tuple_arguments == TupleArguments {
2613 for (i, arg) in args.iter().take(t).enumerate() {
2614 // Warn only for the first loop (the "no closures" one).
2615 // Closure arguments themselves can't be diverging, but
2616 // a previous argument can, e.g. `foo(panic!(), || {})`.
2617 if !check_closures {
2618 self.warn_if_unreachable(arg.id, arg.span, "expression");
2621 let is_closure = match arg.node {
2622 hir::ExprClosure(..) => true,
2626 if is_closure != check_closures {
2630 debug!("checking the argument");
2631 let formal_ty = formal_tys[i];
2633 // The special-cased logic below has three functions:
2634 // 1. Provide as good of an expected type as possible.
2635 let expected = expected_arg_tys.get(i).map(|&ty| {
2636 Expectation::rvalue_hint(self, ty)
2639 let checked_ty = self.check_expr_with_expectation(
2641 expected.unwrap_or(ExpectHasType(formal_ty)));
2643 // 2. Coerce to the most detailed type that could be coerced
2644 // to, which is `expected_ty` if `rvalue_hint` returns an
2645 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2646 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2647 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2649 // 3. Relate the expected type and the formal one,
2650 // if the expected type was used for the coercion.
2651 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2655 // We also need to make sure we at least write the ty of the other
2656 // arguments which we skipped above.
2658 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
2659 use structured_errors::{VariadicError, StructuredDiagnostic};
2660 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
2663 for arg in args.iter().skip(expected_arg_count) {
2664 let arg_ty = self.check_expr(&arg);
2666 // There are a few types which get autopromoted when passed via varargs
2667 // in C but we just error out instead and require explicit casts.
2668 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
2670 ty::TyFloat(ast::FloatTy::F32) => {
2671 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
2673 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2674 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
2676 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2677 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
2679 ty::TyFnDef(..) => {
2680 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
2681 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2682 variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
2690 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2691 (0..len).map(|_| self.tcx.types.err).collect()
2694 // AST fragment checking
2697 expected: Expectation<'tcx>)
2703 ast::LitKind::Str(..) => tcx.mk_static_str(),
2704 ast::LitKind::ByteStr(ref v) => {
2705 tcx.mk_imm_ref(tcx.types.re_static,
2706 tcx.mk_array(tcx.types.u8, v.len() as u64))
2708 ast::LitKind::Byte(_) => tcx.types.u8,
2709 ast::LitKind::Char(_) => tcx.types.char,
2710 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2711 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2712 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2713 let opt_ty = expected.to_option(self).and_then(|ty| {
2715 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2716 ty::TyChar => Some(tcx.types.u8),
2717 ty::TyRawPtr(..) => Some(tcx.types.usize),
2718 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2722 opt_ty.unwrap_or_else(
2723 || tcx.mk_int_var(self.next_int_var_id()))
2725 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2726 ast::LitKind::FloatUnsuffixed(_) => {
2727 let opt_ty = expected.to_option(self).and_then(|ty| {
2729 ty::TyFloat(_) => Some(ty),
2733 opt_ty.unwrap_or_else(
2734 || tcx.mk_float_var(self.next_float_var_id()))
2736 ast::LitKind::Bool(_) => tcx.types.bool
2740 fn check_expr_eq_type(&self,
2741 expr: &'gcx hir::Expr,
2742 expected: Ty<'tcx>) {
2743 let ty = self.check_expr_with_hint(expr, expected);
2744 self.demand_eqtype(expr.span, expected, ty);
2747 pub fn check_expr_has_type_or_error(&self,
2748 expr: &'gcx hir::Expr,
2749 expected: Ty<'tcx>) -> Ty<'tcx> {
2750 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
2753 fn check_expr_meets_expectation_or_error(&self,
2754 expr: &'gcx hir::Expr,
2755 expected: Expectation<'tcx>) -> Ty<'tcx> {
2756 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
2757 let mut ty = self.check_expr_with_expectation(expr, expected);
2759 // While we don't allow *arbitrary* coercions here, we *do* allow
2760 // coercions from ! to `expected`.
2762 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
2763 "expression with never type wound up being adjusted");
2764 let adj_ty = self.next_diverging_ty_var(
2765 ty::UniverseIndex::ROOT,
2766 TypeVariableOrigin::AdjustmentType(expr.span));
2767 self.apply_adjustments(expr, vec![Adjustment {
2768 kind: Adjust::NeverToAny,
2774 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
2775 // Add help to type error if this is an `if` condition with an assignment
2776 match (expected, &expr.node) {
2777 (ExpectIfCondition, &hir::ExprAssign(ref lhs, ref rhs)) => {
2778 let msg = "try comparing for equality";
2779 if let (Ok(left), Ok(right)) = (
2780 self.tcx.sess.codemap().span_to_snippet(lhs.span),
2781 self.tcx.sess.codemap().span_to_snippet(rhs.span))
2783 err.span_suggestion(expr.span, msg, format!("{} == {}", left, right));
2795 fn check_expr_coercable_to_type(&self,
2796 expr: &'gcx hir::Expr,
2797 expected: Ty<'tcx>) -> Ty<'tcx> {
2798 self.check_expr_coercable_to_type_with_needs(expr, expected, Needs::None)
2801 fn check_expr_coercable_to_type_with_needs(&self,
2802 expr: &'gcx hir::Expr,
2806 let ty = self.check_expr_with_expectation_and_needs(
2808 ExpectHasType(expected),
2810 self.demand_coerce(expr, ty, expected)
2813 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2814 expected: Ty<'tcx>) -> Ty<'tcx> {
2815 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2818 fn check_expr_with_expectation(&self,
2819 expr: &'gcx hir::Expr,
2820 expected: Expectation<'tcx>) -> Ty<'tcx> {
2821 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
2824 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2825 self.check_expr_with_expectation(expr, NoExpectation)
2828 fn check_expr_with_needs(&self, expr: &'gcx hir::Expr, needs: Needs) -> Ty<'tcx> {
2829 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
2832 // determine the `self` type, using fresh variables for all variables
2833 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2834 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2836 pub fn impl_self_ty(&self,
2837 span: Span, // (potential) receiver for this impl
2839 -> TypeAndSubsts<'tcx> {
2840 let ity = self.tcx.type_of(did);
2841 debug!("impl_self_ty: ity={:?}", ity);
2843 let substs = self.fresh_substs_for_item(ty::UniverseIndex::ROOT, span, did);
2844 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2846 TypeAndSubsts { substs: substs, ty: substd_ty }
2849 /// Unifies the output type with the expected type early, for more coercions
2850 /// and forward type information on the input expressions.
2851 fn expected_inputs_for_expected_output(&self,
2853 expected_ret: Expectation<'tcx>,
2854 formal_ret: Ty<'tcx>,
2855 formal_args: &[Ty<'tcx>])
2857 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
2858 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2859 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2860 // Attempt to apply a subtyping relationship between the formal
2861 // return type (likely containing type variables if the function
2862 // is polymorphic) and the expected return type.
2863 // No argument expectations are produced if unification fails.
2864 let origin = self.misc(call_span);
2865 let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
2867 // FIXME(#15760) can't use try! here, FromError doesn't default
2868 // to identity so the resulting type is not constrained.
2871 // Process any obligations locally as much as
2872 // we can. We don't care if some things turn
2873 // out unconstrained or ambiguous, as we're
2874 // just trying to get hints here.
2875 let result = self.save_and_restore_in_snapshot_flag(|_| {
2876 let mut fulfill = FulfillmentContext::new();
2877 let ok = ok; // FIXME(#30046)
2878 for obligation in ok.obligations {
2879 fulfill.register_predicate_obligation(self, obligation);
2881 fulfill.select_where_possible(self)
2886 Err(_) => return Err(()),
2889 Err(_) => return Err(()),
2892 // Record all the argument types, with the substitutions
2893 // produced from the above subtyping unification.
2894 Ok(formal_args.iter().map(|ty| {
2895 self.resolve_type_vars_if_possible(ty)
2898 }).unwrap_or(vec![]);
2899 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2900 formal_args, formal_ret,
2901 expected_args, expected_ret);
2905 // Checks a method call.
2906 fn check_method_call(&self,
2907 expr: &'gcx hir::Expr,
2908 segment: &hir::PathSegment,
2910 args: &'gcx [hir::Expr],
2911 expected: Expectation<'tcx>,
2912 needs: Needs) -> Ty<'tcx> {
2913 let rcvr = &args[0];
2914 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
2915 // no need to check for bot/err -- callee does that
2916 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
2918 let method = match self.lookup_method(rcvr_t,
2924 self.write_method_call(expr.hir_id, method);
2928 if segment.name != keywords::Invalid.name() {
2929 self.report_method_error(span,
2940 // Call the generic checker.
2941 self.check_method_argument_types(span,
2949 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2953 .unwrap_or_else(|| span_bug!(return_expr.span,
2954 "check_return_expr called outside fn body"));
2956 let ret_ty = ret_coercion.borrow().expected_ty();
2957 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
2958 ret_coercion.borrow_mut()
2960 &self.cause(return_expr.span,
2961 ObligationCauseCode::ReturnType(return_expr.id)),
2964 self.diverges.get());
2968 // A generic function for checking the then and else in an if
2970 fn check_then_else(&self,
2971 cond_expr: &'gcx hir::Expr,
2972 then_expr: &'gcx hir::Expr,
2973 opt_else_expr: Option<&'gcx hir::Expr>,
2975 expected: Expectation<'tcx>) -> Ty<'tcx> {
2976 let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
2977 let cond_diverges = self.diverges.get();
2978 self.diverges.set(Diverges::Maybe);
2980 let expected = expected.adjust_for_branches(self);
2981 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2982 let then_diverges = self.diverges.get();
2983 self.diverges.set(Diverges::Maybe);
2985 // We've already taken the expected type's preferences
2986 // into account when typing the `then` branch. To figure
2987 // out the initial shot at a LUB, we thus only consider
2988 // `expected` if it represents a *hard* constraint
2989 // (`only_has_type`); otherwise, we just go with a
2990 // fresh type variable.
2991 let coerce_to_ty = expected.coercion_target_type(self, sp);
2992 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2994 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2995 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2997 if let Some(else_expr) = opt_else_expr {
2998 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2999 let else_diverges = self.diverges.get();
3001 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
3003 // We won't diverge unless both branches do (or the condition does).
3004 self.diverges.set(cond_diverges | then_diverges & else_diverges);
3006 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
3007 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
3009 // If the condition is false we can't diverge.
3010 self.diverges.set(cond_diverges);
3013 let result_ty = coerce.complete(self);
3014 if cond_ty.references_error() {
3021 // Check field access expressions
3022 fn check_field(&self,
3023 expr: &'gcx hir::Expr,
3025 base: &'gcx hir::Expr,
3026 field: &Spanned<ast::Name>) -> Ty<'tcx> {
3027 let expr_t = self.check_expr_with_needs(base, needs);
3028 let expr_t = self.structurally_resolved_type(expr.span,
3030 let mut private_candidate = None;
3031 let mut autoderef = self.autoderef(expr.span, expr_t);
3032 while let Some((base_t, _)) = autoderef.next() {
3034 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
3035 debug!("struct named {:?}", base_t);
3036 let (ident, def_scope) =
3037 self.tcx.adjust(field.node, base_def.did, self.body_id);
3038 let fields = &base_def.non_enum_variant().fields;
3039 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3040 let field_ty = self.field_ty(expr.span, field, substs);
3041 if field.vis.is_accessible_from(def_scope, self.tcx) {
3042 let adjustments = autoderef.adjust_steps(needs);
3043 self.apply_adjustments(base, adjustments);
3044 autoderef.finalize();
3046 self.tcx.check_stability(field.did, expr.id, expr.span);
3050 private_candidate = Some((base_def.did, field_ty));
3056 autoderef.unambiguous_final_ty();
3058 if let Some((did, field_ty)) = private_candidate {
3059 let struct_path = self.tcx().item_path_str(did);
3060 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3061 "field `{}` of struct `{}` is private",
3062 field.node, struct_path);
3063 // Also check if an accessible method exists, which is often what is meant.
3064 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
3065 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
3070 } else if field.node == keywords::Invalid.name() {
3071 self.tcx().types.err
3072 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
3073 type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3074 "attempted to take value of method `{}` on type `{}`",
3076 .help("maybe a `()` to call it is missing?")
3078 self.tcx().types.err
3080 if !expr_t.is_primitive_ty() {
3081 let mut err = self.no_such_field_err(field.span, &field.node, expr_t);
3084 ty::TyAdt(def, _) if !def.is_enum() => {
3085 if let Some(suggested_field_name) =
3086 Self::suggest_field_name(def.non_enum_variant(), field, vec![]) {
3087 err.span_label(field.span,
3088 format!("did you mean `{}`?", suggested_field_name));
3090 err.span_label(field.span, "unknown field");
3091 let struct_variant_def = def.non_enum_variant();
3092 let field_names = self.available_field_names(struct_variant_def);
3093 if !field_names.is_empty() {
3094 err.note(&format!("available fields are: {}",
3095 self.name_series_display(field_names)));
3099 ty::TyRawPtr(..) => {
3100 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \
3102 self.tcx.hir.node_to_pretty_string(base.id),
3109 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3110 "`{}` is a primitive type and therefore doesn't have fields",
3113 self.tcx().types.err
3117 // Return an hint about the closest match in field names
3118 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3119 field: &Spanned<ast::Name>,
3120 skip: Vec<InternedString>)
3122 let name = field.node.as_str();
3123 let names = variant.fields.iter().filter_map(|field| {
3124 // ignore already set fields and private fields from non-local crates
3125 if skip.iter().any(|x| *x == field.name.as_str()) ||
3126 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3133 find_best_match_for_name(names, &name, None)
3136 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3137 let mut available = Vec::new();
3138 for field in variant.fields.iter() {
3139 let (_, def_scope) = self.tcx.adjust(field.name, variant.did, self.body_id);
3140 if field.vis.is_accessible_from(def_scope, self.tcx) {
3141 available.push(field.name);
3147 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3148 // dynamic limit, to never omit just one field
3149 let limit = if names.len() == 6 { 6 } else { 5 };
3150 let mut display = names.iter().take(limit)
3151 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3152 if names.len() > limit {
3153 display = format!("{} ... and {} others", display, names.len() - limit);
3158 // Check tuple index expressions
3159 fn check_tup_field(&self,
3160 expr: &'gcx hir::Expr,
3162 base: &'gcx hir::Expr,
3163 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
3164 let expr_t = self.check_expr_with_needs(base, needs);
3165 let expr_t = self.structurally_resolved_type(expr.span,
3167 let mut private_candidate = None;
3168 let mut tuple_like = false;
3169 let mut autoderef = self.autoderef(expr.span, expr_t);
3170 while let Some((base_t, _)) = autoderef.next() {
3171 let field = match base_t.sty {
3172 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
3173 tuple_like = base_def.non_enum_variant().ctor_kind == CtorKind::Fn;
3174 if !tuple_like { continue }
3176 debug!("tuple struct named {:?}", base_t);
3177 let ident = ast::Ident {
3178 name: Symbol::intern(&idx.node.to_string()),
3179 ctxt: idx.span.ctxt().modern(),
3181 let (ident, def_scope) =
3182 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
3183 let fields = &base_def.non_enum_variant().fields;
3184 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3185 let field_ty = self.field_ty(expr.span, field, substs);
3186 if field.vis.is_accessible_from(def_scope, self.tcx) {
3187 self.tcx.check_stability(field.did, expr.id, expr.span);
3190 private_candidate = Some((base_def.did, field_ty));
3197 ty::TyTuple(ref v, _) => {
3199 v.get(idx.node).cloned()
3204 if let Some(field_ty) = field {
3205 let adjustments = autoderef.adjust_steps(needs);
3206 self.apply_adjustments(base, adjustments);
3207 autoderef.finalize();
3211 autoderef.unambiguous_final_ty();
3213 if let Some((did, field_ty)) = private_candidate {
3214 let struct_path = self.tcx().item_path_str(did);
3215 struct_span_err!(self.tcx().sess, expr.span, E0611,
3216 "field `{}` of tuple-struct `{}` is private",
3217 idx.node, struct_path).emit();
3222 type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
3223 "attempted out-of-bounds tuple index `{}` on type `{}`",
3224 idx.node, expr_t).emit();
3226 self.no_such_field_err(expr.span, idx.node, expr_t).emit();
3229 self.tcx().types.err
3232 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
3233 -> DiagnosticBuilder {
3234 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3235 "no field `{}` on type `{}`",
3239 fn report_unknown_field(&self,
3241 variant: &'tcx ty::VariantDef,
3243 skip_fields: &[hir::Field],
3245 let mut err = self.type_error_struct_with_diag(
3247 |actual| match ty.sty {
3248 ty::TyAdt(adt, ..) if adt.is_enum() => {
3249 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3250 "{} `{}::{}` has no field named `{}`",
3251 kind_name, actual, variant.name, field.name.node)
3254 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3255 "{} `{}` has no field named `{}`",
3256 kind_name, actual, field.name.node)
3260 // prevent all specified fields from being suggested
3261 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3262 if let Some(field_name) = Self::suggest_field_name(variant,
3264 skip_fields.collect()) {
3265 err.span_label(field.name.span,
3266 format!("field does not exist - did you mean `{}`?", field_name));
3269 ty::TyAdt(adt, ..) => {
3271 err.span_label(field.name.span,
3272 format!("`{}::{}` does not have this field",
3275 err.span_label(field.name.span,
3276 format!("`{}` does not have this field", ty));
3278 let available_field_names = self.available_field_names(variant);
3279 if !available_field_names.is_empty() {
3280 err.note(&format!("available fields are: {}",
3281 self.name_series_display(available_field_names)));
3284 _ => bug!("non-ADT passed to report_unknown_field")
3290 fn check_expr_struct_fields(&self,
3292 expected: Expectation<'tcx>,
3293 expr_id: ast::NodeId,
3295 variant: &'tcx ty::VariantDef,
3296 ast_fields: &'gcx [hir::Field],
3297 check_completeness: bool) {
3301 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3302 .get(0).cloned().unwrap_or(adt_ty);
3303 // re-link the regions that EIfEO can erase.
3304 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3306 let (substs, adt_kind, kind_name) = match &adt_ty.sty{
3307 &ty::TyAdt(adt, substs) => {
3308 (substs, adt.adt_kind(), adt.variant_descr())
3310 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3313 let mut remaining_fields = FxHashMap();
3314 for field in &variant.fields {
3315 remaining_fields.insert(field.name.to_ident(), field);
3318 let mut seen_fields = FxHashMap();
3320 let mut error_happened = false;
3322 // Typecheck each field.
3323 for field in ast_fields {
3324 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3325 let field_type = if let Some(v_field) = remaining_fields.remove(&ident) {
3326 seen_fields.insert(field.name.node, field.span);
3328 // we don't look at stability attributes on
3329 // struct-like enums (yet...), but it's definitely not
3330 // a bug to have construct one.
3331 if adt_kind != ty::AdtKind::Enum {
3332 tcx.check_stability(v_field.did, expr_id, field.span);
3335 self.field_ty(field.span, v_field, substs)
3337 error_happened = true;
3338 if let Some(_) = variant.find_field_named(field.name.node) {
3339 let mut err = struct_span_err!(self.tcx.sess,
3342 "field `{}` specified more than once",
3345 err.span_label(field.name.span, "used more than once");
3347 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3348 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3353 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3359 // Make sure to give a type to the field even if there's
3360 // an error, so we can continue typechecking
3361 self.check_expr_coercable_to_type(&field.expr, field_type);
3364 // Make sure the programmer specified correct number of fields.
3365 if kind_name == "union" {
3366 if ast_fields.len() != 1 {
3367 tcx.sess.span_err(span, "union expressions should have exactly one field");
3369 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3370 let len = remaining_fields.len();
3372 let mut displayable_field_names = remaining_fields
3374 .map(|ident| ident.name.as_str())
3375 .collect::<Vec<_>>();
3377 displayable_field_names.sort();
3379 let truncated_fields_error = if len <= 3 {
3382 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3385 let remaining_fields_names = displayable_field_names.iter().take(3)
3386 .map(|n| format!("`{}`", n))
3387 .collect::<Vec<_>>()
3390 struct_span_err!(tcx.sess, span, E0063,
3391 "missing field{} {}{} in initializer of `{}`",
3392 if remaining_fields.len() == 1 { "" } else { "s" },
3393 remaining_fields_names,
3394 truncated_fields_error,
3396 .span_label(span, format!("missing {}{}",
3397 remaining_fields_names,
3398 truncated_fields_error))
3403 fn check_struct_fields_on_error(&self,
3404 fields: &'gcx [hir::Field],
3405 base_expr: &'gcx Option<P<hir::Expr>>) {
3406 for field in fields {
3407 self.check_expr(&field.expr);
3411 self.check_expr(&base);
3417 pub fn check_struct_path(&self,
3419 node_id: ast::NodeId)
3420 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3421 let path_span = match *qpath {
3422 hir::QPath::Resolved(_, ref path) => path.span,
3423 hir::QPath::TypeRelative(ref qself, _) => qself.span
3425 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3426 let variant = match def {
3428 self.set_tainted_by_errors();
3431 Def::Variant(..) => {
3433 ty::TyAdt(adt, substs) => {
3434 Some((adt.variant_of_def(def), adt.did, substs))
3436 _ => bug!("unexpected type: {:?}", ty.sty)
3439 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3440 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3442 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3443 Some((adt.non_enum_variant(), adt.did, substs))
3448 _ => bug!("unexpected definition: {:?}", def)
3451 if let Some((variant, did, substs)) = variant {
3452 // Check bounds on type arguments used in the path.
3453 let bounds = self.instantiate_bounds(path_span, did, substs);
3454 let cause = traits::ObligationCause::new(path_span, self.body_id,
3455 traits::ItemObligation(did));
3456 self.add_obligations_for_parameters(cause, &bounds);
3460 struct_span_err!(self.tcx.sess, path_span, E0071,
3461 "expected struct, variant or union type, found {}",
3462 ty.sort_string(self.tcx))
3463 .span_label(path_span, "not a struct")
3469 fn check_expr_struct(&self,
3471 expected: Expectation<'tcx>,
3473 fields: &'gcx [hir::Field],
3474 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3476 // Find the relevant variant
3477 let (variant, struct_ty) =
3478 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3481 self.check_struct_fields_on_error(fields, base_expr);
3482 return self.tcx.types.err;
3485 let path_span = match *qpath {
3486 hir::QPath::Resolved(_, ref path) => path.span,
3487 hir::QPath::TypeRelative(ref qself, _) => qself.span
3490 // Prohibit struct expressions when non exhaustive flag is set.
3491 if let ty::TyAdt(adt, _) = struct_ty.sty {
3492 if !adt.did.is_local() && adt.is_non_exhaustive() {
3493 span_err!(self.tcx.sess, expr.span, E0639,
3494 "cannot create non-exhaustive {} using struct expression",
3495 adt.variant_descr());
3499 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3500 base_expr.is_none());
3501 if let &Some(ref base_expr) = base_expr {
3502 self.check_expr_has_type_or_error(base_expr, struct_ty);
3503 match struct_ty.sty {
3504 ty::TyAdt(adt, substs) if adt.is_struct() => {
3505 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3506 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3511 .fru_field_types_mut()
3512 .insert(expr.hir_id, fru_field_types);
3515 span_err!(self.tcx.sess, base_expr.span, E0436,
3516 "functional record update syntax requires a struct");
3520 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3526 /// If an expression has any sub-expressions that result in a type error,
3527 /// inspecting that expression's type with `ty.references_error()` will return
3528 /// true. Likewise, if an expression is known to diverge, inspecting its
3529 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3530 /// strict, _|_ can appear in the type of an expression that does not,
3531 /// itself, diverge: for example, fn() -> _|_.)
3532 /// Note that inspecting a type's structure *directly* may expose the fact
3533 /// that there are actually multiple representations for `TyError`, so avoid
3534 /// that when err needs to be handled differently.
3535 fn check_expr_with_expectation_and_needs(&self,
3536 expr: &'gcx hir::Expr,
3537 expected: Expectation<'tcx>,
3538 needs: Needs) -> Ty<'tcx> {
3539 debug!(">> typechecking: expr={:?} expected={:?}",
3542 // Warn for expressions after diverging siblings.
3543 self.warn_if_unreachable(expr.id, expr.span, "expression");
3545 // Hide the outer diverging and has_errors flags.
3546 let old_diverges = self.diverges.get();
3547 let old_has_errors = self.has_errors.get();
3548 self.diverges.set(Diverges::Maybe);
3549 self.has_errors.set(false);
3551 let ty = self.check_expr_kind(expr, expected, needs);
3553 // Warn for non-block expressions with diverging children.
3556 hir::ExprLoop(..) | hir::ExprWhile(..) |
3557 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3559 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3562 // Any expression that produces a value of type `!` must have diverged
3564 self.diverges.set(self.diverges.get() | Diverges::Always);
3567 // Record the type, which applies it effects.
3568 // We need to do this after the warning above, so that
3569 // we don't warn for the diverging expression itself.
3570 self.write_ty(expr.hir_id, ty);
3572 // Combine the diverging and has_error flags.
3573 self.diverges.set(self.diverges.get() | old_diverges);
3574 self.has_errors.set(self.has_errors.get() | old_has_errors);
3576 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3577 debug!("... {:?}, expected is {:?}", ty, expected);
3582 fn check_expr_kind(&self,
3583 expr: &'gcx hir::Expr,
3584 expected: Expectation<'tcx>,
3585 needs: Needs) -> Ty<'tcx> {
3589 hir::ExprBox(ref subexpr) => {
3590 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3592 ty::TyAdt(def, _) if def.is_box()
3593 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3597 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3598 tcx.mk_box(referent_ty)
3601 hir::ExprLit(ref lit) => {
3602 self.check_lit(&lit, expected)
3604 hir::ExprBinary(op, ref lhs, ref rhs) => {
3605 self.check_binop(expr, op, lhs, rhs)
3607 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3608 self.check_binop_assign(expr, op, lhs, rhs)
3610 hir::ExprUnary(unop, ref oprnd) => {
3611 let expected_inner = match unop {
3612 hir::UnNot | hir::UnNeg => {
3619 let needs = match unop {
3620 hir::UnDeref => needs,
3623 let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
3627 if !oprnd_t.references_error() {
3628 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3631 if let Some(mt) = oprnd_t.builtin_deref(true) {
3633 } else if let Some(ok) = self.try_overloaded_deref(
3634 expr.span, oprnd_t, needs) {
3635 let method = self.register_infer_ok_obligations(ok);
3636 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3637 let mutbl = match mt.mutbl {
3638 hir::MutImmutable => AutoBorrowMutability::Immutable,
3639 hir::MutMutable => AutoBorrowMutability::Mutable {
3640 // (It shouldn't actually matter for unary ops whether
3641 // we enable two-phase borrows or not, since a unary
3642 // op has no additional operands.)
3643 allow_two_phase_borrow: false,
3646 self.apply_adjustments(oprnd, vec![Adjustment {
3647 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3648 target: method.sig.inputs()[0]
3651 oprnd_t = self.make_overloaded_place_return_type(method).ty;
3652 self.write_method_call(expr.hir_id, method);
3654 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3655 "type `{}` cannot be dereferenced",
3657 oprnd_t = tcx.types.err;
3661 let result = self.check_user_unop(expr, oprnd_t, unop);
3662 // If it's builtin, we can reuse the type, this helps inference.
3663 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3668 let result = self.check_user_unop(expr, oprnd_t, unop);
3669 // If it's builtin, we can reuse the type, this helps inference.
3670 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3678 hir::ExprAddrOf(mutbl, ref oprnd) => {
3679 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3681 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3682 if self.is_place_expr(&oprnd) {
3683 // Places may legitimately have unsized types.
3684 // For example, dereferences of a fat pointer and
3685 // the last field of a struct can be unsized.
3686 ExpectHasType(mt.ty)
3688 Expectation::rvalue_hint(self, mt.ty)
3694 let needs = Needs::maybe_mut_place(mutbl);
3695 let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
3697 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3698 if tm.ty.references_error() {
3701 // Note: at this point, we cannot say what the best lifetime
3702 // is to use for resulting pointer. We want to use the
3703 // shortest lifetime possible so as to avoid spurious borrowck
3704 // errors. Moreover, the longest lifetime will depend on the
3705 // precise details of the value whose address is being taken
3706 // (and how long it is valid), which we don't know yet until type
3707 // inference is complete.
3709 // Therefore, here we simply generate a region variable. The
3710 // region inferencer will then select the ultimate value.
3711 // Finally, borrowck is charged with guaranteeing that the
3712 // value whose address was taken can actually be made to live
3713 // as long as it needs to live.
3714 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3715 tcx.mk_ref(region, tm)
3718 hir::ExprPath(ref qpath) => {
3719 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3720 expr.id, expr.span);
3721 let ty = if def != Def::Err {
3722 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3724 self.set_tainted_by_errors();
3728 // We always require that the type provided as the value for
3729 // a type parameter outlives the moment of instantiation.
3730 let substs = self.tables.borrow().node_substs(expr.hir_id);
3731 self.add_wf_bounds(substs, expr);
3735 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3736 for output in outputs {
3737 self.check_expr(output);
3739 for input in inputs {
3740 self.check_expr(input);
3744 hir::ExprBreak(destination, ref expr_opt) => {
3745 if let Some(target_id) = destination.target_id.opt_id() {
3746 let (e_ty, e_diverges, cause);
3747 if let Some(ref e) = *expr_opt {
3748 // If this is a break with a value, we need to type-check
3749 // the expression. Get an expected type from the loop context.
3750 let opt_coerce_to = {
3751 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3752 enclosing_breakables.find_breakable(target_id)
3755 .map(|coerce| coerce.expected_ty())
3758 // If the loop context is not a `loop { }`, then break with
3759 // a value is illegal, and `opt_coerce_to` will be `None`.
3760 // Just set expectation to error in that case.
3761 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3763 // Recurse without `enclosing_breakables` borrowed.
3764 e_ty = self.check_expr_with_hint(e, coerce_to);
3765 e_diverges = self.diverges.get();
3766 cause = self.misc(e.span);
3768 // Otherwise, this is a break *without* a value. That's
3769 // always legal, and is equivalent to `break ()`.
3770 e_ty = tcx.mk_nil();
3771 e_diverges = Diverges::Maybe;
3772 cause = self.misc(expr.span);
3775 // Now that we have type-checked `expr_opt`, borrow
3776 // the `enclosing_loops` field and let's coerce the
3777 // type of `expr_opt` into what is expected.
3778 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3779 let ctxt = enclosing_breakables.find_breakable(target_id);
3780 if let Some(ref mut coerce) = ctxt.coerce {
3781 if let Some(ref e) = *expr_opt {
3782 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3784 assert!(e_ty.is_nil());
3785 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3788 // If `ctxt.coerce` is `None`, we can just ignore
3789 // the type of the expresison. This is because
3790 // either this was a break *without* a value, in
3791 // which case it is always a legal type (`()`), or
3792 // else an error would have been flagged by the
3793 // `loops` pass for using break with an expression
3794 // where you are not supposed to.
3795 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3798 ctxt.may_break = true;
3800 // Otherwise, we failed to find the enclosing loop;
3801 // this can only happen if the `break` was not
3802 // inside a loop at all, which is caught by the
3803 // loop-checking pass.
3804 assert!(self.tcx.sess.err_count() > 0);
3806 // We still need to assign a type to the inner expression to
3807 // prevent the ICE in #43162.
3808 if let Some(ref e) = *expr_opt {
3809 self.check_expr_with_hint(e, tcx.types.err);
3811 // ... except when we try to 'break rust;'.
3812 // ICE this expression in particular (see #43162).
3813 if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
3814 if path.segments.len() == 1 && path.segments[0].name == "rust" {
3815 fatally_break_rust(self.tcx.sess);
3821 // the type of a `break` is always `!`, since it diverges
3824 hir::ExprAgain(_) => { tcx.types.never }
3825 hir::ExprRet(ref expr_opt) => {
3826 if self.ret_coercion.is_none() {
3827 struct_span_err!(self.tcx.sess, expr.span, E0572,
3828 "return statement outside of function body").emit();
3829 } else if let Some(ref e) = *expr_opt {
3830 self.check_return_expr(e);
3832 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3833 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3834 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3838 hir::ExprAssign(ref lhs, ref rhs) => {
3839 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
3841 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3844 ExpectIfCondition => {
3845 self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
3846 expected error elsehwere");
3849 // Only check this if not in an `if` condition, as the
3850 // mistyped comparison help is more appropriate.
3851 if !self.is_place_expr(&lhs) {
3852 struct_span_err!(self.tcx.sess, expr.span, E0070,
3853 "invalid left-hand side expression")
3854 .span_label(expr.span, "left-hand of expression not valid")
3860 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3862 if lhs_ty.references_error() || rhs_ty.references_error() {
3868 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3869 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3870 expr.span, expected)
3872 hir::ExprWhile(ref cond, ref body, _) => {
3873 let ctxt = BreakableCtxt {
3874 // cannot use break with a value from a while loop
3879 self.with_breakable_ctxt(expr.id, ctxt, || {
3880 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
3881 let cond_diverging = self.diverges.get();
3882 self.check_block_no_value(&body);
3884 // We may never reach the body so it diverging means nothing.
3885 self.diverges.set(cond_diverging);
3890 hir::ExprLoop(ref body, _, source) => {
3891 let coerce = match source {
3892 // you can only use break with a value from a normal `loop { }`
3893 hir::LoopSource::Loop => {
3894 let coerce_to = expected.coercion_target_type(self, body.span);
3895 Some(CoerceMany::new(coerce_to))
3898 hir::LoopSource::WhileLet |
3899 hir::LoopSource::ForLoop => {
3904 let ctxt = BreakableCtxt {
3906 may_break: false, // will get updated if/when we find a `break`
3909 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3910 self.check_block_no_value(&body);
3914 // No way to know whether it's diverging because
3915 // of a `break` or an outer `break` or `return.
3916 self.diverges.set(Diverges::Maybe);
3919 // If we permit break with a value, then result type is
3920 // the LUB of the breaks (possibly ! if none); else, it
3921 // is nil. This makes sense because infinite loops
3922 // (which would have type !) are only possible iff we
3923 // permit break with a value [1].
3924 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3925 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3927 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3928 self.check_match(expr, &discrim, arms, expected, match_src)
3930 hir::ExprClosure(capture, ref decl, body_id, _, gen) => {
3931 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
3933 hir::ExprBlock(ref body) => {
3934 self.check_block_with_expected(&body, expected)
3936 hir::ExprCall(ref callee, ref args) => {
3937 self.check_call(expr, &callee, args, expected)
3939 hir::ExprMethodCall(ref segment, span, ref args) => {
3940 self.check_method_call(expr, segment, span, args, expected, needs)
3942 hir::ExprCast(ref e, ref t) => {
3943 // Find the type of `e`. Supply hints based on the type we are casting to,
3945 let t_cast = self.to_ty(t);
3946 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3947 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3948 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3949 let diverges = self.diverges.get();
3951 // Eagerly check for some obvious errors.
3952 if t_expr.references_error() || t_cast.references_error() {
3955 // Defer other checks until we're done type checking.
3956 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3957 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3959 deferred_cast_checks.push(cast_check);
3962 Err(ErrorReported) => {
3968 hir::ExprType(ref e, ref t) => {
3969 let typ = self.to_ty(&t);
3970 self.check_expr_eq_type(&e, typ);
3973 hir::ExprArray(ref args) => {
3974 let uty = expected.to_option(self).and_then(|uty| {
3976 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3981 let element_ty = if !args.is_empty() {
3982 let coerce_to = uty.unwrap_or_else(
3983 || self.next_ty_var(ty::UniverseIndex::ROOT,
3984 TypeVariableOrigin::TypeInference(expr.span)));
3985 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3986 assert_eq!(self.diverges.get(), Diverges::Maybe);
3988 let e_ty = self.check_expr_with_hint(e, coerce_to);
3989 let cause = self.misc(e.span);
3990 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3992 coerce.complete(self)
3994 self.next_ty_var(ty::UniverseIndex::ROOT,
3995 TypeVariableOrigin::TypeInference(expr.span))
3997 tcx.mk_array(element_ty, args.len() as u64)
3999 hir::ExprRepeat(ref element, count) => {
4000 let count_def_id = tcx.hir.body_owner_def_id(count);
4001 let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing);
4002 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
4003 let instance = ty::Instance::resolve(
4009 let global_id = GlobalId {
4013 let count = tcx.const_eval(param_env.and(global_id));
4015 if let Err(ref err) = count {
4016 err.report(tcx, tcx.def_span(count_def_id), "constant expression");
4019 let uty = match expected {
4020 ExpectHasType(uty) => {
4022 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
4029 let (element_ty, t) = match uty {
4031 self.check_expr_coercable_to_type(&element, uty);
4035 let t: Ty = self.next_ty_var(ty::UniverseIndex::ROOT,
4036 TypeVariableOrigin::MiscVariable(element.span));
4037 let element_ty = self.check_expr_has_type_or_error(&element, t);
4042 if let Ok(count) = count {
4043 let zero_or_one = count.val.to_u128().map_or(false, |count| count <= 1);
4045 // For [foo, ..n] where n > 1, `foo` must have
4047 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4048 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4052 if element_ty.references_error() {
4054 } else if let Ok(count) = count {
4055 tcx.mk_ty(ty::TyArray(t, count))
4060 hir::ExprTup(ref elts) => {
4061 let flds = expected.only_has_type(self).and_then(|ty| {
4062 let ty = self.resolve_type_vars_with_obligations(ty);
4064 ty::TyTuple(ref flds, _) => Some(&flds[..]),
4069 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4070 let t = match flds {
4071 Some(ref fs) if i < fs.len() => {
4073 self.check_expr_coercable_to_type(&e, ety);
4077 self.check_expr_with_expectation(&e, NoExpectation)
4082 let tuple = tcx.mk_tup(elt_ts_iter, false);
4083 if tuple.references_error() {
4086 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4090 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
4091 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4093 hir::ExprField(ref base, ref field) => {
4094 self.check_field(expr, needs, &base, field)
4096 hir::ExprTupField(ref base, idx) => {
4097 self.check_tup_field(expr, needs, &base, idx)
4099 hir::ExprIndex(ref base, ref idx) => {
4100 let base_t = self.check_expr_with_needs(&base, needs);
4101 let idx_t = self.check_expr(&idx);
4103 if base_t.references_error() {
4105 } else if idx_t.references_error() {
4108 let base_t = self.structurally_resolved_type(expr.span, base_t);
4109 match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
4110 Some((index_ty, element_ty)) => {
4111 self.demand_coerce(idx, idx_t, index_ty);
4115 let mut err = type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4116 "cannot index into a value of type `{}`",
4118 // Try to give some advice about indexing tuples.
4119 if let ty::TyTuple(..) = base_t.sty {
4120 let mut needs_note = true;
4121 // If the index is an integer, we can show the actual
4122 // fixed expression:
4123 if let hir::ExprLit(ref lit) = idx.node {
4124 if let ast::LitKind::Int(i,
4125 ast::LitIntType::Unsuffixed) = lit.node {
4126 let snip = tcx.sess.codemap().span_to_snippet(base.span);
4127 if let Ok(snip) = snip {
4128 err.span_suggestion(expr.span,
4129 "to access tuple elements, use",
4130 format!("{}.{}", snip, i));
4136 err.help("to access tuple elements, use tuple indexing \
4137 syntax (e.g. `tuple.0`)");
4146 hir::ExprYield(ref value) => {
4147 match self.yield_ty {
4149 self.check_expr_coercable_to_type(&value, ty);
4152 struct_span_err!(self.tcx.sess, expr.span, E0627,
4153 "yield statement outside of generator literal").emit();
4161 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4162 // The newly resolved definition is written into `type_dependent_defs`.
4163 fn finish_resolving_struct_path(&self,
4166 node_id: ast::NodeId)
4170 hir::QPath::Resolved(ref maybe_qself, ref path) => {
4171 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4172 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
4175 hir::QPath::TypeRelative(ref qself, ref segment) => {
4176 let ty = self.to_ty(qself);
4178 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
4183 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4186 // Write back the new resolution.
4187 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4188 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4195 // Resolve associated value path into a base type and associated constant or method definition.
4196 // The newly resolved definition is written into `type_dependent_defs`.
4197 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4198 qpath: &'b hir::QPath,
4199 node_id: ast::NodeId,
4201 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4203 let (ty, item_segment) = match *qpath {
4204 hir::QPath::Resolved(ref opt_qself, ref path) => {
4206 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4207 &path.segments[..]);
4209 hir::QPath::TypeRelative(ref qself, ref segment) => {
4210 (self.to_ty(qself), segment)
4213 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4214 if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4215 // Return directly on cache hit. This is useful to avoid doubly reporting
4216 // errors with default match binding modes. See #44614.
4217 return (*cached_def, Some(ty), slice::from_ref(&**item_segment))
4219 let item_name = item_segment.name;
4220 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
4223 let def = match error {
4224 method::MethodError::PrivateMatch(def, _) => def,
4227 if item_name != keywords::Invalid.name() {
4228 self.report_method_error(span, ty, item_name, None, error, None);
4234 // Write back the new resolution.
4235 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4236 (def, Some(ty), slice::from_ref(&**item_segment))
4239 pub fn check_decl_initializer(&self,
4240 local: &'gcx hir::Local,
4241 init: &'gcx hir::Expr) -> Ty<'tcx>
4243 // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed
4244 // for #42640 (default match binding modes).
4247 let ref_bindings = local.pat.contains_explicit_ref_binding();
4249 let local_ty = self.local_ty(init.span, local.id);
4250 if let Some(m) = ref_bindings {
4251 // Somewhat subtle: if we have a `ref` binding in the pattern,
4252 // we want to avoid introducing coercions for the RHS. This is
4253 // both because it helps preserve sanity and, in the case of
4254 // ref mut, for soundness (issue #23116). In particular, in
4255 // the latter case, we need to be clear that the type of the
4256 // referent for the reference that results is *equal to* the
4257 // type of the place it is referencing, and not some
4258 // supertype thereof.
4259 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4260 self.demand_eqtype(init.span, local_ty, init_ty);
4263 self.check_expr_coercable_to_type(init, local_ty)
4267 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4268 let t = self.local_ty(local.span, local.id);
4269 self.write_ty(local.hir_id, t);
4271 if let Some(ref init) = local.init {
4272 let init_ty = self.check_decl_initializer(local, &init);
4273 if init_ty.references_error() {
4274 self.write_ty(local.hir_id, init_ty);
4278 self.check_pat_walk(&local.pat, t,
4279 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4281 let pat_ty = self.node_ty(local.pat.hir_id);
4282 if pat_ty.references_error() {
4283 self.write_ty(local.hir_id, pat_ty);
4287 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4288 // Don't do all the complex logic below for DeclItem.
4290 hir::StmtDecl(ref decl, _) => {
4292 hir::DeclLocal(_) => {}
4293 hir::DeclItem(_) => {
4298 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4301 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4303 // Hide the outer diverging and has_errors flags.
4304 let old_diverges = self.diverges.get();
4305 let old_has_errors = self.has_errors.get();
4306 self.diverges.set(Diverges::Maybe);
4307 self.has_errors.set(false);
4310 hir::StmtDecl(ref decl, _) => {
4312 hir::DeclLocal(ref l) => {
4313 self.check_decl_local(&l);
4315 hir::DeclItem(_) => {/* ignore for now */}
4318 hir::StmtExpr(ref expr, _) => {
4319 // Check with expected type of ()
4320 self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
4322 hir::StmtSemi(ref expr, _) => {
4323 self.check_expr(&expr);
4327 // Combine the diverging and has_error flags.
4328 self.diverges.set(self.diverges.get() | old_diverges);
4329 self.has_errors.set(self.has_errors.get() | old_has_errors);
4332 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4333 let unit = self.tcx.mk_nil();
4334 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4336 // if the block produces a `!` value, that can always be
4337 // (effectively) coerced to unit.
4339 self.demand_suptype(blk.span, unit, ty);
4343 fn check_block_with_expected(&self,
4344 blk: &'gcx hir::Block,
4345 expected: Expectation<'tcx>) -> Ty<'tcx> {
4347 let mut fcx_ps = self.ps.borrow_mut();
4348 let unsafety_state = fcx_ps.recurse(blk);
4349 replace(&mut *fcx_ps, unsafety_state)
4352 // In some cases, blocks have just one exit, but other blocks
4353 // can be targeted by multiple breaks. This cannot happen in
4354 // normal Rust syntax today, but it can happen when we desugar
4355 // a `do catch { ... }` expression.
4359 // 'a: { if true { break 'a Err(()); } Ok(()) }
4361 // Here we would wind up with two coercions, one from
4362 // `Err(())` and the other from the tail expression
4363 // `Ok(())`. If the tail expression is omitted, that's a
4364 // "forced unit" -- unless the block diverges, in which
4365 // case we can ignore the tail expression (e.g., `'a: {
4366 // break 'a 22; }` would not force the type of the block
4368 let tail_expr = blk.expr.as_ref();
4369 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4370 let coerce = if blk.targeted_by_break {
4371 CoerceMany::new(coerce_to_ty)
4373 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4374 Some(e) => slice::from_ref(e),
4377 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4380 let prev_diverges = self.diverges.get();
4381 let ctxt = BreakableCtxt {
4382 coerce: Some(coerce),
4386 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4387 for s in &blk.stmts {
4391 // check the tail expression **without** holding the
4392 // `enclosing_breakables` lock below.
4393 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4395 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4396 let ctxt = enclosing_breakables.find_breakable(blk.id);
4397 let coerce = ctxt.coerce.as_mut().unwrap();
4398 if let Some(tail_expr_ty) = tail_expr_ty {
4399 let tail_expr = tail_expr.unwrap();
4400 let cause = self.cause(tail_expr.span,
4401 ObligationCauseCode::BlockTailExpression(blk.id));
4406 self.diverges.get());
4408 // Subtle: if there is no explicit tail expression,
4409 // that is typically equivalent to a tail expression
4410 // of `()` -- except if the block diverges. In that
4411 // case, there is no value supplied from the tail
4412 // expression (assuming there are no other breaks,
4413 // this implies that the type of the block will be
4416 // #41425 -- label the implicit `()` as being the
4417 // "found type" here, rather than the "expected type".
4419 // #44579 -- if the block was recovered during parsing,
4420 // the type would be nonsensical and it is not worth it
4421 // to perform the type check, so we avoid generating the
4422 // diagnostic output.
4423 if !self.diverges.get().always() && !blk.recovered {
4424 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4425 if let Some(expected_ty) = expected.only_has_type(self) {
4426 self.consider_hint_about_removing_semicolon(blk,
4436 // If we can break from the block, then the block's exit is always reachable
4437 // (... as long as the entry is reachable) - regardless of the tail of the block.
4438 self.diverges.set(prev_diverges);
4441 let mut ty = ctxt.coerce.unwrap().complete(self);
4443 if self.has_errors.get() || ty.references_error() {
4444 ty = self.tcx.types.err
4447 self.write_ty(blk.hir_id, ty);
4449 *self.ps.borrow_mut() = prev;
4453 /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
4454 /// suggestion can be made, `None` otherwise.
4455 pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
4456 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4457 // `while` before reaching it, as block tail returns are not available in them.
4458 if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
4459 let parent = self.tcx.hir.get(fn_id);
4461 if let Node::NodeItem(&hir::Item {
4462 name, node: hir::ItemFn(ref decl, ..), ..
4464 decl.clone().and_then(|decl| {
4465 // This is less than ideal, it will not suggest a return type span on any
4466 // method called `main`, regardless of whether it is actually the entry point,
4467 // but it will still present it as the reason for the expected type.
4468 Some((decl, name != Symbol::intern("main")))
4470 } else if let Node::NodeTraitItem(&hir::TraitItem {
4471 node: hir::TraitItemKind::Method(hir::MethodSig {
4475 decl.clone().and_then(|decl| {
4478 } else if let Node::NodeImplItem(&hir::ImplItem {
4479 node: hir::ImplItemKind::Method(hir::MethodSig {
4483 decl.clone().and_then(|decl| {
4494 /// On implicit return expressions with mismatched types, provide the following suggestions:
4496 /// - Point out the method's return type as the reason for the expected type
4497 /// - Possible missing semicolon
4498 /// - Possible missing return type if the return type is the default, and not `fn main()`
4499 pub fn suggest_mismatched_types_on_tail(&self,
4500 err: &mut DiagnosticBuilder<'tcx>,
4501 expression: &'gcx hir::Expr,
4505 blk_id: ast::NodeId) {
4506 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4508 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4509 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4513 /// A common error is to forget to add a semicolon at the end of a block:
4517 /// bar_that_returns_u32()
4521 /// This routine checks if the return expression in a block would make sense on its own as a
4522 /// statement and the return type has been left as default or has been specified as `()`. If so,
4523 /// it suggests adding a semicolon.
4524 fn suggest_missing_semicolon(&self,
4525 err: &mut DiagnosticBuilder<'tcx>,
4526 expression: &'gcx hir::Expr,
4529 if expected.is_nil() {
4530 // `BlockTailExpression` only relevant if the tail expr would be
4531 // useful on its own.
4532 match expression.node {
4534 hir::ExprMethodCall(..) |
4536 hir::ExprWhile(..) |
4538 hir::ExprMatch(..) |
4539 hir::ExprBlock(..) => {
4540 let sp = self.tcx.sess.codemap().next_point(cause_span);
4541 err.span_suggestion(sp,
4542 "try adding a semicolon",
4551 /// A possible error is to forget to add a return type that is needed:
4555 /// bar_that_returns_u32()
4559 /// This routine checks if the return type is left as default, the method is not part of an
4560 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4562 fn suggest_missing_return_type(&self,
4563 err: &mut DiagnosticBuilder<'tcx>,
4564 fn_decl: &hir::FnDecl,
4567 can_suggest: bool) {
4568 // Only suggest changing the return type for methods that
4569 // haven't set a return type at all (and aren't `fn main()` or an impl).
4570 match (&fn_decl.output, found.is_suggestable(), can_suggest) {
4571 (&hir::FunctionRetTy::DefaultReturn(span), true, true) => {
4572 err.span_suggestion(span,
4573 "try adding a return type",
4575 self.resolve_type_vars_with_obligations(found)));
4577 (&hir::FunctionRetTy::DefaultReturn(span), false, true) => {
4578 err.span_label(span, "possibly return type missing here?");
4580 (&hir::FunctionRetTy::DefaultReturn(span), _, _) => {
4581 // `fn main()` must return `()`, do not suggest changing return type
4582 err.span_label(span, "expected `()` because of default return type");
4584 (&hir::FunctionRetTy::Return(ref ty), _, _) => {
4585 // Only point to return type if the expected type is the return type, as if they
4586 // are not, the expectation must have been caused by something else.
4587 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4589 let ty = AstConv::ast_ty_to_ty(self, ty);
4590 debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
4591 debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
4592 if ty.sty == expected.sty {
4593 err.span_label(sp, format!("expected `{}` because of return type",
4601 /// A common error is to add an extra semicolon:
4604 /// fn foo() -> usize {
4609 /// This routine checks if the final statement in a block is an
4610 /// expression with an explicit semicolon whose type is compatible
4611 /// with `expected_ty`. If so, it suggests removing the semicolon.
4612 fn consider_hint_about_removing_semicolon(&self,
4613 blk: &'gcx hir::Block,
4614 expected_ty: Ty<'tcx>,
4615 err: &mut DiagnosticBuilder) {
4616 // Be helpful when the user wrote `{... expr;}` and
4617 // taking the `;` off is enough to fix the error.
4618 let last_stmt = match blk.stmts.last() {
4622 let last_expr = match last_stmt.node {
4623 hir::StmtSemi(ref e, _) => e,
4626 let last_expr_ty = self.node_ty(last_expr.hir_id);
4627 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4630 let original_span = original_sp(last_stmt.span, blk.span);
4631 let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
4632 err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
4635 // Instantiates the given path, which must refer to an item with the given
4636 // number of type parameters and type.
4637 pub fn instantiate_value_path(&self,
4638 segments: &[hir::PathSegment],
4639 opt_self_ty: Option<Ty<'tcx>>,
4642 node_id: ast::NodeId)
4644 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4649 // We need to extract the type parameters supplied by the user in
4650 // the path `path`. Due to the current setup, this is a bit of a
4651 // tricky-process; the problem is that resolve only tells us the
4652 // end-point of the path resolution, and not the intermediate steps.
4653 // Luckily, we can (at least for now) deduce the intermediate steps
4654 // just from the end-point.
4656 // There are basically four cases to consider:
4658 // 1. Reference to a constructor of enum variant or struct:
4660 // struct Foo<T>(...)
4661 // enum E<T> { Foo(...) }
4663 // In these cases, the parameters are declared in the type
4666 // 2. Reference to a fn item or a free constant:
4670 // In this case, the path will again always have the form
4671 // `a::b::foo::<T>` where only the final segment should have
4672 // type parameters. However, in this case, those parameters are
4673 // declared on a value, and hence are in the `FnSpace`.
4675 // 3. Reference to a method or an associated constant:
4677 // impl<A> SomeStruct<A> {
4681 // Here we can have a path like
4682 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4683 // may appear in two places. The penultimate segment,
4684 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4685 // final segment, `foo::<B>` contains parameters in fn space.
4687 // 4. Reference to a local variable
4689 // Local variables can't have any type parameters.
4691 // The first step then is to categorize the segments appropriately.
4693 assert!(!segments.is_empty());
4695 let mut ufcs_associated = None;
4696 let mut type_segment = None;
4697 let mut fn_segment = None;
4699 // Case 1. Reference to a struct/variant constructor.
4700 Def::StructCtor(def_id, ..) |
4701 Def::VariantCtor(def_id, ..) => {
4702 // Everything but the final segment should have no
4703 // parameters at all.
4704 let mut generics = self.tcx.generics_of(def_id);
4705 if let Some(def_id) = generics.parent {
4706 // Variant and struct constructors use the
4707 // generics of their parent type definition.
4708 generics = self.tcx.generics_of(def_id);
4710 type_segment = Some((segments.last().unwrap(), generics));
4713 // Case 2. Reference to a top-level value.
4715 Def::Const(def_id) |
4716 Def::Static(def_id, _) => {
4717 fn_segment = Some((segments.last().unwrap(),
4718 self.tcx.generics_of(def_id)));
4721 // Case 3. Reference to a method or associated const.
4722 Def::Method(def_id) |
4723 Def::AssociatedConst(def_id) => {
4724 let container = self.tcx.associated_item(def_id).container;
4726 ty::TraitContainer(trait_did) => {
4727 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4729 ty::ImplContainer(_) => {}
4732 let generics = self.tcx.generics_of(def_id);
4733 if segments.len() >= 2 {
4734 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4735 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4737 // `<T>::assoc` will end up here, and so can `T::assoc`.
4738 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4739 ufcs_associated = Some((container, self_ty));
4741 fn_segment = Some((segments.last().unwrap(), generics));
4744 // Case 4. Local variable, no generics.
4745 Def::Local(..) | Def::Upvar(..) => {}
4747 _ => bug!("unexpected definition: {:?}", def),
4750 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4752 // Now that we have categorized what space the parameters for each
4753 // segment belong to, let's sort out the parameters that the user
4754 // provided (if any) into their appropriate spaces. We'll also report
4755 // errors if type parameters are provided in an inappropriate place.
4756 let poly_segments = type_segment.is_some() as usize +
4757 fn_segment.is_some() as usize;
4758 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4761 Def::Local(nid) | Def::Upvar(nid, ..) => {
4762 let ty = self.local_ty(span, nid);
4763 let ty = self.normalize_associated_types_in(span, &ty);
4764 self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
4770 // Now we have to compare the types that the user *actually*
4771 // provided against the types that were *expected*. If the user
4772 // did not provide any types, then we want to substitute inference
4773 // variables. If the user provided some types, we may still need
4774 // to add defaults. If the user provided *too many* types, that's
4776 self.check_path_parameter_count(span, &mut type_segment, false);
4777 self.check_path_parameter_count(span, &mut fn_segment, false);
4778 self.check_impl_trait(span, &mut fn_segment);
4780 let (fn_start, has_self) = match (type_segment, fn_segment) {
4781 (_, Some((_, generics))) => {
4782 (generics.parent_count(), generics.has_self)
4784 (Some((_, generics)), None) => {
4785 (generics.own_count(), generics.has_self)
4787 (None, None) => (0, false)
4789 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4790 let mut i = def.index as usize;
4792 let segment = if i < fn_start {
4793 i -= has_self as usize;
4799 let lifetimes = segment.map_or(&[][..], |(s, _)| {
4800 s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
4803 if let Some(lifetime) = lifetimes.get(i) {
4804 AstConv::ast_region_to_region(self, lifetime, Some(def))
4806 self.re_infer(span, Some(def)).unwrap()
4809 let mut i = def.index as usize;
4811 let segment = if i < fn_start {
4812 // Handle Self first, so we can adjust the index to match the AST.
4813 if has_self && i == 0 {
4814 return opt_self_ty.unwrap_or_else(|| {
4815 self.type_var_for_def(ty::UniverseIndex::ROOT, span, def)
4818 i -= has_self as usize;
4824 let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
4825 (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
4828 // Skip over the lifetimes in the same segment.
4829 if let Some((_, generics)) = segment {
4830 i -= generics.regions.len();
4833 if let Some(ast_ty) = types.get(i) {
4834 // A provided type parameter.
4836 } else if !infer_types && def.has_default {
4837 // No type parameter provided, but a default exists.
4838 let default = self.tcx.type_of(def.def_id);
4841 default.subst_spanned(self.tcx, substs, Some(span))
4844 // No type parameters were provided, we can infer all.
4845 // This can also be reached in some error cases:
4846 // We prefer to use inference variables instead of
4847 // TyError to let type inference recover somewhat.
4848 self.type_var_for_def(ty::UniverseIndex::ROOT, span, def)
4852 // The things we are substituting into the type should not contain
4853 // escaping late-bound regions, and nor should the base type scheme.
4854 let ty = self.tcx.type_of(def.def_id());
4855 assert!(!substs.has_escaping_regions());
4856 assert!(!ty.has_escaping_regions());
4858 // Add all the obligations that are required, substituting and
4859 // normalized appropriately.
4860 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4861 self.add_obligations_for_parameters(
4862 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4865 // Substitute the values for the type parameters into the type of
4866 // the referenced item.
4867 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4869 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4870 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4871 // is inherent, there is no `Self` parameter, instead, the impl needs
4872 // type parameters, which we can infer by unifying the provided `Self`
4873 // with the substituted impl type.
4874 let ty = self.tcx.type_of(impl_def_id);
4876 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4877 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4878 Ok(ok) => self.register_infer_ok_obligations(ok),
4881 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4888 self.check_rustc_args_require_const(def.def_id(), node_id, span);
4890 debug!("instantiate_value_path: type of {:?} is {:?}",
4893 self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
4897 fn check_rustc_args_require_const(&self,
4899 node_id: ast::NodeId,
4901 // We're only interested in functions tagged with
4902 // #[rustc_args_required_const], so ignore anything that's not.
4903 if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
4907 // If our calling expression is indeed the function itself, we're good!
4908 // If not, generate an error that this can only be called directly.
4909 match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
4910 Node::NodeExpr(expr) => {
4912 hir::ExprCall(ref callee, ..) => {
4913 if callee.id == node_id {
4923 self.tcx.sess.span_err(span, "this function can only be invoked \
4924 directly, not through a function pointer");
4927 /// Report errors if the provided parameters are too few or too many.
4928 fn check_path_parameter_count(&self,
4930 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
4931 is_method_call: bool) {
4932 let (lifetimes, types, infer_types, bindings) = segment.map_or(
4933 (&[][..], &[][..], true, &[][..]),
4934 |(s, _)| s.parameters.as_ref().map_or(
4935 (&[][..], &[][..], s.infer_types, &[][..]),
4936 |p| (&p.lifetimes[..], &p.types[..],
4937 s.infer_types, &p.bindings[..])));
4938 let infer_lifetimes = lifetimes.len() == 0;
4940 let count_lifetime_params = |n| {
4941 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4943 let count_type_params = |n| {
4944 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4947 // Check provided type parameters.
4948 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4949 if generics.parent.is_none() {
4950 &generics.types[generics.has_self as usize..]
4955 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4956 if types.len() > type_defs.len() {
4957 let span = types[type_defs.len()].span;
4958 let expected_text = count_type_params(type_defs.len());
4959 let actual_text = count_type_params(types.len());
4960 struct_span_err!(self.tcx.sess, span, E0087,
4961 "too many type parameters provided: \
4962 expected at most {}, found {}",
4963 expected_text, actual_text)
4964 .span_label(span, format!("expected {}", expected_text))
4967 // To prevent derived errors to accumulate due to extra
4968 // type parameters, we force instantiate_value_path to
4969 // use inference variables instead of the provided types.
4971 } else if types.len() < required_len && !infer_types {
4972 let expected_text = count_type_params(required_len);
4973 let actual_text = count_type_params(types.len());
4974 struct_span_err!(self.tcx.sess, span, E0089,
4975 "too few type parameters provided: \
4976 expected {}, found {}",
4977 expected_text, actual_text)
4978 .span_label(span, format!("expected {}", expected_text))
4982 if !bindings.is_empty() {
4983 AstConv::prohibit_projection(self, bindings[0].span);
4986 // Check provided lifetime parameters.
4987 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4988 let required_len = lifetime_defs.len();
4990 // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
4991 let has_late_bound_lifetime_defs =
4992 segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
4993 if let (Some(span_late), false) = (has_late_bound_lifetime_defs, lifetimes.is_empty()) {
4994 // Report this as a lint only if no error was reported previously.
4995 let primary_msg = "cannot specify lifetime arguments explicitly \
4996 if late bound lifetime parameters are present";
4997 let note_msg = "the late bound lifetime parameter is introduced here";
4998 if !is_method_call && (lifetimes.len() > lifetime_defs.len() ||
4999 lifetimes.len() < required_len && !infer_lifetimes) {
5000 let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
5001 err.span_note(span_late, note_msg);
5005 let mut multispan = MultiSpan::from_span(lifetimes[0].span);
5006 multispan.push_span_label(span_late, note_msg.to_string());
5007 self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
5008 lifetimes[0].id, multispan, primary_msg);
5013 if lifetimes.len() > lifetime_defs.len() {
5014 let span = lifetimes[lifetime_defs.len()].span;
5015 let expected_text = count_lifetime_params(lifetime_defs.len());
5016 let actual_text = count_lifetime_params(lifetimes.len());
5017 struct_span_err!(self.tcx.sess, span, E0088,
5018 "too many lifetime parameters provided: \
5019 expected at most {}, found {}",
5020 expected_text, actual_text)
5021 .span_label(span, format!("expected {}", expected_text))
5023 } else if lifetimes.len() < required_len && !infer_lifetimes {
5024 let expected_text = count_lifetime_params(lifetime_defs.len());
5025 let actual_text = count_lifetime_params(lifetimes.len());
5026 struct_span_err!(self.tcx.sess, span, E0090,
5027 "too few lifetime parameters provided: \
5028 expected {}, found {}",
5029 expected_text, actual_text)
5030 .span_label(span, format!("expected {}", expected_text))
5035 /// Report error if there is an explicit type parameter when using `impl Trait`.
5036 fn check_impl_trait(&self,
5038 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
5039 use hir::SyntheticTyParamKind::*;
5041 segment.map(|(path_segment, generics)| {
5042 let explicit = !path_segment.infer_types;
5043 let impl_trait = generics.types.iter()
5045 match ty_param.synthetic {
5046 Some(ImplTrait) => true,
5051 if explicit && impl_trait {
5052 let mut err = struct_span_err! {
5056 "cannot provide explicit type parameters when `impl Trait` is \
5057 used in argument position."
5065 // Resolves `typ` by a single level if `typ` is a type variable.
5066 // If no resolution is possible, then an error is reported.
5067 // Numeric inference variables may be left unresolved.
5068 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5069 let ty = self.resolve_type_vars_with_obligations(ty);
5070 if !ty.is_ty_var() {
5073 if !self.is_tainted_by_errors() {
5074 self.need_type_info((**self).body_id, sp, ty);
5076 self.demand_suptype(sp, self.tcx.types.err, ty);
5081 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
5082 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5083 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5086 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5087 index = enclosing_breakables.stack.len();
5088 enclosing_breakables.by_id.insert(id, index);
5089 enclosing_breakables.stack.push(ctxt);
5093 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5094 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5095 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5096 enclosing_breakables.stack.pop().expect("missing breakable context")
5102 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5103 generics: &hir::Generics,
5105 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
5106 generics.ty_params().count(), ty);
5108 // make a vector of booleans initially false, set to true when used
5109 if generics.ty_params().next().is_none() { return; }
5110 let mut tps_used = vec![false; generics.ty_params().count()];
5112 let lifetime_count = generics.lifetimes().count();
5114 for leaf_ty in ty.walk() {
5115 if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty {
5116 debug!("Found use of ty param num {}", idx);
5117 tps_used[idx as usize - lifetime_count] = true;
5118 } else if let ty::TyError = leaf_ty.sty {
5119 // If there already another error, do not emit an error for not using a type Parameter
5120 assert!(tcx.sess.err_count() > 0);
5125 for (&used, param) in tps_used.iter().zip(generics.ty_params()) {
5127 struct_span_err!(tcx.sess, param.span, E0091,
5128 "type parameter `{}` is unused",
5130 .span_label(param.span, "unused type parameter")
5136 fn fatally_break_rust(sess: &Session) {
5137 let handler = sess.diagnostic();
5138 handler.span_bug_no_panic(
5140 "It looks like you're trying to break rust; would you like some ICE?",
5142 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5143 handler.note_without_error(
5144 "we would appreciate a joke overview: \
5145 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5147 handler.note_without_error(&format!("rustc {} running on {}",
5148 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5149 ::session::config::host_triple(),