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};
90 use rustc_back::slice::ref_slice;
91 use namespace::Namespace;
92 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
93 use rustc::infer::type_variable::{TypeVariableOrigin};
94 use rustc::middle::region;
95 use rustc::ty::subst::{Kind, Subst, Substs};
96 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
97 use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
98 use rustc::ty::{self, Ty, TyCtxt, Visibility};
99 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
100 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
101 use rustc::ty::maps::Providers;
102 use rustc::ty::util::{Representability, IntTypeExt};
103 use errors::{DiagnosticBuilder, DiagnosticId};
104 use require_c_abi_if_variadic;
105 use session::{CompileIncomplete, Session};
108 use util::common::{ErrorReported, indenter};
109 use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, NodeMap};
111 use std::cell::{Cell, RefCell, Ref, RefMut};
113 use std::collections::hash_map::Entry;
115 use std::fmt::Display;
116 use std::mem::replace;
117 use std::ops::{self, Deref};
118 use syntax::abi::Abi;
121 use syntax::codemap::{self, original_sp, Spanned};
122 use syntax::feature_gate::{GateIssue, emit_feature_err};
124 use syntax::symbol::{Symbol, InternedString, keywords};
125 use syntax::util::lev_distance::find_best_match_for_name;
126 use syntax_pos::{self, BytePos, Span, MultiSpan};
128 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
129 use rustc::hir::itemlikevisit::ItemLikeVisitor;
130 use rustc::hir::map::Node;
131 use rustc::hir::{self, PatKind};
132 use rustc::middle::lang_items;
133 use rustc_back::slice;
134 use rustc_const_math::ConstInt;
150 mod generator_interior;
154 /// A wrapper for InferCtxt's `in_progress_tables` field.
155 #[derive(Copy, Clone)]
156 struct MaybeInProgressTables<'a, 'tcx: 'a> {
157 maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
160 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
161 fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
162 match self.maybe_tables {
163 Some(tables) => tables.borrow(),
165 bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
170 fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
171 match self.maybe_tables {
172 Some(tables) => tables.borrow_mut(),
174 bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
181 /// closures defined within the function. For example:
184 /// bar(move|| { ... })
187 /// Here, the function `foo()` and the closure passed to
188 /// `bar()` will each have their own `FnCtxt`, but they will
189 /// share the inherited fields.
190 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
191 infcx: InferCtxt<'a, 'gcx, 'tcx>,
193 tables: MaybeInProgressTables<'a, 'tcx>,
195 locals: RefCell<NodeMap<Ty<'tcx>>>,
197 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
199 // When we process a call like `c()` where `c` is a closure type,
200 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
201 // `FnOnce` closure. In that case, we defer full resolution of the
202 // call until upvar inference can kick in and make the
203 // decision. We keep these deferred resolutions grouped by the
204 // def-id of the closure, so that once we decide, we can easily go
205 // back and process them.
206 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
208 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
210 deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
212 // Anonymized types found in explicit return types and their
213 // associated fresh inference variable. Writeback resolves these
214 // variables to get the concrete type, which can be used to
215 // deanonymize TyAnon, after typeck is done with all functions.
216 anon_types: RefCell<DefIdMap<AnonTypeDecl<'tcx>>>,
218 /// Each type parameter has an implicit region bound that
219 /// indicates it must outlive at least the function body (the user
220 /// may specify stronger requirements). This field indicates the
221 /// region of the callee. If it is `None`, then the parameter
222 /// environment is for an item or something where the "callee" is
224 implicit_region_bound: Option<ty::Region<'tcx>>,
226 body_id: Option<hir::BodyId>,
229 /// Information about the anonymous, abstract types whose values we
230 /// are inferring in this function (these are the `impl Trait` that
231 /// appear in the return type).
233 struct AnonTypeDecl<'tcx> {
234 /// The substitutions that we apply to the abstract that that this
235 /// `impl Trait` desugars to. e.g., if:
237 /// fn foo<'a, 'b, T>() -> impl Trait<'a>
239 /// winds up desugared to:
241 /// abstract type Foo<'x, T>: Trait<'x>
242 /// fn foo<'a, 'b, T>() -> Foo<'a, T>
244 /// then `substs` would be `['a, T]`.
245 substs: &'tcx Substs<'tcx>,
247 /// The type variable that represents the value of the abstract type
248 /// that we require. In other words, after we compile this function,
249 /// we will be created a constraint like:
253 /// where `?C` is the value of this type variable. =) It may
254 /// naturally refer to the type and lifetime parameters in scope
255 /// in this function, though ultimately it should only reference
256 /// those that are arguments to `Foo` in the constraint above. (In
257 /// other words, `?C` should not include `'b`, even though it's a
258 /// lifetime parameter on `foo`.)
259 concrete_ty: Ty<'tcx>,
261 /// A list of all required region bounds on the impl Trait type,
262 /// e.g. `'a` and `'b` in `fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b`.
263 required_region_bounds: Vec<ty::Region<'tcx>>,
266 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
267 type Target = InferCtxt<'a, 'gcx, 'tcx>;
268 fn deref(&self) -> &Self::Target {
273 /// When type-checking an expression, we propagate downward
274 /// whatever type hint we are able in the form of an `Expectation`.
275 #[derive(Copy, Clone, Debug)]
276 pub enum Expectation<'tcx> {
277 /// We know nothing about what type this expression should have.
280 /// This expression is an `if` condition, it must resolve to `bool`.
283 /// This expression should have the type given (or some subtype)
284 ExpectHasType(Ty<'tcx>),
286 /// This expression will be cast to the `Ty`
287 ExpectCastableToType(Ty<'tcx>),
289 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
290 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
291 ExpectRvalueLikeUnsized(Ty<'tcx>),
294 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
295 // Disregard "castable to" expectations because they
296 // can lead us astray. Consider for example `if cond
297 // {22} else {c} as u8` -- if we propagate the
298 // "castable to u8" constraint to 22, it will pick the
299 // type 22u8, which is overly constrained (c might not
300 // be a u8). In effect, the problem is that the
301 // "castable to" expectation is not the tightest thing
302 // we can say, so we want to drop it in this case.
303 // The tightest thing we can say is "must unify with
304 // else branch". Note that in the case of a "has type"
305 // constraint, this limitation does not hold.
307 // If the expected type is just a type variable, then don't use
308 // an expected type. Otherwise, we might write parts of the type
309 // when checking the 'then' block which are incompatible with the
311 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
313 ExpectHasType(ety) => {
314 let ety = fcx.shallow_resolve(ety);
315 if !ety.is_ty_var() {
321 ExpectRvalueLikeUnsized(ety) => {
322 ExpectRvalueLikeUnsized(ety)
328 /// Provide an expectation for an rvalue expression given an *optional*
329 /// hint, which is not required for type safety (the resulting type might
330 /// be checked higher up, as is the case with `&expr` and `box expr`), but
331 /// is useful in determining the concrete type.
333 /// The primary use case is where the expected type is a fat pointer,
334 /// like `&[isize]`. For example, consider the following statement:
336 /// let x: &[isize] = &[1, 2, 3];
338 /// In this case, the expected type for the `&[1, 2, 3]` expression is
339 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
340 /// expectation `ExpectHasType([isize])`, that would be too strong --
341 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
342 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
343 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
344 /// which still is useful, because it informs integer literals and the like.
345 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
346 /// for examples of where this comes up,.
347 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
348 match fcx.tcx.struct_tail(ty).sty {
349 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
350 ExpectRvalueLikeUnsized(ty)
352 _ => ExpectHasType(ty)
356 // Resolves `expected` by a single level if it is a variable. If
357 // there is no expected type or resolution is not possible (e.g.,
358 // no constraints yet present), just returns `None`.
359 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
361 NoExpectation => NoExpectation,
362 ExpectIfCondition => ExpectIfCondition,
363 ExpectCastableToType(t) => {
364 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
366 ExpectHasType(t) => {
367 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
369 ExpectRvalueLikeUnsized(t) => {
370 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
375 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
376 match self.resolve(fcx) {
377 NoExpectation => None,
378 ExpectIfCondition => Some(fcx.tcx.types.bool),
379 ExpectCastableToType(ty) |
381 ExpectRvalueLikeUnsized(ty) => Some(ty),
385 /// It sometimes happens that we want to turn an expectation into
386 /// a **hard constraint** (i.e., something that must be satisfied
387 /// for the program to type-check). `only_has_type` will return
388 /// such a constraint, if it exists.
389 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
390 match self.resolve(fcx) {
391 ExpectHasType(ty) => Some(ty),
392 ExpectIfCondition => Some(fcx.tcx.types.bool),
393 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
397 /// Like `only_has_type`, but instead of returning `None` if no
398 /// hard constraint exists, creates a fresh type variable.
399 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
400 self.only_has_type(fcx)
401 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
405 #[derive(Copy, Clone)]
406 pub struct UnsafetyState {
407 pub def: ast::NodeId,
408 pub unsafety: hir::Unsafety,
409 pub unsafe_push_count: u32,
414 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
415 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
418 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
419 match self.unsafety {
420 // If this unsafe, then if the outer function was already marked as
421 // unsafe we shouldn't attribute the unsafe'ness to the block. This
422 // way the block can be warned about instead of ignoring this
423 // extraneous block (functions are never warned about).
424 hir::Unsafety::Unsafe if self.from_fn => *self,
427 let (unsafety, def, count) = match blk.rules {
428 hir::PushUnsafeBlock(..) =>
429 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
430 hir::PopUnsafeBlock(..) =>
431 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
432 hir::UnsafeBlock(..) =>
433 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
435 (unsafety, self.def, self.unsafe_push_count),
439 unsafe_push_count: count,
446 #[derive(Debug, Copy, Clone)]
452 /// Tracks whether executing a node may exit normally (versus
453 /// return/break/panic, which "diverge", leaving dead code in their
454 /// wake). Tracked semi-automatically (through type variables marked
455 /// as diverging), with some manual adjustments for control-flow
456 /// primitives (approximating a CFG).
457 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
459 /// Potentially unknown, some cases converge,
460 /// others require a CFG to determine them.
463 /// Definitely known to diverge and therefore
464 /// not reach the next sibling or its parent.
467 /// Same as `Always` but with a reachability
468 /// warning already emitted
472 // Convenience impls for combinig `Diverges`.
474 impl ops::BitAnd for Diverges {
476 fn bitand(self, other: Self) -> Self {
477 cmp::min(self, other)
481 impl ops::BitOr for Diverges {
483 fn bitor(self, other: Self) -> Self {
484 cmp::max(self, other)
488 impl ops::BitAndAssign for Diverges {
489 fn bitand_assign(&mut self, other: Self) {
490 *self = *self & other;
494 impl ops::BitOrAssign for Diverges {
495 fn bitor_assign(&mut self, other: Self) {
496 *self = *self | other;
501 fn always(self) -> bool {
502 self >= Diverges::Always
506 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
509 // this is `null` for loops where break with a value is illegal,
510 // such as `while`, `for`, and `while let`
511 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
514 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
515 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
516 by_id: NodeMap<usize>,
519 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
520 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
521 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
522 bug!("could not find enclosing breakable with id {}", target_id);
528 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
529 body_id: ast::NodeId,
531 /// The parameter environment used for proving trait obligations
532 /// in this function. This can change when we descend into
533 /// closures (as they bring new things into scope), hence it is
534 /// not part of `Inherited` (as of the time of this writing,
535 /// closures do not yet change the environment, but they will
537 param_env: ty::ParamEnv<'tcx>,
539 // Number of errors that had been reported when we started
540 // checking this function. On exit, if we find that *more* errors
541 // have been reported, we will skip regionck and other work that
542 // expects the types within the function to be consistent.
543 err_count_on_creation: usize,
545 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
547 yield_ty: Option<Ty<'tcx>>,
549 ps: RefCell<UnsafetyState>,
551 /// Whether the last checked node generates a divergence (e.g.,
552 /// `return` will set this to Always). In general, when entering
553 /// an expression or other node in the tree, the initial value
554 /// indicates whether prior parts of the containing expression may
555 /// have diverged. It is then typically set to `Maybe` (and the
556 /// old value remembered) for processing the subparts of the
557 /// current expression. As each subpart is processed, they may set
558 /// the flag to `Always` etc. Finally, at the end, we take the
559 /// result and "union" it with the original value, so that when we
560 /// return the flag indicates if any subpart of the the parent
561 /// expression (up to and including this part) has diverged. So,
562 /// if you read it after evaluating a subexpression `X`, the value
563 /// you get indicates whether any subexpression that was
564 /// evaluating up to and including `X` diverged.
566 /// We use this flag for two purposes:
568 /// - To warn about unreachable code: if, after processing a
569 /// sub-expression but before we have applied the effects of the
570 /// current node, we see that the flag is set to `Always`, we
571 /// can issue a warning. This corresponds to something like
572 /// `foo(return)`; we warn on the `foo()` expression. (We then
573 /// update the flag to `WarnedAlways` to suppress duplicate
574 /// reports.) Similarly, if we traverse to a fresh statement (or
575 /// tail expression) from a `Always` setting, we will issue a
576 /// warning. This corresponds to something like `{return;
577 /// foo();}` or `{return; 22}`, where we would warn on the
580 /// - To permit assignment into a local variable or other lvalue
581 /// (including the "return slot") of type `!`. This is allowed
582 /// if **either** the type of value being assigned is `!`, which
583 /// means the current code is dead, **or** the expression's
584 /// diverging flag is true, which means that a diverging value was
585 /// wrapped (e.g., `let x: ! = foo(return)`).
587 /// To repeat the last point: an expression represents dead-code
588 /// if, after checking it, **either** its type is `!` OR the
589 /// diverges flag is set to something other than `Maybe`.
590 diverges: Cell<Diverges>,
592 /// Whether any child nodes have any type errors.
593 has_errors: Cell<bool>,
595 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
597 inh: &'a Inherited<'a, 'gcx, 'tcx>,
600 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
601 type Target = Inherited<'a, 'gcx, 'tcx>;
602 fn deref(&self) -> &Self::Target {
607 /// Helper type of a temporary returned by Inherited::build(...).
608 /// Necessary because we can't write the following bound:
609 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
610 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
611 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
615 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
616 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
617 -> InheritedBuilder<'a, 'gcx, 'tcx> {
618 let hir_id_root = if def_id.is_local() {
619 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
620 let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
621 DefId::local(hir_id.owner)
627 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
633 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
634 fn enter<F, R>(&'tcx mut self, f: F) -> R
635 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
637 let def_id = self.def_id;
638 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
642 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
643 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
645 let item_id = tcx.hir.as_local_node_id(def_id);
646 let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
647 let implicit_region_bound = body_id.map(|body_id| {
648 let body = tcx.hir.body(body_id);
649 tcx.mk_region(ty::ReScope(region::Scope::CallSite(body.value.hir_id.local_id)))
653 tables: MaybeInProgressTables {
654 maybe_tables: infcx.in_progress_tables,
657 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
658 locals: RefCell::new(NodeMap()),
659 deferred_call_resolutions: RefCell::new(DefIdMap()),
660 deferred_cast_checks: RefCell::new(Vec::new()),
661 deferred_generator_interiors: RefCell::new(Vec::new()),
662 anon_types: RefCell::new(DefIdMap()),
663 implicit_region_bound,
668 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
669 debug!("register_predicate({:?})", obligation);
670 if obligation.has_escaping_regions() {
671 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
676 .register_predicate_obligation(self, obligation);
679 fn register_predicates<I>(&self, obligations: I)
680 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>> {
681 for obligation in obligations {
682 self.register_predicate(obligation);
686 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
687 self.register_predicates(infer_ok.obligations);
691 fn normalize_associated_types_in<T>(&self,
693 body_id: ast::NodeId,
694 param_env: ty::ParamEnv<'tcx>,
696 where T : TypeFoldable<'tcx>
698 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
699 self.register_infer_ok_obligations(ok)
702 /// Replace any late-bound regions bound in `value` with
703 /// free variants attached to `all_outlive_scope`.
704 fn liberate_late_bound_regions<T>(&self,
705 all_outlive_scope: DefId,
706 value: &ty::Binder<T>)
708 where T: TypeFoldable<'tcx>
710 self.tcx.replace_late_bound_regions(value, |br| {
711 self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
712 scope: all_outlive_scope,
719 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
721 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
722 fn visit_item(&mut self, i: &'tcx hir::Item) {
723 check_item_type(self.tcx, i);
725 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
726 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
729 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
730 tcx.sess.track_errors(|| {
731 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
732 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
736 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
737 tcx.sess.track_errors(|| {
738 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
742 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
743 tcx.typeck_item_bodies(LOCAL_CRATE)
746 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
747 -> Result<(), CompileIncomplete>
749 debug_assert!(crate_num == LOCAL_CRATE);
750 Ok(tcx.sess.track_errors(|| {
751 for body_owner_def_id in tcx.body_owners() {
752 ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
757 pub fn provide(providers: &mut Providers) {
758 *providers = Providers {
770 fn generator_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
772 -> Option<ty::PolyGenSig<'tcx>> {
773 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
774 let hir_id = tcx.hir.node_to_hir_id(node_id);
775 tcx.typeck_tables_of(def_id).generator_sigs()[hir_id].map(|s| ty::Binder(s))
778 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
781 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
782 let hir_id = tcx.hir.node_to_hir_id(node_id);
783 tcx.typeck_tables_of(def_id).closure_kinds()[hir_id].0
786 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
788 -> Option<ty::Destructor> {
789 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
792 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
793 /// with information about it's body-id and fn-decl (if any). Otherwise,
796 /// If this function returns "some", then `typeck_tables(def_id)` will
797 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
798 /// may not succeed. In some cases where this function returns `None`
799 /// (notably closures), `typeck_tables(def_id)` would wind up
800 /// redirecting to the owning function.
801 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
803 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
805 match tcx.hir.get(id) {
806 hir::map::NodeItem(item) => {
808 hir::ItemConst(_, body) |
809 hir::ItemStatic(_, _, body) =>
811 hir::ItemFn(ref decl, .., body) =>
812 Some((body, Some(decl))),
817 hir::map::NodeTraitItem(item) => {
819 hir::TraitItemKind::Const(_, Some(body)) =>
821 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
822 Some((body, Some(&sig.decl))),
827 hir::map::NodeImplItem(item) => {
829 hir::ImplItemKind::Const(_, body) =>
831 hir::ImplItemKind::Method(ref sig, body) =>
832 Some((body, Some(&sig.decl))),
837 hir::map::NodeExpr(expr) => {
838 // FIXME(eddyb) Closures should have separate
839 // function definition IDs and expression IDs.
840 // Type-checking should not let closures get
841 // this far in a constant position.
842 // Assume that everything other than closures
843 // is a constant "initializer" expression.
845 hir::ExprClosure(..) =>
848 Some((hir::BodyId { node_id: expr.id }, None)),
855 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
858 // Closures' tables come from their outermost function,
859 // as they are part of the same "inference environment".
860 let outer_def_id = tcx.closure_base_def_id(def_id);
861 if outer_def_id != def_id {
862 return tcx.has_typeck_tables(outer_def_id);
865 let id = tcx.hir.as_local_node_id(def_id).unwrap();
866 primary_body_of(tcx, id).is_some()
869 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
872 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
875 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
877 -> &'tcx ty::TypeckTables<'tcx> {
878 // Closures' tables come from their outermost function,
879 // as they are part of the same "inference environment".
880 let outer_def_id = tcx.closure_base_def_id(def_id);
881 if outer_def_id != def_id {
882 return tcx.typeck_tables_of(outer_def_id);
885 let id = tcx.hir.as_local_node_id(def_id).unwrap();
886 let span = tcx.hir.span(id);
888 // Figure out what primary body this item has.
889 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
890 span_bug!(span, "can't type-check body of {:?}", def_id);
892 let body = tcx.hir.body(body_id);
894 let tables = Inherited::build(tcx, def_id).enter(|inh| {
895 let param_env = tcx.param_env(def_id);
896 let fcx = if let Some(decl) = fn_decl {
897 let fn_sig = tcx.fn_sig(def_id);
899 check_abi(tcx, span, fn_sig.abi());
901 // Compute the fty from point of view of inside fn.
903 inh.liberate_late_bound_regions(def_id, &fn_sig);
905 inh.normalize_associated_types_in(body.value.span,
910 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, false).0;
911 // Ensure anon_types have been instantiated prior to entering regionck
912 fcx.instantiate_anon_types(&fn_sig.output());
915 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
916 let expected_type = tcx.type_of(def_id);
917 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
918 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
920 // Gather locals in statics (because of block expressions).
921 // This is technically unnecessary because locals in static items are forbidden,
922 // but prevents type checking from blowing up before const checking can properly
924 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
926 fcx.check_expr_coercable_to_type(&body.value, expected_type);
931 fcx.select_all_obligations_and_apply_defaults();
932 fcx.closure_analyze(body);
933 fcx.select_obligations_where_possible();
935 fcx.resolve_generator_interiors(def_id);
936 fcx.select_all_obligations_or_error();
938 if fn_decl.is_some() {
939 fcx.regionck_fn(id, body);
941 fcx.regionck_expr(body);
944 fcx.resolve_type_vars_in_body(body)
947 // Consistency check our TypeckTables instance can hold all ItemLocalIds
948 // it will need to hold.
949 assert_eq!(tables.local_id_root,
950 Some(DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner)));
954 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
955 if !tcx.sess.target.target.is_abi_supported(abi) {
956 struct_span_err!(tcx.sess, span, E0570,
957 "The ABI `{}` is not supported for the current target", abi).emit()
961 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
962 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
965 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
966 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
969 // infer the variable's type
970 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
971 self.fcx.locals.borrow_mut().insert(nid, var_ty);
975 // take type that the user specified
976 self.fcx.locals.borrow_mut().insert(nid, typ);
983 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
984 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
985 NestedVisitorMap::None
988 // Add explicitly-declared locals.
989 fn visit_local(&mut self, local: &'gcx hir::Local) {
990 let o_ty = match local.ty {
991 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
994 self.assign(local.span, local.id, o_ty);
995 debug!("Local variable {:?} is assigned type {}",
997 self.fcx.ty_to_string(
998 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
999 intravisit::walk_local(self, local);
1002 // Add pattern bindings.
1003 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
1004 if let PatKind::Binding(_, _, ref path1, _) = p.node {
1005 let var_ty = self.assign(p.span, p.id, None);
1007 self.fcx.require_type_is_sized(var_ty, p.span,
1008 traits::VariableType(p.id));
1010 debug!("Pattern binding {} is assigned to {} with type {:?}",
1012 self.fcx.ty_to_string(
1013 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
1016 intravisit::walk_pat(self, p);
1019 // Don't descend into the bodies of nested closures
1020 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
1021 _: hir::BodyId, _: Span, _: ast::NodeId) { }
1024 /// Helper used for fns and closures. Does the grungy work of checking a function
1025 /// body and returns the function context used for that purpose, since in the case of a fn item
1026 /// there is still a bit more to do.
1029 /// * inherited: other fields inherited from the enclosing fn (if any)
1030 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1031 param_env: ty::ParamEnv<'tcx>,
1032 fn_sig: ty::FnSig<'tcx>,
1033 decl: &'gcx hir::FnDecl,
1035 body: &'gcx hir::Body,
1036 can_be_generator: bool)
1037 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<ty::GeneratorInterior<'tcx>>)
1039 let mut fn_sig = fn_sig.clone();
1041 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1043 // Create the function context. This is either derived from scratch or,
1044 // in the case of function expressions, based on the outer context.
1045 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
1046 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1048 let ret_ty = fn_sig.output();
1049 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType);
1050 let ret_ty = fcx.instantiate_anon_types(&ret_ty);
1051 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
1052 fn_sig = fcx.tcx.mk_fn_sig(
1053 fn_sig.inputs().iter().cloned(),
1060 let span = body.value.span;
1062 if body.is_generator && can_be_generator {
1063 fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
1066 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
1068 // Add formal parameters.
1069 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1070 // Check the pattern.
1071 fcx.check_pat_walk(&arg.pat, arg_ty,
1072 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
1074 // Check that argument is Sized.
1075 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1076 // for simple cases like `fn foo(x: Trait)`,
1077 // where we would error once on the parameter as a whole, and once on the binding `x`.
1078 if arg.pat.simple_name().is_none() {
1079 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
1082 fcx.write_ty(arg.hir_id, arg_ty);
1085 let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
1086 let gen_ty = if can_be_generator && body.is_generator {
1087 let gen_sig = ty::GenSig {
1088 yield_ty: fcx.yield_ty.unwrap(),
1091 inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, Some(gen_sig));
1093 let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
1094 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), witness));
1095 let interior = ty::GeneratorInterior::new(witness);
1097 inherited.tables.borrow_mut().generator_interiors_mut().insert(fn_hir_id, interior);
1101 inherited.tables.borrow_mut().generator_sigs_mut().insert(fn_hir_id, None);
1104 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
1106 fcx.check_return_expr(&body.value);
1108 // Finalize the return check by taking the LUB of the return types
1109 // we saw and assigning it to the expected return type. This isn't
1110 // really expected to fail, since the coercions would have failed
1111 // earlier when trying to find a LUB.
1113 // However, the behavior around `!` is sort of complex. In the
1114 // event that the `actual_return_ty` comes back as `!`, that
1115 // indicates that the fn either does not return or "returns" only
1116 // values of type `!`. In this case, if there is an expected
1117 // return type that is *not* `!`, that should be ok. But if the
1118 // return type is being inferred, we want to "fallback" to `!`:
1120 // let x = move || panic!();
1122 // To allow for that, I am creating a type variable with diverging
1123 // fallback. This was deemed ever so slightly better than unifying
1124 // the return value with `!` because it allows for the caller to
1125 // make more assumptions about the return type (e.g., they could do
1127 // let y: Option<u32> = Some(x());
1129 // which would then cause this return type to become `u32`, not
1131 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1132 let mut actual_return_ty = coercion.complete(&fcx);
1133 if actual_return_ty.is_never() {
1134 actual_return_ty = fcx.next_diverging_ty_var(
1135 TypeVariableOrigin::DivergingFn(span));
1137 fcx.demand_suptype(span, ret_ty, actual_return_ty);
1142 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1145 let def_id = tcx.hir.local_def_id(id);
1146 let def = tcx.adt_def(def_id);
1147 def.destructor(tcx); // force the destructor to be evaluated
1148 check_representable(tcx, span, def_id);
1150 if def.repr.simd() {
1151 check_simd(tcx, span, def_id);
1154 check_packed(tcx, span, def_id);
1157 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1160 let def_id = tcx.hir.local_def_id(id);
1161 let def = tcx.adt_def(def_id);
1162 def.destructor(tcx); // force the destructor to be evaluated
1163 check_representable(tcx, span, def_id);
1165 check_packed(tcx, span, def_id);
1168 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1169 debug!("check_item_type(it.id={}, it.name={})",
1171 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
1172 let _indenter = indenter();
1174 // Consts can play a role in type-checking, so they are included here.
1175 hir::ItemStatic(..) |
1176 hir::ItemConst(..) => {
1177 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1179 hir::ItemEnum(ref enum_definition, _) => {
1182 &enum_definition.variants,
1185 hir::ItemFn(..) => {} // entirely within check_item_body
1186 hir::ItemImpl(.., ref impl_item_refs) => {
1187 debug!("ItemImpl {} with id {}", it.name, it.id);
1188 let impl_def_id = tcx.hir.local_def_id(it.id);
1189 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1190 check_impl_items_against_trait(tcx,
1195 let trait_def_id = impl_trait_ref.def_id;
1196 check_on_unimplemented(tcx, trait_def_id, it);
1199 hir::ItemTrait(..) => {
1200 let def_id = tcx.hir.local_def_id(it.id);
1201 check_on_unimplemented(tcx, def_id, it);
1203 hir::ItemStruct(..) => {
1204 check_struct(tcx, it.id, it.span);
1206 hir::ItemUnion(..) => {
1207 check_union(tcx, it.id, it.span);
1209 hir::ItemTy(_, ref generics) => {
1210 let def_id = tcx.hir.local_def_id(it.id);
1211 let pty_ty = tcx.type_of(def_id);
1212 check_bounds_are_used(tcx, generics, pty_ty);
1214 hir::ItemForeignMod(ref m) => {
1215 check_abi(tcx, it.span, m.abi);
1217 if m.abi == Abi::RustIntrinsic {
1218 for item in &m.items {
1219 intrinsic::check_intrinsic_type(tcx, item);
1221 } else if m.abi == Abi::PlatformIntrinsic {
1222 for item in &m.items {
1223 intrinsic::check_platform_intrinsic_type(tcx, item);
1226 for item in &m.items {
1227 let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
1228 if !generics.types.is_empty() {
1229 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1230 "foreign items may not have type parameters");
1231 span_help!(&mut err, item.span,
1232 "consider using specialization instead of \
1237 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1238 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1243 _ => {/* nothing to do */ }
1247 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1248 trait_def_id: DefId,
1250 let item_def_id = tcx.hir.local_def_id(item.id);
1251 // an error would be reported if this fails.
1252 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1255 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1256 impl_item: &hir::ImplItem,
1259 let mut err = struct_span_err!(
1260 tcx.sess, impl_item.span, E0520,
1261 "`{}` specializes an item from a parent `impl`, but \
1262 that item is not marked `default`",
1264 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1267 match tcx.span_of_impl(parent_impl) {
1269 err.span_label(span, "parent `impl` is here");
1270 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1274 err.note(&format!("parent implementation is in crate `{}`", cname));
1281 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1282 trait_def: &ty::TraitDef,
1283 trait_item: &ty::AssociatedItem,
1285 impl_item: &hir::ImplItem)
1287 let ancestors = trait_def.ancestors(tcx, impl_id);
1289 let kind = match impl_item.node {
1290 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1291 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1292 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1295 let parent = ancestors.defs(tcx, trait_item.name, kind, trait_def.def_id).skip(1).next()
1296 .map(|node_item| node_item.map(|parent| parent.defaultness));
1298 if let Some(parent) = parent {
1299 if tcx.impl_item_is_final(&parent) {
1300 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1306 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1309 impl_trait_ref: ty::TraitRef<'tcx>,
1310 impl_item_refs: &[hir::ImplItemRef]) {
1311 // If the trait reference itself is erroneous (so the compilation is going
1312 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1313 // isn't populated for such impls.
1314 if impl_trait_ref.references_error() { return; }
1316 // Locate trait definition and items
1317 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1318 let mut overridden_associated_type = None;
1320 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1322 // Check existing impl methods to see if they are both present in trait
1323 // and compatible with trait signature
1324 for impl_item in impl_items() {
1325 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1326 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1327 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1328 tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1330 // Not compatible, but needed for the error message
1331 tcx.associated_items(impl_trait_ref.def_id)
1332 .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1335 // Check that impl definition matches trait definition
1336 if let Some(ty_trait_item) = ty_trait_item {
1337 match impl_item.node {
1338 hir::ImplItemKind::Const(..) => {
1339 // Find associated const definition.
1340 if ty_trait_item.kind == ty::AssociatedKind::Const {
1341 compare_const_impl(tcx,
1347 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1348 "item `{}` is an associated const, \
1349 which doesn't match its trait `{}`",
1352 err.span_label(impl_item.span, "does not match trait");
1353 // We can only get the spans from local trait definition
1354 // Same for E0324 and E0325
1355 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1356 err.span_label(trait_span, "item in trait");
1361 hir::ImplItemKind::Method(..) => {
1362 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1363 if ty_trait_item.kind == ty::AssociatedKind::Method {
1364 compare_impl_method(tcx,
1371 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1372 "item `{}` is an associated method, \
1373 which doesn't match its trait `{}`",
1376 err.span_label(impl_item.span, "does not match trait");
1377 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1378 err.span_label(trait_span, "item in trait");
1383 hir::ImplItemKind::Type(_) => {
1384 if ty_trait_item.kind == ty::AssociatedKind::Type {
1385 if ty_trait_item.defaultness.has_value() {
1386 overridden_associated_type = Some(impl_item);
1389 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1390 "item `{}` is an associated type, \
1391 which doesn't match its trait `{}`",
1394 err.span_label(impl_item.span, "does not match trait");
1395 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1396 err.span_label(trait_span, "item in trait");
1403 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1407 // Check for missing items from trait
1408 let mut missing_items = Vec::new();
1409 let mut invalidated_items = Vec::new();
1410 let associated_type_overridden = overridden_associated_type.is_some();
1411 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1412 let is_implemented = trait_def.ancestors(tcx, impl_id)
1413 .defs(tcx, trait_item.name, trait_item.kind, impl_trait_ref.def_id)
1415 .map(|node_item| !node_item.node.is_from_trait())
1418 if !is_implemented {
1419 if !trait_item.defaultness.has_value() {
1420 missing_items.push(trait_item);
1421 } else if associated_type_overridden {
1422 invalidated_items.push(trait_item.name);
1427 if !missing_items.is_empty() {
1428 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1429 "not all trait items implemented, missing: `{}`",
1430 missing_items.iter()
1431 .map(|trait_item| trait_item.name.to_string())
1432 .collect::<Vec<_>>().join("`, `"));
1433 err.span_label(impl_span, format!("missing `{}` in implementation",
1434 missing_items.iter()
1435 .map(|trait_item| trait_item.name.to_string())
1436 .collect::<Vec<_>>().join("`, `")));
1437 for trait_item in missing_items {
1438 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1439 err.span_label(span, format!("`{}` from trait", trait_item.name));
1441 err.note_trait_signature(trait_item.name.to_string(),
1442 trait_item.signature(&tcx));
1448 if !invalidated_items.is_empty() {
1449 let invalidator = overridden_associated_type.unwrap();
1450 span_err!(tcx.sess, invalidator.span, E0399,
1451 "the following trait items need to be reimplemented \
1452 as `{}` was overridden: `{}`",
1454 invalidated_items.iter()
1455 .map(|name| name.to_string())
1456 .collect::<Vec<_>>().join("`, `"))
1460 /// Checks whether a type can be represented in memory. In particular, it
1461 /// identifies types that contain themselves without indirection through a
1462 /// pointer, which would mean their size is unbounded.
1463 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1467 let rty = tcx.type_of(item_def_id);
1469 // Check that it is possible to represent this type. This call identifies
1470 // (1) types that contain themselves and (2) types that contain a different
1471 // recursive type. It is only necessary to throw an error on those that
1472 // contain themselves. For case 2, there must be an inner type that will be
1473 // caught by case 1.
1474 match rty.is_representable(tcx, sp) {
1475 Representability::SelfRecursive(spans) => {
1476 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1478 err.span_label(span, "recursive without indirection");
1483 Representability::Representable | Representability::ContainsRecursive => (),
1488 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1489 let t = tcx.type_of(def_id);
1491 ty::TyAdt(def, substs) if def.is_struct() => {
1492 let fields = &def.struct_variant().fields;
1493 if fields.is_empty() {
1494 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1497 let e = fields[0].ty(tcx, substs);
1498 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1499 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1500 .span_label(sp, "SIMD elements must have the same type")
1505 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1506 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1508 span_err!(tcx.sess, sp, E0077,
1509 "SIMD vector element type should be machine type");
1518 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1519 if tcx.adt_def(def_id).repr.packed() {
1520 if tcx.adt_def(def_id).repr.align > 0 {
1521 struct_span_err!(tcx.sess, sp, E0587,
1522 "type has conflicting packed and align representation hints").emit();
1524 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1525 struct_span_err!(tcx.sess, sp, E0588,
1526 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1531 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1533 stack: &mut Vec<DefId>) -> bool {
1534 let t = tcx.type_of(def_id);
1535 if stack.contains(&def_id) {
1536 debug!("check_packed_inner: {:?} is recursive", t);
1540 ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
1541 if tcx.adt_def(def.did).repr.align > 0 {
1544 // push struct def_id before checking fields
1546 for field in &def.struct_variant().fields {
1547 let f = field.ty(tcx, substs);
1549 ty::TyAdt(def, _) => {
1550 if check_packed_inner(tcx, def.did, stack) {
1557 // only need to pop if not early out
1565 #[allow(trivial_numeric_casts)]
1566 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1568 vs: &'tcx [hir::Variant],
1570 let def_id = tcx.hir.local_def_id(id);
1571 let def = tcx.adt_def(def_id);
1572 def.destructor(tcx); // force the destructor to be evaluated
1575 let attributes = tcx.get_attrs(def_id);
1576 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1578 tcx.sess, attr.span, E0084,
1579 "unsupported representation for zero-variant enum")
1580 .span_label(sp, "zero-variant enum")
1585 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1586 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1587 if !tcx.sess.features.borrow().repr128 {
1588 emit_feature_err(&tcx.sess.parse_sess,
1591 GateIssue::Language,
1592 "repr with 128-bit type is unstable");
1597 if let Some(e) = v.node.disr_expr {
1598 tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
1602 let mut disr_vals: Vec<ConstInt> = Vec::new();
1603 for (discr, v) in def.discriminants(tcx).zip(vs) {
1604 // Check for duplicate discriminant values
1605 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1606 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1607 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1608 let i_span = match variant_i.node.disr_expr {
1609 Some(expr) => tcx.hir.span(expr.node_id),
1610 None => tcx.hir.span(variant_i_node_id)
1612 let span = match v.node.disr_expr {
1613 Some(expr) => tcx.hir.span(expr.node_id),
1616 struct_span_err!(tcx.sess, span, E0081,
1617 "discriminant value `{}` already exists", disr_vals[i])
1618 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1619 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1622 disr_vals.push(discr);
1625 check_representable(tcx, sp, def_id);
1628 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1629 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1631 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1632 -> ty::GenericPredicates<'tcx>
1635 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1636 let item_id = tcx.hir.ty_param_owner(node_id);
1637 let item_def_id = tcx.hir.local_def_id(item_id);
1638 let generics = tcx.generics_of(item_def_id);
1639 let index = generics.type_param_to_index[&def_id.index];
1640 ty::GenericPredicates {
1642 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1644 ty::Predicate::Trait(ref data) => {
1645 data.0.self_ty().is_param(index)
1649 }).cloned().collect()
1653 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1654 -> Option<ty::Region<'tcx>> {
1656 Some(def) => infer::EarlyBoundRegion(span, def.name),
1657 None => infer::MiscVariable(span)
1659 Some(self.next_region_var(v))
1662 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1663 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1666 fn ty_infer_for_def(&self,
1667 ty_param_def: &ty::TypeParameterDef,
1668 substs: &[Kind<'tcx>],
1669 span: Span) -> Ty<'tcx> {
1670 self.type_var_for_def(span, ty_param_def, substs)
1673 fn projected_ty_from_poly_trait_ref(&self,
1676 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1679 let (trait_ref, _) =
1680 self.replace_late_bound_regions_with_fresh_var(
1682 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1685 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1688 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1689 if ty.has_escaping_regions() {
1690 ty // FIXME: normalization and escaping regions
1692 self.normalize_associated_types_in(span, &ty)
1696 fn set_tainted_by_errors(&self) {
1697 self.infcx.set_tainted_by_errors()
1700 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1701 self.write_ty(hir_id, ty)
1705 /// Controls whether the arguments are tupled. This is used for the call
1708 /// Tupling means that all call-side arguments are packed into a tuple and
1709 /// passed as a single parameter. For example, if tupling is enabled, this
1712 /// fn f(x: (isize, isize))
1714 /// Can be called as:
1721 #[derive(Clone, Eq, PartialEq)]
1722 enum TupleArgumentsFlag {
1727 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1728 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1729 param_env: ty::ParamEnv<'tcx>,
1730 body_id: ast::NodeId)
1731 -> FnCtxt<'a, 'gcx, 'tcx> {
1735 err_count_on_creation: inh.tcx.sess.err_count(),
1738 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1739 ast::CRATE_NODE_ID)),
1740 diverges: Cell::new(Diverges::Maybe),
1741 has_errors: Cell::new(false),
1742 enclosing_breakables: RefCell::new(EnclosingBreakables {
1750 pub fn sess(&self) -> &Session {
1754 pub fn err_count_since_creation(&self) -> usize {
1755 self.tcx.sess.err_count() - self.err_count_on_creation
1758 /// Produce warning on the given node, if the current point in the
1759 /// function is unreachable, and there hasn't been another warning.
1760 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1761 if self.diverges.get() == Diverges::Always {
1762 self.diverges.set(Diverges::WarnedAlways);
1764 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1766 self.tcx().lint_node(
1767 lint::builtin::UNREACHABLE_CODE,
1769 &format!("unreachable {}", kind));
1775 code: ObligationCauseCode<'tcx>)
1776 -> ObligationCause<'tcx> {
1777 ObligationCause::new(span, self.body_id, code)
1780 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1781 self.cause(span, ObligationCauseCode::MiscObligation)
1784 /// Resolves type variables in `ty` if possible. Unlike the infcx
1785 /// version (resolve_type_vars_if_possible), this version will
1786 /// also select obligations if it seems useful, in an effort
1787 /// to get more type information.
1788 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1789 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1791 // No TyInfer()? Nothing needs doing.
1792 if !ty.has_infer_types() {
1793 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1797 // If `ty` is a type variable, see whether we already know what it is.
1798 ty = self.resolve_type_vars_if_possible(&ty);
1799 if !ty.has_infer_types() {
1800 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1804 // If not, try resolving pending obligations as much as
1805 // possible. This can help substantially when there are
1806 // indirect dependencies that don't seem worth tracking
1808 self.select_obligations_where_possible();
1809 ty = self.resolve_type_vars_if_possible(&ty);
1811 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1815 fn record_deferred_call_resolution(&self,
1816 closure_def_id: DefId,
1817 r: DeferredCallResolution<'gcx, 'tcx>) {
1818 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1819 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1822 fn remove_deferred_call_resolutions(&self,
1823 closure_def_id: DefId)
1824 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1826 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1827 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1830 pub fn tag(&self) -> String {
1831 let self_ptr: *const FnCtxt = self;
1832 format!("{:?}", self_ptr)
1835 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1836 match self.locals.borrow().get(&nid) {
1839 span_bug!(span, "no type for local variable {}",
1840 self.tcx.hir.node_to_string(nid));
1846 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
1847 debug!("write_ty({:?}, {:?}) in fcx {}",
1848 id, self.resolve_type_vars_if_possible(&ty), self.tag());
1849 self.tables.borrow_mut().node_types_mut().insert(id, ty);
1851 if ty.references_error() {
1852 self.has_errors.set(true);
1853 self.set_tainted_by_errors();
1857 // The NodeId and the ItemLocalId must identify the same item. We just pass
1858 // both of them for consistency checking.
1859 pub fn write_method_call(&self,
1861 method: MethodCallee<'tcx>) {
1864 .type_dependent_defs_mut()
1865 .insert(hir_id, Def::Method(method.def_id));
1866 self.write_substs(hir_id, method.substs);
1869 pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
1870 if !substs.is_noop() {
1871 debug!("write_substs({:?}, {:?}) in fcx {}",
1876 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
1880 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1881 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1887 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
1888 Entry::Vacant(entry) => { entry.insert(adj); },
1889 Entry::Occupied(mut entry) => {
1890 debug!(" - composing on top of {:?}", entry.get());
1891 match (&entry.get()[..], &adj[..]) {
1892 // Applying any adjustment on top of a NeverToAny
1893 // is a valid NeverToAny adjustment, because it can't
1895 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1897 Adjustment { kind: Adjust::Deref(_), .. },
1898 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1900 Adjustment { kind: Adjust::Deref(_), .. },
1901 .. // Any following adjustments are allowed.
1903 // A reborrow has no effect before a dereference.
1905 // FIXME: currently we never try to compose autoderefs
1906 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1908 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1909 expr, entry.get(), adj)
1911 *entry.get_mut() = adj;
1916 /// Basically whenever we are converting from a type scheme into
1917 /// the fn body space, we always want to normalize associated
1918 /// types as well. This function combines the two.
1919 fn instantiate_type_scheme<T>(&self,
1921 substs: &Substs<'tcx>,
1924 where T : TypeFoldable<'tcx>
1926 let value = value.subst(self.tcx, substs);
1927 let result = self.normalize_associated_types_in(span, &value);
1928 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1935 /// As `instantiate_type_scheme`, but for the bounds found in a
1936 /// generic type scheme.
1937 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1938 -> ty::InstantiatedPredicates<'tcx> {
1939 let bounds = self.tcx.predicates_of(def_id);
1940 let result = bounds.instantiate(self.tcx, substs);
1941 let result = self.normalize_associated_types_in(span, &result);
1942 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1949 /// Replace all anonymized types with fresh inference variables
1950 /// and record them for writeback.
1951 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1952 debug!("instantiate_anon_types(value={:?})", value);
1953 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1954 if let ty::TyAnon(def_id, substs) = ty.sty {
1955 debug!("instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})", def_id, substs);
1957 // Use the same type variable if the exact same TyAnon appears more
1958 // than once in the return type (e.g. if it's passed to a type alias).
1959 if let Some(anon_defn) = self.anon_types.borrow().get(&def_id) {
1960 return anon_defn.concrete_ty;
1962 let span = self.tcx.def_span(def_id);
1963 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1965 let predicates_of = self.tcx.predicates_of(def_id);
1966 let bounds = predicates_of.instantiate(self.tcx, substs);
1967 debug!("instantiate_anon_types: bounds={:?}", bounds);
1969 let required_region_bounds =
1970 self.tcx.required_region_bounds(ty, bounds.predicates.clone());
1971 debug!("instantiate_anon_types: required_region_bounds={:?}",
1972 required_region_bounds);
1974 self.anon_types.borrow_mut().insert(def_id, AnonTypeDecl {
1976 concrete_ty: ty_var,
1977 required_region_bounds,
1979 debug!("instantiate_anon_types: ty_var={:?}", ty_var);
1981 for predicate in bounds.predicates {
1982 // Change the predicate to refer to the type variable,
1983 // which will be the concrete type, instead of the TyAnon.
1984 // This also instantiates nested `impl Trait`.
1985 let predicate = self.instantiate_anon_types(&predicate);
1987 // Require that the predicate holds for the concrete type.
1988 let cause = traits::ObligationCause::new(span,
1990 traits::SizedReturnType);
1992 debug!("instantiate_anon_types: predicate={:?}", predicate);
1993 self.register_predicate(traits::Obligation::new(cause,
2005 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2006 where T : TypeFoldable<'tcx>
2008 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2011 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2013 where T : TypeFoldable<'tcx>
2015 self.inh.partially_normalize_associated_types_in(span,
2021 pub fn require_type_meets(&self,
2024 code: traits::ObligationCauseCode<'tcx>,
2027 self.register_bound(
2030 traits::ObligationCause::new(span, self.body_id, code));
2033 pub fn require_type_is_sized(&self,
2036 code: traits::ObligationCauseCode<'tcx>)
2038 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2039 self.require_type_meets(ty, span, code, lang_item);
2042 pub fn register_bound(&self,
2045 cause: traits::ObligationCause<'tcx>)
2047 self.fulfillment_cx.borrow_mut()
2048 .register_bound(self, self.param_env, ty, def_id, cause);
2051 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2052 let t = AstConv::ast_ty_to_ty(self, ast_t);
2053 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2057 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2058 match self.tables.borrow().node_types().get(id) {
2060 None if self.is_tainted_by_errors() => self.tcx.types.err,
2062 let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id);
2063 bug!("no type for node {}: {} in fcx {}",
2064 node_id, self.tcx.hir.node_to_string(node_id),
2070 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2071 /// outlive the region `r`.
2072 pub fn register_wf_obligation(&self,
2075 code: traits::ObligationCauseCode<'tcx>)
2077 // WF obligations never themselves fail, so no real need to give a detailed cause:
2078 let cause = traits::ObligationCause::new(span, self.body_id, code);
2079 self.register_predicate(traits::Obligation::new(cause,
2081 ty::Predicate::WellFormed(ty)));
2084 /// Registers obligations that all types appearing in `substs` are well-formed.
2085 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
2087 for ty in substs.types() {
2088 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2092 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2093 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2094 /// trait/region obligations.
2096 /// For example, if there is a function:
2099 /// fn foo<'a,T:'a>(...)
2102 /// and a reference:
2108 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2109 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2110 pub fn add_obligations_for_parameters(&self,
2111 cause: traits::ObligationCause<'tcx>,
2112 predicates: &ty::InstantiatedPredicates<'tcx>)
2114 assert!(!predicates.has_escaping_regions());
2116 debug!("add_obligations_for_parameters(predicates={:?})",
2119 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2120 self.register_predicate(obligation);
2124 // FIXME(arielb1): use this instead of field.ty everywhere
2125 // Only for fields! Returns <none> for methods>
2126 // Indifferent to privacy flags
2127 pub fn field_ty(&self,
2129 field: &'tcx ty::FieldDef,
2130 substs: &Substs<'tcx>)
2133 self.normalize_associated_types_in(span,
2134 &field.ty(self.tcx, substs))
2137 fn check_casts(&self) {
2138 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2139 for cast in deferred_cast_checks.drain(..) {
2144 fn resolve_generator_interiors(&self, def_id: DefId) {
2145 let mut deferred_generator_interiors = self.deferred_generator_interiors.borrow_mut();
2146 for (body_id, witness) in deferred_generator_interiors.drain(..) {
2147 generator_interior::resolve_interior(self, def_id, body_id, witness);
2151 /// Apply "fallbacks" to some types
2152 /// unconstrained types get replaced with ! or () (depending on whether
2153 /// feature(never_type) is enabled), unconstrained ints with i32, and
2154 /// unconstrained floats with f64.
2155 fn default_type_parameters(&self) {
2156 use rustc::ty::error::UnconstrainedNumeric::Neither;
2157 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2159 // Defaulting inference variables becomes very dubious if we have
2160 // encountered type-checking errors. Therefore, if we think we saw
2161 // some errors in this function, just resolve all uninstanted type
2162 // varibles to TyError.
2163 if self.is_tainted_by_errors() {
2164 for ty in &self.unsolved_variables() {
2165 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
2166 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2167 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2173 for ty in &self.unsolved_variables() {
2174 let resolved = self.resolve_type_vars_if_possible(ty);
2175 if self.type_var_diverges(resolved) {
2176 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
2178 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2179 self.tcx.mk_diverging_default());
2181 match self.type_is_unconstrained_numeric(resolved) {
2182 UnconstrainedInt => {
2183 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
2185 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2187 UnconstrainedFloat => {
2188 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
2190 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2198 // Implements type inference fallback algorithm
2199 fn select_all_obligations_and_apply_defaults(&self) {
2200 self.select_obligations_where_possible();
2201 self.default_type_parameters();
2202 self.select_obligations_where_possible();
2205 fn select_all_obligations_or_error(&self) {
2206 debug!("select_all_obligations_or_error");
2208 // upvar inference should have ensured that all deferred call
2209 // resolutions are handled by now.
2210 assert!(self.deferred_call_resolutions.borrow().is_empty());
2212 self.select_all_obligations_and_apply_defaults();
2214 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2216 match fulfillment_cx.select_all_or_error(self) {
2218 Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2222 /// Select as many obligations as we can at present.
2223 fn select_obligations_where_possible(&self) {
2224 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2226 Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
2230 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2231 /// returns a type of `&T`, but the actual type we assign to the
2232 /// *expression* is `T`. So this function just peels off the return
2233 /// type by one layer to yield `T`.
2234 fn make_overloaded_lvalue_return_type(&self,
2235 method: MethodCallee<'tcx>)
2236 -> ty::TypeAndMut<'tcx>
2238 // extract method return type, which will be &T;
2239 let ret_ty = method.sig.output();
2241 // method returns &T, but the type as visible to user is T, so deref
2242 ret_ty.builtin_deref(true, NoPreference).unwrap()
2245 fn lookup_indexing(&self,
2247 base_expr: &'gcx hir::Expr,
2250 lvalue_pref: LvaluePreference)
2251 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2253 // FIXME(#18741) -- this is almost but not quite the same as the
2254 // autoderef that normal method probing does. They could likely be
2257 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2258 let mut result = None;
2259 while result.is_none() && autoderef.next().is_some() {
2260 result = self.try_index_step(expr, base_expr, &autoderef, lvalue_pref, idx_ty);
2262 autoderef.finalize();
2266 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2267 /// (and otherwise adjust) `base_expr`, looking for a type which either
2268 /// supports builtin indexing or overloaded indexing.
2269 /// This loop implements one step in that search; the autoderef loop
2270 /// is implemented by `lookup_indexing`.
2271 fn try_index_step(&self,
2273 base_expr: &hir::Expr,
2274 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2275 lvalue_pref: LvaluePreference,
2277 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2279 let adjusted_ty = autoderef.unambiguous_final_ty();
2280 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2287 // First, try built-in indexing.
2288 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2289 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2290 debug!("try_index_step: success, using built-in indexing");
2291 let adjustments = autoderef.adjust_steps(lvalue_pref);
2292 self.apply_adjustments(base_expr, adjustments);
2293 return Some((self.tcx.types.usize, ty));
2298 for &unsize in &[false, true] {
2299 let mut self_ty = adjusted_ty;
2301 // We only unsize arrays here.
2302 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2303 self_ty = self.tcx.mk_slice(element_ty);
2309 // If some lookup succeeds, write callee into table and extract index/element
2310 // type from the method signature.
2311 // If some lookup succeeded, install method in table
2312 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2313 let method = self.try_overloaded_lvalue_op(
2314 expr.span, self_ty, &[input_ty], lvalue_pref, LvalueOp::Index);
2316 let result = method.map(|ok| {
2317 debug!("try_index_step: success, using overloaded indexing");
2318 let method = self.register_infer_ok_obligations(ok);
2320 let mut adjustments = autoderef.adjust_steps(lvalue_pref);
2321 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
2322 adjustments.push(Adjustment {
2323 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
2324 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2331 adjustments.push(Adjustment {
2332 kind: Adjust::Unsize,
2333 target: method.sig.inputs()[0]
2336 self.apply_adjustments(base_expr, adjustments);
2338 self.write_method_call(expr.hir_id, method);
2339 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2341 if result.is_some() {
2349 fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2350 let (tr, name) = match (op, is_mut) {
2351 (LvalueOp::Deref, false) =>
2352 (self.tcx.lang_items().deref_trait(), "deref"),
2353 (LvalueOp::Deref, true) =>
2354 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2355 (LvalueOp::Index, false) =>
2356 (self.tcx.lang_items().index_trait(), "index"),
2357 (LvalueOp::Index, true) =>
2358 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2360 (tr, Symbol::intern(name))
2363 fn try_overloaded_lvalue_op(&self,
2366 arg_tys: &[Ty<'tcx>],
2367 lvalue_pref: LvaluePreference,
2369 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2371 debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
2377 // Try Mut first, if preferred.
2378 let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
2379 let method = match (lvalue_pref, mut_tr) {
2380 (PreferMutLvalue, Some(trait_did)) => {
2381 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2386 // Otherwise, fall back to the immutable version.
2387 let (imm_tr, imm_op) = self.resolve_lvalue_op(op, false);
2388 let method = match (method, imm_tr) {
2389 (None, Some(trait_did)) => {
2390 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2392 (method, _) => method,
2398 fn check_method_argument_types(&self,
2401 method: Result<MethodCallee<'tcx>, ()>,
2402 args_no_rcvr: &'gcx [hir::Expr],
2403 tuple_arguments: TupleArgumentsFlag,
2404 expected: Expectation<'tcx>)
2406 let has_error = match method {
2408 method.substs.references_error() || method.sig.references_error()
2413 let err_inputs = self.err_args(args_no_rcvr.len());
2415 let err_inputs = match tuple_arguments {
2416 DontTupleArguments => err_inputs,
2417 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2420 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2421 false, tuple_arguments, None);
2422 return self.tcx.types.err;
2425 let method = method.unwrap();
2426 // HACK(eddyb) ignore self in the definition (see above).
2427 let expected_arg_tys = self.expected_inputs_for_expected_output(
2430 method.sig.output(),
2431 &method.sig.inputs()[1..]
2433 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2434 args_no_rcvr, method.sig.variadic, tuple_arguments,
2435 self.tcx.hir.span_if_local(method.def_id));
2439 /// Generic function that factors out common logic from function calls,
2440 /// method calls and overloaded operators.
2441 fn check_argument_types(&self,
2444 fn_inputs: &[Ty<'tcx>],
2445 expected_arg_tys: &[Ty<'tcx>],
2446 args: &'gcx [hir::Expr],
2448 tuple_arguments: TupleArgumentsFlag,
2449 def_span: Option<Span>) {
2452 // Grab the argument types, supplying fresh type variables
2453 // if the wrong number of arguments were supplied
2454 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2460 // All the input types from the fn signature must outlive the call
2461 // so as to validate implied bounds.
2462 for &fn_input_ty in fn_inputs {
2463 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2466 let mut expected_arg_tys = expected_arg_tys;
2467 let expected_arg_count = fn_inputs.len();
2469 let sp_args = if args.len() > 0 {
2470 let (first, args) = args.split_at(1);
2471 let mut sp_tmp = first[0].span;
2473 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2474 if ! sp_opt.is_some() {
2477 sp_tmp = sp_opt.unwrap();
2484 fn parameter_count_error<'tcx>(sess: &Session,
2487 expected_count: usize,
2491 def_span: Option<Span>,
2493 let mut err = sess.struct_span_err_with_code(sp,
2494 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2495 if variadic {"at least "} else {""},
2497 if expected_count == 1 {""} else {"s"},
2499 if arg_count == 1 {" was"} else {"s were"}),
2500 DiagnosticId::Error(error_code.to_owned()));
2502 if let Some(def_s) = def_span {
2503 err.span_label(def_s, "defined here");
2506 let sugg_span = expr_sp.end_point();
2507 // remove closing `)` from the span
2508 let sugg_span = sugg_span.with_hi(sugg_span.lo());
2509 err.span_suggestion(
2511 "expected the unit value `()`; create it with empty parentheses",
2512 String::from("()"));
2514 err.span_label(sp, format!("expected {}{} parameter{}",
2515 if variadic {"at least "} else {""},
2517 if expected_count == 1 {""} else {"s"}));
2522 let formal_tys = if tuple_arguments == TupleArguments {
2523 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2524 match tuple_type.sty {
2525 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2526 parameter_count_error(tcx.sess, sp_args, expr_sp, arg_types.len(), args.len(),
2527 "E0057", false, def_span, false);
2528 expected_arg_tys = &[];
2529 self.err_args(args.len())
2531 ty::TyTuple(arg_types, _) => {
2532 expected_arg_tys = match expected_arg_tys.get(0) {
2533 Some(&ty) => match ty.sty {
2534 ty::TyTuple(ref tys, _) => &tys,
2542 span_err!(tcx.sess, sp, E0059,
2543 "cannot use call notation; the first type parameter \
2544 for the function trait is neither a tuple nor unit");
2545 expected_arg_tys = &[];
2546 self.err_args(args.len())
2549 } else if expected_arg_count == supplied_arg_count {
2551 } else if variadic {
2552 if supplied_arg_count >= expected_arg_count {
2555 parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2556 supplied_arg_count, "E0060", true, def_span, false);
2557 expected_arg_tys = &[];
2558 self.err_args(supplied_arg_count)
2561 // is the missing argument of type `()`?
2562 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2563 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
2564 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2565 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
2569 parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2570 supplied_arg_count, "E0061", false, def_span, sugg_unit);
2571 expected_arg_tys = &[];
2572 self.err_args(supplied_arg_count)
2575 debug!("check_argument_types: formal_tys={:?}",
2576 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2578 // Check the arguments.
2579 // We do this in a pretty awful way: first we typecheck any arguments
2580 // that are not closures, then we typecheck the closures. This is so
2581 // that we have more information about the types of arguments when we
2582 // typecheck the functions. This isn't really the right way to do this.
2583 for &check_closures in &[false, true] {
2584 debug!("check_closures={}", check_closures);
2586 // More awful hacks: before we check argument types, try to do
2587 // an "opportunistic" vtable resolution of any trait bounds on
2588 // the call. This helps coercions.
2590 self.select_obligations_where_possible();
2593 // For variadic functions, we don't have a declared type for all of
2594 // the arguments hence we only do our usual type checking with
2595 // the arguments who's types we do know.
2596 let t = if variadic {
2598 } else if tuple_arguments == TupleArguments {
2603 for (i, arg) in args.iter().take(t).enumerate() {
2604 // Warn only for the first loop (the "no closures" one).
2605 // Closure arguments themselves can't be diverging, but
2606 // a previous argument can, e.g. `foo(panic!(), || {})`.
2607 if !check_closures {
2608 self.warn_if_unreachable(arg.id, arg.span, "expression");
2611 let is_closure = match arg.node {
2612 hir::ExprClosure(..) => true,
2616 if is_closure != check_closures {
2620 debug!("checking the argument");
2621 let formal_ty = formal_tys[i];
2623 // The special-cased logic below has three functions:
2624 // 1. Provide as good of an expected type as possible.
2625 let expected = expected_arg_tys.get(i).map(|&ty| {
2626 Expectation::rvalue_hint(self, ty)
2629 let checked_ty = self.check_expr_with_expectation(
2631 expected.unwrap_or(ExpectHasType(formal_ty)));
2633 // 2. Coerce to the most detailed type that could be coerced
2634 // to, which is `expected_ty` if `rvalue_hint` returns an
2635 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2636 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2637 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2639 // 3. Relate the expected type and the formal one,
2640 // if the expected type was used for the coercion.
2641 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2645 // We also need to make sure we at least write the ty of the other
2646 // arguments which we skipped above.
2648 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
2649 type_error_struct!(s, span, t, E0617,
2650 "can't pass `{}` to variadic function, cast to `{}`",
2654 for arg in args.iter().skip(expected_arg_count) {
2655 let arg_ty = self.check_expr(&arg);
2657 // There are a few types which get autopromoted when passed via varargs
2658 // in C but we just error out instead and require explicit casts.
2659 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
2661 ty::TyFloat(ast::FloatTy::F32) => {
2662 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
2664 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2665 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
2667 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2668 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
2670 ty::TyFnDef(..) => {
2671 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
2672 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2673 variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
2681 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2682 (0..len).map(|_| self.tcx.types.err).collect()
2685 // AST fragment checking
2688 expected: Expectation<'tcx>)
2694 ast::LitKind::Str(..) => tcx.mk_static_str(),
2695 ast::LitKind::ByteStr(ref v) => {
2696 tcx.mk_imm_ref(tcx.types.re_static,
2697 tcx.mk_array(tcx.types.u8, v.len() as u64))
2699 ast::LitKind::Byte(_) => tcx.types.u8,
2700 ast::LitKind::Char(_) => tcx.types.char,
2701 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2702 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2703 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2704 let opt_ty = expected.to_option(self).and_then(|ty| {
2706 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2707 ty::TyChar => Some(tcx.types.u8),
2708 ty::TyRawPtr(..) => Some(tcx.types.usize),
2709 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2713 opt_ty.unwrap_or_else(
2714 || tcx.mk_int_var(self.next_int_var_id()))
2716 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2717 ast::LitKind::FloatUnsuffixed(_) => {
2718 let opt_ty = expected.to_option(self).and_then(|ty| {
2720 ty::TyFloat(_) => Some(ty),
2724 opt_ty.unwrap_or_else(
2725 || tcx.mk_float_var(self.next_float_var_id()))
2727 ast::LitKind::Bool(_) => tcx.types.bool
2731 fn check_expr_eq_type(&self,
2732 expr: &'gcx hir::Expr,
2733 expected: Ty<'tcx>) {
2734 let ty = self.check_expr_with_hint(expr, expected);
2735 self.demand_eqtype(expr.span, expected, ty);
2738 pub fn check_expr_has_type_or_error(&self,
2739 expr: &'gcx hir::Expr,
2740 expected: Ty<'tcx>) -> Ty<'tcx> {
2741 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
2744 fn check_expr_meets_expectation_or_error(&self,
2745 expr: &'gcx hir::Expr,
2746 expected: Expectation<'tcx>) -> Ty<'tcx> {
2747 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
2748 let mut ty = self.check_expr_with_expectation(expr, expected);
2750 // While we don't allow *arbitrary* coercions here, we *do* allow
2751 // coercions from ! to `expected`.
2753 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
2754 "expression with never type wound up being adjusted");
2755 let adj_ty = self.next_diverging_ty_var(
2756 TypeVariableOrigin::AdjustmentType(expr.span));
2757 self.apply_adjustments(expr, vec![Adjustment {
2758 kind: Adjust::NeverToAny,
2764 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
2765 // Add help to type error if this is an `if` condition with an assignment
2766 match (expected, &expr.node) {
2767 (ExpectIfCondition, &hir::ExprAssign(ref lhs, ref rhs)) => {
2768 let msg = "try comparing for equality";
2769 if let (Ok(left), Ok(right)) = (
2770 self.tcx.sess.codemap().span_to_snippet(lhs.span),
2771 self.tcx.sess.codemap().span_to_snippet(rhs.span))
2773 err.span_suggestion(expr.span, msg, format!("{} == {}", left, right));
2785 fn check_expr_coercable_to_type(&self,
2786 expr: &'gcx hir::Expr,
2787 expected: Ty<'tcx>) -> Ty<'tcx> {
2788 self.check_expr_coercable_to_type_with_lvalue_pref(expr, expected, NoPreference)
2791 fn check_expr_coercable_to_type_with_lvalue_pref(&self,
2792 expr: &'gcx hir::Expr,
2794 lvalue_pref: LvaluePreference)
2796 let ty = self.check_expr_with_expectation_and_lvalue_pref(
2798 ExpectHasType(expected),
2800 self.demand_coerce(expr, ty, expected)
2803 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2804 expected: Ty<'tcx>) -> Ty<'tcx> {
2805 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2808 fn check_expr_with_expectation(&self,
2809 expr: &'gcx hir::Expr,
2810 expected: Expectation<'tcx>) -> Ty<'tcx> {
2811 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2814 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2815 self.check_expr_with_expectation(expr, NoExpectation)
2818 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2819 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2820 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2823 // determine the `self` type, using fresh variables for all variables
2824 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2825 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2827 pub fn impl_self_ty(&self,
2828 span: Span, // (potential) receiver for this impl
2830 -> TypeAndSubsts<'tcx> {
2831 let ity = self.tcx.type_of(did);
2832 debug!("impl_self_ty: ity={:?}", ity);
2834 let substs = self.fresh_substs_for_item(span, did);
2835 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2837 TypeAndSubsts { substs: substs, ty: substd_ty }
2840 /// Unifies the output type with the expected type early, for more coercions
2841 /// and forward type information on the input expressions.
2842 fn expected_inputs_for_expected_output(&self,
2844 expected_ret: Expectation<'tcx>,
2845 formal_ret: Ty<'tcx>,
2846 formal_args: &[Ty<'tcx>])
2848 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
2849 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2850 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2851 // Attempt to apply a subtyping relationship between the formal
2852 // return type (likely containing type variables if the function
2853 // is polymorphic) and the expected return type.
2854 // No argument expectations are produced if unification fails.
2855 let origin = self.misc(call_span);
2856 let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
2858 // FIXME(#15760) can't use try! here, FromError doesn't default
2859 // to identity so the resulting type is not constrained.
2862 // Process any obligations locally as much as
2863 // we can. We don't care if some things turn
2864 // out unconstrained or ambiguous, as we're
2865 // just trying to get hints here.
2866 let result = self.save_and_restore_in_snapshot_flag(|_| {
2867 let mut fulfill = FulfillmentContext::new();
2868 let ok = ok; // FIXME(#30046)
2869 for obligation in ok.obligations {
2870 fulfill.register_predicate_obligation(self, obligation);
2872 fulfill.select_where_possible(self)
2877 Err(_) => return Err(()),
2880 Err(_) => return Err(()),
2883 // Record all the argument types, with the substitutions
2884 // produced from the above subtyping unification.
2885 Ok(formal_args.iter().map(|ty| {
2886 self.resolve_type_vars_if_possible(ty)
2889 }).unwrap_or(vec![]);
2890 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2891 formal_args, formal_ret,
2892 expected_args, expected_ret);
2896 // Checks a method call.
2897 fn check_method_call(&self,
2898 expr: &'gcx hir::Expr,
2899 segment: &hir::PathSegment,
2901 args: &'gcx [hir::Expr],
2902 expected: Expectation<'tcx>,
2903 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2904 let rcvr = &args[0];
2905 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2906 // no need to check for bot/err -- callee does that
2907 let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2909 let method = match self.lookup_method(rcvr_t,
2915 self.write_method_call(expr.hir_id, method);
2919 if segment.name != keywords::Invalid.name() {
2920 self.report_method_error(span,
2931 // Call the generic checker.
2932 self.check_method_argument_types(span,
2940 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2944 .unwrap_or_else(|| span_bug!(return_expr.span,
2945 "check_return_expr called outside fn body"));
2947 let ret_ty = ret_coercion.borrow().expected_ty();
2948 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
2949 ret_coercion.borrow_mut()
2951 &self.cause(return_expr.span,
2952 ObligationCauseCode::ReturnType(return_expr.id)),
2955 self.diverges.get());
2959 // A generic function for checking the then and else in an if
2961 fn check_then_else(&self,
2962 cond_expr: &'gcx hir::Expr,
2963 then_expr: &'gcx hir::Expr,
2964 opt_else_expr: Option<&'gcx hir::Expr>,
2966 expected: Expectation<'tcx>) -> Ty<'tcx> {
2967 let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
2968 let cond_diverges = self.diverges.get();
2969 self.diverges.set(Diverges::Maybe);
2971 let expected = expected.adjust_for_branches(self);
2972 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2973 let then_diverges = self.diverges.get();
2974 self.diverges.set(Diverges::Maybe);
2976 // We've already taken the expected type's preferences
2977 // into account when typing the `then` branch. To figure
2978 // out the initial shot at a LUB, we thus only consider
2979 // `expected` if it represents a *hard* constraint
2980 // (`only_has_type`); otherwise, we just go with a
2981 // fresh type variable.
2982 let coerce_to_ty = expected.coercion_target_type(self, sp);
2983 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2985 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2986 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2988 if let Some(else_expr) = opt_else_expr {
2989 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2990 let else_diverges = self.diverges.get();
2992 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
2994 // We won't diverge unless both branches do (or the condition does).
2995 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2997 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2998 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
3000 // If the condition is false we can't diverge.
3001 self.diverges.set(cond_diverges);
3004 let result_ty = coerce.complete(self);
3005 if cond_ty.references_error() {
3012 // Check field access expressions
3013 fn check_field(&self,
3014 expr: &'gcx hir::Expr,
3015 lvalue_pref: LvaluePreference,
3016 base: &'gcx hir::Expr,
3017 field: &Spanned<ast::Name>) -> Ty<'tcx> {
3018 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
3019 let expr_t = self.structurally_resolved_type(expr.span,
3021 let mut private_candidate = None;
3022 let mut autoderef = self.autoderef(expr.span, expr_t);
3023 while let Some((base_t, _)) = autoderef.next() {
3025 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
3026 debug!("struct named {:?}", base_t);
3027 let (ident, def_scope) =
3028 self.tcx.adjust(field.node, base_def.did, self.body_id);
3029 let fields = &base_def.struct_variant().fields;
3030 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3031 let field_ty = self.field_ty(expr.span, field, substs);
3032 if field.vis.is_accessible_from(def_scope, self.tcx) {
3033 let adjustments = autoderef.adjust_steps(lvalue_pref);
3034 self.apply_adjustments(base, adjustments);
3035 autoderef.finalize();
3037 self.tcx.check_stability(field.did, expr.id, expr.span);
3041 private_candidate = Some((base_def.did, field_ty));
3047 autoderef.unambiguous_final_ty();
3049 if let Some((did, field_ty)) = private_candidate {
3050 let struct_path = self.tcx().item_path_str(did);
3051 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3052 "field `{}` of struct `{}` is private",
3053 field.node, struct_path);
3054 // Also check if an accessible method exists, which is often what is meant.
3055 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
3056 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
3061 } else if field.node == keywords::Invalid.name() {
3062 self.tcx().types.err
3063 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
3064 type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3065 "attempted to take value of method `{}` on type `{}`",
3067 .help("maybe a `()` to call it is missing?")
3069 self.tcx().types.err
3071 if !expr_t.is_primitive_ty() {
3072 let mut err = self.no_such_field_err(field.span, &field.node, expr_t);
3075 ty::TyAdt(def, _) if !def.is_enum() => {
3076 if let Some(suggested_field_name) =
3077 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
3078 err.span_label(field.span,
3079 format!("did you mean `{}`?", suggested_field_name));
3081 err.span_label(field.span, "unknown field");
3082 let struct_variant_def = def.struct_variant();
3083 let field_names = self.available_field_names(struct_variant_def);
3084 if !field_names.is_empty() {
3085 err.note(&format!("available fields are: {}",
3086 self.name_series_display(field_names)));
3090 ty::TyRawPtr(..) => {
3091 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \
3093 self.tcx.hir.node_to_pretty_string(base.id),
3100 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3101 "`{}` is a primitive type and therefore doesn't have fields",
3104 self.tcx().types.err
3108 // Return an hint about the closest match in field names
3109 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3110 field: &Spanned<ast::Name>,
3111 skip: Vec<InternedString>)
3113 let name = field.node.as_str();
3114 let names = variant.fields.iter().filter_map(|field| {
3115 // ignore already set fields and private fields from non-local crates
3116 if skip.iter().any(|x| *x == field.name.as_str()) ||
3117 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3124 find_best_match_for_name(names, &name, None)
3127 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3128 let mut available = Vec::new();
3129 for field in variant.fields.iter() {
3130 let (_, def_scope) = self.tcx.adjust(field.name, variant.did, self.body_id);
3131 if field.vis.is_accessible_from(def_scope, self.tcx) {
3132 available.push(field.name);
3138 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3139 // dynamic limit, to never omit just one field
3140 let limit = if names.len() == 6 { 6 } else { 5 };
3141 let mut display = names.iter().take(limit)
3142 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3143 if names.len() > limit {
3144 display = format!("{} ... and {} others", display, names.len() - limit);
3149 // Check tuple index expressions
3150 fn check_tup_field(&self,
3151 expr: &'gcx hir::Expr,
3152 lvalue_pref: LvaluePreference,
3153 base: &'gcx hir::Expr,
3154 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
3155 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
3156 let expr_t = self.structurally_resolved_type(expr.span,
3158 let mut private_candidate = None;
3159 let mut tuple_like = false;
3160 let mut autoderef = self.autoderef(expr.span, expr_t);
3161 while let Some((base_t, _)) = autoderef.next() {
3162 let field = match base_t.sty {
3163 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
3164 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
3165 if !tuple_like { continue }
3167 debug!("tuple struct named {:?}", base_t);
3168 let ident = ast::Ident {
3169 name: Symbol::intern(&idx.node.to_string()),
3170 ctxt: idx.span.ctxt().modern(),
3172 let (ident, def_scope) =
3173 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
3174 let fields = &base_def.struct_variant().fields;
3175 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3176 let field_ty = self.field_ty(expr.span, field, substs);
3177 if field.vis.is_accessible_from(def_scope, self.tcx) {
3178 self.tcx.check_stability(field.did, expr.id, expr.span);
3181 private_candidate = Some((base_def.did, field_ty));
3188 ty::TyTuple(ref v, _) => {
3190 v.get(idx.node).cloned()
3195 if let Some(field_ty) = field {
3196 let adjustments = autoderef.adjust_steps(lvalue_pref);
3197 self.apply_adjustments(base, adjustments);
3198 autoderef.finalize();
3202 autoderef.unambiguous_final_ty();
3204 if let Some((did, field_ty)) = private_candidate {
3205 let struct_path = self.tcx().item_path_str(did);
3206 struct_span_err!(self.tcx().sess, expr.span, E0611,
3207 "field `{}` of tuple-struct `{}` is private",
3208 idx.node, struct_path).emit();
3213 type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
3214 "attempted out-of-bounds tuple index `{}` on type `{}`",
3215 idx.node, expr_t).emit();
3217 self.no_such_field_err(expr.span, idx.node, expr_t).emit();
3220 self.tcx().types.err
3223 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
3224 -> DiagnosticBuilder {
3225 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3226 "no field `{}` on type `{}`",
3230 fn report_unknown_field(&self,
3232 variant: &'tcx ty::VariantDef,
3234 skip_fields: &[hir::Field],
3236 let mut err = self.type_error_struct_with_diag(
3238 |actual| match ty.sty {
3239 ty::TyAdt(adt, ..) if adt.is_enum() => {
3240 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3241 "{} `{}::{}` has no field named `{}`",
3242 kind_name, actual, variant.name, field.name.node)
3245 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3246 "{} `{}` has no field named `{}`",
3247 kind_name, actual, field.name.node)
3251 // prevent all specified fields from being suggested
3252 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3253 if let Some(field_name) = Self::suggest_field_name(variant,
3255 skip_fields.collect()) {
3256 err.span_label(field.name.span,
3257 format!("field does not exist - did you mean `{}`?", field_name));
3260 ty::TyAdt(adt, ..) => {
3262 err.span_label(field.name.span,
3263 format!("`{}::{}` does not have this field",
3266 err.span_label(field.name.span,
3267 format!("`{}` does not have this field", ty));
3269 let available_field_names = self.available_field_names(variant);
3270 if !available_field_names.is_empty() {
3271 err.note(&format!("available fields are: {}",
3272 self.name_series_display(available_field_names)));
3275 _ => bug!("non-ADT passed to report_unknown_field")
3281 fn check_expr_struct_fields(&self,
3283 expected: Expectation<'tcx>,
3284 expr_id: ast::NodeId,
3286 variant: &'tcx ty::VariantDef,
3287 ast_fields: &'gcx [hir::Field],
3288 check_completeness: bool) {
3292 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3293 .get(0).cloned().unwrap_or(adt_ty);
3294 // re-link the regions that EIfEO can erase.
3295 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3297 let (substs, adt_kind, kind_name) = match &adt_ty.sty{
3298 &ty::TyAdt(adt, substs) => {
3299 (substs, adt.adt_kind(), adt.variant_descr())
3301 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3304 let mut remaining_fields = FxHashMap();
3305 for field in &variant.fields {
3306 remaining_fields.insert(field.name.to_ident(), field);
3309 let mut seen_fields = FxHashMap();
3311 let mut error_happened = false;
3313 // Typecheck each field.
3314 for field in ast_fields {
3315 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3316 let field_type = if let Some(v_field) = remaining_fields.remove(&ident) {
3317 seen_fields.insert(field.name.node, field.span);
3319 // we don't look at stability attributes on
3320 // struct-like enums (yet...), but it's definitely not
3321 // a bug to have construct one.
3322 if adt_kind != ty::AdtKind::Enum {
3323 tcx.check_stability(v_field.did, expr_id, field.span);
3326 self.field_ty(field.span, v_field, substs)
3328 error_happened = true;
3329 if let Some(_) = variant.find_field_named(field.name.node) {
3330 let mut err = struct_span_err!(self.tcx.sess,
3333 "field `{}` specified more than once",
3336 err.span_label(field.name.span, "used more than once");
3338 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3339 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3344 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3350 // Make sure to give a type to the field even if there's
3351 // an error, so we can continue typechecking
3352 self.check_expr_coercable_to_type(&field.expr, field_type);
3355 // Make sure the programmer specified correct number of fields.
3356 if kind_name == "union" {
3357 if ast_fields.len() != 1 {
3358 tcx.sess.span_err(span, "union expressions should have exactly one field");
3360 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3361 let len = remaining_fields.len();
3363 let mut displayable_field_names = remaining_fields
3365 .map(|ident| ident.name.as_str())
3366 .collect::<Vec<_>>();
3368 displayable_field_names.sort();
3370 let truncated_fields_error = if len <= 3 {
3373 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3376 let remaining_fields_names = displayable_field_names.iter().take(3)
3377 .map(|n| format!("`{}`", n))
3378 .collect::<Vec<_>>()
3381 struct_span_err!(tcx.sess, span, E0063,
3382 "missing field{} {}{} in initializer of `{}`",
3383 if remaining_fields.len() == 1 { "" } else { "s" },
3384 remaining_fields_names,
3385 truncated_fields_error,
3387 .span_label(span, format!("missing {}{}",
3388 remaining_fields_names,
3389 truncated_fields_error))
3394 fn check_struct_fields_on_error(&self,
3395 fields: &'gcx [hir::Field],
3396 base_expr: &'gcx Option<P<hir::Expr>>) {
3397 for field in fields {
3398 self.check_expr(&field.expr);
3402 self.check_expr(&base);
3408 pub fn check_struct_path(&self,
3410 node_id: ast::NodeId)
3411 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3412 let path_span = match *qpath {
3413 hir::QPath::Resolved(_, ref path) => path.span,
3414 hir::QPath::TypeRelative(ref qself, _) => qself.span
3416 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3417 let variant = match def {
3419 self.set_tainted_by_errors();
3422 Def::Variant(..) => {
3424 ty::TyAdt(adt, substs) => {
3425 Some((adt.variant_of_def(def), adt.did, substs))
3427 _ => bug!("unexpected type: {:?}", ty.sty)
3430 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3431 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3433 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3434 Some((adt.struct_variant(), adt.did, substs))
3439 _ => bug!("unexpected definition: {:?}", def)
3442 if let Some((variant, did, substs)) = variant {
3443 // Check bounds on type arguments used in the path.
3444 let bounds = self.instantiate_bounds(path_span, did, substs);
3445 let cause = traits::ObligationCause::new(path_span, self.body_id,
3446 traits::ItemObligation(did));
3447 self.add_obligations_for_parameters(cause, &bounds);
3451 struct_span_err!(self.tcx.sess, path_span, E0071,
3452 "expected struct, variant or union type, found {}",
3453 ty.sort_string(self.tcx))
3454 .span_label(path_span, "not a struct")
3460 fn check_expr_struct(&self,
3462 expected: Expectation<'tcx>,
3464 fields: &'gcx [hir::Field],
3465 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3467 // Find the relevant variant
3468 let (variant, struct_ty) =
3469 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3472 self.check_struct_fields_on_error(fields, base_expr);
3473 return self.tcx.types.err;
3476 let path_span = match *qpath {
3477 hir::QPath::Resolved(_, ref path) => path.span,
3478 hir::QPath::TypeRelative(ref qself, _) => qself.span
3481 // Prohibit struct expressions when non exhaustive flag is set.
3482 if let ty::TyAdt(adt, _) = struct_ty.sty {
3483 if !adt.did.is_local() && adt.is_non_exhaustive() {
3484 span_err!(self.tcx.sess, expr.span, E0639,
3485 "cannot create non-exhaustive {} using struct expression",
3486 adt.variant_descr());
3490 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3491 base_expr.is_none());
3492 if let &Some(ref base_expr) = base_expr {
3493 self.check_expr_has_type_or_error(base_expr, struct_ty);
3494 match struct_ty.sty {
3495 ty::TyAdt(adt, substs) if adt.is_struct() => {
3496 let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
3497 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3502 .fru_field_types_mut()
3503 .insert(expr.hir_id, fru_field_types);
3506 span_err!(self.tcx.sess, base_expr.span, E0436,
3507 "functional record update syntax requires a struct");
3511 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3517 /// If an expression has any sub-expressions that result in a type error,
3518 /// inspecting that expression's type with `ty.references_error()` will return
3519 /// true. Likewise, if an expression is known to diverge, inspecting its
3520 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3521 /// strict, _|_ can appear in the type of an expression that does not,
3522 /// itself, diverge: for example, fn() -> _|_.)
3523 /// Note that inspecting a type's structure *directly* may expose the fact
3524 /// that there are actually multiple representations for `TyError`, so avoid
3525 /// that when err needs to be handled differently.
3526 fn check_expr_with_expectation_and_lvalue_pref(&self,
3527 expr: &'gcx hir::Expr,
3528 expected: Expectation<'tcx>,
3529 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3530 debug!(">> typechecking: expr={:?} expected={:?}",
3533 // Warn for expressions after diverging siblings.
3534 self.warn_if_unreachable(expr.id, expr.span, "expression");
3536 // Hide the outer diverging and has_errors flags.
3537 let old_diverges = self.diverges.get();
3538 let old_has_errors = self.has_errors.get();
3539 self.diverges.set(Diverges::Maybe);
3540 self.has_errors.set(false);
3542 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3544 // Warn for non-block expressions with diverging children.
3547 hir::ExprLoop(..) | hir::ExprWhile(..) |
3548 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3550 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3553 // Any expression that produces a value of type `!` must have diverged
3555 self.diverges.set(self.diverges.get() | Diverges::Always);
3558 // Record the type, which applies it effects.
3559 // We need to do this after the warning above, so that
3560 // we don't warn for the diverging expression itself.
3561 self.write_ty(expr.hir_id, ty);
3563 // Combine the diverging and has_error flags.
3564 self.diverges.set(self.diverges.get() | old_diverges);
3565 self.has_errors.set(self.has_errors.get() | old_has_errors);
3567 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3568 debug!("... {:?}, expected is {:?}", ty, expected);
3573 fn check_expr_kind(&self,
3574 expr: &'gcx hir::Expr,
3575 expected: Expectation<'tcx>,
3576 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3580 hir::ExprBox(ref subexpr) => {
3581 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3583 ty::TyAdt(def, _) if def.is_box()
3584 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3588 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3589 tcx.mk_box(referent_ty)
3592 hir::ExprLit(ref lit) => {
3593 self.check_lit(&lit, expected)
3595 hir::ExprBinary(op, ref lhs, ref rhs) => {
3596 self.check_binop(expr, op, lhs, rhs)
3598 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3599 self.check_binop_assign(expr, op, lhs, rhs)
3601 hir::ExprUnary(unop, ref oprnd) => {
3602 let expected_inner = match unop {
3603 hir::UnNot | hir::UnNeg => {
3610 let lvalue_pref = match unop {
3611 hir::UnDeref => lvalue_pref,
3614 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3618 if !oprnd_t.references_error() {
3619 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3622 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3624 } else if let Some(ok) = self.try_overloaded_deref(
3625 expr.span, oprnd_t, lvalue_pref) {
3626 let method = self.register_infer_ok_obligations(ok);
3627 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3628 self.apply_adjustments(oprnd, vec![Adjustment {
3629 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
3630 target: method.sig.inputs()[0]
3633 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3634 self.write_method_call(expr.hir_id, method);
3636 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3637 "type `{}` cannot be dereferenced",
3639 oprnd_t = tcx.types.err;
3643 let result = self.check_user_unop(expr, oprnd_t, unop);
3644 // If it's builtin, we can reuse the type, this helps inference.
3645 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3650 let result = self.check_user_unop(expr, oprnd_t, unop);
3651 // If it's builtin, we can reuse the type, this helps inference.
3652 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3660 hir::ExprAddrOf(mutbl, ref oprnd) => {
3661 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3663 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3664 if self.tcx.expr_is_lval(&oprnd) {
3665 // Lvalues may legitimately have unsized types.
3666 // For example, dereferences of a fat pointer and
3667 // the last field of a struct can be unsized.
3668 ExpectHasType(mt.ty)
3670 Expectation::rvalue_hint(self, mt.ty)
3676 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3677 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3679 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3680 if tm.ty.references_error() {
3683 // Note: at this point, we cannot say what the best lifetime
3684 // is to use for resulting pointer. We want to use the
3685 // shortest lifetime possible so as to avoid spurious borrowck
3686 // errors. Moreover, the longest lifetime will depend on the
3687 // precise details of the value whose address is being taken
3688 // (and how long it is valid), which we don't know yet until type
3689 // inference is complete.
3691 // Therefore, here we simply generate a region variable. The
3692 // region inferencer will then select the ultimate value.
3693 // Finally, borrowck is charged with guaranteeing that the
3694 // value whose address was taken can actually be made to live
3695 // as long as it needs to live.
3696 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3697 tcx.mk_ref(region, tm)
3700 hir::ExprPath(ref qpath) => {
3701 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3702 expr.id, expr.span);
3703 let ty = if def != Def::Err {
3704 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3706 self.set_tainted_by_errors();
3710 // We always require that the type provided as the value for
3711 // a type parameter outlives the moment of instantiation.
3712 let substs = self.tables.borrow().node_substs(expr.hir_id);
3713 self.add_wf_bounds(substs, expr);
3717 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3718 for output in outputs {
3719 self.check_expr(output);
3721 for input in inputs {
3722 self.check_expr(input);
3726 hir::ExprBreak(destination, ref expr_opt) => {
3727 if let Some(target_id) = destination.target_id.opt_id() {
3728 let (e_ty, e_diverges, cause);
3729 if let Some(ref e) = *expr_opt {
3730 // If this is a break with a value, we need to type-check
3731 // the expression. Get an expected type from the loop context.
3732 let opt_coerce_to = {
3733 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3734 enclosing_breakables.find_breakable(target_id)
3737 .map(|coerce| coerce.expected_ty())
3740 // If the loop context is not a `loop { }`, then break with
3741 // a value is illegal, and `opt_coerce_to` will be `None`.
3742 // Just set expectation to error in that case.
3743 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3745 // Recurse without `enclosing_breakables` borrowed.
3746 e_ty = self.check_expr_with_hint(e, coerce_to);
3747 e_diverges = self.diverges.get();
3748 cause = self.misc(e.span);
3750 // Otherwise, this is a break *without* a value. That's
3751 // always legal, and is equivalent to `break ()`.
3752 e_ty = tcx.mk_nil();
3753 e_diverges = Diverges::Maybe;
3754 cause = self.misc(expr.span);
3757 // Now that we have type-checked `expr_opt`, borrow
3758 // the `enclosing_loops` field and let's coerce the
3759 // type of `expr_opt` into what is expected.
3760 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3761 let ctxt = enclosing_breakables.find_breakable(target_id);
3762 if let Some(ref mut coerce) = ctxt.coerce {
3763 if let Some(ref e) = *expr_opt {
3764 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3766 assert!(e_ty.is_nil());
3767 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3770 // If `ctxt.coerce` is `None`, we can just ignore
3771 // the type of the expresison. This is because
3772 // either this was a break *without* a value, in
3773 // which case it is always a legal type (`()`), or
3774 // else an error would have been flagged by the
3775 // `loops` pass for using break with an expression
3776 // where you are not supposed to.
3777 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3780 ctxt.may_break = true;
3782 // Otherwise, we failed to find the enclosing loop;
3783 // this can only happen if the `break` was not
3784 // inside a loop at all, which is caught by the
3785 // loop-checking pass.
3786 assert!(self.tcx.sess.err_count() > 0);
3788 // We still need to assign a type to the inner expression to
3789 // prevent the ICE in #43162.
3790 if let Some(ref e) = *expr_opt {
3791 self.check_expr_with_hint(e, tcx.types.err);
3793 // ... except when we try to 'break rust;'.
3794 // ICE this expression in particular (see #43162).
3795 if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
3796 if path.segments.len() == 1 && path.segments[0].name == "rust" {
3797 fatally_break_rust(self.tcx.sess);
3803 // the type of a `break` is always `!`, since it diverges
3806 hir::ExprAgain(_) => { tcx.types.never }
3807 hir::ExprRet(ref expr_opt) => {
3808 if self.ret_coercion.is_none() {
3809 struct_span_err!(self.tcx.sess, expr.span, E0572,
3810 "return statement outside of function body").emit();
3811 } else if let Some(ref e) = *expr_opt {
3812 self.check_return_expr(e);
3814 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3815 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3816 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3820 hir::ExprAssign(ref lhs, ref rhs) => {
3821 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3823 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3826 ExpectIfCondition => {
3827 self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
3828 expected error elsehwere");
3831 // Only check this if not in an `if` condition, as the
3832 // mistyped comparison help is more appropriate.
3833 if !self.tcx.expr_is_lval(&lhs) {
3834 struct_span_err!(self.tcx.sess, expr.span, E0070,
3835 "invalid left-hand side expression")
3836 .span_label(expr.span, "left-hand of expression not valid")
3842 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3844 if lhs_ty.references_error() || rhs_ty.references_error() {
3850 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3851 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3852 expr.span, expected)
3854 hir::ExprWhile(ref cond, ref body, _) => {
3855 let ctxt = BreakableCtxt {
3856 // cannot use break with a value from a while loop
3861 self.with_breakable_ctxt(expr.id, ctxt, || {
3862 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
3863 let cond_diverging = self.diverges.get();
3864 self.check_block_no_value(&body);
3866 // We may never reach the body so it diverging means nothing.
3867 self.diverges.set(cond_diverging);
3872 hir::ExprLoop(ref body, _, source) => {
3873 let coerce = match source {
3874 // you can only use break with a value from a normal `loop { }`
3875 hir::LoopSource::Loop => {
3876 let coerce_to = expected.coercion_target_type(self, body.span);
3877 Some(CoerceMany::new(coerce_to))
3880 hir::LoopSource::WhileLet |
3881 hir::LoopSource::ForLoop => {
3886 let ctxt = BreakableCtxt {
3888 may_break: false, // will get updated if/when we find a `break`
3891 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3892 self.check_block_no_value(&body);
3896 // No way to know whether it's diverging because
3897 // of a `break` or an outer `break` or `return.
3898 self.diverges.set(Diverges::Maybe);
3901 // If we permit break with a value, then result type is
3902 // the LUB of the breaks (possibly ! if none); else, it
3903 // is nil. This makes sense because infinite loops
3904 // (which would have type !) are only possible iff we
3905 // permit break with a value [1].
3906 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3907 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3909 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3910 self.check_match(expr, &discrim, arms, expected, match_src)
3912 hir::ExprClosure(capture, ref decl, body_id, _, _) => {
3913 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3915 hir::ExprBlock(ref body) => {
3916 self.check_block_with_expected(&body, expected)
3918 hir::ExprCall(ref callee, ref args) => {
3919 self.check_call(expr, &callee, args, expected)
3921 hir::ExprMethodCall(ref segment, span, ref args) => {
3922 self.check_method_call(expr, segment, span, args, expected, lvalue_pref)
3924 hir::ExprCast(ref e, ref t) => {
3925 // Find the type of `e`. Supply hints based on the type we are casting to,
3927 let t_cast = self.to_ty(t);
3928 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3929 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3930 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3931 let diverges = self.diverges.get();
3933 // Eagerly check for some obvious errors.
3934 if t_expr.references_error() || t_cast.references_error() {
3937 // Defer other checks until we're done type checking.
3938 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3939 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3941 deferred_cast_checks.push(cast_check);
3944 Err(ErrorReported) => {
3950 hir::ExprType(ref e, ref t) => {
3951 let typ = self.to_ty(&t);
3952 self.check_expr_eq_type(&e, typ);
3955 hir::ExprArray(ref args) => {
3956 let uty = expected.to_option(self).and_then(|uty| {
3958 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3963 let element_ty = if !args.is_empty() {
3964 let coerce_to = uty.unwrap_or_else(
3965 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3966 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3967 assert_eq!(self.diverges.get(), Diverges::Maybe);
3969 let e_ty = self.check_expr_with_hint(e, coerce_to);
3970 let cause = self.misc(e.span);
3971 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3973 coerce.complete(self)
3975 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3977 tcx.mk_array(element_ty, args.len() as u64)
3979 hir::ExprRepeat(ref element, count) => {
3980 let count_def_id = tcx.hir.body_owner_def_id(count);
3981 let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing);
3982 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
3983 let count = tcx.const_eval(param_env.and((count_def_id, substs)));
3985 if let Err(ref err) = count {
3986 err.report(tcx, tcx.def_span(count_def_id), "constant expression");
3989 let uty = match expected {
3990 ExpectHasType(uty) => {
3992 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3999 let (element_ty, t) = match uty {
4001 self.check_expr_coercable_to_type(&element, uty);
4005 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
4006 let element_ty = self.check_expr_has_type_or_error(&element, t);
4011 if let Ok(count) = count {
4012 let zero_or_one = count.val.to_const_int().and_then(|count| {
4013 count.to_u64().map(|count| count <= 1)
4014 }).unwrap_or(false);
4016 // For [foo, ..n] where n > 1, `foo` must have
4018 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4019 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4023 if element_ty.references_error() {
4025 } else if let Ok(count) = count {
4026 tcx.mk_ty(ty::TyArray(t, count))
4031 hir::ExprTup(ref elts) => {
4032 let flds = expected.only_has_type(self).and_then(|ty| {
4033 let ty = self.resolve_type_vars_with_obligations(ty);
4035 ty::TyTuple(ref flds, _) => Some(&flds[..]),
4040 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4041 let t = match flds {
4042 Some(ref fs) if i < fs.len() => {
4044 self.check_expr_coercable_to_type(&e, ety);
4048 self.check_expr_with_expectation(&e, NoExpectation)
4053 let tuple = tcx.mk_tup(elt_ts_iter, false);
4054 if tuple.references_error() {
4057 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4061 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
4062 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4064 hir::ExprField(ref base, ref field) => {
4065 self.check_field(expr, lvalue_pref, &base, field)
4067 hir::ExprTupField(ref base, idx) => {
4068 self.check_tup_field(expr, lvalue_pref, &base, idx)
4070 hir::ExprIndex(ref base, ref idx) => {
4071 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
4072 let idx_t = self.check_expr(&idx);
4074 if base_t.references_error() {
4076 } else if idx_t.references_error() {
4079 let base_t = self.structurally_resolved_type(expr.span, base_t);
4080 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
4081 Some((index_ty, element_ty)) => {
4082 self.demand_coerce(idx, idx_t, index_ty);
4086 let mut err = type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4087 "cannot index into a value of type `{}`",
4089 // Try to give some advice about indexing tuples.
4090 if let ty::TyTuple(..) = base_t.sty {
4091 let mut needs_note = true;
4092 // If the index is an integer, we can show the actual
4093 // fixed expression:
4094 if let hir::ExprLit(ref lit) = idx.node {
4095 if let ast::LitKind::Int(i,
4096 ast::LitIntType::Unsuffixed) = lit.node {
4097 let snip = tcx.sess.codemap().span_to_snippet(base.span);
4098 if let Ok(snip) = snip {
4099 err.span_suggestion(expr.span,
4100 "to access tuple elements, use",
4101 format!("{}.{}", snip, i));
4107 err.help("to access tuple elements, use tuple indexing \
4108 syntax (e.g. `tuple.0`)");
4117 hir::ExprYield(ref value) => {
4118 match self.yield_ty {
4120 self.check_expr_coercable_to_type(&value, ty);
4123 struct_span_err!(self.tcx.sess, expr.span, E0627,
4124 "yield statement outside of generator literal").emit();
4132 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4133 // The newly resolved definition is written into `type_dependent_defs`.
4134 fn finish_resolving_struct_path(&self,
4137 node_id: ast::NodeId)
4141 hir::QPath::Resolved(ref maybe_qself, ref path) => {
4142 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4143 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
4146 hir::QPath::TypeRelative(ref qself, ref segment) => {
4147 let ty = self.to_ty(qself);
4149 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
4154 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4157 // Write back the new resolution.
4158 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4159 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4166 // Resolve associated value path into a base type and associated constant or method definition.
4167 // The newly resolved definition is written into `type_dependent_defs`.
4168 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4169 qpath: &'b hir::QPath,
4170 node_id: ast::NodeId,
4172 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4174 let (ty, item_segment) = match *qpath {
4175 hir::QPath::Resolved(ref opt_qself, ref path) => {
4177 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4178 &path.segments[..]);
4180 hir::QPath::TypeRelative(ref qself, ref segment) => {
4181 (self.to_ty(qself), segment)
4184 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4185 if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4186 // Return directly on cache hit. This is useful to avoid doubly reporting
4187 // errors with default match binding modes. See #44614.
4188 return (*cached_def, Some(ty), slice::ref_slice(&**item_segment))
4190 let item_name = item_segment.name;
4191 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
4194 let def = match error {
4195 method::MethodError::PrivateMatch(def, _) => def,
4198 if item_name != keywords::Invalid.name() {
4199 self.report_method_error(span, ty, item_name, None, error, None);
4205 // Write back the new resolution.
4206 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4207 (def, Some(ty), slice::ref_slice(&**item_segment))
4210 pub fn check_decl_initializer(&self,
4211 local: &'gcx hir::Local,
4212 init: &'gcx hir::Expr) -> Ty<'tcx>
4214 // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed
4215 // for #42640 (default match binding modes).
4218 let ref_bindings = local.pat.contains_explicit_ref_binding();
4220 let local_ty = self.local_ty(init.span, local.id);
4221 if let Some(m) = ref_bindings {
4222 // Somewhat subtle: if we have a `ref` binding in the pattern,
4223 // we want to avoid introducing coercions for the RHS. This is
4224 // both because it helps preserve sanity and, in the case of
4225 // ref mut, for soundness (issue #23116). In particular, in
4226 // the latter case, we need to be clear that the type of the
4227 // referent for the reference that results is *equal to* the
4228 // type of the lvalue it is referencing, and not some
4229 // supertype thereof.
4230 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
4231 self.demand_eqtype(init.span, init_ty, local_ty);
4234 self.check_expr_coercable_to_type(init, local_ty)
4238 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4239 let t = self.local_ty(local.span, local.id);
4240 self.write_ty(local.hir_id, t);
4242 if let Some(ref init) = local.init {
4243 let init_ty = self.check_decl_initializer(local, &init);
4244 if init_ty.references_error() {
4245 self.write_ty(local.hir_id, init_ty);
4249 self.check_pat_walk(&local.pat, t,
4250 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4252 let pat_ty = self.node_ty(local.pat.hir_id);
4253 if pat_ty.references_error() {
4254 self.write_ty(local.hir_id, pat_ty);
4258 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4259 // Don't do all the complex logic below for DeclItem.
4261 hir::StmtDecl(ref decl, _) => {
4263 hir::DeclLocal(_) => {}
4264 hir::DeclItem(_) => {
4269 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4272 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4274 // Hide the outer diverging and has_errors flags.
4275 let old_diverges = self.diverges.get();
4276 let old_has_errors = self.has_errors.get();
4277 self.diverges.set(Diverges::Maybe);
4278 self.has_errors.set(false);
4281 hir::StmtDecl(ref decl, _) => {
4283 hir::DeclLocal(ref l) => {
4284 self.check_decl_local(&l);
4286 hir::DeclItem(_) => {/* ignore for now */}
4289 hir::StmtExpr(ref expr, _) => {
4290 // Check with expected type of ()
4291 self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
4293 hir::StmtSemi(ref expr, _) => {
4294 self.check_expr(&expr);
4298 // Combine the diverging and has_error flags.
4299 self.diverges.set(self.diverges.get() | old_diverges);
4300 self.has_errors.set(self.has_errors.get() | old_has_errors);
4303 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4304 let unit = self.tcx.mk_nil();
4305 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4307 // if the block produces a `!` value, that can always be
4308 // (effectively) coerced to unit.
4310 self.demand_suptype(blk.span, unit, ty);
4314 fn check_block_with_expected(&self,
4315 blk: &'gcx hir::Block,
4316 expected: Expectation<'tcx>) -> Ty<'tcx> {
4318 let mut fcx_ps = self.ps.borrow_mut();
4319 let unsafety_state = fcx_ps.recurse(blk);
4320 replace(&mut *fcx_ps, unsafety_state)
4323 // In some cases, blocks have just one exit, but other blocks
4324 // can be targeted by multiple breaks. This cannot happen in
4325 // normal Rust syntax today, but it can happen when we desugar
4326 // a `do catch { ... }` expression.
4330 // 'a: { if true { break 'a Err(()); } Ok(()) }
4332 // Here we would wind up with two coercions, one from
4333 // `Err(())` and the other from the tail expression
4334 // `Ok(())`. If the tail expression is omitted, that's a
4335 // "forced unit" -- unless the block diverges, in which
4336 // case we can ignore the tail expression (e.g., `'a: {
4337 // break 'a 22; }` would not force the type of the block
4339 let tail_expr = blk.expr.as_ref();
4340 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4341 let coerce = if blk.targeted_by_break {
4342 CoerceMany::new(coerce_to_ty)
4344 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4345 Some(e) => ref_slice(e),
4348 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4351 let prev_diverges = self.diverges.get();
4352 let ctxt = BreakableCtxt {
4353 coerce: Some(coerce),
4357 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4358 for s in &blk.stmts {
4362 // check the tail expression **without** holding the
4363 // `enclosing_breakables` lock below.
4364 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4366 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4367 let ctxt = enclosing_breakables.find_breakable(blk.id);
4368 let coerce = ctxt.coerce.as_mut().unwrap();
4369 if let Some(tail_expr_ty) = tail_expr_ty {
4370 let tail_expr = tail_expr.unwrap();
4371 let cause = self.cause(tail_expr.span,
4372 ObligationCauseCode::BlockTailExpression(blk.id));
4377 self.diverges.get());
4379 // Subtle: if there is no explicit tail expression,
4380 // that is typically equivalent to a tail expression
4381 // of `()` -- except if the block diverges. In that
4382 // case, there is no value supplied from the tail
4383 // expression (assuming there are no other breaks,
4384 // this implies that the type of the block will be
4387 // #41425 -- label the implicit `()` as being the
4388 // "found type" here, rather than the "expected type".
4389 if !self.diverges.get().always() {
4390 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4391 if let Some(expected_ty) = expected.only_has_type(self) {
4392 self.consider_hint_about_removing_semicolon(blk,
4402 // If we can break from the block, then the block's exit is always reachable
4403 // (... as long as the entry is reachable) - regardless of the tail of the block.
4404 self.diverges.set(prev_diverges);
4407 let mut ty = ctxt.coerce.unwrap().complete(self);
4409 if self.has_errors.get() || ty.references_error() {
4410 ty = self.tcx.types.err
4413 self.write_ty(blk.hir_id, ty);
4415 *self.ps.borrow_mut() = prev;
4419 /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
4420 /// suggestion can be made, `None` otherwise.
4421 pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
4422 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4423 // `while` before reaching it, as block tail returns are not available in them.
4424 if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
4425 let parent = self.tcx.hir.get(fn_id);
4427 if let Node::NodeItem(&hir::Item {
4428 name, node: hir::ItemFn(ref decl, ..), ..
4430 decl.clone().and_then(|decl| {
4431 // This is less than ideal, it will not suggest a return type span on any
4432 // method called `main`, regardless of whether it is actually the entry point,
4433 // but it will still present it as the reason for the expected type.
4434 Some((decl, name != Symbol::intern("main")))
4436 } else if let Node::NodeTraitItem(&hir::TraitItem {
4437 node: hir::TraitItemKind::Method(hir::MethodSig {
4441 decl.clone().and_then(|decl| {
4444 } else if let Node::NodeImplItem(&hir::ImplItem {
4445 node: hir::ImplItemKind::Method(hir::MethodSig {
4449 decl.clone().and_then(|decl| {
4460 /// On implicit return expressions with mismatched types, provide the following suggestions:
4462 /// - Point out the method's return type as the reason for the expected type
4463 /// - Possible missing semicolon
4464 /// - Possible missing return type if the return type is the default, and not `fn main()`
4465 pub fn suggest_mismatched_types_on_tail(&self,
4466 err: &mut DiagnosticBuilder<'tcx>,
4467 expression: &'gcx hir::Expr,
4471 blk_id: ast::NodeId) {
4472 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4474 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4475 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4479 /// A common error is to forget to add a semicolon at the end of a block:
4483 /// bar_that_returns_u32()
4487 /// This routine checks if the return expression in a block would make sense on its own as a
4488 /// statement and the return type has been left as default or has been specified as `()`. If so,
4489 /// it suggests adding a semicolon.
4490 fn suggest_missing_semicolon(&self,
4491 err: &mut DiagnosticBuilder<'tcx>,
4492 expression: &'gcx hir::Expr,
4495 if expected.is_nil() {
4496 // `BlockTailExpression` only relevant if the tail expr would be
4497 // useful on its own.
4498 match expression.node {
4500 hir::ExprMethodCall(..) |
4502 hir::ExprWhile(..) |
4504 hir::ExprMatch(..) |
4505 hir::ExprBlock(..) => {
4506 let sp = cause_span.next_point();
4507 err.span_suggestion(sp,
4508 "try adding a semicolon",
4517 /// A possible error is to forget to add a return type that is needed:
4521 /// bar_that_returns_u32()
4525 /// This routine checks if the return type is left as default, the method is not part of an
4526 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4528 fn suggest_missing_return_type(&self,
4529 err: &mut DiagnosticBuilder<'tcx>,
4530 fn_decl: &hir::FnDecl,
4533 can_suggest: bool) {
4534 // Only suggest changing the return type for methods that
4535 // haven't set a return type at all (and aren't `fn main()` or an impl).
4536 match (&fn_decl.output, found.is_suggestable(), can_suggest) {
4537 (&hir::FunctionRetTy::DefaultReturn(span), true, true) => {
4538 err.span_suggestion(span,
4539 "try adding a return type",
4540 format!("-> {} ", found));
4542 (&hir::FunctionRetTy::DefaultReturn(span), false, true) => {
4543 err.span_label(span, "possibly return type missing here?");
4545 (&hir::FunctionRetTy::DefaultReturn(span), _, _) => {
4546 // `fn main()` must return `()`, do not suggest changing return type
4547 err.span_label(span, "expected `()` because of default return type");
4549 (&hir::FunctionRetTy::Return(ref ty), _, _) => {
4550 // Only point to return type if the expected type is the return type, as if they
4551 // are not, the expectation must have been caused by something else.
4552 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4554 let ty = AstConv::ast_ty_to_ty(self, ty);
4555 debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
4556 debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
4557 if ty.sty == expected.sty {
4558 err.span_label(sp, format!("expected `{}` because of return type",
4566 /// A common error is to add an extra semicolon:
4569 /// fn foo() -> usize {
4574 /// This routine checks if the final statement in a block is an
4575 /// expression with an explicit semicolon whose type is compatible
4576 /// with `expected_ty`. If so, it suggests removing the semicolon.
4577 fn consider_hint_about_removing_semicolon(&self,
4578 blk: &'gcx hir::Block,
4579 expected_ty: Ty<'tcx>,
4580 err: &mut DiagnosticBuilder) {
4581 // Be helpful when the user wrote `{... expr;}` and
4582 // taking the `;` off is enough to fix the error.
4583 let last_stmt = match blk.stmts.last() {
4587 let last_expr = match last_stmt.node {
4588 hir::StmtSemi(ref e, _) => e,
4591 let last_expr_ty = self.node_ty(last_expr.hir_id);
4592 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4595 let original_span = original_sp(last_stmt.span, blk.span);
4596 let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
4597 err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
4600 // Instantiates the given path, which must refer to an item with the given
4601 // number of type parameters and type.
4602 pub fn instantiate_value_path(&self,
4603 segments: &[hir::PathSegment],
4604 opt_self_ty: Option<Ty<'tcx>>,
4607 node_id: ast::NodeId)
4609 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4614 // We need to extract the type parameters supplied by the user in
4615 // the path `path`. Due to the current setup, this is a bit of a
4616 // tricky-process; the problem is that resolve only tells us the
4617 // end-point of the path resolution, and not the intermediate steps.
4618 // Luckily, we can (at least for now) deduce the intermediate steps
4619 // just from the end-point.
4621 // There are basically four cases to consider:
4623 // 1. Reference to a constructor of enum variant or struct:
4625 // struct Foo<T>(...)
4626 // enum E<T> { Foo(...) }
4628 // In these cases, the parameters are declared in the type
4631 // 2. Reference to a fn item or a free constant:
4635 // In this case, the path will again always have the form
4636 // `a::b::foo::<T>` where only the final segment should have
4637 // type parameters. However, in this case, those parameters are
4638 // declared on a value, and hence are in the `FnSpace`.
4640 // 3. Reference to a method or an associated constant:
4642 // impl<A> SomeStruct<A> {
4646 // Here we can have a path like
4647 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4648 // may appear in two places. The penultimate segment,
4649 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4650 // final segment, `foo::<B>` contains parameters in fn space.
4652 // 4. Reference to a local variable
4654 // Local variables can't have any type parameters.
4656 // The first step then is to categorize the segments appropriately.
4658 assert!(!segments.is_empty());
4660 let mut ufcs_associated = None;
4661 let mut type_segment = None;
4662 let mut fn_segment = None;
4664 // Case 1. Reference to a struct/variant constructor.
4665 Def::StructCtor(def_id, ..) |
4666 Def::VariantCtor(def_id, ..) => {
4667 // Everything but the final segment should have no
4668 // parameters at all.
4669 let mut generics = self.tcx.generics_of(def_id);
4670 if let Some(def_id) = generics.parent {
4671 // Variant and struct constructors use the
4672 // generics of their parent type definition.
4673 generics = self.tcx.generics_of(def_id);
4675 type_segment = Some((segments.last().unwrap(), generics));
4678 // Case 2. Reference to a top-level value.
4680 Def::Const(def_id) |
4681 Def::Static(def_id, _) => {
4682 fn_segment = Some((segments.last().unwrap(),
4683 self.tcx.generics_of(def_id)));
4686 // Case 3. Reference to a method or associated const.
4687 Def::Method(def_id) |
4688 Def::AssociatedConst(def_id) => {
4689 let container = self.tcx.associated_item(def_id).container;
4691 ty::TraitContainer(trait_did) => {
4692 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4694 ty::ImplContainer(_) => {}
4697 let generics = self.tcx.generics_of(def_id);
4698 if segments.len() >= 2 {
4699 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4700 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4702 // `<T>::assoc` will end up here, and so can `T::assoc`.
4703 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4704 ufcs_associated = Some((container, self_ty));
4706 fn_segment = Some((segments.last().unwrap(), generics));
4709 // Case 4. Local variable, no generics.
4710 Def::Local(..) | Def::Upvar(..) => {}
4712 _ => bug!("unexpected definition: {:?}", def),
4715 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4717 // Now that we have categorized what space the parameters for each
4718 // segment belong to, let's sort out the parameters that the user
4719 // provided (if any) into their appropriate spaces. We'll also report
4720 // errors if type parameters are provided in an inappropriate place.
4721 let poly_segments = type_segment.is_some() as usize +
4722 fn_segment.is_some() as usize;
4723 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4726 Def::Local(nid) | Def::Upvar(nid, ..) => {
4727 let ty = self.local_ty(span, nid);
4728 let ty = self.normalize_associated_types_in(span, &ty);
4729 self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
4735 // Now we have to compare the types that the user *actually*
4736 // provided against the types that were *expected*. If the user
4737 // did not provide any types, then we want to substitute inference
4738 // variables. If the user provided some types, we may still need
4739 // to add defaults. If the user provided *too many* types, that's
4741 self.check_path_parameter_count(span, &mut type_segment, false);
4742 self.check_path_parameter_count(span, &mut fn_segment, false);
4743 self.check_impl_trait(span, &mut fn_segment);
4745 let (fn_start, has_self) = match (type_segment, fn_segment) {
4746 (_, Some((_, generics))) => {
4747 (generics.parent_count(), generics.has_self)
4749 (Some((_, generics)), None) => {
4750 (generics.own_count(), generics.has_self)
4752 (None, None) => (0, false)
4754 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4755 let mut i = def.index as usize;
4757 let segment = if i < fn_start {
4758 i -= has_self as usize;
4764 let lifetimes = segment.map_or(&[][..], |(s, _)| {
4765 s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
4768 if let Some(lifetime) = lifetimes.get(i) {
4769 AstConv::ast_region_to_region(self, lifetime, Some(def))
4771 self.re_infer(span, Some(def)).unwrap()
4774 let mut i = def.index as usize;
4776 let segment = if i < fn_start {
4777 // Handle Self first, so we can adjust the index to match the AST.
4778 if has_self && i == 0 {
4779 return opt_self_ty.unwrap_or_else(|| {
4780 self.type_var_for_def(span, def, substs)
4783 i -= has_self as usize;
4789 let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
4790 (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
4793 // Skip over the lifetimes in the same segment.
4794 if let Some((_, generics)) = segment {
4795 i -= generics.regions.len();
4798 if let Some(ast_ty) = types.get(i) {
4799 // A provided type parameter.
4801 } else if !infer_types && def.has_default {
4802 // No type parameter provided, but a default exists.
4803 let default = self.tcx.type_of(def.def_id);
4806 default.subst_spanned(self.tcx, substs, Some(span))
4809 // No type parameters were provided, we can infer all.
4810 // This can also be reached in some error cases:
4811 // We prefer to use inference variables instead of
4812 // TyError to let type inference recover somewhat.
4813 self.type_var_for_def(span, def, substs)
4817 // The things we are substituting into the type should not contain
4818 // escaping late-bound regions, and nor should the base type scheme.
4819 let ty = self.tcx.type_of(def.def_id());
4820 assert!(!substs.has_escaping_regions());
4821 assert!(!ty.has_escaping_regions());
4823 // Add all the obligations that are required, substituting and
4824 // normalized appropriately.
4825 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4826 self.add_obligations_for_parameters(
4827 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4830 // Substitute the values for the type parameters into the type of
4831 // the referenced item.
4832 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4834 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4835 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4836 // is inherent, there is no `Self` parameter, instead, the impl needs
4837 // type parameters, which we can infer by unifying the provided `Self`
4838 // with the substituted impl type.
4839 let ty = self.tcx.type_of(impl_def_id);
4841 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4842 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4843 Ok(ok) => self.register_infer_ok_obligations(ok),
4846 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4853 debug!("instantiate_value_path: type of {:?} is {:?}",
4856 self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
4860 /// Report errors if the provided parameters are too few or too many.
4861 fn check_path_parameter_count(&self,
4863 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
4864 is_method_call: bool) {
4865 let (lifetimes, types, infer_types, bindings) = segment.map_or(
4866 (&[][..], &[][..], true, &[][..]),
4867 |(s, _)| s.parameters.as_ref().map_or(
4868 (&[][..], &[][..], s.infer_types, &[][..]),
4869 |p| (&p.lifetimes[..], &p.types[..],
4870 s.infer_types, &p.bindings[..])));
4871 let infer_lifetimes = lifetimes.len() == 0;
4873 let count_lifetime_params = |n| {
4874 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4876 let count_type_params = |n| {
4877 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4880 // Check provided type parameters.
4881 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4882 if generics.parent.is_none() {
4883 &generics.types[generics.has_self as usize..]
4888 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4889 if types.len() > type_defs.len() {
4890 let span = types[type_defs.len()].span;
4891 let expected_text = count_type_params(type_defs.len());
4892 let actual_text = count_type_params(types.len());
4893 struct_span_err!(self.tcx.sess, span, E0087,
4894 "too many type parameters provided: \
4895 expected at most {}, found {}",
4896 expected_text, actual_text)
4897 .span_label(span, format!("expected {}", expected_text))
4900 // To prevent derived errors to accumulate due to extra
4901 // type parameters, we force instantiate_value_path to
4902 // use inference variables instead of the provided types.
4904 } else if types.len() < required_len && !infer_types {
4905 let expected_text = count_type_params(required_len);
4906 let actual_text = count_type_params(types.len());
4907 struct_span_err!(self.tcx.sess, span, E0089,
4908 "too few type parameters provided: \
4909 expected {}, found {}",
4910 expected_text, actual_text)
4911 .span_label(span, format!("expected {}", expected_text))
4915 if !bindings.is_empty() {
4916 AstConv::prohibit_projection(self, bindings[0].span);
4919 // Check provided lifetime parameters.
4920 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4921 let required_len = lifetime_defs.len();
4923 // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
4924 let has_late_bound_lifetime_defs =
4925 segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
4926 if let (Some(span_late), false) = (has_late_bound_lifetime_defs, lifetimes.is_empty()) {
4927 // Report this as a lint only if no error was reported previously.
4928 let primary_msg = "cannot specify lifetime arguments explicitly \
4929 if late bound lifetime parameters are present";
4930 let note_msg = "the late bound lifetime parameter is introduced here";
4931 if !is_method_call && (lifetimes.len() > lifetime_defs.len() ||
4932 lifetimes.len() < required_len && !infer_lifetimes) {
4933 let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
4934 err.span_note(span_late, note_msg);
4938 let mut multispan = MultiSpan::from_span(lifetimes[0].span);
4939 multispan.push_span_label(span_late, note_msg.to_string());
4940 self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
4941 lifetimes[0].id, multispan, primary_msg);
4946 if lifetimes.len() > lifetime_defs.len() {
4947 let span = lifetimes[lifetime_defs.len()].span;
4948 let expected_text = count_lifetime_params(lifetime_defs.len());
4949 let actual_text = count_lifetime_params(lifetimes.len());
4950 struct_span_err!(self.tcx.sess, span, E0088,
4951 "too many lifetime parameters provided: \
4952 expected at most {}, found {}",
4953 expected_text, actual_text)
4954 .span_label(span, format!("expected {}", expected_text))
4956 } else if lifetimes.len() < required_len && !infer_lifetimes {
4957 let expected_text = count_lifetime_params(lifetime_defs.len());
4958 let actual_text = count_lifetime_params(lifetimes.len());
4959 struct_span_err!(self.tcx.sess, span, E0090,
4960 "too few lifetime parameters provided: \
4961 expected {}, found {}",
4962 expected_text, actual_text)
4963 .span_label(span, format!("expected {}", expected_text))
4968 /// Report error if there is an explicit type parameter when using `impl Trait`.
4969 fn check_impl_trait(&self,
4971 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4972 use hir::SyntheticTyParamKind::*;
4974 segment.map(|(path_segment, generics)| {
4975 let explicit = !path_segment.infer_types;
4976 let impl_trait = generics.types.iter()
4978 match ty_param.synthetic {
4979 Some(ImplTrait) => true,
4984 if explicit && impl_trait {
4985 let mut err = struct_span_err! {
4989 "cannot provide explicit type parameters when `impl Trait` is \
4990 used in argument position."
4998 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
5000 where F: Fn() -> Ty<'tcx>
5002 let mut ty = self.resolve_type_vars_with_obligations(ty);
5005 let alternative = f();
5008 if alternative.is_ty_var() || alternative.references_error() {
5009 if !self.is_tainted_by_errors() {
5010 type_error_struct!(self.tcx.sess, sp, ty, E0619,
5011 "the type of this value must be known in this context")
5014 self.demand_suptype(sp, self.tcx.types.err, ty);
5015 ty = self.tcx.types.err;
5017 self.demand_suptype(sp, alternative, ty);
5025 // Resolves `typ` by a single level if `typ` is a type variable. If no
5026 // resolution is possible, then an error is reported.
5027 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5028 self.structurally_resolve_type_or_else(sp, ty, || {
5033 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
5034 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5035 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5038 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5039 index = enclosing_breakables.stack.len();
5040 enclosing_breakables.by_id.insert(id, index);
5041 enclosing_breakables.stack.push(ctxt);
5045 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5046 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5047 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5048 enclosing_breakables.stack.pop().expect("missing breakable context")
5054 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5055 generics: &hir::Generics,
5057 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
5058 generics.ty_params.len(), ty);
5060 // make a vector of booleans initially false, set to true when used
5061 if generics.ty_params.is_empty() { return; }
5062 let mut tps_used = vec![false; generics.ty_params.len()];
5064 for leaf_ty in ty.walk() {
5065 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
5066 debug!("Found use of ty param num {}", idx);
5067 tps_used[idx as usize - generics.lifetimes.len()] = true;
5068 } else if let ty::TyError = leaf_ty.sty {
5069 // If there already another error, do not emit an error for not using a type Parameter
5070 assert!(tcx.sess.err_count() > 0);
5075 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
5077 struct_span_err!(tcx.sess, param.span, E0091,
5078 "type parameter `{}` is unused",
5080 .span_label(param.span, "unused type parameter")
5086 fn fatally_break_rust(sess: &Session) {
5087 let handler = sess.diagnostic();
5088 handler.span_bug_no_panic(
5090 "It looks like you're trying to break rust; would you like some ICE?",
5092 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5093 handler.note_without_error(
5094 "we would appreciate a joke overview: \
5095 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5097 handler.note_without_error(&format!("rustc {} running on {}",
5098 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5099 ::session::config::host_triple(),