1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 Within the check phase of type check, we check each item one at a time
16 (bodies of function expressions are checked as part of the containing
17 function). Inference is used to supply types wherever they are
20 By far the most complex case is checking the body of a function. This
21 can be broken down into several distinct phases:
23 - gather: creates type variables to represent the type of each local
24 variable and pattern binding.
26 - main: the main pass does the lion's share of the work: it
27 determines the types of all expressions, resolves
28 methods, checks for most invalid conditions, and so forth. In
29 some cases, where a type is unknown, it may create a type or region
30 variable and use that as the type of an expression.
32 In the process of checking, various constraints will be placed on
33 these type variables through the subtyping relationships requested
34 through the `demand` module. The `infer` module is in charge
35 of resolving those constraints.
37 - regionck: after main is complete, the regionck pass goes over all
38 types looking for regions and making sure that they did not escape
39 into places they are not in scope. This may also influence the
40 final assignments of the various region variables if there is some
43 - vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
46 - writeback: writes the final types within a function body, replacing
47 type variables with their final inferred types. These final types
48 are written into the `tcx.node_types` table, which should *never* contain
49 any reference to a type variable.
53 While type checking a function, the intermediate types for the
54 expressions, blocks, and so forth contained within the function are
55 stored in `fcx.node_types` and `fcx.node_substs`. These types
56 may contain unresolved type variables. After type checking is
57 complete, the functions in the writeback module are used to take the
58 types from this table, resolve them, and then write them into their
59 permanent home in the type context `tcx`.
61 This means that during inferencing you should use `fcx.write_ty()`
62 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63 nodes within the function.
65 The types of top-level items, which never contain unbound type
66 variables, are stored directly into the `tcx` tables.
68 n.b.: A type variable is not the same thing as a type parameter. A
69 type variable is rather an "instance" of a type parameter: that is,
70 given a generic function `fn foo<T>(t: T)`: while checking the
71 function `foo`, the type `ty_param(0)` refers to the type `T`, which
72 is treated in abstract. When `foo()` is called, however, `T` will be
73 substituted for a fresh type variable `N`. This variable will
74 eventually be resolved to some concrete type (which might itself be
79 pub use self::Expectation::*;
80 use self::autoderef::Autoderef;
81 use self::callee::DeferredCallResolution;
82 use self::coercion::{CoerceMany, DynamicCoerceMany};
83 pub use self::compare_method::{compare_impl_method, compare_const_impl};
84 use self::method::MethodCallee;
85 use self::TupleArgumentsFlag::*;
88 use fmt_macros::{Parser, Piece, Position};
89 use hir::def::{Def, CtorKind};
90 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
91 use rustc_back::slice::ref_slice;
92 use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
93 use rustc::infer::type_variable::{TypeVariableOrigin};
94 use rustc::middle::region::CodeExtent;
95 use rustc::ty::subst::{Kind, Subst, Substs};
96 use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
97 use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
98 use rustc::ty::{self, Ty, TyCtxt, Visibility};
99 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
100 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
101 use rustc::ty::maps::Providers;
102 use rustc::ty::util::{Representability, IntTypeExt};
103 use errors::DiagnosticBuilder;
104 use require_c_abi_if_variadic;
105 use session::{Session, CompileResult};
108 use util::common::{ErrorReported, indenter};
109 use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
111 use std::cell::{Cell, RefCell};
112 use std::collections::hash_map::Entry;
114 use std::mem::replace;
115 use std::ops::{self, Deref};
116 use syntax::abi::Abi;
118 use syntax::codemap::{self, original_sp, Spanned};
119 use syntax::feature_gate::{GateIssue, emit_feature_err};
121 use syntax::symbol::{Symbol, InternedString, keywords};
122 use syntax::util::lev_distance::find_best_match_for_name;
123 use syntax_pos::{self, BytePos, Span, DUMMY_SP};
125 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
126 use rustc::hir::itemlikevisit::ItemLikeVisitor;
127 use rustc::hir::{self, PatKind};
128 use rustc::middle::lang_items;
129 use rustc_back::slice;
130 use rustc::middle::const_val::eval_length;
131 use rustc_const_math::ConstInt;
150 /// closures defined within the function. For example:
153 /// bar(move|| { ... })
156 /// Here, the function `foo()` and the closure passed to
157 /// `bar()` will each have their own `FnCtxt`, but they will
158 /// share the inherited fields.
159 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
160 infcx: InferCtxt<'a, 'gcx, 'tcx>,
162 locals: RefCell<NodeMap<Ty<'tcx>>>,
164 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
166 // When we process a call like `c()` where `c` is a closure type,
167 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
168 // `FnOnce` closure. In that case, we defer full resolution of the
169 // call until upvar inference can kick in and make the
170 // decision. We keep these deferred resolutions grouped by the
171 // def-id of the closure, so that once we decide, we can easily go
172 // back and process them.
173 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolution<'gcx, 'tcx>>>>,
175 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
177 // Anonymized types found in explicit return types and their
178 // associated fresh inference variable. Writeback resolves these
179 // variables to get the concrete type, which can be used to
180 // deanonymize TyAnon, after typeck is done with all functions.
181 anon_types: RefCell<NodeMap<Ty<'tcx>>>,
183 /// Each type parameter has an implicit region bound that
184 /// indicates it must outlive at least the function body (the user
185 /// may specify stronger requirements). This field indicates the
186 /// region of the callee. If it is `None`, then the parameter
187 /// environment is for an item or something where the "callee" is
189 implicit_region_bound: Option<ty::Region<'tcx>>,
192 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
193 type Target = InferCtxt<'a, 'gcx, 'tcx>;
194 fn deref(&self) -> &Self::Target {
199 /// When type-checking an expression, we propagate downward
200 /// whatever type hint we are able in the form of an `Expectation`.
201 #[derive(Copy, Clone, Debug)]
202 pub enum Expectation<'tcx> {
203 /// We know nothing about what type this expression should have.
206 /// This expression should have the type given (or some subtype)
207 ExpectHasType(Ty<'tcx>),
209 /// This expression will be cast to the `Ty`
210 ExpectCastableToType(Ty<'tcx>),
212 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
213 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
214 ExpectRvalueLikeUnsized(Ty<'tcx>),
217 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
218 // Disregard "castable to" expectations because they
219 // can lead us astray. Consider for example `if cond
220 // {22} else {c} as u8` -- if we propagate the
221 // "castable to u8" constraint to 22, it will pick the
222 // type 22u8, which is overly constrained (c might not
223 // be a u8). In effect, the problem is that the
224 // "castable to" expectation is not the tightest thing
225 // we can say, so we want to drop it in this case.
226 // The tightest thing we can say is "must unify with
227 // else branch". Note that in the case of a "has type"
228 // constraint, this limitation does not hold.
230 // If the expected type is just a type variable, then don't use
231 // an expected type. Otherwise, we might write parts of the type
232 // when checking the 'then' block which are incompatible with the
234 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
236 ExpectHasType(ety) => {
237 let ety = fcx.shallow_resolve(ety);
238 if !ety.is_ty_var() {
244 ExpectRvalueLikeUnsized(ety) => {
245 ExpectRvalueLikeUnsized(ety)
251 /// Provide an expectation for an rvalue expression given an *optional*
252 /// hint, which is not required for type safety (the resulting type might
253 /// be checked higher up, as is the case with `&expr` and `box expr`), but
254 /// is useful in determining the concrete type.
256 /// The primary use case is where the expected type is a fat pointer,
257 /// like `&[isize]`. For example, consider the following statement:
259 /// let x: &[isize] = &[1, 2, 3];
261 /// In this case, the expected type for the `&[1, 2, 3]` expression is
262 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
263 /// expectation `ExpectHasType([isize])`, that would be too strong --
264 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
265 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
266 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
267 /// which still is useful, because it informs integer literals and the like.
268 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
269 /// for examples of where this comes up,.
270 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
271 match fcx.tcx.struct_tail(ty).sty {
272 ty::TySlice(_) | ty::TyStr | ty::TyDynamic(..) => {
273 ExpectRvalueLikeUnsized(ty)
275 _ => ExpectHasType(ty)
279 // Resolves `expected` by a single level if it is a variable. If
280 // there is no expected type or resolution is not possible (e.g.,
281 // no constraints yet present), just returns `None`.
282 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
287 ExpectCastableToType(t) => {
288 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
290 ExpectHasType(t) => {
291 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
293 ExpectRvalueLikeUnsized(t) => {
294 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
299 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
300 match self.resolve(fcx) {
301 NoExpectation => None,
302 ExpectCastableToType(ty) |
304 ExpectRvalueLikeUnsized(ty) => Some(ty),
308 /// It sometimes happens that we want to turn an expectation into
309 /// a **hard constraint** (i.e., something that must be satisfied
310 /// for the program to type-check). `only_has_type` will return
311 /// such a constraint, if it exists.
312 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
313 match self.resolve(fcx) {
314 ExpectHasType(ty) => Some(ty),
319 /// Like `only_has_type`, but instead of returning `None` if no
320 /// hard constraint exists, creates a fresh type variable.
321 fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
322 self.only_has_type(fcx)
323 .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
327 #[derive(Copy, Clone)]
328 pub struct UnsafetyState {
329 pub def: ast::NodeId,
330 pub unsafety: hir::Unsafety,
331 pub unsafe_push_count: u32,
336 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
337 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
340 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
341 match self.unsafety {
342 // If this unsafe, then if the outer function was already marked as
343 // unsafe we shouldn't attribute the unsafe'ness to the block. This
344 // way the block can be warned about instead of ignoring this
345 // extraneous block (functions are never warned about).
346 hir::Unsafety::Unsafe if self.from_fn => *self,
349 let (unsafety, def, count) = match blk.rules {
350 hir::PushUnsafeBlock(..) =>
351 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
352 hir::PopUnsafeBlock(..) =>
353 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
354 hir::UnsafeBlock(..) =>
355 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
357 (unsafety, self.def, self.unsafe_push_count),
359 UnsafetyState{ def: def,
361 unsafe_push_count: count,
368 #[derive(Debug, Copy, Clone)]
374 /// Tracks whether executing a node may exit normally (versus
375 /// return/break/panic, which "diverge", leaving dead code in their
376 /// wake). Tracked semi-automatically (through type variables marked
377 /// as diverging), with some manual adjustments for control-flow
378 /// primitives (approximating a CFG).
379 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
381 /// Potentially unknown, some cases converge,
382 /// others require a CFG to determine them.
385 /// Definitely known to diverge and therefore
386 /// not reach the next sibling or its parent.
389 /// Same as `Always` but with a reachability
390 /// warning already emitted
394 // Convenience impls for combinig `Diverges`.
396 impl ops::BitAnd for Diverges {
398 fn bitand(self, other: Self) -> Self {
399 cmp::min(self, other)
403 impl ops::BitOr for Diverges {
405 fn bitor(self, other: Self) -> Self {
406 cmp::max(self, other)
410 impl ops::BitAndAssign for Diverges {
411 fn bitand_assign(&mut self, other: Self) {
412 *self = *self & other;
416 impl ops::BitOrAssign for Diverges {
417 fn bitor_assign(&mut self, other: Self) {
418 *self = *self | other;
423 fn always(self) -> bool {
424 self >= Diverges::Always
428 pub struct BreakableCtxt<'gcx: 'tcx, 'tcx> {
431 // this is `null` for loops where break with a value is illegal,
432 // such as `while`, `for`, and `while let`
433 coerce: Option<DynamicCoerceMany<'gcx, 'tcx>>,
436 pub struct EnclosingBreakables<'gcx: 'tcx, 'tcx> {
437 stack: Vec<BreakableCtxt<'gcx, 'tcx>>,
438 by_id: NodeMap<usize>,
441 impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> {
442 fn find_breakable(&mut self, target_id: ast::NodeId) -> &mut BreakableCtxt<'gcx, 'tcx> {
443 let ix = *self.by_id.get(&target_id).unwrap_or_else(|| {
444 bug!("could not find enclosing breakable with id {}", target_id);
450 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
451 body_id: ast::NodeId,
453 /// The parameter environment used for proving trait obligations
454 /// in this function. This can change when we descend into
455 /// closures (as they bring new things into scope), hence it is
456 /// not part of `Inherited` (as of the time of this writing,
457 /// closures do not yet change the environment, but they will
459 param_env: ty::ParamEnv<'tcx>,
461 // Number of errors that had been reported when we started
462 // checking this function. On exit, if we find that *more* errors
463 // have been reported, we will skip regionck and other work that
464 // expects the types within the function to be consistent.
465 err_count_on_creation: usize,
467 ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
469 ps: RefCell<UnsafetyState>,
471 /// Whether the last checked node generates a divergence (e.g.,
472 /// `return` will set this to Always). In general, when entering
473 /// an expression or other node in the tree, the initial value
474 /// indicates whether prior parts of the containing expression may
475 /// have diverged. It is then typically set to `Maybe` (and the
476 /// old value remembered) for processing the subparts of the
477 /// current expression. As each subpart is processed, they may set
478 /// the flag to `Always` etc. Finally, at the end, we take the
479 /// result and "union" it with the original value, so that when we
480 /// return the flag indicates if any subpart of the the parent
481 /// expression (up to and including this part) has diverged. So,
482 /// if you read it after evaluating a subexpression `X`, the value
483 /// you get indicates whether any subexpression that was
484 /// evaluating up to and including `X` diverged.
486 /// We use this flag for two purposes:
488 /// - To warn about unreachable code: if, after processing a
489 /// sub-expression but before we have applied the effects of the
490 /// current node, we see that the flag is set to `Always`, we
491 /// can issue a warning. This corresponds to something like
492 /// `foo(return)`; we warn on the `foo()` expression. (We then
493 /// update the flag to `WarnedAlways` to suppress duplicate
494 /// reports.) Similarly, if we traverse to a fresh statement (or
495 /// tail expression) from a `Always` setting, we will isssue a
496 /// warning. This corresponds to something like `{return;
497 /// foo();}` or `{return; 22}`, where we would warn on the
500 /// - To permit assignment into a local variable or other lvalue
501 /// (including the "return slot") of type `!`. This is allowed
502 /// if **either** the type of value being assigned is `!`, which
503 /// means the current code is dead, **or** the expression's
504 /// divering flag is true, which means that a divering value was
505 /// wrapped (e.g., `let x: ! = foo(return)`).
507 /// To repeat the last point: an expression represents dead-code
508 /// if, after checking it, **either** its type is `!` OR the
509 /// diverges flag is set to something other than `Maybe`.
510 diverges: Cell<Diverges>,
512 /// Whether any child nodes have any type errors.
513 has_errors: Cell<bool>,
515 enclosing_breakables: RefCell<EnclosingBreakables<'gcx, 'tcx>>,
517 inh: &'a Inherited<'a, 'gcx, 'tcx>,
520 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
521 type Target = Inherited<'a, 'gcx, 'tcx>;
522 fn deref(&self) -> &Self::Target {
527 /// Helper type of a temporary returned by Inherited::build(...).
528 /// Necessary because we can't write the following bound:
529 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
530 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
531 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
535 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
536 pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
537 -> InheritedBuilder<'a, 'gcx, 'tcx> {
538 let tables = ty::TypeckTables::empty();
540 infcx: tcx.infer_ctxt(tables),
546 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
547 fn enter<F, R>(&'tcx mut self, f: F) -> R
548 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
550 let def_id = self.def_id;
551 self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
555 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
556 fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
558 let item_id = tcx.hir.as_local_node_id(def_id);
559 let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
560 let implicit_region_bound = body_id.map(|body| {
561 tcx.mk_region(ty::ReScope(CodeExtent::CallSiteScope(body)))
566 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
567 locals: RefCell::new(NodeMap()),
568 deferred_call_resolutions: RefCell::new(DefIdMap()),
569 deferred_cast_checks: RefCell::new(Vec::new()),
570 anon_types: RefCell::new(NodeMap()),
571 implicit_region_bound,
575 fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
576 debug!("register_predicate({:?})", obligation);
577 if obligation.has_escaping_regions() {
578 span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
583 .register_predicate_obligation(self, obligation);
586 fn register_predicates(&self, obligations: Vec<traits::PredicateObligation<'tcx>>) {
587 for obligation in obligations {
588 self.register_predicate(obligation);
592 fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
593 self.register_predicates(infer_ok.obligations);
597 fn normalize_associated_types_in<T>(&self,
599 body_id: ast::NodeId,
600 param_env: ty::ParamEnv<'tcx>,
602 where T : TypeFoldable<'tcx>
604 let ok = self.normalize_associated_types_in_as_infer_ok(span, body_id, param_env, value);
605 self.register_infer_ok_obligations(ok)
608 fn normalize_associated_types_in_as_infer_ok<T>(&self,
610 body_id: ast::NodeId,
611 param_env: ty::ParamEnv<'tcx>,
614 where T : TypeFoldable<'tcx>
616 debug!("normalize_associated_types_in(value={:?})", value);
617 let mut selcx = traits::SelectionContext::new(self);
618 let cause = ObligationCause::misc(span, body_id);
619 let traits::Normalized { value, obligations } =
620 traits::normalize(&mut selcx, param_env, cause, value);
621 debug!("normalize_associated_types_in: result={:?} predicates={:?}",
624 InferOk { value, obligations }
627 /// Replace any late-bound regions bound in `value` with
628 /// free variants attached to `all_outlive_scope`.
629 fn liberate_late_bound_regions<T>(&self,
630 all_outlive_scope: DefId,
631 value: &ty::Binder<T>)
633 where T: TypeFoldable<'tcx>
635 self.tcx.replace_late_bound_regions(value, |br| {
636 self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
637 scope: all_outlive_scope,
644 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
646 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
647 fn visit_item(&mut self, i: &'tcx hir::Item) {
648 check_item_type(self.tcx, i);
650 fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
651 fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
654 pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
655 tcx.sess.track_errors(|| {
656 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
657 tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
661 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
662 tcx.sess.track_errors(|| {
663 tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
667 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
668 tcx.typeck_item_bodies(LOCAL_CRATE)
671 fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
672 debug_assert!(crate_num == LOCAL_CRATE);
673 tcx.sess.track_errors(|| {
674 for body_owner_def_id in tcx.body_owners() {
675 tcx.typeck_tables_of(body_owner_def_id);
680 pub fn provide(providers: &mut Providers) {
681 *providers = Providers {
692 fn closure_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
694 -> ty::PolyFnSig<'tcx> {
695 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
696 tcx.typeck_tables_of(def_id).closure_tys[&node_id]
699 fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
702 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
703 tcx.typeck_tables_of(def_id).closure_kinds[&node_id].0
706 fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
708 -> Option<ty::Destructor> {
709 tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
712 /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
713 /// with information about it's body-id and fn-decl (if any). Otherwise,
716 /// If this function returns "some", then `typeck_tables(def_id)` will
717 /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
718 /// may not succeed. In some cases where this function returns `None`
719 /// (notably closures), `typeck_tables(def_id)` would wind up
720 /// redirecting to the owning function.
721 fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
723 -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
725 match tcx.hir.get(id) {
726 hir::map::NodeItem(item) => {
728 hir::ItemConst(_, body) |
729 hir::ItemStatic(_, _, body) =>
731 hir::ItemFn(ref decl, .., body) =>
732 Some((body, Some(decl))),
737 hir::map::NodeTraitItem(item) => {
739 hir::TraitItemKind::Const(_, Some(body)) =>
741 hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
742 Some((body, Some(&sig.decl))),
747 hir::map::NodeImplItem(item) => {
749 hir::ImplItemKind::Const(_, body) =>
751 hir::ImplItemKind::Method(ref sig, body) =>
752 Some((body, Some(&sig.decl))),
757 hir::map::NodeExpr(expr) => {
758 // FIXME(eddyb) Closures should have separate
759 // function definition IDs and expression IDs.
760 // Type-checking should not let closures get
761 // this far in a constant position.
762 // Assume that everything other than closures
763 // is a constant "initializer" expression.
765 hir::ExprClosure(..) =>
768 Some((hir::BodyId { node_id: expr.id }, None)),
775 fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
778 // Closures' tables come from their outermost function,
779 // as they are part of the same "inference environment".
780 let outer_def_id = tcx.closure_base_def_id(def_id);
781 if outer_def_id != def_id {
782 return tcx.has_typeck_tables(outer_def_id);
785 let id = tcx.hir.as_local_node_id(def_id).unwrap();
786 primary_body_of(tcx, id).is_some()
789 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
791 -> &'tcx ty::TypeckTables<'tcx> {
792 // Closures' tables come from their outermost function,
793 // as they are part of the same "inference environment".
794 let outer_def_id = tcx.closure_base_def_id(def_id);
795 if outer_def_id != def_id {
796 return tcx.typeck_tables_of(outer_def_id);
799 let id = tcx.hir.as_local_node_id(def_id).unwrap();
800 let span = tcx.hir.span(id);
802 // Figure out what primary body this item has.
803 let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
804 span_bug!(span, "can't type-check body of {:?}", def_id);
806 let body = tcx.hir.body(body_id);
808 Inherited::build(tcx, def_id).enter(|inh| {
809 let param_env = tcx.param_env(def_id);
810 let fcx = if let Some(decl) = fn_decl {
811 let fn_sig = tcx.type_of(def_id).fn_sig();
813 check_abi(tcx, span, fn_sig.abi());
815 // Compute the fty from point of view of inside fn.
817 inh.liberate_late_bound_regions(def_id, &fn_sig);
819 inh.normalize_associated_types_in(body.value.span,
824 check_fn(&inh, param_env, fn_sig, decl, id, body)
826 let fcx = FnCtxt::new(&inh, param_env, body.value.id);
827 let expected_type = tcx.type_of(def_id);
828 let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
829 fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
831 // Gather locals in statics (because of block expressions).
832 // This is technically unnecessary because locals in static items are forbidden,
833 // but prevents type checking from blowing up before const checking can properly
835 GatherLocalsVisitor { fcx: &fcx }.visit_body(body);
837 fcx.check_expr_coercable_to_type(&body.value, expected_type);
842 fcx.select_all_obligations_and_apply_defaults();
843 fcx.closure_analyze(body);
844 fcx.select_obligations_where_possible();
846 fcx.select_all_obligations_or_error();
848 if fn_decl.is_some() {
849 fcx.regionck_fn(id, body);
851 fcx.regionck_expr(body);
854 fcx.resolve_type_vars_in_body(body)
858 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
859 if !tcx.sess.target.target.is_abi_supported(abi) {
860 struct_span_err!(tcx.sess, span, E0570,
861 "The ABI `{}` is not supported for the current target", abi).emit()
865 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
866 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
869 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
870 fn assign(&mut self, span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
873 // infer the variable's type
874 let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
875 self.fcx.locals.borrow_mut().insert(nid, var_ty);
879 // take type that the user specified
880 self.fcx.locals.borrow_mut().insert(nid, typ);
887 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
888 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
889 NestedVisitorMap::None
892 // Add explicitly-declared locals.
893 fn visit_local(&mut self, local: &'gcx hir::Local) {
894 let o_ty = match local.ty {
895 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
898 self.assign(local.span, local.id, o_ty);
899 debug!("Local variable {:?} is assigned type {}",
901 self.fcx.ty_to_string(
902 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
903 intravisit::walk_local(self, local);
906 // Add pattern bindings.
907 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
908 if let PatKind::Binding(_, _, ref path1, _) = p.node {
909 let var_ty = self.assign(p.span, p.id, None);
911 self.fcx.require_type_is_sized(var_ty, p.span,
912 traits::VariableType(p.id));
914 debug!("Pattern binding {} is assigned to {} with type {:?}",
916 self.fcx.ty_to_string(
917 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
920 intravisit::walk_pat(self, p);
923 // Don't descend into the bodies of nested closures
924 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
925 _: hir::BodyId, _: Span, _: ast::NodeId) { }
928 /// Helper used for fns and closures. Does the grungy work of checking a function
929 /// body and returns the function context used for that purpose, since in the case of a fn item
930 /// there is still a bit more to do.
933 /// * inherited: other fields inherited from the enclosing fn (if any)
934 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
935 param_env: ty::ParamEnv<'tcx>,
936 fn_sig: ty::FnSig<'tcx>,
937 decl: &'gcx hir::FnDecl,
939 body: &'gcx hir::Body)
940 -> FnCtxt<'a, 'gcx, 'tcx>
942 let mut fn_sig = fn_sig.clone();
944 debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
946 // Create the function context. This is either derived from scratch or,
947 // in the case of function expressions, based on the outer context.
948 let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
949 *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
951 let ret_ty = fn_sig.output();
952 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
953 let ret_ty = fcx.instantiate_anon_types(&ret_ty);
954 fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
955 fn_sig = fcx.tcx.mk_fn_sig(
956 fn_sig.inputs().iter().cloned(),
963 GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
965 // Add formal parameters.
966 for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
967 // The type of the argument must be well-formed.
969 // NB -- this is now checked in wfcheck, but that
970 // currently only results in warnings, so we issue an
971 // old-style WF obligation here so that we still get the
972 // errors that we used to get.
973 fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
975 // Check the pattern.
976 fcx.check_pat_arg(&arg.pat, arg_ty, true);
977 fcx.write_ty(arg.id, arg_ty);
980 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
982 fcx.check_return_expr(&body.value);
984 // Finalize the return check by taking the LUB of the return types
985 // we saw and assigning it to the expected return type. This isn't
986 // really expected to fail, since the coercions would have failed
987 // earlier when trying to find a LUB.
989 // However, the behavior around `!` is sort of complex. In the
990 // event that the `actual_return_ty` comes back as `!`, that
991 // indicates that the fn either does not return or "returns" only
992 // values of type `!`. In this case, if there is an expected
993 // return type that is *not* `!`, that should be ok. But if the
994 // return type is being inferred, we want to "fallback" to `!`:
996 // let x = move || panic!();
998 // To allow for that, I am creating a type variable with diverging
999 // fallback. This was deemed ever so slightly better than unifying
1000 // the return value with `!` because it allows for the caller to
1001 // make more assumptions about the return type (e.g., they could do
1003 // let y: Option<u32> = Some(x());
1005 // which would then cause this return type to become `u32`, not
1007 let coercion = fcx.ret_coercion.take().unwrap().into_inner();
1008 let mut actual_return_ty = coercion.complete(&fcx);
1009 if actual_return_ty.is_never() {
1010 actual_return_ty = fcx.next_diverging_ty_var(
1011 TypeVariableOrigin::DivergingFn(body.value.span));
1013 fcx.demand_suptype(body.value.span, ret_ty, actual_return_ty);
1018 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1021 let def_id = tcx.hir.local_def_id(id);
1022 let def = tcx.adt_def(def_id);
1023 def.destructor(tcx); // force the destructor to be evaluated
1024 check_representable(tcx, span, def_id);
1026 if def.repr.simd() {
1027 check_simd(tcx, span, def_id);
1030 // if struct is packed and not aligned, check fields for alignment.
1031 // Checks for combining packed and align attrs on single struct are done elsewhere.
1032 if tcx.adt_def(def_id).repr.packed() && tcx.adt_def(def_id).repr.align == 0 {
1033 check_packed(tcx, span, def_id);
1037 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1040 let def_id = tcx.hir.local_def_id(id);
1041 let def = tcx.adt_def(def_id);
1042 def.destructor(tcx); // force the destructor to be evaluated
1043 check_representable(tcx, span, def_id);
1046 pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
1047 debug!("check_item_type(it.id={}, it.name={})",
1049 tcx.item_path_str(tcx.hir.local_def_id(it.id)));
1050 let _indenter = indenter();
1052 // Consts can play a role in type-checking, so they are included here.
1053 hir::ItemStatic(..) |
1054 hir::ItemConst(..) => {
1055 tcx.typeck_tables_of(tcx.hir.local_def_id(it.id));
1057 hir::ItemEnum(ref enum_definition, _) => {
1060 &enum_definition.variants,
1063 hir::ItemFn(..) => {} // entirely within check_item_body
1064 hir::ItemImpl(.., ref impl_item_refs) => {
1065 debug!("ItemImpl {} with id {}", it.name, it.id);
1066 let impl_def_id = tcx.hir.local_def_id(it.id);
1067 if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1068 check_impl_items_against_trait(tcx,
1073 let trait_def_id = impl_trait_ref.def_id;
1074 check_on_unimplemented(tcx, trait_def_id, it);
1077 hir::ItemTrait(..) => {
1078 let def_id = tcx.hir.local_def_id(it.id);
1079 check_on_unimplemented(tcx, def_id, it);
1081 hir::ItemStruct(..) => {
1082 check_struct(tcx, it.id, it.span);
1084 hir::ItemUnion(..) => {
1085 check_union(tcx, it.id, it.span);
1087 hir::ItemTy(_, ref generics) => {
1088 let def_id = tcx.hir.local_def_id(it.id);
1089 let pty_ty = tcx.type_of(def_id);
1090 check_bounds_are_used(tcx, generics, pty_ty);
1092 hir::ItemForeignMod(ref m) => {
1093 check_abi(tcx, it.span, m.abi);
1095 if m.abi == Abi::RustIntrinsic {
1096 for item in &m.items {
1097 intrinsic::check_intrinsic_type(tcx, item);
1099 } else if m.abi == Abi::PlatformIntrinsic {
1100 for item in &m.items {
1101 intrinsic::check_platform_intrinsic_type(tcx, item);
1104 for item in &m.items {
1105 let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
1106 if !generics.types.is_empty() {
1107 let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1108 "foreign items may not have type parameters");
1109 span_help!(&mut err, item.span,
1110 "consider using specialization instead of \
1115 if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
1116 require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span);
1121 _ => {/* nothing to do */ }
1125 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1128 let generics = tcx.generics_of(def_id);
1129 if let Some(ref attr) = item.attrs.iter().find(|a| {
1130 a.check_name("rustc_on_unimplemented")
1132 if let Some(istring) = attr.value_str() {
1133 let istring = istring.as_str();
1134 let parser = Parser::new(&istring);
1135 let types = &generics.types;
1136 for token in parser {
1138 Piece::String(_) => (), // Normal string, no need to check it
1139 Piece::NextArgument(a) => match a.position {
1140 // `{Self}` is allowed
1141 Position::ArgumentNamed(s) if s == "Self" => (),
1142 // So is `{A}` if A is a type parameter
1143 Position::ArgumentNamed(s) => match types.iter().find(|t| {
1148 let name = tcx.item_name(def_id);
1149 span_err!(tcx.sess, attr.span, E0230,
1150 "there is no type parameter \
1155 // `{:1}` and `{}` are not to be used
1156 Position::ArgumentIs(_) => {
1157 span_err!(tcx.sess, attr.span, E0231,
1158 "only named substitution \
1159 parameters are allowed");
1166 tcx.sess, attr.span, E0232,
1167 "this attribute must have a value")
1168 .span_label(attr.span, "attribute requires a value")
1169 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
1175 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1176 impl_item: &hir::ImplItem,
1179 let mut err = struct_span_err!(
1180 tcx.sess, impl_item.span, E0520,
1181 "`{}` specializes an item from a parent `impl`, but \
1182 that item is not marked `default`",
1184 err.span_label(impl_item.span, format!("cannot specialize default item `{}`",
1187 match tcx.span_of_impl(parent_impl) {
1189 err.span_label(span, "parent `impl` is here");
1190 err.note(&format!("to specialize, `{}` in the parent `impl` must be marked `default`",
1194 err.note(&format!("parent implementation is in crate `{}`", cname));
1201 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1202 trait_def: &ty::TraitDef,
1204 impl_item: &hir::ImplItem)
1206 let ancestors = trait_def.ancestors(tcx, impl_id);
1208 let kind = match impl_item.node {
1209 hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
1210 hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
1211 hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
1213 let parent = ancestors.defs(tcx, impl_item.name, kind).skip(1).next()
1214 .map(|node_item| node_item.map(|parent| parent.defaultness));
1216 if let Some(parent) = parent {
1217 if tcx.impl_item_is_final(&parent) {
1218 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
1224 fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1227 impl_trait_ref: ty::TraitRef<'tcx>,
1228 impl_item_refs: &[hir::ImplItemRef]) {
1229 // If the trait reference itself is erroneous (so the compilation is going
1230 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
1231 // isn't populated for such impls.
1232 if impl_trait_ref.references_error() { return; }
1234 // Locate trait definition and items
1235 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
1236 let mut overridden_associated_type = None;
1238 let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id));
1240 // Check existing impl methods to see if they are both present in trait
1241 // and compatible with trait signature
1242 for impl_item in impl_items() {
1243 let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id));
1244 let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
1245 .find(|ac| ac.name == ty_impl_item.name);
1247 // Check that impl definition matches trait definition
1248 if let Some(ty_trait_item) = ty_trait_item {
1249 match impl_item.node {
1250 hir::ImplItemKind::Const(..) => {
1251 // Find associated const definition.
1252 if ty_trait_item.kind == ty::AssociatedKind::Const {
1253 compare_const_impl(tcx,
1259 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1260 "item `{}` is an associated const, \
1261 which doesn't match its trait `{}`",
1264 err.span_label(impl_item.span, "does not match trait");
1265 // We can only get the spans from local trait definition
1266 // Same for E0324 and E0325
1267 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1268 err.span_label(trait_span, "item in trait");
1273 hir::ImplItemKind::Method(..) => {
1274 let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
1275 if ty_trait_item.kind == ty::AssociatedKind::Method {
1276 let err_count = tcx.sess.err_count();
1277 compare_impl_method(tcx,
1283 true); // start with old-broken-mode
1284 if err_count == tcx.sess.err_count() {
1285 // old broken mode did not report an error. Try with the new mode.
1286 compare_impl_method(tcx,
1292 false); // use the new mode
1295 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1296 "item `{}` is an associated method, \
1297 which doesn't match its trait `{}`",
1300 err.span_label(impl_item.span, "does not match trait");
1301 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1302 err.span_label(trait_span, "item in trait");
1307 hir::ImplItemKind::Type(_) => {
1308 if ty_trait_item.kind == ty::AssociatedKind::Type {
1309 if ty_trait_item.defaultness.has_value() {
1310 overridden_associated_type = Some(impl_item);
1313 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1314 "item `{}` is an associated type, \
1315 which doesn't match its trait `{}`",
1318 err.span_label(impl_item.span, "does not match trait");
1319 if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) {
1320 err.span_label(trait_span, "item in trait");
1328 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1331 // Check for missing items from trait
1332 let mut missing_items = Vec::new();
1333 let mut invalidated_items = Vec::new();
1334 let associated_type_overridden = overridden_associated_type.is_some();
1335 for trait_item in tcx.associated_items(impl_trait_ref.def_id) {
1336 let is_implemented = trait_def.ancestors(tcx, impl_id)
1337 .defs(tcx, trait_item.name, trait_item.kind)
1339 .map(|node_item| !node_item.node.is_from_trait())
1342 if !is_implemented {
1343 if !trait_item.defaultness.has_value() {
1344 missing_items.push(trait_item);
1345 } else if associated_type_overridden {
1346 invalidated_items.push(trait_item.name);
1351 let signature = |item: &ty::AssociatedItem| {
1353 ty::AssociatedKind::Method => {
1354 format!("{}", tcx.type_of(item.def_id).fn_sig().0)
1356 ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
1357 ty::AssociatedKind::Const => {
1358 format!("const {}: {:?};", item.name.to_string(), tcx.type_of(item.def_id))
1363 if !missing_items.is_empty() {
1364 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1365 "not all trait items implemented, missing: `{}`",
1366 missing_items.iter()
1367 .map(|trait_item| trait_item.name.to_string())
1368 .collect::<Vec<_>>().join("`, `"));
1369 err.span_label(impl_span, format!("missing `{}` in implementation",
1370 missing_items.iter()
1371 .map(|trait_item| trait_item.name.to_string())
1372 .collect::<Vec<_>>().join("`, `")));
1373 for trait_item in missing_items {
1374 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1375 err.span_label(span, format!("`{}` from trait", trait_item.name));
1377 err.note(&format!("`{}` from trait: `{}`",
1379 signature(&trait_item)));
1385 if !invalidated_items.is_empty() {
1386 let invalidator = overridden_associated_type.unwrap();
1387 span_err!(tcx.sess, invalidator.span, E0399,
1388 "the following trait items need to be reimplemented \
1389 as `{}` was overridden: `{}`",
1391 invalidated_items.iter()
1392 .map(|name| name.to_string())
1393 .collect::<Vec<_>>().join("`, `"))
1397 /// Checks whether a type can be represented in memory. In particular, it
1398 /// identifies types that contain themselves without indirection through a
1399 /// pointer, which would mean their size is unbounded.
1400 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1404 let rty = tcx.type_of(item_def_id);
1406 // Check that it is possible to represent this type. This call identifies
1407 // (1) types that contain themselves and (2) types that contain a different
1408 // recursive type. It is only necessary to throw an error on those that
1409 // contain themselves. For case 2, there must be an inner type that will be
1410 // caught by case 1.
1411 match rty.is_representable(tcx, sp) {
1412 Representability::SelfRecursive(spans) => {
1413 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1415 err.span_label(span, "recursive without indirection");
1420 Representability::Representable | Representability::ContainsRecursive => (),
1425 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1426 let t = tcx.type_of(def_id);
1428 ty::TyAdt(def, substs) if def.is_struct() => {
1429 let fields = &def.struct_variant().fields;
1430 if fields.is_empty() {
1431 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1434 let e = fields[0].ty(tcx, substs);
1435 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1436 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1437 .span_label(sp, "SIMD elements must have the same type")
1442 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1443 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1445 span_err!(tcx.sess, sp, E0077,
1446 "SIMD vector element type should be machine type");
1455 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1456 if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1457 struct_span_err!(tcx.sess, sp, E0588,
1458 "packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1462 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1464 stack: &mut Vec<DefId>) -> bool {
1465 let t = tcx.type_of(def_id);
1466 if stack.contains(&def_id) {
1467 debug!("check_packed_inner: {:?} is recursive", t);
1471 ty::TyAdt(def, substs) if def.is_struct() => {
1472 if tcx.adt_def(def.did).repr.align > 0 {
1475 // push struct def_id before checking fields
1477 for field in &def.struct_variant().fields {
1478 let f = field.ty(tcx, substs);
1480 ty::TyAdt(def, _) => {
1481 if check_packed_inner(tcx, def.did, stack) {
1488 // only need to pop if not early out
1496 #[allow(trivial_numeric_casts)]
1497 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1499 vs: &'tcx [hir::Variant],
1501 let def_id = tcx.hir.local_def_id(id);
1502 let def = tcx.adt_def(def_id);
1503 def.destructor(tcx); // force the destructor to be evaluated
1505 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1507 tcx.sess, sp, E0084,
1508 "unsupported representation for zero-variant enum")
1509 .span_label(sp, "unsupported enum representation")
1513 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1514 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1515 if !tcx.sess.features.borrow().i128_type {
1516 emit_feature_err(&tcx.sess.parse_sess,
1517 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1522 if let Some(e) = v.node.disr_expr {
1523 tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
1527 let mut disr_vals: Vec<ConstInt> = Vec::new();
1528 for (discr, v) in def.discriminants(tcx).zip(vs) {
1529 // Check for duplicate discriminant values
1530 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1531 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1532 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1533 let i_span = match variant_i.node.disr_expr {
1534 Some(expr) => tcx.hir.span(expr.node_id),
1535 None => tcx.hir.span(variant_i_node_id)
1537 let span = match v.node.disr_expr {
1538 Some(expr) => tcx.hir.span(expr.node_id),
1541 struct_span_err!(tcx.sess, span, E0081,
1542 "discriminant value `{}` already exists", disr_vals[i])
1543 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1544 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1547 disr_vals.push(discr);
1550 check_representable(tcx, sp, def_id);
1553 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1554 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1556 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1557 -> ty::GenericPredicates<'tcx>
1560 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1561 let item_id = tcx.hir.ty_param_owner(node_id);
1562 let item_def_id = tcx.hir.local_def_id(item_id);
1563 let generics = tcx.generics_of(item_def_id);
1564 let index = generics.type_param_to_index[&def_id.index];
1565 ty::GenericPredicates {
1567 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1569 ty::Predicate::Trait(ref data) => {
1570 data.0.self_ty().is_param(index)
1574 }).cloned().collect()
1578 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1579 -> Option<ty::Region<'tcx>> {
1581 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1582 None => infer::MiscVariable(span)
1584 Some(self.next_region_var(v))
1587 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1588 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1591 fn ty_infer_for_def(&self,
1592 ty_param_def: &ty::TypeParameterDef,
1593 substs: &[Kind<'tcx>],
1594 span: Span) -> Ty<'tcx> {
1595 self.type_var_for_def(span, ty_param_def, substs)
1598 fn projected_ty_from_poly_trait_ref(&self,
1600 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1601 item_name: ast::Name)
1604 let (trait_ref, _) =
1605 self.replace_late_bound_regions_with_fresh_var(
1607 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1610 self.tcx().mk_projection(trait_ref, item_name)
1613 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1614 if ty.has_escaping_regions() {
1615 ty // FIXME: normalization and escaping regions
1617 self.normalize_associated_types_in(span, &ty)
1621 fn set_tainted_by_errors(&self) {
1622 self.infcx.set_tainted_by_errors()
1626 /// Controls whether the arguments are tupled. This is used for the call
1629 /// Tupling means that all call-side arguments are packed into a tuple and
1630 /// passed as a single parameter. For example, if tupling is enabled, this
1633 /// fn f(x: (isize, isize))
1635 /// Can be called as:
1642 #[derive(Clone, Eq, PartialEq)]
1643 enum TupleArgumentsFlag {
1648 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1649 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1650 param_env: ty::ParamEnv<'tcx>,
1651 body_id: ast::NodeId)
1652 -> FnCtxt<'a, 'gcx, 'tcx> {
1656 err_count_on_creation: inh.tcx.sess.err_count(),
1658 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1659 ast::CRATE_NODE_ID)),
1660 diverges: Cell::new(Diverges::Maybe),
1661 has_errors: Cell::new(false),
1662 enclosing_breakables: RefCell::new(EnclosingBreakables {
1670 pub fn sess(&self) -> &Session {
1674 pub fn err_count_since_creation(&self) -> usize {
1675 self.tcx.sess.err_count() - self.err_count_on_creation
1678 /// Produce warning on the given node, if the current point in the
1679 /// function is unreachable, and there hasn't been another warning.
1680 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1681 if self.diverges.get() == Diverges::Always {
1682 self.diverges.set(Diverges::WarnedAlways);
1684 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1686 self.tables.borrow_mut().lints.add_lint(
1687 lint::builtin::UNREACHABLE_CODE,
1689 format!("unreachable {}", kind));
1695 code: ObligationCauseCode<'tcx>)
1696 -> ObligationCause<'tcx> {
1697 ObligationCause::new(span, self.body_id, code)
1700 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1701 self.cause(span, ObligationCauseCode::MiscObligation)
1704 /// Resolves type variables in `ty` if possible. Unlike the infcx
1705 /// version (resolve_type_vars_if_possible), this version will
1706 /// also select obligations if it seems useful, in an effort
1707 /// to get more type information.
1708 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1709 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1711 // No TyInfer()? Nothing needs doing.
1712 if !ty.has_infer_types() {
1713 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1717 // If `ty` is a type variable, see whether we already know what it is.
1718 ty = self.resolve_type_vars_if_possible(&ty);
1719 if !ty.has_infer_types() {
1720 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1724 // If not, try resolving pending obligations as much as
1725 // possible. This can help substantially when there are
1726 // indirect dependencies that don't seem worth tracking
1728 self.select_obligations_where_possible();
1729 ty = self.resolve_type_vars_if_possible(&ty);
1731 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1735 fn record_deferred_call_resolution(&self,
1736 closure_def_id: DefId,
1737 r: DeferredCallResolution<'gcx, 'tcx>) {
1738 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1739 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1742 fn remove_deferred_call_resolutions(&self,
1743 closure_def_id: DefId)
1744 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1746 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1747 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1750 pub fn tag(&self) -> String {
1751 let self_ptr: *const FnCtxt = self;
1752 format!("{:?}", self_ptr)
1755 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1756 match self.locals.borrow().get(&nid) {
1759 span_bug!(span, "no type for local variable {}",
1760 self.tcx.hir.node_to_string(nid));
1766 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1767 debug!("write_ty({}, {:?}) in fcx {}",
1768 node_id, self.resolve_type_vars_if_possible(&ty), self.tag());
1769 self.tables.borrow_mut().node_types.insert(node_id, ty);
1771 if ty.references_error() {
1772 self.has_errors.set(true);
1773 self.set_tainted_by_errors();
1777 pub fn write_method_call(&self, node_id: ast::NodeId, method: MethodCallee<'tcx>) {
1778 self.tables.borrow_mut().type_dependent_defs.insert(node_id, Def::Method(method.def_id));
1779 self.write_substs(node_id, method.substs);
1782 pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) {
1783 if !substs.is_noop() {
1784 debug!("write_substs({}, {:?}) in fcx {}",
1789 self.tables.borrow_mut().node_substs.insert(node_id, substs);
1793 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1794 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1800 match self.tables.borrow_mut().adjustments.entry(expr.id) {
1801 Entry::Vacant(entry) => { entry.insert(adj); },
1802 Entry::Occupied(mut entry) => {
1803 debug!(" - composing on top of {:?}", entry.get());
1804 match (&entry.get()[..], &adj[..]) {
1805 // Applying any adjustment on top of a NeverToAny
1806 // is a valid NeverToAny adjustment, because it can't
1808 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1810 Adjustment { kind: Adjust::Deref(_), .. },
1811 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1813 Adjustment { kind: Adjust::Deref(_), .. },
1814 .. // Any following adjustments are allowed.
1816 // A reborrow has no effect before a dereference.
1818 // FIXME: currently we never try to compose autoderefs
1819 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1821 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1822 expr, entry.get(), adj)
1824 *entry.get_mut() = adj;
1829 /// Basically whenever we are converting from a type scheme into
1830 /// the fn body space, we always want to normalize associated
1831 /// types as well. This function combines the two.
1832 fn instantiate_type_scheme<T>(&self,
1834 substs: &Substs<'tcx>,
1837 where T : TypeFoldable<'tcx>
1839 let value = value.subst(self.tcx, substs);
1840 let result = self.normalize_associated_types_in(span, &value);
1841 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1848 /// As `instantiate_type_scheme`, but for the bounds found in a
1849 /// generic type scheme.
1850 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1851 -> ty::InstantiatedPredicates<'tcx> {
1852 let bounds = self.tcx.predicates_of(def_id);
1853 let result = bounds.instantiate(self.tcx, substs);
1854 let result = self.normalize_associated_types_in(span, &result);
1855 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1862 /// Replace all anonymized types with fresh inference variables
1863 /// and record them for writeback.
1864 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1865 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1866 if let ty::TyAnon(def_id, substs) = ty.sty {
1867 // Use the same type variable if the exact same TyAnon appears more
1868 // than once in the return type (e.g. if it's pased to a type alias).
1869 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1870 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1873 let span = self.tcx.def_span(def_id);
1874 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1875 self.anon_types.borrow_mut().insert(id, ty_var);
1877 let predicates_of = self.tcx.predicates_of(def_id);
1878 let bounds = predicates_of.instantiate(self.tcx, substs);
1880 for predicate in bounds.predicates {
1881 // Change the predicate to refer to the type variable,
1882 // which will be the concrete type, instead of the TyAnon.
1883 // This also instantiates nested `impl Trait`.
1884 let predicate = self.instantiate_anon_types(&predicate);
1886 // Require that the predicate holds for the concrete type.
1887 let cause = traits::ObligationCause::new(span, self.body_id,
1888 traits::ReturnType);
1889 self.register_predicate(traits::Obligation::new(cause,
1901 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1902 where T : TypeFoldable<'tcx>
1904 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
1907 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
1909 where T : TypeFoldable<'tcx>
1911 self.inh.normalize_associated_types_in_as_infer_ok(span, self.body_id, self.param_env, value)
1914 pub fn write_nil(&self, node_id: ast::NodeId) {
1915 self.write_ty(node_id, self.tcx.mk_nil());
1918 pub fn write_error(&self, node_id: ast::NodeId) {
1919 self.write_ty(node_id, self.tcx.types.err);
1922 pub fn require_type_meets(&self,
1925 code: traits::ObligationCauseCode<'tcx>,
1928 self.register_bound(
1931 traits::ObligationCause::new(span, self.body_id, code));
1934 pub fn require_type_is_sized(&self,
1937 code: traits::ObligationCauseCode<'tcx>)
1939 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1940 self.require_type_meets(ty, span, code, lang_item);
1943 pub fn register_bound(&self,
1946 cause: traits::ObligationCause<'tcx>)
1948 self.fulfillment_cx.borrow_mut()
1949 .register_bound(self, self.param_env, ty, def_id, cause);
1952 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1953 let t = AstConv::ast_ty_to_ty(self, ast_t);
1954 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1958 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1959 match self.tables.borrow().node_types.get(&id) {
1961 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1963 bug!("no type for node {}: {} in fcx {}",
1964 id, self.tcx.hir.node_to_string(id),
1970 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1971 /// outlive the region `r`.
1972 pub fn register_region_obligation(&self,
1974 region: ty::Region<'tcx>,
1975 cause: traits::ObligationCause<'tcx>)
1977 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1978 fulfillment_cx.register_region_obligation(ty, region, cause);
1981 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1982 /// outlive the region `r`.
1983 pub fn register_wf_obligation(&self,
1986 code: traits::ObligationCauseCode<'tcx>)
1988 // WF obligations never themselves fail, so no real need to give a detailed cause:
1989 let cause = traits::ObligationCause::new(span, self.body_id, code);
1990 self.register_predicate(traits::Obligation::new(cause,
1992 ty::Predicate::WellFormed(ty)));
1995 pub fn register_old_wf_obligation(&self,
1998 code: traits::ObligationCauseCode<'tcx>)
2000 // Registers an "old-style" WF obligation that uses the
2001 // implicator code. This is basically a buggy version of
2002 // `register_wf_obligation` that is being kept around
2003 // temporarily just to help with phasing in the newer rules.
2005 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
2006 let cause = traits::ObligationCause::new(span, self.body_id, code);
2007 self.register_region_obligation(ty, self.tcx.types.re_empty, cause);
2010 /// Registers obligations that all types appearing in `substs` are well-formed.
2011 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
2013 for ty in substs.types() {
2014 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2018 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2019 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2020 /// trait/region obligations.
2022 /// For example, if there is a function:
2025 /// fn foo<'a,T:'a>(...)
2028 /// and a reference:
2034 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2035 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2036 pub fn add_obligations_for_parameters(&self,
2037 cause: traits::ObligationCause<'tcx>,
2038 predicates: &ty::InstantiatedPredicates<'tcx>)
2040 assert!(!predicates.has_escaping_regions());
2042 debug!("add_obligations_for_parameters(predicates={:?})",
2045 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2046 self.register_predicate(obligation);
2050 // FIXME(arielb1): use this instead of field.ty everywhere
2051 // Only for fields! Returns <none> for methods>
2052 // Indifferent to privacy flags
2053 pub fn field_ty(&self,
2055 field: &'tcx ty::FieldDef,
2056 substs: &Substs<'tcx>)
2059 self.normalize_associated_types_in(span,
2060 &field.ty(self.tcx, substs))
2063 fn check_casts(&self) {
2064 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2065 for cast in deferred_cast_checks.drain(..) {
2070 /// Apply "fallbacks" to some types
2071 /// unconstrained types get replaced with ! or () (depending on whether
2072 /// feature(never_type) is enabled), unconstrained ints with i32, and
2073 /// unconstrained floats with f64.
2074 fn default_type_parameters(&self) {
2075 use rustc::ty::error::UnconstrainedNumeric::Neither;
2076 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2078 // Defaulting inference variables becomes very dubious if we have
2079 // encountered type-checking errors. Therefore, if we think we saw
2080 // some errors in this function, just resolve all uninstanted type
2081 // varibles to TyError.
2082 if self.is_tainted_by_errors() {
2083 for ty in &self.unsolved_variables() {
2084 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
2085 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2086 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2092 for ty in &self.unsolved_variables() {
2093 let resolved = self.resolve_type_vars_if_possible(ty);
2094 if self.type_var_diverges(resolved) {
2095 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
2097 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2098 self.tcx.mk_diverging_default());
2100 match self.type_is_unconstrained_numeric(resolved) {
2101 UnconstrainedInt => {
2102 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
2104 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2106 UnconstrainedFloat => {
2107 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
2109 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2117 // Implements type inference fallback algorithm
2118 fn select_all_obligations_and_apply_defaults(&self) {
2119 self.select_obligations_where_possible();
2120 self.default_type_parameters();
2121 self.select_obligations_where_possible();
2124 fn select_all_obligations_or_error(&self) {
2125 debug!("select_all_obligations_or_error");
2127 // upvar inference should have ensured that all deferred call
2128 // resolutions are handled by now.
2129 assert!(self.deferred_call_resolutions.borrow().is_empty());
2131 self.select_all_obligations_and_apply_defaults();
2133 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2135 match fulfillment_cx.select_all_or_error(self) {
2137 Err(errors) => { self.report_fulfillment_errors(&errors); }
2141 /// Select as many obligations as we can at present.
2142 fn select_obligations_where_possible(&self) {
2143 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2145 Err(errors) => { self.report_fulfillment_errors(&errors); }
2149 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2150 /// returns a type of `&T`, but the actual type we assign to the
2151 /// *expression* is `T`. So this function just peels off the return
2152 /// type by one layer to yield `T`.
2153 fn make_overloaded_lvalue_return_type(&self,
2154 method: MethodCallee<'tcx>)
2155 -> ty::TypeAndMut<'tcx>
2157 // extract method return type, which will be &T;
2158 // all LB regions should have been instantiated during method lookup
2159 let ret_ty = method.sig.output();
2161 // method returns &T, but the type as visible to user is T, so deref
2162 ret_ty.builtin_deref(true, NoPreference).unwrap()
2165 fn lookup_indexing(&self,
2167 base_expr: &'gcx hir::Expr,
2170 lvalue_pref: LvaluePreference)
2171 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2173 // FIXME(#18741) -- this is almost but not quite the same as the
2174 // autoderef that normal method probing does. They could likely be
2177 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2178 let mut result = None;
2179 while result.is_none() && autoderef.next().is_some() {
2180 result = self.try_index_step(expr, base_expr, &autoderef, lvalue_pref, idx_ty);
2182 autoderef.finalize();
2186 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2187 /// (and otherwise adjust) `base_expr`, looking for a type which either
2188 /// supports builtin indexing or overloaded indexing.
2189 /// This loop implements one step in that search; the autoderef loop
2190 /// is implemented by `lookup_indexing`.
2191 fn try_index_step(&self,
2193 base_expr: &hir::Expr,
2194 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2195 lvalue_pref: LvaluePreference,
2197 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2199 let adjusted_ty = autoderef.unambiguous_final_ty();
2200 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2208 // First, try built-in indexing.
2209 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2210 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2211 debug!("try_index_step: success, using built-in indexing");
2212 let adjustments = autoderef.adjust_steps(lvalue_pref);
2213 self.apply_adjustments(base_expr, adjustments);
2214 return Some((self.tcx.types.usize, ty));
2219 for &unsize in &[false, true] {
2220 let mut self_ty = adjusted_ty;
2222 // We only unsize arrays here.
2223 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2224 self_ty = self.tcx.mk_slice(element_ty);
2230 // If some lookup succeeds, write callee into table and extract index/element
2231 // type from the method signature.
2232 // If some lookup succeeded, install method in table
2233 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2234 let method = self.try_overloaded_lvalue_op(
2235 expr.span, self_ty, &[input_ty], lvalue_pref, LvalueOp::Index);
2237 let result = method.map(|ok| {
2238 debug!("try_index_step: success, using overloaded indexing");
2239 let method = self.register_infer_ok_obligations(ok);
2241 let mut adjustments = autoderef.adjust_steps(lvalue_pref);
2242 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
2243 adjustments.push(Adjustment {
2244 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
2245 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2252 adjustments.push(Adjustment {
2253 kind: Adjust::Unsize,
2254 target: method.sig.inputs()[0]
2257 self.apply_adjustments(base_expr, adjustments);
2259 self.write_method_call(expr.id, method);
2260 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2262 if result.is_some() {
2270 fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2271 let (tr, name) = match (op, is_mut) {
2272 (LvalueOp::Deref, false) =>
2273 (self.tcx.lang_items.deref_trait(), "deref"),
2274 (LvalueOp::Deref, true) =>
2275 (self.tcx.lang_items.deref_mut_trait(), "deref_mut"),
2276 (LvalueOp::Index, false) =>
2277 (self.tcx.lang_items.index_trait(), "index"),
2278 (LvalueOp::Index, true) =>
2279 (self.tcx.lang_items.index_mut_trait(), "index_mut"),
2281 (tr, Symbol::intern(name))
2284 fn try_overloaded_lvalue_op(&self,
2287 arg_tys: &[Ty<'tcx>],
2288 lvalue_pref: LvaluePreference,
2290 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2292 debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
2298 // Try Mut first, if preferred.
2299 let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
2300 let method = match (lvalue_pref, mut_tr) {
2301 (PreferMutLvalue, Some(trait_did)) => {
2302 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2307 // Otherwise, fall back to the immutable version.
2308 let (imm_tr, imm_op) = self.resolve_lvalue_op(op, false);
2309 let method = match (method, imm_tr) {
2310 (None, Some(trait_did)) => {
2311 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2313 (method, _) => method,
2319 fn check_method_argument_types(&self,
2321 method: Result<MethodCallee<'tcx>, ()>,
2322 args_no_rcvr: &'gcx [hir::Expr],
2323 tuple_arguments: TupleArgumentsFlag,
2324 expected: Expectation<'tcx>)
2326 let has_error = match method {
2328 method.substs.references_error() || method.sig.references_error()
2333 let err_inputs = self.err_args(args_no_rcvr.len());
2335 let err_inputs = match tuple_arguments {
2336 DontTupleArguments => err_inputs,
2337 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2340 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2341 false, tuple_arguments, None);
2342 return self.tcx.types.err;
2345 let method = method.unwrap();
2346 // HACK(eddyb) ignore self in the definition (see above).
2347 let expected_arg_tys = self.expected_inputs_for_expected_output(
2350 method.sig.output(),
2351 &method.sig.inputs()[1..]
2353 self.check_argument_types(sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2354 args_no_rcvr, method.sig.variadic, tuple_arguments,
2355 self.tcx.hir.span_if_local(method.def_id));
2359 /// Generic function that factors out common logic from function calls,
2360 /// method calls and overloaded operators.
2361 fn check_argument_types(&self,
2363 fn_inputs: &[Ty<'tcx>],
2364 expected_arg_tys: &[Ty<'tcx>],
2365 args: &'gcx [hir::Expr],
2367 tuple_arguments: TupleArgumentsFlag,
2368 def_span: Option<Span>) {
2371 // Grab the argument types, supplying fresh type variables
2372 // if the wrong number of arguments were supplied
2373 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2379 // All the input types from the fn signature must outlive the call
2380 // so as to validate implied bounds.
2381 for &fn_input_ty in fn_inputs {
2382 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2385 let mut expected_arg_tys = expected_arg_tys;
2386 let expected_arg_count = fn_inputs.len();
2388 let sp_args = if args.len() > 0 {
2389 let (first, args) = args.split_at(1);
2390 let mut sp_tmp = first[0].span;
2392 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2393 if ! sp_opt.is_some() {
2396 sp_tmp = sp_opt.unwrap();
2403 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2404 arg_count: usize, error_code: &str, variadic: bool,
2405 def_span: Option<Span>) {
2406 let mut err = sess.struct_span_err_with_code(sp,
2407 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2408 if variadic {"at least "} else {""},
2410 if expected_count == 1 {""} else {"s"},
2412 if arg_count == 1 {" was"} else {"s were"}),
2415 err.span_label(sp, format!("expected {}{} parameter{}",
2416 if variadic {"at least "} else {""},
2418 if expected_count == 1 {""} else {"s"}));
2419 if let Some(def_s) = def_span {
2420 err.span_label(def_s, "defined here");
2425 let formal_tys = if tuple_arguments == TupleArguments {
2426 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2427 match tuple_type.sty {
2428 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2429 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2430 "E0057", false, def_span);
2431 expected_arg_tys = &[];
2432 self.err_args(args.len())
2434 ty::TyTuple(arg_types, _) => {
2435 expected_arg_tys = match expected_arg_tys.get(0) {
2436 Some(&ty) => match ty.sty {
2437 ty::TyTuple(ref tys, _) => &tys,
2445 span_err!(tcx.sess, sp, E0059,
2446 "cannot use call notation; the first type parameter \
2447 for the function trait is neither a tuple nor unit");
2448 expected_arg_tys = &[];
2449 self.err_args(args.len())
2452 } else if expected_arg_count == supplied_arg_count {
2454 } else if variadic {
2455 if supplied_arg_count >= expected_arg_count {
2458 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2459 supplied_arg_count, "E0060", true, def_span);
2460 expected_arg_tys = &[];
2461 self.err_args(supplied_arg_count)
2464 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2465 supplied_arg_count, "E0061", false, def_span);
2466 expected_arg_tys = &[];
2467 self.err_args(supplied_arg_count)
2470 debug!("check_argument_types: formal_tys={:?}",
2471 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2473 // Check the arguments.
2474 // We do this in a pretty awful way: first we typecheck any arguments
2475 // that are not closures, then we typecheck the closures. This is so
2476 // that we have more information about the types of arguments when we
2477 // typecheck the functions. This isn't really the right way to do this.
2478 for &check_closures in &[false, true] {
2479 debug!("check_closures={}", check_closures);
2481 // More awful hacks: before we check argument types, try to do
2482 // an "opportunistic" vtable resolution of any trait bounds on
2483 // the call. This helps coercions.
2485 self.select_obligations_where_possible();
2488 // For variadic functions, we don't have a declared type for all of
2489 // the arguments hence we only do our usual type checking with
2490 // the arguments who's types we do know.
2491 let t = if variadic {
2493 } else if tuple_arguments == TupleArguments {
2498 for (i, arg) in args.iter().take(t).enumerate() {
2499 // Warn only for the first loop (the "no closures" one).
2500 // Closure arguments themselves can't be diverging, but
2501 // a previous argument can, e.g. `foo(panic!(), || {})`.
2502 if !check_closures {
2503 self.warn_if_unreachable(arg.id, arg.span, "expression");
2506 let is_closure = match arg.node {
2507 hir::ExprClosure(..) => true,
2511 if is_closure != check_closures {
2515 debug!("checking the argument");
2516 let formal_ty = formal_tys[i];
2518 // The special-cased logic below has three functions:
2519 // 1. Provide as good of an expected type as possible.
2520 let expected = expected_arg_tys.get(i).map(|&ty| {
2521 Expectation::rvalue_hint(self, ty)
2524 let checked_ty = self.check_expr_with_expectation(
2526 expected.unwrap_or(ExpectHasType(formal_ty)));
2528 // 2. Coerce to the most detailed type that could be coerced
2529 // to, which is `expected_ty` if `rvalue_hint` returns an
2530 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2531 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2532 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2534 // 3. Relate the expected type and the formal one,
2535 // if the expected type was used for the coercion.
2536 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2540 // We also need to make sure we at least write the ty of the other
2541 // arguments which we skipped above.
2543 for arg in args.iter().skip(expected_arg_count) {
2544 let arg_ty = self.check_expr(&arg);
2546 // There are a few types which get autopromoted when passed via varargs
2547 // in C but we just error out instead and require explicit casts.
2548 let arg_ty = self.structurally_resolved_type(arg.span,
2551 ty::TyFloat(ast::FloatTy::F32) => {
2552 self.type_error_message(arg.span, |t| {
2553 format!("can't pass an `{}` to variadic \
2554 function, cast to `c_double`", t)
2557 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2558 self.type_error_message(arg.span, |t| {
2559 format!("can't pass `{}` to variadic \
2560 function, cast to `c_int`",
2564 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2565 self.type_error_message(arg.span, |t| {
2566 format!("can't pass `{}` to variadic \
2567 function, cast to `c_uint`",
2571 ty::TyFnDef(.., f) => {
2572 let ptr_ty = self.tcx.mk_fn_ptr(f);
2573 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2574 self.type_error_message(arg.span,
2576 format!("can't pass `{}` to variadic \
2577 function, cast to `{}`", t, ptr_ty)
2586 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2587 (0..len).map(|_| self.tcx.types.err).collect()
2590 // AST fragment checking
2593 expected: Expectation<'tcx>)
2599 ast::LitKind::Str(..) => tcx.mk_static_str(),
2600 ast::LitKind::ByteStr(ref v) => {
2601 tcx.mk_imm_ref(tcx.types.re_static,
2602 tcx.mk_array(tcx.types.u8, v.len()))
2604 ast::LitKind::Byte(_) => tcx.types.u8,
2605 ast::LitKind::Char(_) => tcx.types.char,
2606 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2607 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2608 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2609 let opt_ty = expected.to_option(self).and_then(|ty| {
2611 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2612 ty::TyChar => Some(tcx.types.u8),
2613 ty::TyRawPtr(..) => Some(tcx.types.usize),
2614 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2618 opt_ty.unwrap_or_else(
2619 || tcx.mk_int_var(self.next_int_var_id()))
2621 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2622 ast::LitKind::FloatUnsuffixed(_) => {
2623 let opt_ty = expected.to_option(self).and_then(|ty| {
2625 ty::TyFloat(_) => Some(ty),
2629 opt_ty.unwrap_or_else(
2630 || tcx.mk_float_var(self.next_float_var_id()))
2632 ast::LitKind::Bool(_) => tcx.types.bool
2636 fn check_expr_eq_type(&self,
2637 expr: &'gcx hir::Expr,
2638 expected: Ty<'tcx>) {
2639 let ty = self.check_expr_with_hint(expr, expected);
2640 self.demand_eqtype(expr.span, expected, ty);
2643 pub fn check_expr_has_type(&self,
2644 expr: &'gcx hir::Expr,
2645 expected: Ty<'tcx>) -> Ty<'tcx> {
2646 let mut ty = self.check_expr_with_hint(expr, expected);
2648 // While we don't allow *arbitrary* coercions here, we *do* allow
2649 // coercions from ! to `expected`.
2651 assert!(!self.tables.borrow().adjustments.contains_key(&expr.id),
2652 "expression with never type wound up being adjusted");
2653 let adj_ty = self.next_diverging_ty_var(
2654 TypeVariableOrigin::AdjustmentType(expr.span));
2655 self.apply_adjustments(expr, vec![Adjustment {
2656 kind: Adjust::NeverToAny,
2662 self.demand_suptype(expr.span, expected, ty);
2666 fn check_expr_coercable_to_type(&self,
2667 expr: &'gcx hir::Expr,
2668 expected: Ty<'tcx>) -> Ty<'tcx> {
2669 let ty = self.check_expr_with_hint(expr, expected);
2670 self.demand_coerce(expr, ty, expected);
2674 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2675 expected: Ty<'tcx>) -> Ty<'tcx> {
2676 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2679 fn check_expr_with_expectation(&self,
2680 expr: &'gcx hir::Expr,
2681 expected: Expectation<'tcx>) -> Ty<'tcx> {
2682 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2685 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2686 self.check_expr_with_expectation(expr, NoExpectation)
2689 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2690 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2691 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2694 // determine the `self` type, using fresh variables for all variables
2695 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2696 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2698 pub fn impl_self_ty(&self,
2699 span: Span, // (potential) receiver for this impl
2701 -> TypeAndSubsts<'tcx> {
2702 let ity = self.tcx.type_of(did);
2703 debug!("impl_self_ty: ity={:?}", ity);
2705 let substs = self.fresh_substs_for_item(span, did);
2706 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2708 TypeAndSubsts { substs: substs, ty: substd_ty }
2711 /// Unifies the output type with the expected type early, for more coercions
2712 /// and forward type information on the input expressions.
2713 fn expected_inputs_for_expected_output(&self,
2715 expected_ret: Expectation<'tcx>,
2716 formal_ret: Ty<'tcx>,
2717 formal_args: &[Ty<'tcx>])
2719 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2720 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2721 // Attempt to apply a subtyping relationship between the formal
2722 // return type (likely containing type variables if the function
2723 // is polymorphic) and the expected return type.
2724 // No argument expectations are produced if unification fails.
2725 let origin = self.misc(call_span);
2726 let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
2728 // FIXME(#15760) can't use try! here, FromError doesn't default
2729 // to identity so the resulting type is not constrained.
2732 // Process any obligations locally as much as
2733 // we can. We don't care if some things turn
2734 // out unconstrained or ambiguous, as we're
2735 // just trying to get hints here.
2736 let result = self.save_and_restore_in_snapshot_flag(|_| {
2737 let mut fulfill = FulfillmentContext::new();
2738 let ok = ok; // FIXME(#30046)
2739 for obligation in ok.obligations {
2740 fulfill.register_predicate_obligation(self, obligation);
2742 fulfill.select_where_possible(self)
2747 Err(_) => return Err(()),
2750 Err(_) => return Err(()),
2753 // Record all the argument types, with the substitutions
2754 // produced from the above subtyping unification.
2755 Ok(formal_args.iter().map(|ty| {
2756 self.resolve_type_vars_if_possible(ty)
2759 }).unwrap_or(vec![]);
2760 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2761 formal_args, formal_ret,
2762 expected_args, expected_ret);
2766 // Checks a method call.
2767 fn check_method_call(&self,
2768 expr: &'gcx hir::Expr,
2769 method_name: Spanned<ast::Name>,
2770 args: &'gcx [hir::Expr],
2772 expected: Expectation<'tcx>,
2773 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2774 let rcvr = &args[0];
2775 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2777 // no need to check for bot/err -- callee does that
2778 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2780 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2781 let method = match self.lookup_method(method_name.span,
2788 self.write_method_call(expr.id, method);
2792 if method_name.node != keywords::Invalid.name() {
2793 self.report_method_error(method_name.span,
2804 // Call the generic checker.
2805 self.check_method_argument_types(method_name.span, method,
2811 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2815 .unwrap_or_else(|| span_bug!(return_expr.span,
2816 "check_return_expr called outside fn body"));
2818 let ret_ty = ret_coercion.borrow().expected_ty();
2819 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
2820 ret_coercion.borrow_mut()
2822 &self.misc(return_expr.span),
2825 self.diverges.get());
2829 // A generic function for checking the then and else in an if
2831 fn check_then_else(&self,
2832 cond_expr: &'gcx hir::Expr,
2833 then_expr: &'gcx hir::Expr,
2834 opt_else_expr: Option<&'gcx hir::Expr>,
2836 expected: Expectation<'tcx>) -> Ty<'tcx> {
2837 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2838 let cond_diverges = self.diverges.get();
2839 self.diverges.set(Diverges::Maybe);
2841 let expected = expected.adjust_for_branches(self);
2842 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2843 let then_diverges = self.diverges.get();
2844 self.diverges.set(Diverges::Maybe);
2846 // We've already taken the expected type's preferences
2847 // into account when typing the `then` branch. To figure
2848 // out the initial shot at a LUB, we thus only consider
2849 // `expected` if it represents a *hard* constraint
2850 // (`only_has_type`); otherwise, we just go with a
2851 // fresh type variable.
2852 let coerce_to_ty = expected.coercion_target_type(self, sp);
2853 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2855 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2856 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2858 if let Some(else_expr) = opt_else_expr {
2859 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2860 let else_diverges = self.diverges.get();
2862 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
2864 // We won't diverge unless both branches do (or the condition does).
2865 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2867 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2868 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
2870 // If the condition is false we can't diverge.
2871 self.diverges.set(cond_diverges);
2874 let result_ty = coerce.complete(self);
2875 if cond_ty.references_error() {
2882 // Check field access expressions
2883 fn check_field(&self,
2884 expr: &'gcx hir::Expr,
2885 lvalue_pref: LvaluePreference,
2886 base: &'gcx hir::Expr,
2887 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2888 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2889 let expr_t = self.structurally_resolved_type(expr.span,
2891 let mut private_candidate = None;
2892 let mut autoderef = self.autoderef(expr.span, expr_t);
2893 while let Some((base_t, _)) = autoderef.next() {
2895 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2896 debug!("struct named {:?}", base_t);
2897 let (ident, def_scope) =
2898 self.tcx.adjust(field.node, base_def.did, self.body_id);
2899 let fields = &base_def.struct_variant().fields;
2900 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
2901 let field_ty = self.field_ty(expr.span, field, substs);
2902 if field.vis.is_accessible_from(def_scope, self.tcx) {
2903 let adjustments = autoderef.adjust_steps(lvalue_pref);
2904 self.apply_adjustments(base, adjustments);
2905 autoderef.finalize();
2907 self.tcx.check_stability(field.did, expr.id, expr.span);
2911 private_candidate = Some((base_def.did, field_ty));
2917 autoderef.unambiguous_final_ty();
2919 if let Some((did, field_ty)) = private_candidate {
2920 let struct_path = self.tcx().item_path_str(did);
2921 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2922 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2923 // Also check if an accessible method exists, which is often what is meant.
2924 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2925 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2930 } else if field.node == keywords::Invalid.name() {
2931 self.tcx().types.err
2932 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2933 self.type_error_struct(field.span, |actual| {
2934 format!("attempted to take value of method `{}` on type \
2935 `{}`", field.node, actual)
2937 .help("maybe a `()` to call it is missing? \
2938 If not, try an anonymous function")
2940 self.tcx().types.err
2942 let mut err = self.type_error_struct(field.span, |actual| {
2943 format!("no field `{}` on type `{}`",
2947 ty::TyAdt(def, _) if !def.is_enum() => {
2948 if let Some(suggested_field_name) =
2949 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2950 err.span_label(field.span,
2951 format!("did you mean `{}`?", suggested_field_name));
2953 err.span_label(field.span,
2957 ty::TyRawPtr(..) => {
2958 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2960 self.tcx.hir.node_to_pretty_string(base.id),
2966 self.tcx().types.err
2970 // Return an hint about the closest match in field names
2971 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2972 field: &Spanned<ast::Name>,
2973 skip : Vec<InternedString>)
2975 let name = field.node.as_str();
2976 let names = variant.fields.iter().filter_map(|field| {
2977 // ignore already set fields and private fields from non-local crates
2978 if skip.iter().any(|x| *x == field.name.as_str()) ||
2979 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2986 // only find fits with at least one matching letter
2987 find_best_match_for_name(names, &name, Some(name.len()))
2990 // Check tuple index expressions
2991 fn check_tup_field(&self,
2992 expr: &'gcx hir::Expr,
2993 lvalue_pref: LvaluePreference,
2994 base: &'gcx hir::Expr,
2995 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2996 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2997 let expr_t = self.structurally_resolved_type(expr.span,
2999 let mut private_candidate = None;
3000 let mut tuple_like = false;
3001 let mut autoderef = self.autoderef(expr.span, expr_t);
3002 while let Some((base_t, _)) = autoderef.next() {
3003 let field = match base_t.sty {
3004 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
3005 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
3006 if !tuple_like { continue }
3008 debug!("tuple struct named {:?}", base_t);
3009 let ident = ast::Ident {
3010 name: Symbol::intern(&idx.node.to_string()),
3011 ctxt: idx.span.ctxt.modern(),
3013 let (ident, def_scope) =
3014 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
3015 let fields = &base_def.struct_variant().fields;
3016 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
3017 let field_ty = self.field_ty(expr.span, field, substs);
3018 if field.vis.is_accessible_from(def_scope, self.tcx) {
3019 self.tcx.check_stability(field.did, expr.id, expr.span);
3022 private_candidate = Some((base_def.did, field_ty));
3029 ty::TyTuple(ref v, _) => {
3031 v.get(idx.node).cloned()
3036 if let Some(field_ty) = field {
3037 let adjustments = autoderef.adjust_steps(lvalue_pref);
3038 self.apply_adjustments(base, adjustments);
3039 autoderef.finalize();
3043 autoderef.unambiguous_final_ty();
3045 if let Some((did, field_ty)) = private_candidate {
3046 let struct_path = self.tcx().item_path_str(did);
3047 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3048 self.tcx().sess.span_err(expr.span, &msg);
3052 self.type_error_message(
3056 format!("attempted out-of-bounds tuple index `{}` on \
3061 format!("attempted tuple index `{}` on type `{}`, but the \
3062 type was not a tuple or tuple struct",
3069 self.tcx().types.err
3072 fn report_unknown_field(&self,
3074 variant: &'tcx ty::VariantDef,
3076 skip_fields: &[hir::Field],
3078 let mut err = self.type_error_struct_with_diag(
3080 |actual| match ty.sty {
3081 ty::TyAdt(adt, ..) if adt.is_enum() => {
3082 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3083 "{} `{}::{}` has no field named `{}`",
3084 kind_name, actual, variant.name, field.name.node)
3087 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3088 "{} `{}` has no field named `{}`",
3089 kind_name, actual, field.name.node)
3093 // prevent all specified fields from being suggested
3094 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3095 if let Some(field_name) = Self::suggest_field_name(variant,
3097 skip_fields.collect()) {
3098 err.span_label(field.name.span,
3099 format!("field does not exist - did you mean `{}`?", field_name));
3102 ty::TyAdt(adt, ..) if adt.is_enum() => {
3103 err.span_label(field.name.span, format!("`{}::{}` does not have this field",
3107 err.span_label(field.name.span, format!("`{}` does not have this field", ty));
3114 fn check_expr_struct_fields(&self,
3116 expected: Expectation<'tcx>,
3117 expr_id: ast::NodeId,
3119 variant: &'tcx ty::VariantDef,
3120 ast_fields: &'gcx [hir::Field],
3121 check_completeness: bool) {
3125 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3126 .get(0).cloned().unwrap_or(adt_ty);
3128 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3129 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3130 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3132 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3135 let mut remaining_fields = FxHashMap();
3136 for field in &variant.fields {
3137 remaining_fields.insert(field.name.to_ident(), field);
3140 let mut seen_fields = FxHashMap();
3142 let mut error_happened = false;
3144 // Typecheck each field.
3145 for field in ast_fields {
3146 let final_field_type;
3147 let field_type_hint;
3149 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3150 if let Some(v_field) = remaining_fields.remove(&ident) {
3151 final_field_type = self.field_ty(field.span, v_field, substs);
3152 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3154 seen_fields.insert(field.name.node, field.span);
3156 // we don't look at stability attributes on
3157 // struct-like enums (yet...), but it's definitely not
3158 // a bug to have construct one.
3159 if adt_kind != ty::AdtKind::Enum {
3160 tcx.check_stability(v_field.did, expr_id, field.span);
3163 error_happened = true;
3164 final_field_type = tcx.types.err;
3165 field_type_hint = tcx.types.err;
3166 if let Some(_) = variant.find_field_named(field.name.node) {
3167 let mut err = struct_span_err!(self.tcx.sess,
3170 "field `{}` specified more than once",
3173 err.span_label(field.name.span, "used more than once");
3175 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3176 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3181 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3185 // Make sure to give a type to the field even if there's
3186 // an error, so we can continue typechecking
3187 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3188 self.demand_coerce(&field.expr, ty, final_field_type);
3191 // Make sure the programmer specified correct number of fields.
3192 if kind_name == "union" {
3193 if ast_fields.len() != 1 {
3194 tcx.sess.span_err(span, "union expressions should have exactly one field");
3196 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3197 let len = remaining_fields.len();
3199 let mut displayable_field_names = remaining_fields
3201 .map(|ident| ident.name.as_str())
3202 .collect::<Vec<_>>();
3204 displayable_field_names.sort();
3206 let truncated_fields_error = if len <= 3 {
3209 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3212 let remaining_fields_names = displayable_field_names.iter().take(3)
3213 .map(|n| format!("`{}`", n))
3214 .collect::<Vec<_>>()
3217 struct_span_err!(tcx.sess, span, E0063,
3218 "missing field{} {}{} in initializer of `{}`",
3219 if remaining_fields.len() == 1 {""} else {"s"},
3220 remaining_fields_names,
3221 truncated_fields_error,
3223 .span_label(span, format!("missing {}{}",
3224 remaining_fields_names,
3225 truncated_fields_error))
3230 fn check_struct_fields_on_error(&self,
3231 fields: &'gcx [hir::Field],
3232 base_expr: &'gcx Option<P<hir::Expr>>) {
3233 for field in fields {
3234 self.check_expr(&field.expr);
3238 self.check_expr(&base);
3244 pub fn check_struct_path(&self,
3246 node_id: ast::NodeId)
3247 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3248 let path_span = match *qpath {
3249 hir::QPath::Resolved(_, ref path) => path.span,
3250 hir::QPath::TypeRelative(ref qself, _) => qself.span
3252 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3253 let variant = match def {
3255 self.set_tainted_by_errors();
3258 Def::Variant(..) => {
3260 ty::TyAdt(adt, substs) => {
3261 Some((adt.variant_of_def(def), adt.did, substs))
3263 _ => bug!("unexpected type: {:?}", ty.sty)
3266 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3267 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3269 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3270 Some((adt.struct_variant(), adt.did, substs))
3275 _ => bug!("unexpected definition: {:?}", def)
3278 if let Some((variant, did, substs)) = variant {
3279 // Check bounds on type arguments used in the path.
3280 let bounds = self.instantiate_bounds(path_span, did, substs);
3281 let cause = traits::ObligationCause::new(path_span, self.body_id,
3282 traits::ItemObligation(did));
3283 self.add_obligations_for_parameters(cause, &bounds);
3287 struct_span_err!(self.tcx.sess, path_span, E0071,
3288 "expected struct, variant or union type, found {}",
3289 ty.sort_string(self.tcx))
3290 .span_label(path_span, "not a struct")
3296 fn check_expr_struct(&self,
3298 expected: Expectation<'tcx>,
3300 fields: &'gcx [hir::Field],
3301 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3303 // Find the relevant variant
3304 let (variant, struct_ty) =
3305 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3308 self.check_struct_fields_on_error(fields, base_expr);
3309 return self.tcx.types.err;
3312 let path_span = match *qpath {
3313 hir::QPath::Resolved(_, ref path) => path.span,
3314 hir::QPath::TypeRelative(ref qself, _) => qself.span
3317 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3318 base_expr.is_none());
3319 if let &Some(ref base_expr) = base_expr {
3320 self.check_expr_has_type(base_expr, struct_ty);
3321 match struct_ty.sty {
3322 ty::TyAdt(adt, substs) if adt.is_struct() => {
3323 self.tables.borrow_mut().fru_field_types.insert(
3325 adt.struct_variant().fields.iter().map(|f| {
3326 self.normalize_associated_types_in(
3327 expr.span, &f.ty(self.tcx, substs)
3333 span_err!(self.tcx.sess, base_expr.span, E0436,
3334 "functional record update syntax requires a struct");
3338 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3344 /// If an expression has any sub-expressions that result in a type error,
3345 /// inspecting that expression's type with `ty.references_error()` will return
3346 /// true. Likewise, if an expression is known to diverge, inspecting its
3347 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3348 /// strict, _|_ can appear in the type of an expression that does not,
3349 /// itself, diverge: for example, fn() -> _|_.)
3350 /// Note that inspecting a type's structure *directly* may expose the fact
3351 /// that there are actually multiple representations for `TyError`, so avoid
3352 /// that when err needs to be handled differently.
3353 fn check_expr_with_expectation_and_lvalue_pref(&self,
3354 expr: &'gcx hir::Expr,
3355 expected: Expectation<'tcx>,
3356 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3357 debug!(">> typechecking: expr={:?} expected={:?}",
3360 // Warn for expressions after diverging siblings.
3361 self.warn_if_unreachable(expr.id, expr.span, "expression");
3363 // Hide the outer diverging and has_errors flags.
3364 let old_diverges = self.diverges.get();
3365 let old_has_errors = self.has_errors.get();
3366 self.diverges.set(Diverges::Maybe);
3367 self.has_errors.set(false);
3369 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3371 // Warn for non-block expressions with diverging children.
3374 hir::ExprLoop(..) | hir::ExprWhile(..) |
3375 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3377 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3380 // Any expression that produces a value of type `!` must have diverged
3382 self.diverges.set(self.diverges.get() | Diverges::Always);
3385 // Record the type, which applies it effects.
3386 // We need to do this after the warning above, so that
3387 // we don't warn for the diverging expression itself.
3388 self.write_ty(expr.id, ty);
3390 // Combine the diverging and has_error flags.
3391 self.diverges.set(self.diverges.get() | old_diverges);
3392 self.has_errors.set(self.has_errors.get() | old_has_errors);
3394 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3395 debug!("... {:?}, expected is {:?}", ty, expected);
3400 fn check_expr_kind(&self,
3401 expr: &'gcx hir::Expr,
3402 expected: Expectation<'tcx>,
3403 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3407 hir::ExprBox(ref subexpr) => {
3408 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3410 ty::TyAdt(def, _) if def.is_box()
3411 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3415 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3416 tcx.mk_box(referent_ty)
3419 hir::ExprLit(ref lit) => {
3420 self.check_lit(&lit, expected)
3422 hir::ExprBinary(op, ref lhs, ref rhs) => {
3423 self.check_binop(expr, op, lhs, rhs)
3425 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3426 self.check_binop_assign(expr, op, lhs, rhs)
3428 hir::ExprUnary(unop, ref oprnd) => {
3429 let expected_inner = match unop {
3430 hir::UnNot | hir::UnNeg => {
3437 let lvalue_pref = match unop {
3438 hir::UnDeref => lvalue_pref,
3441 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3445 if !oprnd_t.references_error() {
3446 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3449 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3451 } else if let Some(ok) = self.try_overloaded_deref(
3452 expr.span, oprnd_t, lvalue_pref) {
3453 let method = self.register_infer_ok_obligations(ok);
3454 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3455 self.apply_adjustments(oprnd, vec![Adjustment {
3456 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
3457 target: method.sig.inputs()[0]
3460 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3461 self.write_method_call(expr.id, method);
3463 self.type_error_message(expr.span, |actual| {
3464 format!("type `{}` cannot be \
3465 dereferenced", actual)
3467 oprnd_t = tcx.types.err;
3471 let result = self.check_user_unop(expr, oprnd_t, unop);
3472 // If it's builtin, we can reuse the type, this helps inference.
3473 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3478 let result = self.check_user_unop(expr, oprnd_t, unop);
3479 // If it's builtin, we can reuse the type, this helps inference.
3480 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3488 hir::ExprAddrOf(mutbl, ref oprnd) => {
3489 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3491 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3492 if self.tcx.expr_is_lval(&oprnd) {
3493 // Lvalues may legitimately have unsized types.
3494 // For example, dereferences of a fat pointer and
3495 // the last field of a struct can be unsized.
3496 ExpectHasType(mt.ty)
3498 Expectation::rvalue_hint(self, mt.ty)
3504 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3505 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3507 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3508 if tm.ty.references_error() {
3511 // Note: at this point, we cannot say what the best lifetime
3512 // is to use for resulting pointer. We want to use the
3513 // shortest lifetime possible so as to avoid spurious borrowck
3514 // errors. Moreover, the longest lifetime will depend on the
3515 // precise details of the value whose address is being taken
3516 // (and how long it is valid), which we don't know yet until type
3517 // inference is complete.
3519 // Therefore, here we simply generate a region variable. The
3520 // region inferencer will then select the ultimate value.
3521 // Finally, borrowck is charged with guaranteeing that the
3522 // value whose address was taken can actually be made to live
3523 // as long as it needs to live.
3524 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3525 tcx.mk_ref(region, tm)
3528 hir::ExprPath(ref qpath) => {
3529 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3530 expr.id, expr.span);
3531 let ty = if def != Def::Err {
3532 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3534 self.set_tainted_by_errors();
3538 // We always require that the type provided as the value for
3539 // a type parameter outlives the moment of instantiation.
3540 let substs = self.tables.borrow().node_substs(expr.id);
3541 self.add_wf_bounds(substs, expr);
3545 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3546 for output in outputs {
3547 self.check_expr(output);
3549 for input in inputs {
3550 self.check_expr(input);
3554 hir::ExprBreak(destination, ref expr_opt) => {
3555 if let Some(target_id) = destination.target_id.opt_id() {
3556 let (e_ty, e_diverges, cause);
3557 if let Some(ref e) = *expr_opt {
3558 // If this is a break with a value, we need to type-check
3559 // the expression. Get an expected type from the loop context.
3560 let opt_coerce_to = {
3561 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3562 enclosing_breakables.find_breakable(target_id)
3565 .map(|coerce| coerce.expected_ty())
3568 // If the loop context is not a `loop { }`, then break with
3569 // a value is illegal, and `opt_coerce_to` will be `None`.
3570 // Just set expectation to error in that case.
3571 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3573 // Recurse without `enclosing_breakables` borrowed.
3574 e_ty = self.check_expr_with_hint(e, coerce_to);
3575 e_diverges = self.diverges.get();
3576 cause = self.misc(e.span);
3578 // Otherwise, this is a break *without* a value. That's
3579 // always legal, and is equivalent to `break ()`.
3580 e_ty = tcx.mk_nil();
3581 e_diverges = Diverges::Maybe;
3582 cause = self.misc(expr.span);
3585 // Now that we have type-checked `expr_opt`, borrow
3586 // the `enclosing_loops` field and let's coerce the
3587 // type of `expr_opt` into what is expected.
3588 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3589 let ctxt = enclosing_breakables.find_breakable(target_id);
3590 if let Some(ref mut coerce) = ctxt.coerce {
3591 if let Some(ref e) = *expr_opt {
3592 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3594 assert!(e_ty.is_nil());
3595 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3598 // If `ctxt.coerce` is `None`, we can just ignore
3599 // the type of the expresison. This is because
3600 // either this was a break *without* a value, in
3601 // which case it is always a legal type (`()`), or
3602 // else an error would have been flagged by the
3603 // `loops` pass for using break with an expression
3604 // where you are not supposed to.
3605 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3608 ctxt.may_break = true;
3610 // Otherwise, we failed to find the enclosing loop;
3611 // this can only happen if the `break` was not
3612 // inside a loop at all, which is caught by the
3613 // loop-checking pass.
3614 assert!(self.tcx.sess.err_count() > 0);
3617 // the type of a `break` is always `!`, since it diverges
3620 hir::ExprAgain(_) => { tcx.types.never }
3621 hir::ExprRet(ref expr_opt) => {
3622 if self.ret_coercion.is_none() {
3623 struct_span_err!(self.tcx.sess, expr.span, E0572,
3624 "return statement outside of function body").emit();
3625 } else if let Some(ref e) = *expr_opt {
3626 self.check_return_expr(e);
3628 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3629 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3630 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3634 hir::ExprAssign(ref lhs, ref rhs) => {
3635 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3638 if !tcx.expr_is_lval(&lhs) {
3640 tcx.sess, expr.span, E0070,
3641 "invalid left-hand side expression")
3644 "left-hand of expression not valid")
3648 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3650 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3652 if lhs_ty.references_error() || rhs_ty.references_error() {
3658 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3659 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3660 expr.span, expected)
3662 hir::ExprWhile(ref cond, ref body, _) => {
3663 let ctxt = BreakableCtxt {
3664 // cannot use break with a value from a while loop
3669 self.with_breakable_ctxt(expr.id, ctxt, || {
3670 self.check_expr_has_type(&cond, tcx.types.bool);
3671 let cond_diverging = self.diverges.get();
3672 self.check_block_no_value(&body);
3674 // We may never reach the body so it diverging means nothing.
3675 self.diverges.set(cond_diverging);
3680 hir::ExprLoop(ref body, _, source) => {
3681 let coerce = match source {
3682 // you can only use break with a value from a normal `loop { }`
3683 hir::LoopSource::Loop => {
3684 let coerce_to = expected.coercion_target_type(self, body.span);
3685 Some(CoerceMany::new(coerce_to))
3688 hir::LoopSource::WhileLet |
3689 hir::LoopSource::ForLoop => {
3694 let ctxt = BreakableCtxt {
3696 may_break: false, // will get updated if/when we find a `break`
3699 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3700 self.check_block_no_value(&body);
3704 // No way to know whether it's diverging because
3705 // of a `break` or an outer `break` or `return.
3706 self.diverges.set(Diverges::Maybe);
3709 // If we permit break with a value, then result type is
3710 // the LUB of the breaks (possibly ! if none); else, it
3711 // is nil. This makes sense because infinite loops
3712 // (which would have type !) are only possible iff we
3713 // permit break with a value [1].
3714 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3715 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3717 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3718 self.check_match(expr, &discrim, arms, expected, match_src)
3720 hir::ExprClosure(capture, ref decl, body_id, _) => {
3721 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3723 hir::ExprBlock(ref body) => {
3724 self.check_block_with_expected(&body, expected)
3726 hir::ExprCall(ref callee, ref args) => {
3727 self.check_call(expr, &callee, args, expected)
3729 hir::ExprMethodCall(name, ref tps, ref args) => {
3730 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3732 hir::ExprCast(ref e, ref t) => {
3733 // Find the type of `e`. Supply hints based on the type we are casting to,
3735 let t_cast = self.to_ty(t);
3736 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3737 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3738 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3739 let diverges = self.diverges.get();
3741 // Eagerly check for some obvious errors.
3742 if t_expr.references_error() || t_cast.references_error() {
3745 // Defer other checks until we're done type checking.
3746 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3747 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3749 deferred_cast_checks.push(cast_check);
3752 Err(ErrorReported) => {
3758 hir::ExprType(ref e, ref t) => {
3759 let typ = self.to_ty(&t);
3760 self.check_expr_eq_type(&e, typ);
3763 hir::ExprArray(ref args) => {
3764 let uty = expected.to_option(self).and_then(|uty| {
3766 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3771 let element_ty = if !args.is_empty() {
3772 let coerce_to = uty.unwrap_or_else(
3773 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3774 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3775 assert_eq!(self.diverges.get(), Diverges::Maybe);
3777 let e_ty = self.check_expr_with_hint(e, coerce_to);
3778 let cause = self.misc(e.span);
3779 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3781 coerce.complete(self)
3783 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3785 tcx.mk_array(element_ty, args.len())
3787 hir::ExprRepeat(ref element, count) => {
3788 let count = eval_length(self.tcx, count, "repeat count")
3791 let uty = match expected {
3792 ExpectHasType(uty) => {
3794 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3801 let (element_ty, t) = match uty {
3803 self.check_expr_coercable_to_type(&element, uty);
3807 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3808 let element_ty = self.check_expr_has_type(&element, t);
3814 // For [foo, ..n] where n > 1, `foo` must have
3816 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3817 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3820 if element_ty.references_error() {
3823 tcx.mk_array(t, count)
3826 hir::ExprTup(ref elts) => {
3827 let flds = expected.only_has_type(self).and_then(|ty| {
3829 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3834 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3835 let t = match flds {
3836 Some(ref fs) if i < fs.len() => {
3838 self.check_expr_coercable_to_type(&e, ety);
3842 self.check_expr_with_expectation(&e, NoExpectation)
3847 let tuple = tcx.mk_tup(elt_ts_iter, false);
3848 if tuple.references_error() {
3854 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3855 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3857 hir::ExprField(ref base, ref field) => {
3858 self.check_field(expr, lvalue_pref, &base, field)
3860 hir::ExprTupField(ref base, idx) => {
3861 self.check_tup_field(expr, lvalue_pref, &base, idx)
3863 hir::ExprIndex(ref base, ref idx) => {
3864 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3865 let idx_t = self.check_expr(&idx);
3867 if base_t.references_error() {
3869 } else if idx_t.references_error() {
3872 let base_t = self.structurally_resolved_type(expr.span, base_t);
3873 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3874 Some((index_ty, element_ty)) => {
3875 self.demand_coerce(idx, idx_t, index_ty);
3879 let mut err = self.type_error_struct(
3882 format!("cannot index a value of type `{}`",
3886 // Try to give some advice about indexing tuples.
3887 if let ty::TyTuple(..) = base_t.sty {
3888 let mut needs_note = true;
3889 // If the index is an integer, we can show the actual
3890 // fixed expression:
3891 if let hir::ExprLit(ref lit) = idx.node {
3892 if let ast::LitKind::Int(i,
3893 ast::LitIntType::Unsuffixed) = lit.node {
3894 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3895 if let Ok(snip) = snip {
3896 err.span_suggestion(expr.span,
3897 "to access tuple elements, use",
3898 format!("{}.{}", snip, i));
3904 err.help("to access tuple elements, use tuple indexing \
3905 syntax (e.g. `tuple.0`)");
3917 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3918 // The newly resolved definition is written into `type_dependent_defs`.
3919 fn finish_resolving_struct_path(&self,
3922 node_id: ast::NodeId)
3926 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3927 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3928 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3931 hir::QPath::TypeRelative(ref qself, ref segment) => {
3932 let ty = self.to_ty(qself);
3934 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3939 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3942 // Write back the new resolution.
3943 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3950 // Resolve associated value path into a base type and associated constant or method definition.
3951 // The newly resolved definition is written into `type_dependent_defs`.
3952 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3953 qpath: &'b hir::QPath,
3954 node_id: ast::NodeId,
3956 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3958 let (ty, item_segment) = match *qpath {
3959 hir::QPath::Resolved(ref opt_qself, ref path) => {
3961 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3962 &path.segments[..]);
3964 hir::QPath::TypeRelative(ref qself, ref segment) => {
3965 (self.to_ty(qself), segment)
3968 let item_name = item_segment.name;
3969 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3972 let def = match error {
3973 method::MethodError::PrivateMatch(def) => def,
3976 if item_name != keywords::Invalid.name() {
3977 self.report_method_error(span, ty, item_name, None, error, None);
3983 // Write back the new resolution.
3984 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3985 (def, Some(ty), slice::ref_slice(&**item_segment))
3988 pub fn check_decl_initializer(&self,
3989 local: &'gcx hir::Local,
3990 init: &'gcx hir::Expr) -> Ty<'tcx>
3992 let ref_bindings = local.pat.contains_ref_binding();
3994 let local_ty = self.local_ty(init.span, local.id);
3995 if let Some(m) = ref_bindings {
3996 // Somewhat subtle: if we have a `ref` binding in the pattern,
3997 // we want to avoid introducing coercions for the RHS. This is
3998 // both because it helps preserve sanity and, in the case of
3999 // ref mut, for soundness (issue #23116). In particular, in
4000 // the latter case, we need to be clear that the type of the
4001 // referent for the reference that results is *equal to* the
4002 // type of the lvalue it is referencing, and not some
4003 // supertype thereof.
4004 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
4005 self.demand_eqtype(init.span, init_ty, local_ty);
4008 self.check_expr_coercable_to_type(init, local_ty)
4012 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
4013 let t = self.local_ty(local.span, local.id);
4014 self.write_ty(local.id, t);
4016 if let Some(ref init) = local.init {
4017 let init_ty = self.check_decl_initializer(local, &init);
4018 if init_ty.references_error() {
4019 self.write_ty(local.id, init_ty);
4023 self.check_pat(&local.pat, t);
4024 let pat_ty = self.node_ty(local.pat.id);
4025 if pat_ty.references_error() {
4026 self.write_ty(local.id, pat_ty);
4030 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4031 // Don't do all the complex logic below for DeclItem.
4033 hir::StmtDecl(ref decl, id) => {
4035 hir::DeclLocal(_) => {}
4036 hir::DeclItem(_) => {
4042 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4045 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4047 // Hide the outer diverging and has_errors flags.
4048 let old_diverges = self.diverges.get();
4049 let old_has_errors = self.has_errors.get();
4050 self.diverges.set(Diverges::Maybe);
4051 self.has_errors.set(false);
4053 let (node_id, _span) = match stmt.node {
4054 hir::StmtDecl(ref decl, id) => {
4055 let span = match decl.node {
4056 hir::DeclLocal(ref l) => {
4057 self.check_decl_local(&l);
4060 hir::DeclItem(_) => {/* ignore for now */
4066 hir::StmtExpr(ref expr, id) => {
4067 // Check with expected type of ()
4068 self.check_expr_has_type(&expr, self.tcx.mk_nil());
4071 hir::StmtSemi(ref expr, id) => {
4072 self.check_expr(&expr);
4077 if self.has_errors.get() {
4078 self.write_error(node_id);
4080 self.write_nil(node_id);
4083 // Combine the diverging and has_error flags.
4084 self.diverges.set(self.diverges.get() | old_diverges);
4085 self.has_errors.set(self.has_errors.get() | old_has_errors);
4088 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4089 let unit = self.tcx.mk_nil();
4090 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4092 // if the block produces a `!` value, that can always be
4093 // (effectively) coerced to unit.
4095 self.demand_suptype(blk.span, unit, ty);
4099 fn check_block_with_expected(&self,
4100 blk: &'gcx hir::Block,
4101 expected: Expectation<'tcx>) -> Ty<'tcx> {
4103 let mut fcx_ps = self.ps.borrow_mut();
4104 let unsafety_state = fcx_ps.recurse(blk);
4105 replace(&mut *fcx_ps, unsafety_state)
4108 // In some cases, blocks have just one exit, but other blocks
4109 // can be targeted by multiple breaks. This cannot happen in
4110 // normal Rust syntax today, but it can happen when we desugar
4111 // a `do catch { ... }` expression.
4115 // 'a: { if true { break 'a Err(()); } Ok(()) }
4117 // Here we would wind up with two coercions, one from
4118 // `Err(())` and the other from the tail expression
4119 // `Ok(())`. If the tail expression is omitted, that's a
4120 // "forced unit" -- unless the block diverges, in which
4121 // case we can ignore the tail expression (e.g., `'a: {
4122 // break 'a 22; }` would not force the type of the block
4124 let tail_expr = blk.expr.as_ref();
4125 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4126 let coerce = if blk.targeted_by_break {
4127 CoerceMany::new(coerce_to_ty)
4129 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4130 Some(e) => ref_slice(e),
4133 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4136 let ctxt = BreakableCtxt {
4137 coerce: Some(coerce),
4141 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4142 for s in &blk.stmts {
4146 // check the tail expression **without** holding the
4147 // `enclosing_breakables` lock below.
4148 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4150 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4151 let mut ctxt = enclosing_breakables.find_breakable(blk.id);
4152 let mut coerce = ctxt.coerce.as_mut().unwrap();
4153 if let Some(tail_expr_ty) = tail_expr_ty {
4154 let tail_expr = tail_expr.unwrap();
4156 &self.misc(tail_expr.span),
4159 self.diverges.get());
4161 // Subtle: if there is no explicit tail expression,
4162 // that is typically equivalent to a tail expression
4163 // of `()` -- except if the block diverges. In that
4164 // case, there is no value supplied from the tail
4165 // expression (assuming there are no other breaks,
4166 // this implies that the type of the block will be
4169 // #41425 -- label the implicit `()` as being the
4170 // "found type" here, rather than the "expected type".
4171 if !self.diverges.get().always() {
4172 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4173 if let Some(expected_ty) = expected.only_has_type(self) {
4174 self.consider_hint_about_removing_semicolon(blk,
4183 let mut ty = ctxt.coerce.unwrap().complete(self);
4185 if self.has_errors.get() || ty.references_error() {
4186 ty = self.tcx.types.err
4189 self.write_ty(blk.id, ty);
4191 *self.ps.borrow_mut() = prev;
4195 /// A common error is to add an extra semicolon:
4198 /// fn foo() -> usize {
4203 /// This routine checks if the final statement in a block is an
4204 /// expression with an explicit semicolon whose type is compatible
4205 /// with `expected_ty`. If so, it suggests removing the semicolon.
4206 fn consider_hint_about_removing_semicolon(&self,
4207 blk: &'gcx hir::Block,
4208 expected_ty: Ty<'tcx>,
4209 err: &mut DiagnosticBuilder) {
4210 // Be helpful when the user wrote `{... expr;}` and
4211 // taking the `;` off is enough to fix the error.
4212 let last_stmt = match blk.stmts.last() {
4216 let last_expr = match last_stmt.node {
4217 hir::StmtSemi(ref e, _) => e,
4220 let last_expr_ty = self.expr_ty(last_expr);
4221 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4224 let original_span = original_sp(last_stmt.span, blk.span);
4225 let span_semi = Span {
4226 lo: original_span.hi - BytePos(1),
4227 hi: original_span.hi,
4228 ctxt: original_span.ctxt,
4230 err.span_help(span_semi, "consider removing this semicolon:");
4233 // Instantiates the given path, which must refer to an item with the given
4234 // number of type parameters and type.
4235 pub fn instantiate_value_path(&self,
4236 segments: &[hir::PathSegment],
4237 opt_self_ty: Option<Ty<'tcx>>,
4240 node_id: ast::NodeId)
4242 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4247 // We need to extract the type parameters supplied by the user in
4248 // the path `path`. Due to the current setup, this is a bit of a
4249 // tricky-process; the problem is that resolve only tells us the
4250 // end-point of the path resolution, and not the intermediate steps.
4251 // Luckily, we can (at least for now) deduce the intermediate steps
4252 // just from the end-point.
4254 // There are basically four cases to consider:
4256 // 1. Reference to a constructor of enum variant or struct:
4258 // struct Foo<T>(...)
4259 // enum E<T> { Foo(...) }
4261 // In these cases, the parameters are declared in the type
4264 // 2. Reference to a fn item or a free constant:
4268 // In this case, the path will again always have the form
4269 // `a::b::foo::<T>` where only the final segment should have
4270 // type parameters. However, in this case, those parameters are
4271 // declared on a value, and hence are in the `FnSpace`.
4273 // 3. Reference to a method or an associated constant:
4275 // impl<A> SomeStruct<A> {
4279 // Here we can have a path like
4280 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4281 // may appear in two places. The penultimate segment,
4282 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4283 // final segment, `foo::<B>` contains parameters in fn space.
4285 // 4. Reference to a local variable
4287 // Local variables can't have any type parameters.
4289 // The first step then is to categorize the segments appropriately.
4291 assert!(!segments.is_empty());
4293 let mut ufcs_associated = None;
4294 let mut type_segment = None;
4295 let mut fn_segment = None;
4297 // Case 1. Reference to a struct/variant constructor.
4298 Def::StructCtor(def_id, ..) |
4299 Def::VariantCtor(def_id, ..) => {
4300 // Everything but the final segment should have no
4301 // parameters at all.
4302 let mut generics = self.tcx.generics_of(def_id);
4303 if let Some(def_id) = generics.parent {
4304 // Variant and struct constructors use the
4305 // generics of their parent type definition.
4306 generics = self.tcx.generics_of(def_id);
4308 type_segment = Some((segments.last().unwrap(), generics));
4311 // Case 2. Reference to a top-level value.
4313 Def::Const(def_id) |
4314 Def::Static(def_id, _) => {
4315 fn_segment = Some((segments.last().unwrap(),
4316 self.tcx.generics_of(def_id)));
4319 // Case 3. Reference to a method or associated const.
4320 Def::Method(def_id) |
4321 Def::AssociatedConst(def_id) => {
4322 let container = self.tcx.associated_item(def_id).container;
4324 ty::TraitContainer(trait_did) => {
4325 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4327 ty::ImplContainer(_) => {}
4330 let generics = self.tcx.generics_of(def_id);
4331 if segments.len() >= 2 {
4332 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4333 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4335 // `<T>::assoc` will end up here, and so can `T::assoc`.
4336 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4337 ufcs_associated = Some((container, self_ty));
4339 fn_segment = Some((segments.last().unwrap(), generics));
4342 // Case 4. Local variable, no generics.
4343 Def::Local(..) | Def::Upvar(..) => {}
4345 _ => bug!("unexpected definition: {:?}", def),
4348 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4350 // Now that we have categorized what space the parameters for each
4351 // segment belong to, let's sort out the parameters that the user
4352 // provided (if any) into their appropriate spaces. We'll also report
4353 // errors if type parameters are provided in an inappropriate place.
4354 let poly_segments = type_segment.is_some() as usize +
4355 fn_segment.is_some() as usize;
4356 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4359 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4360 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4361 let ty = self.local_ty(span, nid);
4362 let ty = self.normalize_associated_types_in(span, &ty);
4363 self.write_ty(node_id, ty);
4369 // Now we have to compare the types that the user *actually*
4370 // provided against the types that were *expected*. If the user
4371 // did not provide any types, then we want to substitute inference
4372 // variables. If the user provided some types, we may still need
4373 // to add defaults. If the user provided *too many* types, that's
4375 self.check_path_parameter_count(span, &mut type_segment);
4376 self.check_path_parameter_count(span, &mut fn_segment);
4378 let (fn_start, has_self) = match (type_segment, fn_segment) {
4379 (_, Some((_, generics))) => {
4380 (generics.parent_count(), generics.has_self)
4382 (Some((_, generics)), None) => {
4383 (generics.own_count(), generics.has_self)
4385 (None, None) => (0, false)
4387 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4388 let mut i = def.index as usize;
4390 let segment = if i < fn_start {
4391 i -= has_self as usize;
4397 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4398 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4399 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4403 if let Some(lifetime) = lifetimes.get(i) {
4404 AstConv::ast_region_to_region(self, lifetime, Some(def))
4406 self.re_infer(span, Some(def)).unwrap()
4409 let mut i = def.index as usize;
4411 let segment = if i < fn_start {
4412 // Handle Self first, so we can adjust the index to match the AST.
4413 if has_self && i == 0 {
4414 return opt_self_ty.unwrap_or_else(|| {
4415 self.type_var_for_def(span, def, substs)
4418 i -= has_self as usize;
4424 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4425 Some(&hir::AngleBracketedParameters(ref data)) => {
4426 (&data.types[..], data.infer_types)
4428 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4429 None => (&[][..], true)
4432 // Skip over the lifetimes in the same segment.
4433 if let Some((_, generics)) = segment {
4434 i -= generics.regions.len();
4437 if let Some(ast_ty) = types.get(i) {
4438 // A provided type parameter.
4440 } else if !infer_types && def.has_default {
4441 // No type parameter provided, but a default exists.
4442 let default = self.tcx.type_of(def.def_id);
4445 default.subst_spanned(self.tcx, substs, Some(span))
4448 // No type parameters were provided, we can infer all.
4449 // This can also be reached in some error cases:
4450 // We prefer to use inference variables instead of
4451 // TyError to let type inference recover somewhat.
4452 self.type_var_for_def(span, def, substs)
4456 // The things we are substituting into the type should not contain
4457 // escaping late-bound regions, and nor should the base type scheme.
4458 let ty = self.tcx.type_of(def.def_id());
4459 assert!(!substs.has_escaping_regions());
4460 assert!(!ty.has_escaping_regions());
4462 // Add all the obligations that are required, substituting and
4463 // normalized appropriately.
4464 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4465 self.add_obligations_for_parameters(
4466 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4469 // Substitute the values for the type parameters into the type of
4470 // the referenced item.
4471 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4473 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4474 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4475 // is inherent, there is no `Self` parameter, instead, the impl needs
4476 // type parameters, which we can infer by unifying the provided `Self`
4477 // with the substituted impl type.
4478 let ty = self.tcx.type_of(impl_def_id);
4480 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4481 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4482 Ok(ok) => self.register_infer_ok_obligations(ok),
4485 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4492 debug!("instantiate_value_path: type of {:?} is {:?}",
4495 self.write_substs(node_id, substs);
4499 /// Report errors if the provided parameters are too few or too many.
4500 fn check_path_parameter_count(&self,
4502 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4503 let (lifetimes, types, infer_types, bindings) = {
4504 match segment.map(|(s, _)| &s.parameters) {
4505 Some(&hir::AngleBracketedParameters(ref data)) => {
4506 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4508 Some(&hir::ParenthesizedParameters(_)) => {
4509 AstConv::prohibit_parenthesized_params(self, &segment.as_ref().unwrap().0,
4511 (&[][..], &[][..], true, &[][..])
4513 None => (&[][..], &[][..], true, &[][..])
4517 let count_lifetime_params = |n| {
4518 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4520 let count_type_params = |n| {
4521 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4524 // Check provided lifetime parameters.
4525 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4526 if lifetimes.len() > lifetime_defs.len() {
4527 let expected_text = count_lifetime_params(lifetime_defs.len());
4528 let actual_text = count_lifetime_params(lifetimes.len());
4529 struct_span_err!(self.tcx.sess, span, E0088,
4530 "too many lifetime parameters provided: \
4531 expected at most {}, found {}",
4532 expected_text, actual_text)
4533 .span_label(span, format!("expected {}", expected_text))
4535 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4536 let expected_text = count_lifetime_params(lifetime_defs.len());
4537 let actual_text = count_lifetime_params(lifetimes.len());
4538 struct_span_err!(self.tcx.sess, span, E0090,
4539 "too few lifetime parameters provided: \
4540 expected {}, found {}",
4541 expected_text, actual_text)
4542 .span_label(span, format!("expected {}", expected_text))
4546 // The case where there is not enough lifetime parameters is not checked,
4547 // because this is not possible - a function never takes lifetime parameters.
4548 // See discussion for Pull Request 36208.
4550 // Check provided type parameters.
4551 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4552 if generics.parent.is_none() {
4553 &generics.types[generics.has_self as usize..]
4558 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4559 if types.len() > type_defs.len() {
4560 let span = types[type_defs.len()].span;
4561 let expected_text = count_type_params(type_defs.len());
4562 let actual_text = count_type_params(types.len());
4563 struct_span_err!(self.tcx.sess, span, E0087,
4564 "too many type parameters provided: \
4565 expected at most {}, found {}",
4566 expected_text, actual_text)
4567 .span_label(span, format!("expected {}", expected_text))
4570 // To prevent derived errors to accumulate due to extra
4571 // type parameters, we force instantiate_value_path to
4572 // use inference variables instead of the provided types.
4574 } else if !infer_types && types.len() < required_len {
4575 let expected_text = count_type_params(required_len);
4576 let actual_text = count_type_params(types.len());
4577 struct_span_err!(self.tcx.sess, span, E0089,
4578 "too few type parameters provided: \
4579 expected {}, found {}",
4580 expected_text, actual_text)
4581 .span_label(span, format!("expected {}", expected_text))
4585 if !bindings.is_empty() {
4586 span_err!(self.tcx.sess, bindings[0].span, E0182,
4587 "unexpected binding of associated item in expression path \
4588 (only allowed in type paths)");
4592 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4594 where F: Fn() -> Ty<'tcx>
4596 let mut ty = self.resolve_type_vars_with_obligations(ty);
4599 let alternative = f();
4602 if alternative.is_ty_var() || alternative.references_error() {
4603 if !self.is_tainted_by_errors() {
4604 self.type_error_message(sp, |_actual| {
4605 "the type of this value must be known in this context".to_string()
4608 self.demand_suptype(sp, self.tcx.types.err, ty);
4609 ty = self.tcx.types.err;
4611 self.demand_suptype(sp, alternative, ty);
4619 // Resolves `typ` by a single level if `typ` is a type variable. If no
4620 // resolution is possible, then an error is reported.
4621 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4622 self.structurally_resolve_type_or_else(sp, ty, || {
4627 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4628 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4629 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4632 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4633 index = enclosing_breakables.stack.len();
4634 enclosing_breakables.by_id.insert(id, index);
4635 enclosing_breakables.stack.push(ctxt);
4639 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4640 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4641 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4642 enclosing_breakables.stack.pop().expect("missing breakable context")
4648 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4649 generics: &hir::Generics,
4651 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4652 generics.ty_params.len(), ty);
4654 // make a vector of booleans initially false, set to true when used
4655 if generics.ty_params.is_empty() { return; }
4656 let mut tps_used = vec![false; generics.ty_params.len()];
4658 for leaf_ty in ty.walk() {
4659 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4660 debug!("Found use of ty param num {}", idx);
4661 tps_used[idx as usize - generics.lifetimes.len()] = true;
4665 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4667 struct_span_err!(tcx.sess, param.span, E0091,
4668 "type parameter `{}` is unused",
4670 .span_label(param.span, "unused type parameter")