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::*;
89 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
91 use namespace::Namespace;
92 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
93 use rustc::infer::anon_types::AnonTypeDecl;
94 use rustc::infer::type_variable::{TypeVariableOrigin};
95 use rustc::middle::region;
96 use rustc::mir::interpret::{GlobalId};
97 use rustc::ty::subst::{UnpackedKind, Subst, Substs};
98 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
99 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
100 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
101 use rustc::ty::fold::TypeFoldable;
102 use rustc::ty::maps::Providers;
103 use rustc::ty::util::{Representability, IntTypeExt, Discr};
104 use errors::{DiagnosticBuilder, DiagnosticId};
106 use require_c_abi_if_variadic;
107 use session::{CompileIncomplete, config, Session};
110 use util::common::{ErrorReported, indenter};
111 use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, NodeMap};
113 use std::cell::{Cell, RefCell, Ref, RefMut};
114 use rustc_data_structures::sync::Lrc;
115 use std::collections::hash_map::Entry;
117 use std::fmt::Display;
118 use std::mem::replace;
119 use std::ops::{self, Deref};
120 use rustc_target::spec::abi::Abi;
123 use syntax::codemap::original_sp;
124 use syntax::feature_gate::{GateIssue, emit_feature_err};
126 use syntax::symbol::{Symbol, LocalInternedString, keywords};
127 use syntax::util::lev_distance::find_best_match_for_name;
128 use syntax_pos::{self, BytePos, Span, MultiSpan};
130 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
131 use rustc::hir::itemlikevisit::ItemLikeVisitor;
132 use rustc::hir::map::Node;
133 use rustc::hir::{self, PatKind};
134 use rustc::middle::lang_items;
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<Box<dyn TraitEngine<'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 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
230 type Target = InferCtxt<'a, 'gcx, 'tcx>;
231 fn deref(&self) -> &Self::Target {
236 /// When type-checking an expression, we propagate downward
237 /// whatever type hint we are able in the form of an `Expectation`.
238 #[derive(Copy, Clone, Debug)]
239 pub enum Expectation<'tcx> {
240 /// We know nothing about what type this expression should have.
243 /// This expression is an `if` condition, it must resolve to `bool`.
246 /// This expression should have the type given (or some subtype)
247 ExpectHasType(Ty<'tcx>),
249 /// This expression will be cast to the `Ty`
250 ExpectCastableToType(Ty<'tcx>),
252 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
253 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
254 ExpectRvalueLikeUnsized(Ty<'tcx>),
257 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
258 // Disregard "castable to" expectations because they
259 // can lead us astray. Consider for example `if cond
260 // {22} else {c} as u8` -- if we propagate the
261 // "castable to u8" constraint to 22, it will pick the
262 // type 22u8, which is overly constrained (c might not
263 // be a u8). In effect, the problem is that the
264 // "castable to" expectation is not the tightest thing
265 // we can say, so we want to drop it in this case.
266 // The tightest thing we can say is "must unify with
267 // else branch". Note that in the case of a "has type"
268 // constraint, this limitation does not hold.
270 // If the expected type is just a type variable, then don't use
271 // an expected type. Otherwise, we might write parts of the type
272 // when checking the 'then' block which are incompatible with the
274 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
276 ExpectHasType(ety) => {
277 let ety = fcx.shallow_resolve(ety);
278 if !ety.is_ty_var() {
284 ExpectRvalueLikeUnsized(ety) => {
285 ExpectRvalueLikeUnsized(ety)
291 /// Provide an expectation for an rvalue expression given an *optional*
292 /// hint, which is not required for type safety (the resulting type might
293 /// be checked higher up, as is the case with `&expr` and `box expr`), but
294 /// is useful in determining the concrete type.
296 /// The primary use case is where the expected type is a fat pointer,
297 /// like `&[isize]`. For example, consider the following statement:
299 /// let x: &[isize] = &[1, 2, 3];
301 /// In this case, the expected type for the `&[1, 2, 3]` expression is
302 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
303 /// expectation `ExpectHasType([isize])`, that would be too strong --
304 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
305 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
306 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
307 /// which still is useful, because it informs integer literals and the like.
308 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
309 /// for examples of where this comes up,.
310 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
311 match fcx.tcx.struct_tail(ty).sty {
312 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
313 ExpectRvalueLikeUnsized(ty)
315 _ => ExpectHasType(ty)
319 // Resolves `expected` by a single level if it is a variable. If
320 // there is no expected type or resolution is not possible (e.g.,
321 // no constraints yet present), just returns `None`.
322 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
324 NoExpectation => NoExpectation,
325 ExpectIfCondition => ExpectIfCondition,
326 ExpectCastableToType(t) => {
327 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
329 ExpectHasType(t) => {
330 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
332 ExpectRvalueLikeUnsized(t) => {
333 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
338 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
339 match self.resolve(fcx) {
340 NoExpectation => None,
341 ExpectIfCondition => Some(fcx.tcx.types.bool),
342 ExpectCastableToType(ty) |
344 ExpectRvalueLikeUnsized(ty) => Some(ty),
348 /// It sometimes happens that we want to turn an expectation into
349 /// a **hard constraint** (i.e., something that must be satisfied
350 /// for the program to type-check). `only_has_type` will return
351 /// such a constraint, if it exists.
352 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
353 match self.resolve(fcx) {
354 ExpectHasType(ty) => Some(ty),
355 ExpectIfCondition => Some(fcx.tcx.types.bool),
356 NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
360 /// Like `only_has_type`, but instead of returning `None` if no
361 /// hard constraint exists, creates a fresh type variable.
362 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
363 self.only_has_type(fcx)
364 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
368 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
375 fn maybe_mut_place(m: hir::Mutability) -> Self {
377 hir::MutMutable => Needs::MutPlace,
378 hir::MutImmutable => Needs::None,
383 #[derive(Copy, Clone)]
384 pub struct UnsafetyState {
385 pub def: ast::NodeId,
386 pub unsafety: hir::Unsafety,
387 pub unsafe_push_count: u32,
392 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
393 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
396 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
397 match self.unsafety {
398 // If this unsafe, then if the outer function was already marked as
399 // unsafe we shouldn't attribute the unsafe'ness to the block. This
400 // way the block can be warned about instead of ignoring this
401 // extraneous block (functions are never warned about).
402 hir::Unsafety::Unsafe if self.from_fn => *self,
405 let (unsafety, def, count) = match blk.rules {
406 hir::PushUnsafeBlock(..) =>
407 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
408 hir::PopUnsafeBlock(..) =>
409 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
410 hir::UnsafeBlock(..) =>
411 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
413 (unsafety, self.def, self.unsafe_push_count),
417 unsafe_push_count: count,
424 #[derive(Debug, Copy, Clone)]
430 /// Tracks whether executing a node may exit normally (versus
431 /// return/break/panic, which "diverge", leaving dead code in their
432 /// wake). Tracked semi-automatically (through type variables marked
433 /// as diverging), with some manual adjustments for control-flow
434 /// primitives (approximating a CFG).
435 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
437 /// Potentially unknown, some cases converge,
438 /// others require a CFG to determine them.
441 /// Definitely known to diverge and therefore
442 /// not reach the next sibling or its parent.
445 /// Same as `Always` but with a reachability
446 /// warning already emitted
450 // Convenience impls for combinig `Diverges`.
452 impl ops::BitAnd for Diverges {
454 fn bitand(self, other: Self) -> Self {
455 cmp::min(self, other)
459 impl ops::BitOr for Diverges {
461 fn bitor(self, other: Self) -> Self {
462 cmp::max(self, other)
466 impl ops::BitAndAssign for Diverges {
467 fn bitand_assign(&mut self, other: Self) {
468 *self = *self & other;
472 impl ops::BitOrAssign for Diverges {
473 fn bitor_assign(&mut self, other: Self) {
474 *self = *self | other;
479 fn always(self) -> bool {
480 self >= Diverges::Always
484 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
487 // this is `null` for loops where break with a value is illegal,
488 // such as `while`, `for`, and `while let`
489 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
492 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
493 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
494 by_id: NodeMap<usize>,
497 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
498 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
499 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
500 bug!("could not find enclosing breakable with id {}", target_id);
506 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
507 body_id: ast::NodeId,
509 /// The parameter environment used for proving trait obligations
510 /// in this function. This can change when we descend into
511 /// closures (as they bring new things into scope), hence it is
512 /// not part of `Inherited` (as of the time of this writing,
513 /// closures do not yet change the environment, but they will
515 param_env: ty::ParamEnv<'tcx>,
517 // Number of errors that had been reported when we started
518 // checking this function. On exit, if we find that *more* errors
519 // have been reported, we will skip regionck and other work that
520 // expects the types within the function to be consistent.
521 err_count_on_creation: usize,
523 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
525 yield_ty: Option<Ty<'tcx>>,
527 ps: RefCell<UnsafetyState>,
529 /// Whether the last checked node generates a divergence (e.g.,
530 /// `return` will set this to Always). In general, when entering
531 /// an expression or other node in the tree, the initial value
532 /// indicates whether prior parts of the containing expression may
533 /// have diverged. It is then typically set to `Maybe` (and the
534 /// old value remembered) for processing the subparts of the
535 /// current expression. As each subpart is processed, they may set
536 /// the flag to `Always` etc. Finally, at the end, we take the
537 /// result and "union" it with the original value, so that when we
538 /// return the flag indicates if any subpart of the the parent
539 /// expression (up to and including this part) has diverged. So,
540 /// if you read it after evaluating a subexpression `X`, the value
541 /// you get indicates whether any subexpression that was
542 /// evaluating up to and including `X` diverged.
544 /// We currently use this flag only for diagnostic purposes:
546 /// - To warn about unreachable code: if, after processing a
547 /// sub-expression but before we have applied the effects of the
548 /// current node, we see that the flag is set to `Always`, we
549 /// can issue a warning. This corresponds to something like
550 /// `foo(return)`; we warn on the `foo()` expression. (We then
551 /// update the flag to `WarnedAlways` to suppress duplicate
552 /// reports.) Similarly, if we traverse to a fresh statement (or
553 /// tail expression) from a `Always` setting, we will issue a
554 /// warning. This corresponds to something like `{return;
555 /// foo();}` or `{return; 22}`, where we would warn on the
558 /// An expression represents dead-code if, after checking it,
559 /// the diverges flag is set to something other than `Maybe`.
560 diverges: Cell<Diverges>,
562 /// Whether any child nodes have any type errors.
563 has_errors: Cell<bool>,
565 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
567 inh: &'a Inherited<'a, 'gcx, 'tcx>,
570 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
571 type Target = Inherited<'a, 'gcx, 'tcx>;
572 fn deref(&self) -> &Self::Target {
577 /// Helper type of a temporary returned by Inherited::build(...).
578 /// Necessary because we can't write the following bound:
579 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
580 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
581 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
585 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
586 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
587 -> InheritedBuilder<'a, 'gcx, 'tcx> {
588 let hir_id_root = if def_id.is_local() {
589 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
590 let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
591 DefId::local(hir_id.owner)
597 infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
603 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
604 fn enter<F, R>(&'tcx mut self, f: F) -> R
605 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
607 let def_id = self.def_id;
608 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
612 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
613 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
615 let item_id = tcx.hir.as_local_node_id(def_id);
616 let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
617 let implicit_region_bound = body_id.map(|body_id| {
618 let body = tcx.hir.body(body_id);
619 tcx.mk_region(ty::ReScope(region::Scope::CallSite(body.value.hir_id.local_id)))
623 tables: MaybeInProgressTables {
624 maybe_tables: infcx.in_progress_tables,
627 fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
628 locals: RefCell::new(NodeMap()),
629 deferred_call_resolutions: RefCell::new(DefIdMap()),
630 deferred_cast_checks: RefCell::new(Vec::new()),
631 deferred_generator_interiors: RefCell::new(Vec::new()),
632 anon_types: RefCell::new(DefIdMap()),
633 implicit_region_bound,
638 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
639 debug!("register_predicate({:?})", obligation);
640 if obligation.has_escaping_regions() {
641 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
646 .register_predicate_obligation(self, obligation);
649 fn register_predicates<I>(&self, obligations: I)
650 where I: IntoIterator<Item = traits::PredicateObligation<'tcx>> {
651 for obligation in obligations {
652 self.register_predicate(obligation);
656 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
657 self.register_predicates(infer_ok.obligations);
661 fn normalize_associated_types_in<T>(&self,
663 body_id: ast::NodeId,
664 param_env: ty::ParamEnv<'tcx>,
666 where T : TypeFoldable<'tcx>
668 let ok = self.partially_normalize_associated_types_in(span, body_id, param_env, value);
669 self.register_infer_ok_obligations(ok)
673 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
675 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
676 fn visit_item(&mut self, i: &'tcx hir::Item) {
677 check_item_type(self.tcx, i);
679 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
680 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
683 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
684 tcx.sess.track_errors(|| {
685 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
686 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
690 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
691 tcx.sess.track_errors(|| {
692 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
696 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
697 tcx.typeck_item_bodies(LOCAL_CRATE)
700 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
701 -> Result<(), CompileIncomplete>
703 debug_assert!(crate_num == LOCAL_CRATE);
704 Ok(tcx.sess.track_errors(|| {
705 for body_owner_def_id in tcx.body_owners() {
706 ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
711 fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
712 wfcheck::check_item_well_formed(tcx, def_id);
715 fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
716 wfcheck::check_trait_item(tcx, def_id);
719 fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
720 wfcheck::check_impl_item(tcx, def_id);
723 pub fn provide(providers: &mut Providers) {
724 method::provide(providers);
725 *providers = Providers {
731 check_item_well_formed,
732 check_trait_item_well_formed,
733 check_impl_item_well_formed,
738 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
740 -> Option<ty::Destructor> {
741 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
744 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
745 /// with information about it's body-id and fn-decl (if any). Otherwise,
748 /// If this function returns "some", then `typeck_tables(def_id)` will
749 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
750 /// may not succeed. In some cases where this function returns `None`
751 /// (notably closures), `typeck_tables(def_id)` would wind up
752 /// redirecting to the owning function.
753 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
755 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
757 match tcx.hir.get(id) {
758 hir::map::NodeItem(item) => {
760 hir::ItemConst(_, body) |
761 hir::ItemStatic(_, _, body) =>
763 hir::ItemFn(ref decl, .., body) =>
764 Some((body, Some(decl))),
769 hir::map::NodeTraitItem(item) => {
771 hir::TraitItemKind::Const(_, Some(body)) =>
773 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
774 Some((body, Some(&sig.decl))),
779 hir::map::NodeImplItem(item) => {
781 hir::ImplItemKind::Const(_, body) =>
783 hir::ImplItemKind::Method(ref sig, body) =>
784 Some((body, Some(&sig.decl))),
789 hir::map::NodeAnonConst(constant) => Some((constant.body, None)),
794 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
797 // Closures' tables come from their outermost function,
798 // as they are part of the same "inference environment".
799 let outer_def_id = tcx.closure_base_def_id(def_id);
800 if outer_def_id != def_id {
801 return tcx.has_typeck_tables(outer_def_id);
804 let id = tcx.hir.as_local_node_id(def_id).unwrap();
805 primary_body_of(tcx, id).is_some()
808 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
811 tcx.typeck_tables_of(def_id).used_trait_imports.clone()
814 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
816 -> &'tcx ty::TypeckTables<'tcx> {
817 // Closures' tables come from their outermost function,
818 // as they are part of the same "inference environment".
819 let outer_def_id = tcx.closure_base_def_id(def_id);
820 if outer_def_id != def_id {
821 return tcx.typeck_tables_of(outer_def_id);
824 let id = tcx.hir.as_local_node_id(def_id).unwrap();
825 let span = tcx.hir.span(id);
827 // Figure out what primary body this item has.
828 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
829 span_bug!(span, "can't type-check body of {:?}", def_id);
831 let body = tcx.hir.body(body_id);
833 let tables = Inherited::build(tcx, def_id).enter(|inh| {
834 let param_env = tcx.param_env(def_id);
835 let fcx = if let Some(decl) = fn_decl {
836 let fn_sig = tcx.fn_sig(def_id);
838 check_abi(tcx, span, fn_sig.abi());
840 // Compute the fty from point of view of inside fn.
842 tcx.liberate_late_bound_regions(def_id, &fn_sig);
844 inh.normalize_associated_types_in(body.value.span,
849 let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
852 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
853 let expected_type = tcx.type_of(def_id);
854 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
855 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
857 // Gather locals in statics (because of block expressions).
858 // This is technically unnecessary because locals in static items are forbidden,
859 // but prevents type checking from blowing up before const checking can properly
861 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
863 fcx.check_expr_coercable_to_type(&body.value, expected_type);
868 // All type checking constraints were added, try to fallback unsolved variables.
869 fcx.select_obligations_where_possible(false);
870 let mut fallback_has_occurred = false;
871 for ty in &fcx.unsolved_variables() {
872 fallback_has_occurred |= fcx.fallback_if_possible(ty);
874 fcx.select_obligations_where_possible(fallback_has_occurred);
876 // Even though coercion casts provide type hints, we check casts after fallback for
877 // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
880 // Closure and generater analysis may run after fallback
881 // because they don't constrain other type variables.
882 fcx.closure_analyze(body);
883 assert!(fcx.deferred_call_resolutions.borrow().is_empty());
884 fcx.resolve_generator_interiors(def_id);
885 fcx.select_all_obligations_or_error();
887 if fn_decl.is_some() {
888 fcx.regionck_fn(id, body);
890 fcx.regionck_expr(body);
893 fcx.resolve_type_vars_in_body(body)
896 // Consistency check our TypeckTables instance can hold all ItemLocalIds
897 // it will need to hold.
898 assert_eq!(tables.local_id_root,
899 Some(DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner)));
903 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
904 if !tcx.sess.target.target.is_abi_supported(abi) {
905 struct_span_err!(tcx.sess, span, E0570,
906 "The ABI `{}` is not supported for the current target", abi).emit()
910 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
911 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
914 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
915 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
918 // infer the variable's type
919 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
920 self.fcx.locals.borrow_mut().insert(nid, var_ty);
924 // take type that the user specified
925 self.fcx.locals.borrow_mut().insert(nid, typ);
932 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
933 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
934 NestedVisitorMap::None
937 // Add explicitly-declared locals.
938 fn visit_local(&mut self, local: &'gcx hir::Local) {
939 let o_ty = match local.ty {
941 let o_ty = self.fcx.to_ty(&ty);
943 let (c_ty, _orig_values) = self.fcx.inh.infcx.canonicalize_response(&o_ty);
944 debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
945 self.fcx.tables.borrow_mut().user_provided_tys_mut().insert(ty.hir_id, c_ty);
951 self.assign(local.span, local.id, o_ty);
953 debug!("Local variable {:?} is assigned type {}",
955 self.fcx.ty_to_string(
956 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
957 intravisit::walk_local(self, local);
960 // Add pattern bindings.
961 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
962 if let PatKind::Binding(_, _, ref path1, _) = p.node {
963 let var_ty = self.assign(p.span, p.id, None);
965 self.fcx.require_type_is_sized(var_ty, p.span,
966 traits::VariableType(p.id));
968 debug!("Pattern binding {} is assigned to {} with type {:?}",
970 self.fcx.ty_to_string(
971 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
974 intravisit::walk_pat(self, p);
977 // Don't descend into the bodies of nested closures
978 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
979 _: hir::BodyId, _: Span, _: ast::NodeId) { }
982 /// When `check_fn` is invoked on a generator (i.e., a body that
983 /// includes yield), it returns back some information about the yield
985 struct GeneratorTypes<'tcx> {
986 /// Type of value that is yielded.
987 yield_ty: ty::Ty<'tcx>,
989 /// Types that are captured (see `GeneratorInterior` for more).
990 interior: ty::Ty<'tcx>,
992 /// Indicates if the generator is movable or static (immovable)
993 movability: hir::GeneratorMovability,
996 /// Helper used for fns and closures. Does the grungy work of checking a function
997 /// body and returns the function context used for that purpose, since in the case of a fn item
998 /// there is still a bit more to do.
1001 /// * inherited: other fields inherited from the enclosing fn (if any)
1002 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1003 param_env: ty::ParamEnv<'tcx>,
1004 fn_sig: ty::FnSig<'tcx>,
1005 decl: &'gcx hir::FnDecl,
1007 body: &'gcx hir::Body,
1008 can_be_generator: Option<hir::GeneratorMovability>)
1009 -> (FnCtxt<'a, 'gcx, 'tcx>, Option<GeneratorTypes<'tcx>>)
1011 let mut fn_sig = fn_sig.clone();
1013 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
1015 // Create the function context. This is either derived from scratch or,
1016 // in the case of function expressions, based on the outer context.
1017 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
1018 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
1020 let declared_ret_ty = fn_sig.output();
1021 fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
1022 let revealed_ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &declared_ret_ty);
1023 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
1024 fn_sig = fcx.tcx.mk_fn_sig(
1025 fn_sig.inputs().iter().cloned(),
1032 let span = body.value.span;
1034 if body.is_generator && can_be_generator.is_some() {
1035 let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
1036 fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1037 fcx.yield_ty = Some(yield_ty);
1040 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
1042 // Add formal parameters.
1043 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
1044 // Check the pattern.
1045 fcx.check_pat_walk(&arg.pat, arg_ty,
1046 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
1048 // Check that argument is Sized.
1049 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
1050 // for simple cases like `fn foo(x: Trait)`,
1051 // where we would error once on the parameter as a whole, and once on the binding `x`.
1052 if arg.pat.simple_name().is_none() {
1053 fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
1056 fcx.write_ty(arg.hir_id, arg_ty);
1059 let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
1060 inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
1062 fcx.check_return_expr(&body.value);
1064 // We insert the deferred_generator_interiors entry after visiting the body.
1065 // This ensures that all nested generators appear before the entry of this generator.
1066 // resolve_generator_interiors relies on this property.
1067 let gen_ty = if can_be_generator.is_some() && body.is_generator {
1068 let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
1069 fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
1070 Some(GeneratorTypes {
1071 yield_ty: fcx.yield_ty.unwrap(),
1073 movability: can_be_generator.unwrap(),
1079 // Finalize the return check by taking the LUB of the return types
1080 // we saw and assigning it to the expected return type. This isn't
1081 // really expected to fail, since the coercions would have failed
1082 // earlier when trying to find a LUB.
1084 // However, the behavior around `!` is sort of complex. In the
1085 // event that the `actual_return_ty` comes back as `!`, that
1086 // indicates that the fn either does not return or "returns" only
1087 // values of type `!`. In this case, if there is an expected
1088 // return type that is *not* `!`, that should be ok. But if the
1089 // return type is being inferred, we want to "fallback" to `!`:
1091 // let x = move || panic!();
1093 // To allow for that, I am creating a type variable with diverging
1094 // fallback. This was deemed ever so slightly better than unifying
1095 // the return value with `!` because it allows for the caller to
1096 // make more assumptions about the return type (e.g., they could do
1098 // let y: Option<u32> = Some(x());
1100 // which would then cause this return type to become `u32`, not
1102 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1103 let mut actual_return_ty = coercion.complete(&fcx);
1104 if actual_return_ty.is_never() {
1105 actual_return_ty = fcx.next_diverging_ty_var(
1106 TypeVariableOrigin::DivergingFn(span));
1108 fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
1110 // Check that the main return type implements the termination trait.
1111 if let Some(term_id) = fcx.tcx.lang_items().termination() {
1112 if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
1115 config::EntryMain => {
1116 let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
1117 let trait_ref = ty::TraitRef::new(term_id, substs);
1118 let return_ty_span = decl.output.span();
1119 let cause = traits::ObligationCause::new(
1120 return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
1122 inherited.register_predicate(
1123 traits::Obligation::new(
1124 cause, param_env, trait_ref.to_predicate()));
1126 config::EntryStart => {},
1135 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1138 let def_id = tcx.hir.local_def_id(id);
1139 let def = tcx.adt_def(def_id);
1140 def.destructor(tcx); // force the destructor to be evaluated
1141 check_representable(tcx, span, def_id);
1143 if def.repr.simd() {
1144 check_simd(tcx, span, def_id);
1147 check_transparent(tcx, span, def_id);
1148 check_packed(tcx, span, def_id);
1151 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1154 let def_id = tcx.hir.local_def_id(id);
1155 let def = tcx.adt_def(def_id);
1156 def.destructor(tcx); // force the destructor to be evaluated
1157 check_representable(tcx, span, def_id);
1159 check_packed(tcx, span, def_id);
1162 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1163 debug!("check_item_type(it.id={}, it.name={})",
1165 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
1166 let _indenter = indenter();
1168 // Consts can play a role in type-checking, so they are included here.
1169 hir::ItemStatic(..) => {
1170 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1172 hir::ItemConst(..) => {
1173 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1174 if it.attrs.iter().any(|a| a.check_name("wasm_custom_section")) {
1175 let def_id = tcx.hir.local_def_id(it.id);
1176 check_const_is_u8_array(tcx, def_id, it.span);
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.params.len() - generics.own_counts().lifetimes != 0 {
1229 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1230 "foreign items may not have type parameters");
1231 err.span_label(item.span, "can't have type parameters");
1232 // FIXME: once we start storing spans for type arguments, turn this into a
1234 err.help("use specialization instead of type parameters by replacing them \
1235 with concrete types like `u32`");
1239 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1240 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1245 _ => {/* nothing to do */ }
1249 fn check_const_is_u8_array<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1252 match tcx.type_of(def_id).sty {
1253 ty::TyArray(t, _) => {
1255 ty::TyUint(ast::UintTy::U8) => return,
1261 tcx.sess.span_err(span, "must be an array of bytes like `[u8; N]`");
1264 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1265 trait_def_id: DefId,
1267 let item_def_id = tcx.hir.local_def_id(item.id);
1268 // an error would be reported if this fails.
1269 let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
1272 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1273 impl_item: &hir::ImplItem,
1276 let mut err = struct_span_err!(
1277 tcx.sess, impl_item.span, E0520,
1278 "`{}` specializes an item from a parent `impl`, but \
1279 that item is not marked `default`",
1281 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1284 match tcx.span_of_impl(parent_impl) {
1286 err.span_label(span, "parent `impl` is here");
1287 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1291 err.note(&format!("parent implementation is in crate `{}`", cname));
1298 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1299 trait_def: &ty::TraitDef,
1300 trait_item: &ty::AssociatedItem,
1302 impl_item: &hir::ImplItem)
1304 let ancestors = trait_def.ancestors(tcx, impl_id);
1306 let kind = match impl_item.node {
1307 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1308 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1309 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1312 let parent = ancestors.defs(tcx, trait_item.name, kind, trait_def.def_id).skip(1).next()
1313 .map(|node_item| node_item.map(|parent| parent.defaultness));
1315 if let Some(parent) = parent {
1316 if tcx.impl_item_is_final(&parent) {
1317 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1323 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1326 impl_trait_ref: ty::TraitRef<'tcx>,
1327 impl_item_refs: &[hir::ImplItemRef]) {
1328 let impl_span = tcx.sess.codemap().def_span(impl_span);
1330 // If the trait reference itself is erroneous (so the compilation is going
1331 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1332 // isn't populated for such impls.
1333 if impl_trait_ref.references_error() { return; }
1335 // Locate trait definition and items
1336 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1337 let mut overridden_associated_type = None;
1339 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1341 // Check existing impl methods to see if they are both present in trait
1342 // and compatible with trait signature
1343 for impl_item in impl_items() {
1344 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1345 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1346 .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
1347 tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1349 // Not compatible, but needed for the error message
1350 tcx.associated_items(impl_trait_ref.def_id)
1351 .find(|ac| tcx.hygienic_eq(ty_impl_item.name, ac.name, impl_trait_ref.def_id))
1354 // Check that impl definition matches trait definition
1355 if let Some(ty_trait_item) = ty_trait_item {
1356 match impl_item.node {
1357 hir::ImplItemKind::Const(..) => {
1358 // Find associated const definition.
1359 if ty_trait_item.kind == ty::AssociatedKind::Const {
1360 compare_const_impl(tcx,
1366 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1367 "item `{}` is an associated const, \
1368 which doesn't match its trait `{}`",
1371 err.span_label(impl_item.span, "does not match trait");
1372 // We can only get the spans from local trait definition
1373 // Same for E0324 and E0325
1374 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1375 err.span_label(trait_span, "item in trait");
1380 hir::ImplItemKind::Method(..) => {
1381 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1382 if ty_trait_item.kind == ty::AssociatedKind::Method {
1383 compare_impl_method(tcx,
1390 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1391 "item `{}` is an associated method, \
1392 which doesn't match its trait `{}`",
1395 err.span_label(impl_item.span, "does not match trait");
1396 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1397 err.span_label(trait_span, "item in trait");
1402 hir::ImplItemKind::Type(_) => {
1403 if ty_trait_item.kind == ty::AssociatedKind::Type {
1404 if ty_trait_item.defaultness.has_value() {
1405 overridden_associated_type = Some(impl_item);
1408 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1409 "item `{}` is an associated type, \
1410 which doesn't match its trait `{}`",
1413 err.span_label(impl_item.span, "does not match trait");
1414 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1415 err.span_label(trait_span, "item in trait");
1422 check_specialization_validity(tcx, trait_def, &ty_trait_item, impl_id, impl_item);
1426 // Check for missing items from trait
1427 let mut missing_items = Vec::new();
1428 let mut invalidated_items = Vec::new();
1429 let associated_type_overridden = overridden_associated_type.is_some();
1430 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1431 let is_implemented = trait_def.ancestors(tcx, impl_id)
1432 .defs(tcx, trait_item.name, trait_item.kind, impl_trait_ref.def_id)
1434 .map(|node_item| !node_item.node.is_from_trait())
1437 if !is_implemented && !tcx.impl_is_default(impl_id) {
1438 if !trait_item.defaultness.has_value() {
1439 missing_items.push(trait_item);
1440 } else if associated_type_overridden {
1441 invalidated_items.push(trait_item.name);
1446 if !missing_items.is_empty() {
1447 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1448 "not all trait items implemented, missing: `{}`",
1449 missing_items.iter()
1450 .map(|trait_item| trait_item.name.to_string())
1451 .collect::<Vec<_>>().join("`, `"));
1452 err.span_label(impl_span, format!("missing `{}` in implementation",
1453 missing_items.iter()
1454 .map(|trait_item| trait_item.name.to_string())
1455 .collect::<Vec<_>>().join("`, `")));
1456 for trait_item in missing_items {
1457 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1458 err.span_label(span, format!("`{}` from trait", trait_item.name));
1460 err.note_trait_signature(trait_item.name.to_string(),
1461 trait_item.signature(&tcx));
1467 if !invalidated_items.is_empty() {
1468 let invalidator = overridden_associated_type.unwrap();
1469 span_err!(tcx.sess, invalidator.span, E0399,
1470 "the following trait items need to be reimplemented \
1471 as `{}` was overridden: `{}`",
1473 invalidated_items.iter()
1474 .map(|name| name.to_string())
1475 .collect::<Vec<_>>().join("`, `"))
1479 /// Checks whether a type can be represented in memory. In particular, it
1480 /// identifies types that contain themselves without indirection through a
1481 /// pointer, which would mean their size is unbounded.
1482 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1486 let rty = tcx.type_of(item_def_id);
1488 // Check that it is possible to represent this type. This call identifies
1489 // (1) types that contain themselves and (2) types that contain a different
1490 // recursive type. It is only necessary to throw an error on those that
1491 // contain themselves. For case 2, there must be an inner type that will be
1492 // caught by case 1.
1493 match rty.is_representable(tcx, sp) {
1494 Representability::SelfRecursive(spans) => {
1495 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1497 err.span_label(span, "recursive without indirection");
1502 Representability::Representable | Representability::ContainsRecursive => (),
1507 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1508 let t = tcx.type_of(def_id);
1510 ty::TyAdt(def, substs) if def.is_struct() => {
1511 let fields = &def.non_enum_variant().fields;
1512 if fields.is_empty() {
1513 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1516 let e = fields[0].ty(tcx, substs);
1517 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1518 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1519 .span_label(sp, "SIMD elements must have the same type")
1524 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1525 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1527 span_err!(tcx.sess, sp, E0077,
1528 "SIMD vector element type should be machine type");
1537 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1538 let repr = tcx.adt_def(def_id).repr;
1540 for attr in tcx.get_attrs(def_id).iter() {
1541 for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
1542 if let attr::ReprPacked(pack) = r {
1543 if pack != repr.pack {
1544 struct_span_err!(tcx.sess, sp, E0634,
1545 "type has conflicting packed representation hints").emit();
1551 struct_span_err!(tcx.sess, sp, E0587,
1552 "type has conflicting packed and align representation hints").emit();
1554 else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1555 struct_span_err!(tcx.sess, sp, E0588,
1556 "packed type cannot transitively contain a `[repr(align)]` type").emit();
1561 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1563 stack: &mut Vec<DefId>) -> bool {
1564 let t = tcx.type_of(def_id);
1565 if stack.contains(&def_id) {
1566 debug!("check_packed_inner: {:?} is recursive", t);
1570 ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => {
1571 if tcx.adt_def(def.did).repr.align > 0 {
1574 // push struct def_id before checking fields
1576 for field in &def.non_enum_variant().fields {
1577 let f = field.ty(tcx, substs);
1579 ty::TyAdt(def, _) => {
1580 if check_packed_inner(tcx, def.did, stack) {
1587 // only need to pop if not early out
1595 fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1596 let adt = tcx.adt_def(def_id);
1597 if !adt.repr.transparent() {
1601 // For each field, figure out if it's known to be a ZST and align(1)
1602 let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| {
1603 let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
1604 let param_env = tcx.param_env(field.did);
1605 let layout = tcx.layout_of(param_env.and(ty));
1606 // We are currently checking the type this field came from, so it must be local
1607 let span = tcx.hir.span_if_local(field.did).unwrap();
1608 let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
1609 let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false);
1613 let non_zst_fields = field_infos.iter().filter(|(_span, zst, _align1)| !*zst);
1614 let non_zst_count = non_zst_fields.clone().count();
1615 if non_zst_count != 1 {
1616 let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| *span).collect();
1617 struct_span_err!(tcx.sess, sp, E0690,
1618 "transparent struct needs exactly one non-zero-sized field, but has {}",
1620 .span_note(field_spans, "non-zero-sized field")
1623 for &(span, zst, align1) in &field_infos {
1625 span_err!(tcx.sess, span, E0691,
1626 "zero-sized field in transparent struct has alignment larger than 1");
1631 #[allow(trivial_numeric_casts)]
1632 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1634 vs: &'tcx [hir::Variant],
1636 let def_id = tcx.hir.local_def_id(id);
1637 let def = tcx.adt_def(def_id);
1638 def.destructor(tcx); // force the destructor to be evaluated
1641 let attributes = tcx.get_attrs(def_id);
1642 if let Some(attr) = attr::find_by_name(&attributes, "repr") {
1644 tcx.sess, attr.span, E0084,
1645 "unsupported representation for zero-variant enum")
1646 .span_label(sp, "zero-variant enum")
1651 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1652 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1653 if !tcx.features().repr128 {
1654 emit_feature_err(&tcx.sess.parse_sess,
1657 GateIssue::Language,
1658 "repr with 128-bit type is unstable");
1663 if let Some(ref e) = v.node.disr_expr {
1664 tcx.typeck_tables_of(tcx.hir.local_def_id(e.id));
1668 let mut disr_vals: Vec<Discr<'tcx>> = Vec::new();
1669 for (discr, v) in def.discriminants(tcx).zip(vs) {
1670 // Check for duplicate discriminant values
1671 if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1672 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1673 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1674 let i_span = match variant_i.node.disr_expr {
1675 Some(ref expr) => tcx.hir.span(expr.id),
1676 None => tcx.hir.span(variant_i_node_id)
1678 let span = match v.node.disr_expr {
1679 Some(ref expr) => tcx.hir.span(expr.id),
1682 struct_span_err!(tcx.sess, span, E0081,
1683 "discriminant value `{}` already exists", disr_vals[i])
1684 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1685 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1688 disr_vals.push(discr);
1691 check_representable(tcx, sp, def_id);
1694 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1695 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1697 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1698 -> ty::GenericPredicates<'tcx>
1701 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1702 let item_id = tcx.hir.ty_param_owner(node_id);
1703 let item_def_id = tcx.hir.local_def_id(item_id);
1704 let generics = tcx.generics_of(item_def_id);
1705 let index = generics.param_def_id_to_index[&def_id];
1706 ty::GenericPredicates {
1708 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1710 ty::Predicate::Trait(ref data) => {
1711 data.skip_binder().self_ty().is_param(index)
1715 }).cloned().collect()
1719 fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
1720 -> Option<ty::Region<'tcx>> {
1722 Some(def) => infer::EarlyBoundRegion(span, def.name),
1723 None => infer::MiscVariable(span)
1725 Some(self.next_region_var(v))
1728 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1729 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1732 fn ty_infer_for_def(&self,
1733 ty_param_def: &ty::GenericParamDef,
1734 span: Span) -> Ty<'tcx> {
1735 if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
1741 fn projected_ty_from_poly_trait_ref(&self,
1744 poly_trait_ref: ty::PolyTraitRef<'tcx>)
1747 let (trait_ref, _) =
1748 self.replace_late_bound_regions_with_fresh_var(
1750 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
1753 self.tcx().mk_projection(item_def_id, trait_ref.substs)
1756 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1757 if ty.has_escaping_regions() {
1758 ty // FIXME: normalization and escaping regions
1760 self.normalize_associated_types_in(span, &ty)
1764 fn set_tainted_by_errors(&self) {
1765 self.infcx.set_tainted_by_errors()
1768 fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1769 self.write_ty(hir_id, ty)
1773 /// Controls whether the arguments are tupled. This is used for the call
1776 /// Tupling means that all call-side arguments are packed into a tuple and
1777 /// passed as a single parameter. For example, if tupling is enabled, this
1780 /// fn f(x: (isize, isize))
1782 /// Can be called as:
1789 #[derive(Clone, Eq, PartialEq)]
1790 enum TupleArgumentsFlag {
1795 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1796 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1797 param_env: ty::ParamEnv<'tcx>,
1798 body_id: ast::NodeId)
1799 -> FnCtxt<'a, 'gcx, 'tcx> {
1803 err_count_on_creation: inh.tcx.sess.err_count(),
1806 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1807 ast::CRATE_NODE_ID)),
1808 diverges: Cell::new(Diverges::Maybe),
1809 has_errors: Cell::new(false),
1810 enclosing_breakables: RefCell::new(EnclosingBreakables {
1818 pub fn sess(&self) -> &Session {
1822 pub fn err_count_since_creation(&self) -> usize {
1823 self.tcx.sess.err_count() - self.err_count_on_creation
1826 /// Produce warning on the given node, if the current point in the
1827 /// function is unreachable, and there hasn't been another warning.
1828 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1829 if self.diverges.get() == Diverges::Always {
1830 self.diverges.set(Diverges::WarnedAlways);
1832 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1834 self.tcx().lint_node(
1835 lint::builtin::UNREACHABLE_CODE,
1837 &format!("unreachable {}", kind));
1843 code: ObligationCauseCode<'tcx>)
1844 -> ObligationCause<'tcx> {
1845 ObligationCause::new(span, self.body_id, code)
1848 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1849 self.cause(span, ObligationCauseCode::MiscObligation)
1852 /// Resolves type variables in `ty` if possible. Unlike the infcx
1853 /// version (resolve_type_vars_if_possible), this version will
1854 /// also select obligations if it seems useful, in an effort
1855 /// to get more type information.
1856 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1857 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1859 // No TyInfer()? Nothing needs doing.
1860 if !ty.has_infer_types() {
1861 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1865 // If `ty` is a type variable, see whether we already know what it is.
1866 ty = self.resolve_type_vars_if_possible(&ty);
1867 if !ty.has_infer_types() {
1868 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1872 // If not, try resolving pending obligations as much as
1873 // possible. This can help substantially when there are
1874 // indirect dependencies that don't seem worth tracking
1876 self.select_obligations_where_possible(false);
1877 ty = self.resolve_type_vars_if_possible(&ty);
1879 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1883 fn record_deferred_call_resolution(&self,
1884 closure_def_id: DefId,
1885 r: DeferredCallResolution<'gcx, 'tcx>) {
1886 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1887 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1890 fn remove_deferred_call_resolutions(&self,
1891 closure_def_id: DefId)
1892 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1894 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1895 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1898 pub fn tag(&self) -> String {
1899 let self_ptr: *const FnCtxt = self;
1900 format!("{:?}", self_ptr)
1903 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1904 match self.locals.borrow().get(&nid) {
1907 span_bug!(span, "no type for local variable {}",
1908 self.tcx.hir.node_to_string(nid));
1914 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
1915 debug!("write_ty({:?}, {:?}) in fcx {}",
1916 id, self.resolve_type_vars_if_possible(&ty), self.tag());
1917 self.tables.borrow_mut().node_types_mut().insert(id, ty);
1919 if ty.references_error() {
1920 self.has_errors.set(true);
1921 self.set_tainted_by_errors();
1925 pub fn write_field_index(&self, node_id: ast::NodeId, index: usize) {
1926 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
1927 self.tables.borrow_mut().field_indices_mut().insert(hir_id, index);
1930 // The NodeId and the ItemLocalId must identify the same item. We just pass
1931 // both of them for consistency checking.
1932 pub fn write_method_call(&self,
1934 method: MethodCallee<'tcx>) {
1937 .type_dependent_defs_mut()
1938 .insert(hir_id, Def::Method(method.def_id));
1939 self.write_substs(hir_id, method.substs);
1942 pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
1943 if !substs.is_noop() {
1944 debug!("write_substs({:?}, {:?}) in fcx {}",
1949 self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
1953 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1954 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1960 match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
1961 Entry::Vacant(entry) => { entry.insert(adj); },
1962 Entry::Occupied(mut entry) => {
1963 debug!(" - composing on top of {:?}", entry.get());
1964 match (&entry.get()[..], &adj[..]) {
1965 // Applying any adjustment on top of a NeverToAny
1966 // is a valid NeverToAny adjustment, because it can't
1968 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1970 Adjustment { kind: Adjust::Deref(_), .. },
1971 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1973 Adjustment { kind: Adjust::Deref(_), .. },
1974 .. // Any following adjustments are allowed.
1976 // A reborrow has no effect before a dereference.
1978 // FIXME: currently we never try to compose autoderefs
1979 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1981 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1982 expr, entry.get(), adj)
1984 *entry.get_mut() = adj;
1989 /// Basically whenever we are converting from a type scheme into
1990 /// the fn body space, we always want to normalize associated
1991 /// types as well. This function combines the two.
1992 fn instantiate_type_scheme<T>(&self,
1994 substs: &Substs<'tcx>,
1997 where T : TypeFoldable<'tcx>
1999 let value = value.subst(self.tcx, substs);
2000 let result = self.normalize_associated_types_in(span, &value);
2001 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
2008 /// As `instantiate_type_scheme`, but for the bounds found in a
2009 /// generic type scheme.
2010 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
2011 -> ty::InstantiatedPredicates<'tcx> {
2012 let bounds = self.tcx.predicates_of(def_id);
2013 let result = bounds.instantiate(self.tcx, substs);
2014 let result = self.normalize_associated_types_in(span, &result);
2015 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
2022 /// Replace the anonymized types from the return value of the
2023 /// function with type variables and records the `AnonTypeMap` for
2024 /// later use during writeback. See
2025 /// `InferCtxt::instantiate_anon_types` for more details.
2026 fn instantiate_anon_types_from_return_value<T: TypeFoldable<'tcx>>(
2031 let fn_def_id = self.tcx.hir.local_def_id(fn_id);
2033 "instantiate_anon_types_from_return_value(fn_def_id={:?}, value={:?})",
2038 let (value, anon_type_map) = self.register_infer_ok_obligations(
2039 self.instantiate_anon_types(
2047 let mut anon_types = self.anon_types.borrow_mut();
2048 for (ty, decl) in anon_type_map {
2049 let old_value = anon_types.insert(ty, decl);
2050 assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
2056 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
2057 where T : TypeFoldable<'tcx>
2059 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
2062 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
2064 where T : TypeFoldable<'tcx>
2066 self.inh.partially_normalize_associated_types_in(span,
2072 pub fn require_type_meets(&self,
2075 code: traits::ObligationCauseCode<'tcx>,
2078 self.register_bound(
2081 traits::ObligationCause::new(span, self.body_id, code));
2084 pub fn require_type_is_sized(&self,
2087 code: traits::ObligationCauseCode<'tcx>)
2089 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
2090 self.require_type_meets(ty, span, code, lang_item);
2093 pub fn register_bound(&self,
2096 cause: traits::ObligationCause<'tcx>)
2098 self.fulfillment_cx.borrow_mut()
2099 .register_bound(self, self.param_env, ty, def_id, cause);
2102 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
2103 let t = AstConv::ast_ty_to_ty(self, ast_t);
2104 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
2108 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
2109 match self.tables.borrow().node_types().get(id) {
2111 None if self.is_tainted_by_errors() => self.tcx.types.err,
2113 let node_id = self.tcx.hir.hir_to_node_id(id);
2114 bug!("no type for node {}: {} in fcx {}",
2115 node_id, self.tcx.hir.node_to_string(node_id),
2121 /// Registers an obligation for checking later, during regionck, that the type `ty` must
2122 /// outlive the region `r`.
2123 pub fn register_wf_obligation(&self,
2126 code: traits::ObligationCauseCode<'tcx>)
2128 // WF obligations never themselves fail, so no real need to give a detailed cause:
2129 let cause = traits::ObligationCause::new(span, self.body_id, code);
2130 self.register_predicate(traits::Obligation::new(cause,
2132 ty::Predicate::WellFormed(ty)));
2135 /// Registers obligations that all types appearing in `substs` are well-formed.
2136 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
2138 for ty in substs.types() {
2139 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2143 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2144 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2145 /// trait/region obligations.
2147 /// For example, if there is a function:
2150 /// fn foo<'a,T:'a>(...)
2153 /// and a reference:
2159 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2160 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2161 pub fn add_obligations_for_parameters(&self,
2162 cause: traits::ObligationCause<'tcx>,
2163 predicates: &ty::InstantiatedPredicates<'tcx>)
2165 assert!(!predicates.has_escaping_regions());
2167 debug!("add_obligations_for_parameters(predicates={:?})",
2170 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2171 self.register_predicate(obligation);
2175 // FIXME(arielb1): use this instead of field.ty everywhere
2176 // Only for fields! Returns <none> for methods>
2177 // Indifferent to privacy flags
2178 pub fn field_ty(&self,
2180 field: &'tcx ty::FieldDef,
2181 substs: &Substs<'tcx>)
2184 self.normalize_associated_types_in(span,
2185 &field.ty(self.tcx, substs))
2188 fn check_casts(&self) {
2189 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2190 for cast in deferred_cast_checks.drain(..) {
2195 fn resolve_generator_interiors(&self, def_id: DefId) {
2196 let mut generators = self.deferred_generator_interiors.borrow_mut();
2197 for (body_id, interior) in generators.drain(..) {
2198 self.select_obligations_where_possible(false);
2199 generator_interior::resolve_interior(self, def_id, body_id, interior);
2203 // Tries to apply a fallback to `ty` if it is an unsolved variable.
2204 // Non-numerics get replaced with ! or () (depending on whether
2205 // feature(never_type) is enabled, unconstrained ints with i32,
2206 // unconstrained floats with f64.
2207 // Fallback becomes very dubious if we have encountered type-checking errors.
2208 // In that case, fallback to TyError.
2209 // The return value indicates whether fallback has occured.
2210 fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool {
2211 use rustc::ty::error::UnconstrainedNumeric::Neither;
2212 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2214 assert!(ty.is_ty_infer());
2215 let fallback = match self.type_is_unconstrained_numeric(ty) {
2216 _ if self.is_tainted_by_errors() => self.tcx().types.err,
2217 UnconstrainedInt => self.tcx.types.i32,
2218 UnconstrainedFloat => self.tcx.types.f64,
2219 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2220 Neither => return false,
2222 debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
2223 self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
2227 fn select_all_obligations_or_error(&self) {
2228 debug!("select_all_obligations_or_error");
2229 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
2230 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
2234 /// Select as many obligations as we can at present.
2235 fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2236 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2239 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
2244 fn is_place_expr(&self, expr: &hir::Expr) -> bool {
2246 hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
2248 Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
2253 hir::ExprType(ref e, _) => {
2254 self.is_place_expr(e)
2257 hir::ExprUnary(hir::UnDeref, _) |
2258 hir::ExprField(..) |
2259 hir::ExprIndex(..) => {
2263 // Partially qualified paths in expressions can only legally
2264 // refer to associated items which are always rvalues.
2265 hir::ExprPath(hir::QPath::TypeRelative(..)) |
2268 hir::ExprMethodCall(..) |
2269 hir::ExprStruct(..) |
2272 hir::ExprMatch(..) |
2273 hir::ExprClosure(..) |
2274 hir::ExprBlock(..) |
2275 hir::ExprRepeat(..) |
2276 hir::ExprArray(..) |
2277 hir::ExprBreak(..) |
2278 hir::ExprAgain(..) |
2280 hir::ExprWhile(..) |
2282 hir::ExprAssign(..) |
2283 hir::ExprInlineAsm(..) |
2284 hir::ExprAssignOp(..) |
2286 hir::ExprUnary(..) |
2288 hir::ExprAddrOf(..) |
2289 hir::ExprBinary(..) |
2290 hir::ExprYield(..) |
2291 hir::ExprCast(..) => {
2297 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
2298 /// returns a type of `&T`, but the actual type we assign to the
2299 /// *expression* is `T`. So this function just peels off the return
2300 /// type by one layer to yield `T`.
2301 fn make_overloaded_place_return_type(&self,
2302 method: MethodCallee<'tcx>)
2303 -> ty::TypeAndMut<'tcx>
2305 // extract method return type, which will be &T;
2306 let ret_ty = method.sig.output();
2308 // method returns &T, but the type as visible to user is T, so deref
2309 ret_ty.builtin_deref(true).unwrap()
2312 fn lookup_indexing(&self,
2314 base_expr: &'gcx hir::Expr,
2318 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2320 // FIXME(#18741) -- this is almost but not quite the same as the
2321 // autoderef that normal method probing does. They could likely be
2324 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2325 let mut result = None;
2326 while result.is_none() && autoderef.next().is_some() {
2327 result = self.try_index_step(expr, base_expr, &autoderef, needs, idx_ty);
2329 autoderef.finalize();
2333 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2334 /// (and otherwise adjust) `base_expr`, looking for a type which either
2335 /// supports builtin indexing or overloaded indexing.
2336 /// This loop implements one step in that search; the autoderef loop
2337 /// is implemented by `lookup_indexing`.
2338 fn try_index_step(&self,
2340 base_expr: &hir::Expr,
2341 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2344 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2346 let adjusted_ty = autoderef.unambiguous_final_ty();
2347 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2354 for &unsize in &[false, true] {
2355 let mut self_ty = adjusted_ty;
2357 // We only unsize arrays here.
2358 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2359 self_ty = self.tcx.mk_slice(element_ty);
2365 // If some lookup succeeds, write callee into table and extract index/element
2366 // type from the method signature.
2367 // If some lookup succeeded, install method in table
2368 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2369 let method = self.try_overloaded_place_op(
2370 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
2372 let result = method.map(|ok| {
2373 debug!("try_index_step: success, using overloaded indexing");
2374 let method = self.register_infer_ok_obligations(ok);
2376 let mut adjustments = autoderef.adjust_steps(needs);
2377 if let ty::TyRef(region, _, r_mutbl) = method.sig.inputs()[0].sty {
2378 let mutbl = match r_mutbl {
2379 hir::MutImmutable => AutoBorrowMutability::Immutable,
2380 hir::MutMutable => AutoBorrowMutability::Mutable {
2381 // Indexing can be desugared to a method call,
2382 // so maybe we could use two-phase here.
2383 // See the documentation of AllowTwoPhase for why that's
2384 // not the case today.
2385 allow_two_phase_borrow: AllowTwoPhase::No,
2388 adjustments.push(Adjustment {
2389 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
2390 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2397 adjustments.push(Adjustment {
2398 kind: Adjust::Unsize,
2399 target: method.sig.inputs()[0]
2402 self.apply_adjustments(base_expr, adjustments);
2404 self.write_method_call(expr.hir_id, method);
2405 (input_ty, self.make_overloaded_place_return_type(method).ty)
2407 if result.is_some() {
2415 fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2416 let (tr, name) = match (op, is_mut) {
2417 (PlaceOp::Deref, false) =>
2418 (self.tcx.lang_items().deref_trait(), "deref"),
2419 (PlaceOp::Deref, true) =>
2420 (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
2421 (PlaceOp::Index, false) =>
2422 (self.tcx.lang_items().index_trait(), "index"),
2423 (PlaceOp::Index, true) =>
2424 (self.tcx.lang_items().index_mut_trait(), "index_mut"),
2426 (tr, Symbol::intern(name))
2429 fn try_overloaded_place_op(&self,
2432 arg_tys: &[Ty<'tcx>],
2435 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2437 debug!("try_overloaded_place_op({:?},{:?},{:?},{:?})",
2443 // Try Mut first, if needed.
2444 let (mut_tr, mut_op) = self.resolve_place_op(op, true);
2445 let method = match (needs, mut_tr) {
2446 (Needs::MutPlace, Some(trait_did)) => {
2447 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2452 // Otherwise, fall back to the immutable version.
2453 let (imm_tr, imm_op) = self.resolve_place_op(op, false);
2454 let method = match (method, imm_tr) {
2455 (None, Some(trait_did)) => {
2456 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2458 (method, _) => method,
2464 fn check_method_argument_types(&self,
2467 method: Result<MethodCallee<'tcx>, ()>,
2468 args_no_rcvr: &'gcx [hir::Expr],
2469 tuple_arguments: TupleArgumentsFlag,
2470 expected: Expectation<'tcx>)
2472 let has_error = match method {
2474 method.substs.references_error() || method.sig.references_error()
2479 let err_inputs = self.err_args(args_no_rcvr.len());
2481 let err_inputs = match tuple_arguments {
2482 DontTupleArguments => err_inputs,
2483 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
2486 self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
2487 false, tuple_arguments, None);
2488 return self.tcx.types.err;
2491 let method = method.unwrap();
2492 // HACK(eddyb) ignore self in the definition (see above).
2493 let expected_arg_tys = self.expected_inputs_for_expected_output(
2496 method.sig.output(),
2497 &method.sig.inputs()[1..]
2499 self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2500 args_no_rcvr, method.sig.variadic, tuple_arguments,
2501 self.tcx.hir.span_if_local(method.def_id));
2505 /// Generic function that factors out common logic from function calls,
2506 /// method calls and overloaded operators.
2507 fn check_argument_types(&self,
2510 fn_inputs: &[Ty<'tcx>],
2511 mut expected_arg_tys: &[Ty<'tcx>],
2512 args: &'gcx [hir::Expr],
2514 tuple_arguments: TupleArgumentsFlag,
2515 def_span: Option<Span>) {
2518 // Grab the argument types, supplying fresh type variables
2519 // if the wrong number of arguments were supplied
2520 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2526 // All the input types from the fn signature must outlive the call
2527 // so as to validate implied bounds.
2528 for &fn_input_ty in fn_inputs {
2529 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2532 let expected_arg_count = fn_inputs.len();
2534 let param_count_error = |expected_count: usize,
2539 let mut err = tcx.sess.struct_span_err_with_code(sp,
2540 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2541 if variadic {"at least "} else {""},
2543 if expected_count == 1 {""} else {"s"},
2545 if arg_count == 1 {" was"} else {"s were"}),
2546 DiagnosticId::Error(error_code.to_owned()));
2548 if let Some(def_s) = def_span.map(|sp| tcx.sess.codemap().def_span(sp)) {
2549 err.span_label(def_s, "defined here");
2552 let sugg_span = tcx.sess.codemap().end_point(expr_sp);
2553 // remove closing `)` from the span
2554 let sugg_span = sugg_span.shrink_to_lo();
2555 err.span_suggestion(
2557 "expected the unit value `()`; create it with empty parentheses",
2558 String::from("()"));
2560 err.span_label(sp, format!("expected {}{} parameter{}",
2561 if variadic {"at least "} else {""},
2563 if expected_count == 1 {""} else {"s"}));
2568 let formal_tys = if tuple_arguments == TupleArguments {
2569 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2570 match tuple_type.sty {
2571 ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
2572 param_count_error(arg_types.len(), args.len(), "E0057", false, false);
2573 expected_arg_tys = &[];
2574 self.err_args(args.len())
2576 ty::TyTuple(arg_types) => {
2577 expected_arg_tys = match expected_arg_tys.get(0) {
2578 Some(&ty) => match ty.sty {
2579 ty::TyTuple(ref tys) => &tys,
2587 span_err!(tcx.sess, sp, E0059,
2588 "cannot use call notation; the first type parameter \
2589 for the function trait is neither a tuple nor unit");
2590 expected_arg_tys = &[];
2591 self.err_args(args.len())
2594 } else if expected_arg_count == supplied_arg_count {
2596 } else if variadic {
2597 if supplied_arg_count >= expected_arg_count {
2600 param_count_error(expected_arg_count, supplied_arg_count, "E0060", true, false);
2601 expected_arg_tys = &[];
2602 self.err_args(supplied_arg_count)
2605 // is the missing argument of type `()`?
2606 let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
2607 self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
2608 } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
2609 self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
2613 param_count_error(expected_arg_count, supplied_arg_count, "E0061", false, sugg_unit);
2615 expected_arg_tys = &[];
2616 self.err_args(supplied_arg_count)
2618 // If there is no expectation, expect formal_tys.
2619 let expected_arg_tys = if !expected_arg_tys.is_empty() {
2625 debug!("check_argument_types: formal_tys={:?}",
2626 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2628 // Check the arguments.
2629 // We do this in a pretty awful way: first we typecheck any arguments
2630 // that are not closures, then we typecheck the closures. This is so
2631 // that we have more information about the types of arguments when we
2632 // typecheck the functions. This isn't really the right way to do this.
2633 for &check_closures in &[false, true] {
2634 debug!("check_closures={}", check_closures);
2636 // More awful hacks: before we check argument types, try to do
2637 // an "opportunistic" vtable resolution of any trait bounds on
2638 // the call. This helps coercions.
2640 self.select_obligations_where_possible(false);
2643 // For variadic functions, we don't have a declared type for all of
2644 // the arguments hence we only do our usual type checking with
2645 // the arguments who's types we do know.
2646 let t = if variadic {
2648 } else if tuple_arguments == TupleArguments {
2653 for (i, arg) in args.iter().take(t).enumerate() {
2654 // Warn only for the first loop (the "no closures" one).
2655 // Closure arguments themselves can't be diverging, but
2656 // a previous argument can, e.g. `foo(panic!(), || {})`.
2657 if !check_closures {
2658 self.warn_if_unreachable(arg.id, arg.span, "expression");
2661 let is_closure = match arg.node {
2662 hir::ExprClosure(..) => true,
2666 if is_closure != check_closures {
2670 debug!("checking the argument");
2671 let formal_ty = formal_tys[i];
2673 // The special-cased logic below has three functions:
2674 // 1. Provide as good of an expected type as possible.
2675 let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
2677 let checked_ty = self.check_expr_with_expectation(&arg, expected);
2679 // 2. Coerce to the most detailed type that could be coerced
2680 // to, which is `expected_ty` if `rvalue_hint` returns an
2681 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2682 let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
2683 // We're processing function arguments so we definitely want to use
2684 // two-phase borrows.
2685 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
2687 // 3. Relate the expected type and the formal one,
2688 // if the expected type was used for the coercion.
2689 self.demand_suptype(arg.span, formal_ty, coerce_ty);
2693 // We also need to make sure we at least write the ty of the other
2694 // arguments which we skipped above.
2696 fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
2697 use structured_errors::{VariadicError, StructuredDiagnostic};
2698 VariadicError::new(s, span, t, cast_ty).diagnostic().emit();
2701 for arg in args.iter().skip(expected_arg_count) {
2702 let arg_ty = self.check_expr(&arg);
2704 // There are a few types which get autopromoted when passed via varargs
2705 // in C but we just error out instead and require explicit casts.
2706 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
2708 ty::TyFloat(ast::FloatTy::F32) => {
2709 variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
2711 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2712 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
2714 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2715 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
2717 ty::TyFnDef(..) => {
2718 let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
2719 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2720 variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
2728 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2729 (0..len).map(|_| self.tcx.types.err).collect()
2732 // AST fragment checking
2735 expected: Expectation<'tcx>)
2741 ast::LitKind::Str(..) => tcx.mk_static_str(),
2742 ast::LitKind::ByteStr(ref v) => {
2743 tcx.mk_imm_ref(tcx.types.re_static,
2744 tcx.mk_array(tcx.types.u8, v.len() as u64))
2746 ast::LitKind::Byte(_) => tcx.types.u8,
2747 ast::LitKind::Char(_) => tcx.types.char,
2748 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2749 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2750 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2751 let opt_ty = expected.to_option(self).and_then(|ty| {
2753 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2754 ty::TyChar => Some(tcx.types.u8),
2755 ty::TyRawPtr(..) => Some(tcx.types.usize),
2756 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2760 opt_ty.unwrap_or_else(
2761 || tcx.mk_int_var(self.next_int_var_id()))
2763 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2764 ast::LitKind::FloatUnsuffixed(_) => {
2765 let opt_ty = expected.to_option(self).and_then(|ty| {
2767 ty::TyFloat(_) => Some(ty),
2771 opt_ty.unwrap_or_else(
2772 || tcx.mk_float_var(self.next_float_var_id()))
2774 ast::LitKind::Bool(_) => tcx.types.bool
2778 fn check_expr_eq_type(&self,
2779 expr: &'gcx hir::Expr,
2780 expected: Ty<'tcx>) {
2781 let ty = self.check_expr_with_hint(expr, expected);
2782 self.demand_eqtype(expr.span, expected, ty);
2785 pub fn check_expr_has_type_or_error(&self,
2786 expr: &'gcx hir::Expr,
2787 expected: Ty<'tcx>) -> Ty<'tcx> {
2788 self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
2791 fn check_expr_meets_expectation_or_error(&self,
2792 expr: &'gcx hir::Expr,
2793 expected: Expectation<'tcx>) -> Ty<'tcx> {
2794 let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
2795 let mut ty = self.check_expr_with_expectation(expr, expected);
2797 // While we don't allow *arbitrary* coercions here, we *do* allow
2798 // coercions from ! to `expected`.
2800 assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
2801 "expression with never type wound up being adjusted");
2802 let adj_ty = self.next_diverging_ty_var(
2803 TypeVariableOrigin::AdjustmentType(expr.span));
2804 self.apply_adjustments(expr, vec![Adjustment {
2805 kind: Adjust::NeverToAny,
2811 if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
2812 // Add help to type error if this is an `if` condition with an assignment
2813 match (expected, &expr.node) {
2814 (ExpectIfCondition, &hir::ExprAssign(ref lhs, ref rhs)) => {
2815 let msg = "try comparing for equality";
2816 if let (Ok(left), Ok(right)) = (
2817 self.tcx.sess.codemap().span_to_snippet(lhs.span),
2818 self.tcx.sess.codemap().span_to_snippet(rhs.span))
2820 err.span_suggestion(expr.span, msg, format!("{} == {}", left, right));
2832 fn check_expr_coercable_to_type(&self,
2833 expr: &'gcx hir::Expr,
2834 expected: Ty<'tcx>) -> Ty<'tcx> {
2835 let ty = self.check_expr_with_hint(expr, expected);
2836 // checks don't need two phase
2837 self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
2840 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2841 expected: Ty<'tcx>) -> Ty<'tcx> {
2842 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2845 fn check_expr_with_expectation(&self,
2846 expr: &'gcx hir::Expr,
2847 expected: Expectation<'tcx>) -> Ty<'tcx> {
2848 self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
2851 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2852 self.check_expr_with_expectation(expr, NoExpectation)
2855 fn check_expr_with_needs(&self, expr: &'gcx hir::Expr, needs: Needs) -> Ty<'tcx> {
2856 self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
2859 // determine the `self` type, using fresh variables for all variables
2860 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2861 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2863 pub fn impl_self_ty(&self,
2864 span: Span, // (potential) receiver for this impl
2866 -> TypeAndSubsts<'tcx> {
2867 let ity = self.tcx.type_of(did);
2868 debug!("impl_self_ty: ity={:?}", ity);
2870 let substs = self.fresh_substs_for_item(span, did);
2871 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2873 TypeAndSubsts { substs: substs, ty: substd_ty }
2876 /// Unifies the output type with the expected type early, for more coercions
2877 /// and forward type information on the input expressions.
2878 fn expected_inputs_for_expected_output(&self,
2880 expected_ret: Expectation<'tcx>,
2881 formal_ret: Ty<'tcx>,
2882 formal_args: &[Ty<'tcx>])
2884 let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
2885 let ret_ty = match expected_ret.only_has_type(self) {
2887 None => return Vec::new()
2889 let expect_args = self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2890 // Attempt to apply a subtyping relationship between the formal
2891 // return type (likely containing type variables if the function
2892 // is polymorphic) and the expected return type.
2893 // No argument expectations are produced if unification fails.
2894 let origin = self.misc(call_span);
2895 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
2897 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2898 // to identity so the resulting type is not constrained.
2901 // Process any obligations locally as much as
2902 // we can. We don't care if some things turn
2903 // out unconstrained or ambiguous, as we're
2904 // just trying to get hints here.
2905 self.save_and_restore_in_snapshot_flag(|_| {
2906 let mut fulfill = TraitEngine::new(self.tcx);
2907 for obligation in ok.obligations {
2908 fulfill.register_predicate_obligation(self, obligation);
2910 fulfill.select_where_possible(self)
2911 }).map_err(|_| ())?;
2913 Err(_) => return Err(()),
2916 // Record all the argument types, with the substitutions
2917 // produced from the above subtyping unification.
2918 Ok(formal_args.iter().map(|ty| {
2919 self.resolve_type_vars_if_possible(ty)
2921 }).unwrap_or(Vec::new());
2922 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2923 formal_args, formal_ret,
2924 expect_args, expected_ret);
2928 // Checks a method call.
2929 fn check_method_call(&self,
2930 expr: &'gcx hir::Expr,
2931 segment: &hir::PathSegment,
2933 args: &'gcx [hir::Expr],
2934 expected: Expectation<'tcx>,
2935 needs: Needs) -> Ty<'tcx> {
2936 let rcvr = &args[0];
2937 let rcvr_t = self.check_expr_with_needs(&rcvr, needs);
2938 // no need to check for bot/err -- callee does that
2939 let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
2941 let method = match self.lookup_method(rcvr_t,
2947 self.write_method_call(expr.hir_id, method);
2951 if segment.name != keywords::Invalid.name() {
2952 self.report_method_error(span,
2963 // Call the generic checker.
2964 self.check_method_argument_types(span,
2972 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2976 .unwrap_or_else(|| span_bug!(return_expr.span,
2977 "check_return_expr called outside fn body"));
2979 let ret_ty = ret_coercion.borrow().expected_ty();
2980 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
2981 ret_coercion.borrow_mut()
2983 &self.cause(return_expr.span,
2984 ObligationCauseCode::ReturnType(return_expr.id)),
2990 // A generic function for checking the then and else in an if
2992 fn check_then_else(&self,
2993 cond_expr: &'gcx hir::Expr,
2994 then_expr: &'gcx hir::Expr,
2995 opt_else_expr: Option<&'gcx hir::Expr>,
2997 expected: Expectation<'tcx>) -> Ty<'tcx> {
2998 let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
2999 let cond_diverges = self.diverges.get();
3000 self.diverges.set(Diverges::Maybe);
3002 let expected = expected.adjust_for_branches(self);
3003 let then_ty = self.check_expr_with_expectation(then_expr, expected);
3004 let then_diverges = self.diverges.get();
3005 self.diverges.set(Diverges::Maybe);
3007 // We've already taken the expected type's preferences
3008 // into account when typing the `then` branch. To figure
3009 // out the initial shot at a LUB, we thus only consider
3010 // `expected` if it represents a *hard* constraint
3011 // (`only_has_type`); otherwise, we just go with a
3012 // fresh type variable.
3013 let coerce_to_ty = expected.coercion_target_type(self, sp);
3014 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
3016 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
3017 coerce.coerce(self, &if_cause, then_expr, then_ty);
3019 if let Some(else_expr) = opt_else_expr {
3020 let else_ty = self.check_expr_with_expectation(else_expr, expected);
3021 let else_diverges = self.diverges.get();
3023 coerce.coerce(self, &if_cause, else_expr, else_ty);
3025 // We won't diverge unless both branches do (or the condition does).
3026 self.diverges.set(cond_diverges | then_diverges & else_diverges);
3028 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
3029 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
3031 // If the condition is false we can't diverge.
3032 self.diverges.set(cond_diverges);
3035 let result_ty = coerce.complete(self);
3036 if cond_ty.references_error() {
3043 // Check field access expressions
3044 fn check_field(&self,
3045 expr: &'gcx hir::Expr,
3047 base: &'gcx hir::Expr,
3048 field: ast::Ident) -> Ty<'tcx> {
3049 let expr_t = self.check_expr_with_needs(base, needs);
3050 let expr_t = self.structurally_resolved_type(base.span,
3052 let mut private_candidate = None;
3053 let mut autoderef = self.autoderef(expr.span, expr_t);
3054 while let Some((base_t, _)) = autoderef.next() {
3056 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
3057 debug!("struct named {:?}", base_t);
3058 let (ident, def_scope) =
3059 self.tcx.adjust_ident(field, base_def.did, self.body_id);
3060 let fields = &base_def.non_enum_variant().fields;
3061 if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
3062 let field = &fields[index];
3063 let field_ty = self.field_ty(expr.span, field, substs);
3064 // Save the index of all fields regardless of their visibility in case
3065 // of error recovery.
3066 self.write_field_index(expr.id, index);
3067 if field.vis.is_accessible_from(def_scope, self.tcx) {
3068 let adjustments = autoderef.adjust_steps(needs);
3069 self.apply_adjustments(base, adjustments);
3070 autoderef.finalize();
3072 self.tcx.check_stability(field.did, Some(expr.id), expr.span);
3075 private_candidate = Some((base_def.did, field_ty));
3078 ty::TyTuple(ref tys) => {
3079 let fstr = field.as_str();
3080 if let Ok(index) = fstr.parse::<usize>() {
3081 if fstr == index.to_string() {
3082 if let Some(field_ty) = tys.get(index) {
3083 let adjustments = autoderef.adjust_steps(needs);
3084 self.apply_adjustments(base, adjustments);
3085 autoderef.finalize();
3087 self.write_field_index(expr.id, index);
3096 autoderef.unambiguous_final_ty();
3098 if let Some((did, field_ty)) = private_candidate {
3099 let struct_path = self.tcx().item_path_str(did);
3100 let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
3101 "field `{}` of struct `{}` is private",
3102 field, struct_path);
3103 // Also check if an accessible method exists, which is often what is meant.
3104 if self.method_exists(field, expr_t, expr.id, false) {
3105 err.note(&format!("a method `{}` also exists, perhaps you wish to call it", field));
3109 } else if field.name == keywords::Invalid.name() {
3110 self.tcx().types.err
3111 } else if self.method_exists(field, expr_t, expr.id, true) {
3112 type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
3113 "attempted to take value of method `{}` on type `{}`",
3115 .help("maybe a `()` to call it is missing?")
3117 self.tcx().types.err
3119 if !expr_t.is_primitive_ty() {
3120 let mut err = self.no_such_field_err(field.span, field, expr_t);
3123 ty::TyAdt(def, _) if !def.is_enum() => {
3124 if let Some(suggested_field_name) =
3125 Self::suggest_field_name(def.non_enum_variant(),
3126 &field.as_str(), vec![]) {
3127 err.span_label(field.span,
3128 format!("did you mean `{}`?", suggested_field_name));
3130 err.span_label(field.span, "unknown field");
3131 let struct_variant_def = def.non_enum_variant();
3132 let field_names = self.available_field_names(struct_variant_def);
3133 if !field_names.is_empty() {
3134 err.note(&format!("available fields are: {}",
3135 self.name_series_display(field_names)));
3139 ty::TyRawPtr(..) => {
3140 let base = self.tcx.hir.node_to_pretty_string(base.id);
3141 let msg = format!("`{}` is a native pointer; try dereferencing it", base);
3142 let suggestion = format!("(*{}).{}", base, field);
3143 err.span_suggestion(field.span, &msg, suggestion);
3149 type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
3150 "`{}` is a primitive type and therefore doesn't have fields",
3153 self.tcx().types.err
3157 // Return an hint about the closest match in field names
3158 fn suggest_field_name(variant: &'tcx ty::VariantDef,
3160 skip: Vec<LocalInternedString>)
3162 let names = variant.fields.iter().filter_map(|field| {
3163 // ignore already set fields and private fields from non-local crates
3164 if skip.iter().any(|x| *x == field.ident.as_str()) ||
3165 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3168 Some(&field.ident.name)
3172 find_best_match_for_name(names, field, None)
3175 fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
3176 let mut available = Vec::new();
3177 for field in variant.fields.iter() {
3178 let def_scope = self.tcx.adjust_ident(field.ident, variant.did, self.body_id).1;
3179 if field.vis.is_accessible_from(def_scope, self.tcx) {
3180 available.push(field.ident.name);
3186 fn name_series_display(&self, names: Vec<ast::Name>) -> String {
3187 // dynamic limit, to never omit just one field
3188 let limit = if names.len() == 6 { 6 } else { 5 };
3189 let mut display = names.iter().take(limit)
3190 .map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
3191 if names.len() > limit {
3192 display = format!("{} ... and {} others", display, names.len() - limit);
3197 fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS)
3198 -> DiagnosticBuilder {
3199 type_error_struct!(self.tcx().sess, span, expr_t, E0609,
3200 "no field `{}` on type `{}`",
3204 fn report_unknown_field(&self,
3206 variant: &'tcx ty::VariantDef,
3208 skip_fields: &[hir::Field],
3210 let mut err = self.type_error_struct_with_diag(
3212 |actual| match ty.sty {
3213 ty::TyAdt(adt, ..) if adt.is_enum() => {
3214 struct_span_err!(self.tcx.sess, field.ident.span, E0559,
3215 "{} `{}::{}` has no field named `{}`",
3216 kind_name, actual, variant.name, field.ident)
3219 struct_span_err!(self.tcx.sess, field.ident.span, E0560,
3220 "{} `{}` has no field named `{}`",
3221 kind_name, actual, field.ident)
3225 // prevent all specified fields from being suggested
3226 let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
3227 if let Some(field_name) = Self::suggest_field_name(variant,
3228 &field.ident.as_str(),
3229 skip_fields.collect()) {
3230 err.span_label(field.ident.span,
3231 format!("field does not exist - did you mean `{}`?", field_name));
3234 ty::TyAdt(adt, ..) => {
3236 err.span_label(field.ident.span,
3237 format!("`{}::{}` does not have this field",
3240 err.span_label(field.ident.span,
3241 format!("`{}` does not have this field", ty));
3243 let available_field_names = self.available_field_names(variant);
3244 if !available_field_names.is_empty() {
3245 err.note(&format!("available fields are: {}",
3246 self.name_series_display(available_field_names)));
3249 _ => bug!("non-ADT passed to report_unknown_field")
3255 fn check_expr_struct_fields(&self,
3257 expected: Expectation<'tcx>,
3258 expr_id: ast::NodeId,
3260 variant: &'tcx ty::VariantDef,
3261 ast_fields: &'gcx [hir::Field],
3262 check_completeness: bool) -> bool {
3266 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3267 .get(0).cloned().unwrap_or(adt_ty);
3268 // re-link the regions that EIfEO can erase.
3269 self.demand_eqtype(span, adt_ty_hint, adt_ty);
3271 let (substs, adt_kind, kind_name) = match &adt_ty.sty{
3272 &ty::TyAdt(adt, substs) => {
3273 (substs, adt.adt_kind(), adt.variant_descr())
3275 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3278 let mut remaining_fields = FxHashMap();
3279 for (i, field) in variant.fields.iter().enumerate() {
3280 remaining_fields.insert(field.ident.modern(), (i, field));
3283 let mut seen_fields = FxHashMap();
3285 let mut error_happened = false;
3287 // Typecheck each field.
3288 for field in ast_fields {
3289 let ident = tcx.adjust_ident(field.ident, variant.did, self.body_id).0;
3290 let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
3291 seen_fields.insert(ident, field.span);
3292 self.write_field_index(field.id, i);
3294 // we don't look at stability attributes on
3295 // struct-like enums (yet...), but it's definitely not
3296 // a bug to have construct one.
3297 if adt_kind != ty::AdtKind::Enum {
3298 tcx.check_stability(v_field.did, Some(expr_id), field.span);
3301 self.field_ty(field.span, v_field, substs)
3303 error_happened = true;
3304 if let Some(prev_span) = seen_fields.get(&ident) {
3305 let mut err = struct_span_err!(self.tcx.sess,
3308 "field `{}` specified more than once",
3311 err.span_label(field.ident.span, "used more than once");
3312 err.span_label(*prev_span, format!("first use of `{}`", ident));
3316 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3322 // Make sure to give a type to the field even if there's
3323 // an error, so we can continue typechecking
3324 self.check_expr_coercable_to_type(&field.expr, field_type);
3327 // Make sure the programmer specified correct number of fields.
3328 if kind_name == "union" {
3329 if ast_fields.len() != 1 {
3330 tcx.sess.span_err(span, "union expressions should have exactly one field");
3332 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3333 let len = remaining_fields.len();
3335 let mut displayable_field_names = remaining_fields
3337 .map(|ident| ident.as_str())
3338 .collect::<Vec<_>>();
3340 displayable_field_names.sort();
3342 let truncated_fields_error = if len <= 3 {
3345 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3348 let remaining_fields_names = displayable_field_names.iter().take(3)
3349 .map(|n| format!("`{}`", n))
3350 .collect::<Vec<_>>()
3353 struct_span_err!(tcx.sess, span, E0063,
3354 "missing field{} {}{} in initializer of `{}`",
3355 if remaining_fields.len() == 1 { "" } else { "s" },
3356 remaining_fields_names,
3357 truncated_fields_error,
3359 .span_label(span, format!("missing {}{}",
3360 remaining_fields_names,
3361 truncated_fields_error))
3367 fn check_struct_fields_on_error(&self,
3368 fields: &'gcx [hir::Field],
3369 base_expr: &'gcx Option<P<hir::Expr>>) {
3370 for field in fields {
3371 self.check_expr(&field.expr);
3375 self.check_expr(&base);
3381 pub fn check_struct_path(&self,
3383 node_id: ast::NodeId)
3384 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3385 let path_span = match *qpath {
3386 hir::QPath::Resolved(_, ref path) => path.span,
3387 hir::QPath::TypeRelative(ref qself, _) => qself.span
3389 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3390 let variant = match def {
3392 self.set_tainted_by_errors();
3395 Def::Variant(..) => {
3397 ty::TyAdt(adt, substs) => {
3398 Some((adt.variant_of_def(def), adt.did, substs))
3400 _ => bug!("unexpected type: {:?}", ty.sty)
3403 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3404 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3406 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3407 Some((adt.non_enum_variant(), adt.did, substs))
3412 _ => bug!("unexpected definition: {:?}", def)
3415 if let Some((variant, did, substs)) = variant {
3416 // Check bounds on type arguments used in the path.
3417 let bounds = self.instantiate_bounds(path_span, did, substs);
3418 let cause = traits::ObligationCause::new(path_span, self.body_id,
3419 traits::ItemObligation(did));
3420 self.add_obligations_for_parameters(cause, &bounds);
3424 struct_span_err!(self.tcx.sess, path_span, E0071,
3425 "expected struct, variant or union type, found {}",
3426 ty.sort_string(self.tcx))
3427 .span_label(path_span, "not a struct")
3433 fn check_expr_struct(&self,
3435 expected: Expectation<'tcx>,
3437 fields: &'gcx [hir::Field],
3438 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3440 // Find the relevant variant
3441 let (variant, struct_ty) =
3442 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3445 self.check_struct_fields_on_error(fields, base_expr);
3446 return self.tcx.types.err;
3449 let path_span = match *qpath {
3450 hir::QPath::Resolved(_, ref path) => path.span,
3451 hir::QPath::TypeRelative(ref qself, _) => qself.span
3454 // Prohibit struct expressions when non exhaustive flag is set.
3455 if let ty::TyAdt(adt, _) = struct_ty.sty {
3456 if !adt.did.is_local() && adt.is_non_exhaustive() {
3457 span_err!(self.tcx.sess, expr.span, E0639,
3458 "cannot create non-exhaustive {} using struct expression",
3459 adt.variant_descr());
3463 let error_happened = self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span,
3464 variant, fields, base_expr.is_none());
3465 if let &Some(ref base_expr) = base_expr {
3466 // If check_expr_struct_fields hit an error, do not attempt to populate
3467 // the fields with the base_expr. This could cause us to hit errors later
3468 // when certain fields are assumed to exist that in fact do not.
3469 if !error_happened {
3470 self.check_expr_has_type_or_error(base_expr, struct_ty);
3471 match struct_ty.sty {
3472 ty::TyAdt(adt, substs) if adt.is_struct() => {
3473 let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3474 self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3479 .fru_field_types_mut()
3480 .insert(expr.hir_id, fru_field_types);
3483 span_err!(self.tcx.sess, base_expr.span, E0436,
3484 "functional record update syntax requires a struct");
3489 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3495 /// If an expression has any sub-expressions that result in a type error,
3496 /// inspecting that expression's type with `ty.references_error()` will return
3497 /// true. Likewise, if an expression is known to diverge, inspecting its
3498 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3499 /// strict, _|_ can appear in the type of an expression that does not,
3500 /// itself, diverge: for example, fn() -> _|_.)
3501 /// Note that inspecting a type's structure *directly* may expose the fact
3502 /// that there are actually multiple representations for `TyError`, so avoid
3503 /// that when err needs to be handled differently.
3504 fn check_expr_with_expectation_and_needs(&self,
3505 expr: &'gcx hir::Expr,
3506 expected: Expectation<'tcx>,
3507 needs: Needs) -> Ty<'tcx> {
3508 debug!(">> typechecking: expr={:?} expected={:?}",
3511 // Warn for expressions after diverging siblings.
3512 self.warn_if_unreachable(expr.id, expr.span, "expression");
3514 // Hide the outer diverging and has_errors flags.
3515 let old_diverges = self.diverges.get();
3516 let old_has_errors = self.has_errors.get();
3517 self.diverges.set(Diverges::Maybe);
3518 self.has_errors.set(false);
3520 let ty = self.check_expr_kind(expr, expected, needs);
3522 // Warn for non-block expressions with diverging children.
3524 hir::ExprBlock(..) |
3525 hir::ExprLoop(..) | hir::ExprWhile(..) |
3526 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3528 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3531 // Any expression that produces a value of type `!` must have diverged
3533 self.diverges.set(self.diverges.get() | Diverges::Always);
3536 // Record the type, which applies it effects.
3537 // We need to do this after the warning above, so that
3538 // we don't warn for the diverging expression itself.
3539 self.write_ty(expr.hir_id, ty);
3541 // Combine the diverging and has_error flags.
3542 self.diverges.set(self.diverges.get() | old_diverges);
3543 self.has_errors.set(self.has_errors.get() | old_has_errors);
3545 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3546 debug!("... {:?}, expected is {:?}", ty, expected);
3551 fn check_expr_kind(&self,
3552 expr: &'gcx hir::Expr,
3553 expected: Expectation<'tcx>,
3554 needs: Needs) -> Ty<'tcx> {
3558 hir::ExprBox(ref subexpr) => {
3559 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3561 ty::TyAdt(def, _) if def.is_box()
3562 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3566 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3567 tcx.mk_box(referent_ty)
3570 hir::ExprLit(ref lit) => {
3571 self.check_lit(&lit, expected)
3573 hir::ExprBinary(op, ref lhs, ref rhs) => {
3574 self.check_binop(expr, op, lhs, rhs)
3576 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3577 self.check_binop_assign(expr, op, lhs, rhs)
3579 hir::ExprUnary(unop, ref oprnd) => {
3580 let expected_inner = match unop {
3581 hir::UnNot | hir::UnNeg => {
3588 let needs = match unop {
3589 hir::UnDeref => needs,
3592 let mut oprnd_t = self.check_expr_with_expectation_and_needs(&oprnd,
3596 if !oprnd_t.references_error() {
3597 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3600 if let Some(mt) = oprnd_t.builtin_deref(true) {
3602 } else if let Some(ok) = self.try_overloaded_deref(
3603 expr.span, oprnd_t, needs) {
3604 let method = self.register_infer_ok_obligations(ok);
3605 if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
3606 let mutbl = match mutbl {
3607 hir::MutImmutable => AutoBorrowMutability::Immutable,
3608 hir::MutMutable => AutoBorrowMutability::Mutable {
3609 // (It shouldn't actually matter for unary ops whether
3610 // we enable two-phase borrows or not, since a unary
3611 // op has no additional operands.)
3612 allow_two_phase_borrow: AllowTwoPhase::No,
3615 self.apply_adjustments(oprnd, vec![Adjustment {
3616 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
3617 target: method.sig.inputs()[0]
3620 oprnd_t = self.make_overloaded_place_return_type(method).ty;
3621 self.write_method_call(expr.hir_id, method);
3623 type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3624 "type `{}` cannot be dereferenced",
3626 oprnd_t = tcx.types.err;
3630 let result = self.check_user_unop(expr, oprnd_t, unop);
3631 // If it's builtin, we can reuse the type, this helps inference.
3632 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3637 let result = self.check_user_unop(expr, oprnd_t, unop);
3638 // If it's builtin, we can reuse the type, this helps inference.
3639 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3647 hir::ExprAddrOf(mutbl, ref oprnd) => {
3648 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3650 ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
3651 if self.is_place_expr(&oprnd) {
3652 // Places may legitimately have unsized types.
3653 // For example, dereferences of a fat pointer and
3654 // the last field of a struct can be unsized.
3657 Expectation::rvalue_hint(self, ty)
3663 let needs = Needs::maybe_mut_place(mutbl);
3664 let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
3666 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3667 if tm.ty.references_error() {
3670 // Note: at this point, we cannot say what the best lifetime
3671 // is to use for resulting pointer. We want to use the
3672 // shortest lifetime possible so as to avoid spurious borrowck
3673 // errors. Moreover, the longest lifetime will depend on the
3674 // precise details of the value whose address is being taken
3675 // (and how long it is valid), which we don't know yet until type
3676 // inference is complete.
3678 // Therefore, here we simply generate a region variable. The
3679 // region inferencer will then select the ultimate value.
3680 // Finally, borrowck is charged with guaranteeing that the
3681 // value whose address was taken can actually be made to live
3682 // as long as it needs to live.
3683 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3684 tcx.mk_ref(region, tm)
3687 hir::ExprPath(ref qpath) => {
3688 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3689 expr.id, expr.span);
3690 let ty = if def != Def::Err {
3691 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3693 self.set_tainted_by_errors();
3697 // We always require that the type provided as the value for
3698 // a type parameter outlives the moment of instantiation.
3699 let substs = self.tables.borrow().node_substs(expr.hir_id);
3700 self.add_wf_bounds(substs, expr);
3704 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3705 for output in outputs {
3706 self.check_expr(output);
3708 for input in inputs {
3709 self.check_expr(input);
3713 hir::ExprBreak(destination, ref expr_opt) => {
3714 if let Ok(target_id) = destination.target_id {
3716 if let Some(ref e) = *expr_opt {
3717 // If this is a break with a value, we need to type-check
3718 // the expression. Get an expected type from the loop context.
3719 let opt_coerce_to = {
3720 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3721 enclosing_breakables.find_breakable(target_id)
3724 .map(|coerce| coerce.expected_ty())
3727 // If the loop context is not a `loop { }`, then break with
3728 // a value is illegal, and `opt_coerce_to` will be `None`.
3729 // Just set expectation to error in that case.
3730 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3732 // Recurse without `enclosing_breakables` borrowed.
3733 e_ty = self.check_expr_with_hint(e, coerce_to);
3734 cause = self.misc(e.span);
3736 // Otherwise, this is a break *without* a value. That's
3737 // always legal, and is equivalent to `break ()`.
3738 e_ty = tcx.mk_nil();
3739 cause = self.misc(expr.span);
3742 // Now that we have type-checked `expr_opt`, borrow
3743 // the `enclosing_loops` field and let's coerce the
3744 // type of `expr_opt` into what is expected.
3745 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3746 let ctxt = enclosing_breakables.find_breakable(target_id);
3747 if let Some(ref mut coerce) = ctxt.coerce {
3748 if let Some(ref e) = *expr_opt {
3749 coerce.coerce(self, &cause, e, e_ty);
3751 assert!(e_ty.is_nil());
3752 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3755 // If `ctxt.coerce` is `None`, we can just ignore
3756 // the type of the expresison. This is because
3757 // either this was a break *without* a value, in
3758 // which case it is always a legal type (`()`), or
3759 // else an error would have been flagged by the
3760 // `loops` pass for using break with an expression
3761 // where you are not supposed to.
3762 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3765 ctxt.may_break = true;
3767 // the type of a `break` is always `!`, since it diverges
3770 // Otherwise, we failed to find the enclosing loop;
3771 // this can only happen if the `break` was not
3772 // inside a loop at all, which is caught by the
3773 // loop-checking pass.
3774 assert!(self.tcx.sess.err_count() > 0);
3776 // We still need to assign a type to the inner expression to
3777 // prevent the ICE in #43162.
3778 if let Some(ref e) = *expr_opt {
3779 self.check_expr_with_hint(e, tcx.types.err);
3781 // ... except when we try to 'break rust;'.
3782 // ICE this expression in particular (see #43162).
3783 if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
3784 if path.segments.len() == 1 && path.segments[0].name == "rust" {
3785 fatally_break_rust(self.tcx.sess);
3789 // There was an error, make typecheck fail
3794 hir::ExprAgain(_) => { tcx.types.never }
3795 hir::ExprRet(ref expr_opt) => {
3796 if self.ret_coercion.is_none() {
3797 struct_span_err!(self.tcx.sess, expr.span, E0572,
3798 "return statement outside of function body").emit();
3799 } else if let Some(ref e) = *expr_opt {
3800 self.check_return_expr(e);
3802 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3803 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3804 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3808 hir::ExprAssign(ref lhs, ref rhs) => {
3809 let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
3811 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3814 ExpectIfCondition => {
3815 self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
3816 expected error elsehwere");
3819 // Only check this if not in an `if` condition, as the
3820 // mistyped comparison help is more appropriate.
3821 if !self.is_place_expr(&lhs) {
3822 struct_span_err!(self.tcx.sess, expr.span, E0070,
3823 "invalid left-hand side expression")
3824 .span_label(expr.span, "left-hand of expression not valid")
3830 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3832 if lhs_ty.references_error() || rhs_ty.references_error() {
3838 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3839 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3840 expr.span, expected)
3842 hir::ExprWhile(ref cond, ref body, _) => {
3843 let ctxt = BreakableCtxt {
3844 // cannot use break with a value from a while loop
3846 may_break: false, // Will get updated if/when we find a `break`.
3849 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3850 self.check_expr_has_type_or_error(&cond, tcx.types.bool);
3851 let cond_diverging = self.diverges.get();
3852 self.check_block_no_value(&body);
3854 // We may never reach the body so it diverging means nothing.
3855 self.diverges.set(cond_diverging);
3859 // No way to know whether it's diverging because
3860 // of a `break` or an outer `break` or `return`.
3861 self.diverges.set(Diverges::Maybe);
3866 hir::ExprLoop(ref body, _, source) => {
3867 let coerce = match source {
3868 // you can only use break with a value from a normal `loop { }`
3869 hir::LoopSource::Loop => {
3870 let coerce_to = expected.coercion_target_type(self, body.span);
3871 Some(CoerceMany::new(coerce_to))
3874 hir::LoopSource::WhileLet |
3875 hir::LoopSource::ForLoop => {
3880 let ctxt = BreakableCtxt {
3882 may_break: false, // Will get updated if/when we find a `break`.
3885 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3886 self.check_block_no_value(&body);
3890 // No way to know whether it's diverging because
3891 // of a `break` or an outer `break` or `return`.
3892 self.diverges.set(Diverges::Maybe);
3895 // If we permit break with a value, then result type is
3896 // the LUB of the breaks (possibly ! if none); else, it
3897 // is nil. This makes sense because infinite loops
3898 // (which would have type !) are only possible iff we
3899 // permit break with a value [1].
3900 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3901 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3903 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3904 self.check_match(expr, &discrim, arms, expected, match_src)
3906 hir::ExprClosure(capture, ref decl, body_id, _, gen) => {
3907 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
3909 hir::ExprBlock(ref body, _) => {
3910 self.check_block_with_expected(&body, expected)
3912 hir::ExprCall(ref callee, ref args) => {
3913 self.check_call(expr, &callee, args, expected)
3915 hir::ExprMethodCall(ref segment, span, ref args) => {
3916 self.check_method_call(expr, segment, span, args, expected, needs)
3918 hir::ExprCast(ref e, ref t) => {
3919 // Find the type of `e`. Supply hints based on the type we are casting to,
3921 let t_cast = self.to_ty(t);
3922 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3923 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3924 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3926 // Eagerly check for some obvious errors.
3927 if t_expr.references_error() || t_cast.references_error() {
3930 // Defer other checks until we're done type checking.
3931 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3932 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3934 deferred_cast_checks.push(cast_check);
3937 Err(ErrorReported) => {
3943 hir::ExprType(ref e, ref t) => {
3944 let typ = self.to_ty(&t);
3945 self.check_expr_eq_type(&e, typ);
3948 hir::ExprArray(ref args) => {
3949 let uty = expected.to_option(self).and_then(|uty| {
3951 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3956 let element_ty = if !args.is_empty() {
3957 let coerce_to = uty.unwrap_or_else(
3958 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3959 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3960 assert_eq!(self.diverges.get(), Diverges::Maybe);
3962 let e_ty = self.check_expr_with_hint(e, coerce_to);
3963 let cause = self.misc(e.span);
3964 coerce.coerce(self, &cause, e, e_ty);
3966 coerce.complete(self)
3968 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3970 tcx.mk_array(element_ty, args.len() as u64)
3972 hir::ExprRepeat(ref element, ref count) => {
3973 let count_def_id = tcx.hir.local_def_id(count.id);
3974 let param_env = ty::ParamEnv::empty();
3975 let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
3976 let instance = ty::Instance::resolve(
3982 let global_id = GlobalId {
3986 let count = tcx.const_eval(param_env.and(global_id));
3988 if let Err(ref err) = count {
3989 err.report(tcx, tcx.def_span(count_def_id), "constant expression");
3992 let uty = match expected {
3993 ExpectHasType(uty) => {
3995 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
4002 let (element_ty, t) = match uty {
4004 self.check_expr_coercable_to_type(&element, uty);
4008 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
4009 let element_ty = self.check_expr_has_type_or_error(&element, t);
4014 if let Ok(count) = count {
4015 let zero_or_one = count.assert_usize(tcx).map_or(false, |count| count <= 1);
4017 // For [foo, ..n] where n > 1, `foo` must have
4019 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
4020 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
4024 if element_ty.references_error() {
4026 } else if let Ok(count) = count {
4027 tcx.mk_ty(ty::TyArray(t, count))
4032 hir::ExprTup(ref elts) => {
4033 let flds = expected.only_has_type(self).and_then(|ty| {
4034 let ty = self.resolve_type_vars_with_obligations(ty);
4036 ty::TyTuple(ref flds) => Some(&flds[..]),
4041 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
4042 let t = match flds {
4043 Some(ref fs) if i < fs.len() => {
4045 self.check_expr_coercable_to_type(&e, ety);
4049 self.check_expr_with_expectation(&e, NoExpectation)
4054 let tuple = tcx.mk_tup(elt_ts_iter);
4055 if tuple.references_error() {
4058 self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
4062 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
4063 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
4065 hir::ExprField(ref base, field) => {
4066 self.check_field(expr, needs, &base, field)
4068 hir::ExprIndex(ref base, ref idx) => {
4069 let base_t = self.check_expr_with_needs(&base, needs);
4070 let idx_t = self.check_expr(&idx);
4072 if base_t.references_error() {
4074 } else if idx_t.references_error() {
4077 let base_t = self.structurally_resolved_type(base.span, base_t);
4078 match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
4079 Some((index_ty, element_ty)) => {
4080 // two-phase not needed because index_ty is never mutable
4081 self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
4085 let mut err = type_error_struct!(tcx.sess, expr.span, base_t, E0608,
4086 "cannot index into a value of type `{}`",
4088 // Try to give some advice about indexing tuples.
4089 if let ty::TyTuple(..) = base_t.sty {
4090 let mut needs_note = true;
4091 // If the index is an integer, we can show the actual
4092 // fixed expression:
4093 if let hir::ExprLit(ref lit) = idx.node {
4094 if let ast::LitKind::Int(i,
4095 ast::LitIntType::Unsuffixed) = lit.node {
4096 let snip = tcx.sess.codemap().span_to_snippet(base.span);
4097 if let Ok(snip) = snip {
4098 err.span_suggestion(expr.span,
4099 "to access tuple elements, use",
4100 format!("{}.{}", snip, i));
4106 err.help("to access tuple elements, use tuple indexing \
4107 syntax (e.g. `tuple.0`)");
4116 hir::ExprYield(ref value) => {
4117 match self.yield_ty {
4119 self.check_expr_coercable_to_type(&value, ty);
4122 struct_span_err!(self.tcx.sess, expr.span, E0627,
4123 "yield statement outside of generator literal").emit();
4131 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
4132 // The newly resolved definition is written into `type_dependent_defs`.
4133 fn finish_resolving_struct_path(&self,
4136 node_id: ast::NodeId)
4140 hir::QPath::Resolved(ref maybe_qself, ref path) => {
4141 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
4142 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
4145 hir::QPath::TypeRelative(ref qself, ref segment) => {
4146 let ty = self.to_ty(qself);
4148 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
4153 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
4156 // Write back the new resolution.
4157 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4158 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4165 // Resolve associated value path into a base type and associated constant or method definition.
4166 // The newly resolved definition is written into `type_dependent_defs`.
4167 pub fn resolve_ty_and_def_ufcs<'b>(&self,
4168 qpath: &'b hir::QPath,
4169 node_id: ast::NodeId,
4171 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
4173 let (ty, item_segment) = match *qpath {
4174 hir::QPath::Resolved(ref opt_qself, ref path) => {
4176 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
4177 &path.segments[..]);
4179 hir::QPath::TypeRelative(ref qself, ref segment) => {
4180 (self.to_ty(qself), segment)
4183 let hir_id = self.tcx.hir.node_to_hir_id(node_id);
4184 if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
4185 // Return directly on cache hit. This is useful to avoid doubly reporting
4186 // errors with default match binding modes. See #44614.
4187 return (*cached_def, Some(ty), slice::from_ref(&**item_segment))
4189 let item_name = item_segment.name;
4190 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
4193 let def = match error {
4194 method::MethodError::PrivateMatch(def, _) => def,
4197 if item_name != keywords::Invalid.name() {
4198 self.report_method_error(span, ty, item_name, None, error, None);
4204 // Write back the new resolution.
4205 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
4206 (def, Some(ty), slice::from_ref(&**item_segment))
4209 pub fn check_decl_initializer(&self,
4210 local: &'gcx hir::Local,
4211 init: &'gcx hir::Expr) -> Ty<'tcx>
4213 // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed
4214 // for #42640 (default match binding modes).
4217 let ref_bindings = local.pat.contains_explicit_ref_binding();
4219 let local_ty = self.local_ty(init.span, local.id);
4220 if let Some(m) = ref_bindings {
4221 // Somewhat subtle: if we have a `ref` binding in the pattern,
4222 // we want to avoid introducing coercions for the RHS. This is
4223 // both because it helps preserve sanity and, in the case of
4224 // ref mut, for soundness (issue #23116). In particular, in
4225 // the latter case, we need to be clear that the type of the
4226 // referent for the reference that results is *equal to* the
4227 // type of the place it is referencing, and not some
4228 // supertype thereof.
4229 let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
4230 self.demand_eqtype(init.span, local_ty, init_ty);
4233 self.check_expr_coercable_to_type(init, local_ty)
4237 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4238 let t = self.local_ty(local.span, local.id);
4239 self.write_ty(local.hir_id, t);
4241 if let Some(ref init) = local.init {
4242 let init_ty = self.check_decl_initializer(local, &init);
4243 if init_ty.references_error() {
4244 self.write_ty(local.hir_id, init_ty);
4248 self.check_pat_walk(&local.pat, t,
4249 ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
4251 let pat_ty = self.node_ty(local.pat.hir_id);
4252 if pat_ty.references_error() {
4253 self.write_ty(local.hir_id, pat_ty);
4257 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4258 // Don't do all the complex logic below for DeclItem.
4260 hir::StmtDecl(ref decl, _) => {
4262 hir::DeclLocal(_) => {}
4263 hir::DeclItem(_) => {
4268 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4271 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4273 // Hide the outer diverging and has_errors flags.
4274 let old_diverges = self.diverges.get();
4275 let old_has_errors = self.has_errors.get();
4276 self.diverges.set(Diverges::Maybe);
4277 self.has_errors.set(false);
4280 hir::StmtDecl(ref decl, _) => {
4282 hir::DeclLocal(ref l) => {
4283 self.check_decl_local(&l);
4285 hir::DeclItem(_) => {/* ignore for now */}
4288 hir::StmtExpr(ref expr, _) => {
4289 // Check with expected type of ()
4290 self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
4292 hir::StmtSemi(ref expr, _) => {
4293 self.check_expr(&expr);
4297 // Combine the diverging and has_error flags.
4298 self.diverges.set(self.diverges.get() | old_diverges);
4299 self.has_errors.set(self.has_errors.get() | old_has_errors);
4302 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4303 let unit = self.tcx.mk_nil();
4304 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4306 // if the block produces a `!` value, that can always be
4307 // (effectively) coerced to unit.
4309 self.demand_suptype(blk.span, unit, ty);
4313 fn check_block_with_expected(&self,
4314 blk: &'gcx hir::Block,
4315 expected: Expectation<'tcx>) -> Ty<'tcx> {
4317 let mut fcx_ps = self.ps.borrow_mut();
4318 let unsafety_state = fcx_ps.recurse(blk);
4319 replace(&mut *fcx_ps, unsafety_state)
4322 // In some cases, blocks have just one exit, but other blocks
4323 // can be targeted by multiple breaks. This can happen both
4324 // with labeled blocks as well as when we desugar
4325 // a `do catch { ... }` expression.
4329 // 'a: { if true { break 'a Err(()); } Ok(()) }
4331 // Here we would wind up with two coercions, one from
4332 // `Err(())` and the other from the tail expression
4333 // `Ok(())`. If the tail expression is omitted, that's a
4334 // "forced unit" -- unless the block diverges, in which
4335 // case we can ignore the tail expression (e.g., `'a: {
4336 // break 'a 22; }` would not force the type of the block
4338 let tail_expr = blk.expr.as_ref();
4339 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4340 let coerce = if blk.targeted_by_break {
4341 CoerceMany::new(coerce_to_ty)
4343 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4344 Some(e) => slice::from_ref(e),
4347 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4350 let prev_diverges = self.diverges.get();
4351 let ctxt = BreakableCtxt {
4352 coerce: Some(coerce),
4356 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4357 for s in &blk.stmts {
4361 // check the tail expression **without** holding the
4362 // `enclosing_breakables` lock below.
4363 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4365 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4366 let ctxt = enclosing_breakables.find_breakable(blk.id);
4367 let coerce = ctxt.coerce.as_mut().unwrap();
4368 if let Some(tail_expr_ty) = tail_expr_ty {
4369 let tail_expr = tail_expr.unwrap();
4370 let cause = self.cause(tail_expr.span,
4371 ObligationCauseCode::BlockTailExpression(blk.id));
4377 // Subtle: if there is no explicit tail expression,
4378 // that is typically equivalent to a tail expression
4379 // of `()` -- except if the block diverges. In that
4380 // case, there is no value supplied from the tail
4381 // expression (assuming there are no other breaks,
4382 // this implies that the type of the block will be
4385 // #41425 -- label the implicit `()` as being the
4386 // "found type" here, rather than the "expected type".
4388 // #44579 -- if the block was recovered during parsing,
4389 // the type would be nonsensical and it is not worth it
4390 // to perform the type check, so we avoid generating the
4391 // diagnostic output.
4392 if !self.diverges.get().always() && !blk.recovered {
4393 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4394 if let Some(expected_ty) = expected.only_has_type(self) {
4395 self.consider_hint_about_removing_semicolon(blk,
4405 // If we can break from the block, then the block's exit is always reachable
4406 // (... as long as the entry is reachable) - regardless of the tail of the block.
4407 self.diverges.set(prev_diverges);
4410 let mut ty = ctxt.coerce.unwrap().complete(self);
4412 if self.has_errors.get() || ty.references_error() {
4413 ty = self.tcx.types.err
4416 self.write_ty(blk.hir_id, ty);
4418 *self.ps.borrow_mut() = prev;
4422 /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
4423 /// suggestion can be made, `None` otherwise.
4424 pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
4425 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
4426 // `while` before reaching it, as block tail returns are not available in them.
4427 if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
4428 let parent = self.tcx.hir.get(fn_id);
4430 if let Node::NodeItem(&hir::Item {
4431 name, node: hir::ItemFn(ref decl, ..), ..
4433 decl.clone().and_then(|decl| {
4434 // This is less than ideal, it will not suggest a return type span on any
4435 // method called `main`, regardless of whether it is actually the entry point,
4436 // but it will still present it as the reason for the expected type.
4437 Some((decl, name != Symbol::intern("main")))
4439 } else if let Node::NodeTraitItem(&hir::TraitItem {
4440 node: hir::TraitItemKind::Method(hir::MethodSig {
4444 decl.clone().and_then(|decl| {
4447 } else if let Node::NodeImplItem(&hir::ImplItem {
4448 node: hir::ImplItemKind::Method(hir::MethodSig {
4452 decl.clone().and_then(|decl| {
4463 /// On implicit return expressions with mismatched types, provide the following suggestions:
4465 /// - Point out the method's return type as the reason for the expected type
4466 /// - Possible missing semicolon
4467 /// - Possible missing return type if the return type is the default, and not `fn main()`
4468 pub fn suggest_mismatched_types_on_tail(&self,
4469 err: &mut DiagnosticBuilder<'tcx>,
4470 expression: &'gcx hir::Expr,
4474 blk_id: ast::NodeId) {
4475 self.suggest_missing_semicolon(err, expression, expected, cause_span);
4477 if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
4478 self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
4482 /// A common error is to forget to add a semicolon at the end of a block:
4486 /// bar_that_returns_u32()
4490 /// This routine checks if the return expression in a block would make sense on its own as a
4491 /// statement and the return type has been left as default or has been specified as `()`. If so,
4492 /// it suggests adding a semicolon.
4493 fn suggest_missing_semicolon(&self,
4494 err: &mut DiagnosticBuilder<'tcx>,
4495 expression: &'gcx hir::Expr,
4498 if expected.is_nil() {
4499 // `BlockTailExpression` only relevant if the tail expr would be
4500 // useful on its own.
4501 match expression.node {
4503 hir::ExprMethodCall(..) |
4505 hir::ExprWhile(..) |
4507 hir::ExprMatch(..) |
4508 hir::ExprBlock(..) => {
4509 let sp = self.tcx.sess.codemap().next_point(cause_span);
4510 err.span_suggestion(sp,
4511 "try adding a semicolon",
4520 /// A possible error is to forget to add a return type that is needed:
4524 /// bar_that_returns_u32()
4528 /// This routine checks if the return type is left as default, the method is not part of an
4529 /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
4531 fn suggest_missing_return_type(&self,
4532 err: &mut DiagnosticBuilder<'tcx>,
4533 fn_decl: &hir::FnDecl,
4536 can_suggest: bool) {
4537 // Only suggest changing the return type for methods that
4538 // haven't set a return type at all (and aren't `fn main()` or an impl).
4539 match (&fn_decl.output, found.is_suggestable(), can_suggest) {
4540 (&hir::FunctionRetTy::DefaultReturn(span), true, true) => {
4541 err.span_suggestion(span,
4542 "try adding a return type",
4544 self.resolve_type_vars_with_obligations(found)));
4546 (&hir::FunctionRetTy::DefaultReturn(span), false, true) => {
4547 err.span_label(span, "possibly return type missing here?");
4549 (&hir::FunctionRetTy::DefaultReturn(span), _, _) => {
4550 // `fn main()` must return `()`, do not suggest changing return type
4551 err.span_label(span, "expected `()` because of default return type");
4553 (&hir::FunctionRetTy::Return(ref ty), _, _) => {
4554 // Only point to return type if the expected type is the return type, as if they
4555 // are not, the expectation must have been caused by something else.
4556 debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node);
4558 let ty = AstConv::ast_ty_to_ty(self, ty);
4559 debug!("suggest_missing_return_type: return type sty {:?}", ty.sty);
4560 debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty);
4561 if ty.sty == expected.sty {
4562 err.span_label(sp, format!("expected `{}` because of return type",
4570 /// A common error is to add an extra semicolon:
4573 /// fn foo() -> usize {
4578 /// This routine checks if the final statement in a block is an
4579 /// expression with an explicit semicolon whose type is compatible
4580 /// with `expected_ty`. If so, it suggests removing the semicolon.
4581 fn consider_hint_about_removing_semicolon(&self,
4582 blk: &'gcx hir::Block,
4583 expected_ty: Ty<'tcx>,
4584 err: &mut DiagnosticBuilder) {
4585 // Be helpful when the user wrote `{... expr;}` and
4586 // taking the `;` off is enough to fix the error.
4587 let last_stmt = match blk.stmts.last() {
4591 let last_expr = match last_stmt.node {
4592 hir::StmtSemi(ref e, _) => e,
4595 let last_expr_ty = self.node_ty(last_expr.hir_id);
4596 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4599 let original_span = original_sp(last_stmt.span, blk.span);
4600 let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
4601 err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
4604 // Instantiates the given path, which must refer to an item with the given
4605 // number of type parameters and type.
4606 pub fn instantiate_value_path(&self,
4607 segments: &[hir::PathSegment],
4608 opt_self_ty: Option<Ty<'tcx>>,
4611 node_id: ast::NodeId)
4613 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4618 // We need to extract the type parameters supplied by the user in
4619 // the path `path`. Due to the current setup, this is a bit of a
4620 // tricky-process; the problem is that resolve only tells us the
4621 // end-point of the path resolution, and not the intermediate steps.
4622 // Luckily, we can (at least for now) deduce the intermediate steps
4623 // just from the end-point.
4625 // There are basically four cases to consider:
4627 // 1. Reference to a constructor of enum variant or struct:
4629 // struct Foo<T>(...)
4630 // enum E<T> { Foo(...) }
4632 // In these cases, the parameters are declared in the type
4635 // 2. Reference to a fn item or a free constant:
4639 // In this case, the path will again always have the form
4640 // `a::b::foo::<T>` where only the final segment should have
4641 // type parameters. However, in this case, those parameters are
4642 // declared on a value, and hence are in the `FnSpace`.
4644 // 3. Reference to a method or an associated constant:
4646 // impl<A> SomeStruct<A> {
4650 // Here we can have a path like
4651 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4652 // may appear in two places. The penultimate segment,
4653 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4654 // final segment, `foo::<B>` contains parameters in fn space.
4656 // 4. Reference to a local variable
4658 // Local variables can't have any type parameters.
4660 // The first step then is to categorize the segments appropriately.
4662 assert!(!segments.is_empty());
4664 let mut ufcs_associated = None;
4665 let mut type_segment = None;
4666 let mut fn_segment = None;
4668 // Case 1. Reference to a struct/variant constructor.
4669 Def::StructCtor(def_id, ..) |
4670 Def::VariantCtor(def_id, ..) => {
4671 // Everything but the final segment should have no
4672 // parameters at all.
4673 let mut generics = self.tcx.generics_of(def_id);
4674 if let Some(def_id) = generics.parent {
4675 // Variant and struct constructors use the
4676 // generics of their parent type definition.
4677 generics = self.tcx.generics_of(def_id);
4679 type_segment = Some((segments.last().unwrap(), generics));
4682 // Case 2. Reference to a top-level value.
4684 Def::Const(def_id) |
4685 Def::Static(def_id, _) => {
4686 fn_segment = Some((segments.last().unwrap(),
4687 self.tcx.generics_of(def_id)));
4690 // Case 3. Reference to a method or associated const.
4691 Def::Method(def_id) |
4692 Def::AssociatedConst(def_id) => {
4693 let container = self.tcx.associated_item(def_id).container;
4695 ty::TraitContainer(trait_did) => {
4696 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4698 ty::ImplContainer(_) => {}
4701 let generics = self.tcx.generics_of(def_id);
4702 if segments.len() >= 2 {
4703 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4704 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4706 // `<T>::assoc` will end up here, and so can `T::assoc`.
4707 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4708 ufcs_associated = Some((container, self_ty));
4710 fn_segment = Some((segments.last().unwrap(), generics));
4713 // Case 4. Local variable, no generics.
4714 Def::Local(..) | Def::Upvar(..) => {}
4716 _ => bug!("unexpected definition: {:?}", def),
4719 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4721 // Now that we have categorized what space the parameters for each
4722 // segment belong to, let's sort out the parameters that the user
4723 // provided (if any) into their appropriate spaces. We'll also report
4724 // errors if type parameters are provided in an inappropriate place.
4725 let poly_segments = type_segment.is_some() as usize +
4726 fn_segment.is_some() as usize;
4727 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4730 Def::Local(nid) | Def::Upvar(nid, ..) => {
4731 let ty = self.local_ty(span, nid);
4732 let ty = self.normalize_associated_types_in(span, &ty);
4733 self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
4739 // Now we have to compare the types that the user *actually*
4740 // provided against the types that were *expected*. If the user
4741 // did not provide any types, then we want to substitute inference
4742 // variables. If the user provided some types, we may still need
4743 // to add defaults. If the user provided *too many* types, that's
4745 let supress_mismatch = self.check_impl_trait(span, fn_segment);
4746 self.check_path_parameter_count(span, &mut type_segment, false, supress_mismatch);
4747 self.check_path_parameter_count(span, &mut fn_segment, false, supress_mismatch);
4749 let (fn_start, has_self) = match (type_segment, fn_segment) {
4750 (_, Some((_, generics))) => {
4751 (generics.parent_count, generics.has_self)
4753 (Some((_, generics)), None) => {
4754 (generics.params.len(), generics.has_self)
4756 (None, None) => (0, false)
4758 let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
4759 let mut i = param.index as usize;
4761 let segment = if i < fn_start {
4762 if let GenericParamDefKind::Type {..} = param.kind {
4763 // Handle Self first, so we can adjust the index to match the AST.
4764 if has_self && i == 0 {
4765 return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
4766 self.var_for_def(span, param)
4770 i -= has_self as usize;
4778 GenericParamDefKind::Lifetime => {
4779 let lifetimes = segment.map_or(&[][..], |(s, _)| {
4780 s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
4783 if let Some(lifetime) = lifetimes.get(i) {
4784 AstConv::ast_region_to_region(self, lifetime, Some(param)).into()
4786 self.re_infer(span, Some(param)).unwrap().into()
4789 GenericParamDefKind::Type {..} => {
4790 let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
4791 (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
4794 // Skip over the lifetimes in the same segment.
4795 if let Some((_, generics)) = segment {
4796 i -= generics.own_counts().lifetimes;
4799 let has_default = match param.kind {
4800 GenericParamDefKind::Type { has_default, .. } => has_default,
4804 if let Some(ast_ty) = types.get(i) {
4805 // A provided type parameter.
4806 self.to_ty(ast_ty).into()
4807 } else if !infer_types && has_default {
4808 // No type parameter provided, but a default exists.
4809 let default = self.tcx.type_of(param.def_id);
4812 default.subst_spanned(self.tcx, substs, Some(span))
4815 // No type parameters were provided, we can infer all.
4816 // This can also be reached in some error cases:
4817 // We prefer to use inference variables instead of
4818 // TyError to let type inference recover somewhat.
4819 self.var_for_def(span, param)
4825 // The things we are substituting into the type should not contain
4826 // escaping late-bound regions, and nor should the base type scheme.
4827 let ty = self.tcx.type_of(def.def_id());
4828 assert!(!substs.has_escaping_regions());
4829 assert!(!ty.has_escaping_regions());
4831 // Add all the obligations that are required, substituting and
4832 // normalized appropriately.
4833 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4834 self.add_obligations_for_parameters(
4835 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4838 // Substitute the values for the type parameters into the type of
4839 // the referenced item.
4840 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4842 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4843 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4844 // is inherent, there is no `Self` parameter, instead, the impl needs
4845 // type parameters, which we can infer by unifying the provided `Self`
4846 // with the substituted impl type.
4847 let ty = self.tcx.type_of(impl_def_id);
4849 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4850 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4851 Ok(ok) => self.register_infer_ok_obligations(ok),
4854 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4861 self.check_rustc_args_require_const(def.def_id(), node_id, span);
4863 debug!("instantiate_value_path: type of {:?} is {:?}",
4866 self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
4870 fn check_rustc_args_require_const(&self,
4872 node_id: ast::NodeId,
4874 // We're only interested in functions tagged with
4875 // #[rustc_args_required_const], so ignore anything that's not.
4876 if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
4880 // If our calling expression is indeed the function itself, we're good!
4881 // If not, generate an error that this can only be called directly.
4882 match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
4883 Node::NodeExpr(expr) => {
4885 hir::ExprCall(ref callee, ..) => {
4886 if callee.id == node_id {
4896 self.tcx.sess.span_err(span, "this function can only be invoked \
4897 directly, not through a function pointer");
4900 /// Report errors if the provided parameters are too few or too many.
4901 fn check_path_parameter_count(&self,
4903 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>,
4904 is_method_call: bool,
4905 supress_mismatch_error: bool) {
4906 let (lifetimes, types, infer_types, bindings) = segment.map_or(
4907 (&[][..], &[][..], true, &[][..]),
4908 |(s, _)| s.parameters.as_ref().map_or(
4909 (&[][..], &[][..], s.infer_types, &[][..]),
4910 |p| (&p.lifetimes[..], &p.types[..],
4911 s.infer_types, &p.bindings[..])));
4912 let infer_lifetimes = lifetimes.len() == 0;
4914 let count_lifetime_params = |n| {
4915 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4917 let count_type_params = |n| {
4918 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4921 // Check provided parameters.
4922 let ((ty_required, ty_accepted), lt_accepted) =
4923 segment.map_or(((0, 0), 0), |(_, generics)| {
4929 let mut lt_accepted = 0;
4930 let mut ty_params = ParamRange { required: 0, accepted: 0 };
4931 for param in &generics.params {
4933 GenericParamDefKind::Lifetime => {
4936 GenericParamDefKind::Type { has_default, .. } => {
4937 ty_params.accepted += 1;
4939 ty_params.required += 1;
4944 if generics.parent.is_none() && generics.has_self {
4945 ty_params.required -= 1;
4946 ty_params.accepted -= 1;
4949 ((ty_params.required, ty_params.accepted), lt_accepted)
4952 if types.len() > ty_accepted {
4953 let span = types[ty_accepted].span;
4954 let expected_text = count_type_params(ty_accepted);
4955 let actual_text = count_type_params(types.len());
4956 struct_span_err!(self.tcx.sess, span, E0087,
4957 "too many type parameters provided: \
4958 expected at most {}, found {}",
4959 expected_text, actual_text)
4960 .span_label(span, format!("expected {}", expected_text))
4963 // To prevent derived errors to accumulate due to extra
4964 // type parameters, we force instantiate_value_path to
4965 // use inference variables instead of the provided types.
4967 } else if types.len() < ty_required && !infer_types && !supress_mismatch_error {
4968 let expected_text = count_type_params(ty_required);
4969 let actual_text = count_type_params(types.len());
4970 struct_span_err!(self.tcx.sess, span, E0089,
4971 "too few type parameters provided: \
4972 expected {}, found {}",
4973 expected_text, actual_text)
4974 .span_label(span, format!("expected {}", expected_text))
4978 if !bindings.is_empty() {
4979 AstConv::prohibit_projection(self, bindings[0].span);
4982 // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
4983 let has_late_bound_lifetime_defs =
4984 segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
4985 if let (Some(span_late), false) = (has_late_bound_lifetime_defs, lifetimes.is_empty()) {
4986 // Report this as a lint only if no error was reported previously.
4987 let primary_msg = "cannot specify lifetime arguments explicitly \
4988 if late bound lifetime parameters are present";
4989 let note_msg = "the late bound lifetime parameter is introduced here";
4990 if !is_method_call && (lifetimes.len() > lt_accepted ||
4991 lifetimes.len() < lt_accepted && !infer_lifetimes) {
4992 let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
4993 err.span_note(span_late, note_msg);
4997 let mut multispan = MultiSpan::from_span(lifetimes[0].span);
4998 multispan.push_span_label(span_late, note_msg.to_string());
4999 self.tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
5000 lifetimes[0].id, multispan, primary_msg);
5005 if lifetimes.len() > lt_accepted {
5006 let span = lifetimes[lt_accepted].span;
5007 let expected_text = count_lifetime_params(lt_accepted);
5008 let actual_text = count_lifetime_params(lifetimes.len());
5009 struct_span_err!(self.tcx.sess, span, E0088,
5010 "too many lifetime parameters provided: \
5011 expected at most {}, found {}",
5012 expected_text, actual_text)
5013 .span_label(span, format!("expected {}", expected_text))
5015 } else if lifetimes.len() < lt_accepted && !infer_lifetimes {
5016 let expected_text = count_lifetime_params(lt_accepted);
5017 let actual_text = count_lifetime_params(lifetimes.len());
5018 struct_span_err!(self.tcx.sess, span, E0090,
5019 "too few lifetime parameters provided: \
5020 expected {}, found {}",
5021 expected_text, actual_text)
5022 .span_label(span, format!("expected {}", expected_text))
5027 /// Report error if there is an explicit type parameter when using `impl Trait`.
5028 fn check_impl_trait(&self,
5030 segment: Option<(&hir::PathSegment, &ty::Generics)>)
5032 let segment = segment.map(|(path_segment, generics)| {
5033 let explicit = !path_segment.infer_types;
5034 let impl_trait = generics.params.iter().any(|param| {
5036 ty::GenericParamDefKind::Type {
5037 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
5043 if explicit && impl_trait {
5044 let mut err = struct_span_err! {
5048 "cannot provide explicit type parameters when `impl Trait` is \
5049 used in argument position."
5058 segment.unwrap_or(false)
5061 // Resolves `typ` by a single level if `typ` is a type variable.
5062 // If no resolution is possible, then an error is reported.
5063 // Numeric inference variables may be left unresolved.
5064 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
5065 let ty = self.resolve_type_vars_with_obligations(ty);
5066 if !ty.is_ty_var() {
5069 if !self.is_tainted_by_errors() {
5070 self.need_type_info_err((**self).body_id, sp, ty)
5071 .note("type must be known at this point")
5074 self.demand_suptype(sp, self.tcx.types.err, ty);
5079 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
5080 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
5081 -> (BreakableCtxt<'gcx, 'tcx>, R) {
5084 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5085 index = enclosing_breakables.stack.len();
5086 enclosing_breakables.by_id.insert(id, index);
5087 enclosing_breakables.stack.push(ctxt);
5091 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
5092 debug_assert!(enclosing_breakables.stack.len() == index + 1);
5093 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
5094 enclosing_breakables.stack.pop().expect("missing breakable context")
5100 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5101 generics: &hir::Generics,
5103 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
5104 generics.ty_params().count(), ty);
5106 // make a vector of booleans initially false, set to true when used
5107 if generics.ty_params().next().is_none() { return; }
5108 let mut tps_used = vec![false; generics.ty_params().count()];
5110 let lifetime_count = generics.lifetimes().count();
5112 for leaf_ty in ty.walk() {
5113 if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty {
5114 debug!("Found use of ty param num {}", idx);
5115 tps_used[idx as usize - lifetime_count] = true;
5116 } else if let ty::TyError = leaf_ty.sty {
5117 // If there already another error, do not emit an error for not using a type Parameter
5118 assert!(tcx.sess.err_count() > 0);
5123 for (&used, param) in tps_used.iter().zip(generics.ty_params()) {
5125 struct_span_err!(tcx.sess, param.span, E0091,
5126 "type parameter `{}` is unused",
5128 .span_label(param.span, "unused type parameter")
5134 fn fatally_break_rust(sess: &Session) {
5135 let handler = sess.diagnostic();
5136 handler.span_bug_no_panic(
5138 "It looks like you're trying to break rust; would you like some ICE?",
5140 handler.note_without_error("the compiler expectedly panicked. this is a feature.");
5141 handler.note_without_error(
5142 "we would appreciate a joke overview: \
5143 https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675"
5145 handler.note_without_error(&format!("rustc {} running on {}",
5146 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
5147 ::session::config::host_triple(),