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};
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 if !missing_items.is_empty() {
1352 let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
1353 "not all trait items implemented, missing: `{}`",
1354 missing_items.iter()
1355 .map(|trait_item| trait_item.name.to_string())
1356 .collect::<Vec<_>>().join("`, `"));
1357 err.span_label(impl_span, format!("missing `{}` in implementation",
1358 missing_items.iter()
1359 .map(|trait_item| trait_item.name.to_string())
1360 .collect::<Vec<_>>().join("`, `")));
1361 for trait_item in missing_items {
1362 if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
1363 err.span_label(span, format!("`{}` from trait", trait_item.name));
1365 err.note_trait_signature(trait_item.name.to_string(),
1366 trait_item.signature(&tcx));
1372 if !invalidated_items.is_empty() {
1373 let invalidator = overridden_associated_type.unwrap();
1374 span_err!(tcx.sess, invalidator.span, E0399,
1375 "the following trait items need to be reimplemented \
1376 as `{}` was overridden: `{}`",
1378 invalidated_items.iter()
1379 .map(|name| name.to_string())
1380 .collect::<Vec<_>>().join("`, `"))
1384 /// Checks whether a type can be represented in memory. In particular, it
1385 /// identifies types that contain themselves without indirection through a
1386 /// pointer, which would mean their size is unbounded.
1387 fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1391 let rty = tcx.type_of(item_def_id);
1393 // Check that it is possible to represent this type. This call identifies
1394 // (1) types that contain themselves and (2) types that contain a different
1395 // recursive type. It is only necessary to throw an error on those that
1396 // contain themselves. For case 2, there must be an inner type that will be
1397 // caught by case 1.
1398 match rty.is_representable(tcx, sp) {
1399 Representability::SelfRecursive(spans) => {
1400 let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
1402 err.span_label(span, "recursive without indirection");
1407 Representability::Representable | Representability::ContainsRecursive => (),
1412 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1413 let t = tcx.type_of(def_id);
1415 ty::TyAdt(def, substs) if def.is_struct() => {
1416 let fields = &def.struct_variant().fields;
1417 if fields.is_empty() {
1418 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1421 let e = fields[0].ty(tcx, substs);
1422 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1423 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1424 .span_label(sp, "SIMD elements must have the same type")
1429 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1430 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1432 span_err!(tcx.sess, sp, E0077,
1433 "SIMD vector element type should be machine type");
1442 fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1443 if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1444 struct_span_err!(tcx.sess, sp, E0588,
1445 "packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1449 fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1451 stack: &mut Vec<DefId>) -> bool {
1452 let t = tcx.type_of(def_id);
1453 if stack.contains(&def_id) {
1454 debug!("check_packed_inner: {:?} is recursive", t);
1458 ty::TyAdt(def, substs) if def.is_struct() => {
1459 if tcx.adt_def(def.did).repr.align > 0 {
1462 // push struct def_id before checking fields
1464 for field in &def.struct_variant().fields {
1465 let f = field.ty(tcx, substs);
1467 ty::TyAdt(def, _) => {
1468 if check_packed_inner(tcx, def.did, stack) {
1475 // only need to pop if not early out
1483 #[allow(trivial_numeric_casts)]
1484 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1486 vs: &'tcx [hir::Variant],
1488 let def_id = tcx.hir.local_def_id(id);
1489 let def = tcx.adt_def(def_id);
1490 def.destructor(tcx); // force the destructor to be evaluated
1492 if vs.is_empty() && tcx.has_attr(def_id, "repr") {
1494 tcx.sess, sp, E0084,
1495 "unsupported representation for zero-variant enum")
1496 .span_label(sp, "unsupported enum representation")
1500 let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1501 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1502 if !tcx.sess.features.borrow().i128_type {
1503 emit_feature_err(&tcx.sess.parse_sess,
1504 "i128_type", sp, GateIssue::Language, "128-bit type is unstable");
1509 if let Some(e) = v.node.disr_expr {
1510 tcx.typeck_tables_of(tcx.hir.local_def_id(e.node_id));
1514 let mut disr_vals: Vec<ConstInt> = Vec::new();
1515 for (discr, v) in def.discriminants(tcx).zip(vs) {
1516 // Check for duplicate discriminant values
1517 if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
1518 let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
1519 let variant_i = tcx.hir.expect_variant(variant_i_node_id);
1520 let i_span = match variant_i.node.disr_expr {
1521 Some(expr) => tcx.hir.span(expr.node_id),
1522 None => tcx.hir.span(variant_i_node_id)
1524 let span = match v.node.disr_expr {
1525 Some(expr) => tcx.hir.span(expr.node_id),
1528 struct_span_err!(tcx.sess, span, E0081,
1529 "discriminant value `{}` already exists", disr_vals[i])
1530 .span_label(i_span, format!("first use of `{}`", disr_vals[i]))
1531 .span_label(span , format!("enum already has `{}`", disr_vals[i]))
1534 disr_vals.push(discr);
1537 check_representable(tcx, sp, def_id);
1540 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1541 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1543 fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1544 -> ty::GenericPredicates<'tcx>
1547 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
1548 let item_id = tcx.hir.ty_param_owner(node_id);
1549 let item_def_id = tcx.hir.local_def_id(item_id);
1550 let generics = tcx.generics_of(item_def_id);
1551 let index = generics.type_param_to_index[&def_id.index];
1552 ty::GenericPredicates {
1554 predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
1556 ty::Predicate::Trait(ref data) => {
1557 data.0.self_ty().is_param(index)
1561 }).cloned().collect()
1565 fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
1566 -> Option<ty::Region<'tcx>> {
1568 Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
1569 None => infer::MiscVariable(span)
1571 Some(self.next_region_var(v))
1574 fn ty_infer(&self, span: Span) -> Ty<'tcx> {
1575 self.next_ty_var(TypeVariableOrigin::TypeInference(span))
1578 fn ty_infer_for_def(&self,
1579 ty_param_def: &ty::TypeParameterDef,
1580 substs: &[Kind<'tcx>],
1581 span: Span) -> Ty<'tcx> {
1582 self.type_var_for_def(span, ty_param_def, substs)
1585 fn projected_ty_from_poly_trait_ref(&self,
1587 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1588 item_name: ast::Name)
1591 let (trait_ref, _) =
1592 self.replace_late_bound_regions_with_fresh_var(
1594 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1597 self.tcx().mk_projection(trait_ref, item_name)
1600 fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1601 if ty.has_escaping_regions() {
1602 ty // FIXME: normalization and escaping regions
1604 self.normalize_associated_types_in(span, &ty)
1608 fn set_tainted_by_errors(&self) {
1609 self.infcx.set_tainted_by_errors()
1613 /// Controls whether the arguments are tupled. This is used for the call
1616 /// Tupling means that all call-side arguments are packed into a tuple and
1617 /// passed as a single parameter. For example, if tupling is enabled, this
1620 /// fn f(x: (isize, isize))
1622 /// Can be called as:
1629 #[derive(Clone, Eq, PartialEq)]
1630 enum TupleArgumentsFlag {
1635 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1636 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1637 param_env: ty::ParamEnv<'tcx>,
1638 body_id: ast::NodeId)
1639 -> FnCtxt<'a, 'gcx, 'tcx> {
1643 err_count_on_creation: inh.tcx.sess.err_count(),
1645 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
1646 ast::CRATE_NODE_ID)),
1647 diverges: Cell::new(Diverges::Maybe),
1648 has_errors: Cell::new(false),
1649 enclosing_breakables: RefCell::new(EnclosingBreakables {
1657 pub fn sess(&self) -> &Session {
1661 pub fn err_count_since_creation(&self) -> usize {
1662 self.tcx.sess.err_count() - self.err_count_on_creation
1665 /// Produce warning on the given node, if the current point in the
1666 /// function is unreachable, and there hasn't been another warning.
1667 fn warn_if_unreachable(&self, id: ast::NodeId, span: Span, kind: &str) {
1668 if self.diverges.get() == Diverges::Always {
1669 self.diverges.set(Diverges::WarnedAlways);
1671 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
1673 self.tables.borrow_mut().lints.add_lint(
1674 lint::builtin::UNREACHABLE_CODE,
1676 format!("unreachable {}", kind));
1682 code: ObligationCauseCode<'tcx>)
1683 -> ObligationCause<'tcx> {
1684 ObligationCause::new(span, self.body_id, code)
1687 pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
1688 self.cause(span, ObligationCauseCode::MiscObligation)
1691 /// Resolves type variables in `ty` if possible. Unlike the infcx
1692 /// version (resolve_type_vars_if_possible), this version will
1693 /// also select obligations if it seems useful, in an effort
1694 /// to get more type information.
1695 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1696 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1698 // No TyInfer()? Nothing needs doing.
1699 if !ty.has_infer_types() {
1700 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1704 // If `ty` is a type variable, see whether we already know what it is.
1705 ty = self.resolve_type_vars_if_possible(&ty);
1706 if !ty.has_infer_types() {
1707 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1711 // If not, try resolving pending obligations as much as
1712 // possible. This can help substantially when there are
1713 // indirect dependencies that don't seem worth tracking
1715 self.select_obligations_where_possible();
1716 ty = self.resolve_type_vars_if_possible(&ty);
1718 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1722 fn record_deferred_call_resolution(&self,
1723 closure_def_id: DefId,
1724 r: DeferredCallResolution<'gcx, 'tcx>) {
1725 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1726 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1729 fn remove_deferred_call_resolutions(&self,
1730 closure_def_id: DefId)
1731 -> Vec<DeferredCallResolution<'gcx, 'tcx>>
1733 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1734 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(vec![])
1737 pub fn tag(&self) -> String {
1738 let self_ptr: *const FnCtxt = self;
1739 format!("{:?}", self_ptr)
1742 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1743 match self.locals.borrow().get(&nid) {
1746 span_bug!(span, "no type for local variable {}",
1747 self.tcx.hir.node_to_string(nid));
1753 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1754 debug!("write_ty({}, {:?}) in fcx {}",
1755 node_id, self.resolve_type_vars_if_possible(&ty), self.tag());
1756 self.tables.borrow_mut().node_types.insert(node_id, ty);
1758 if ty.references_error() {
1759 self.has_errors.set(true);
1760 self.set_tainted_by_errors();
1764 pub fn write_method_call(&self, node_id: ast::NodeId, method: MethodCallee<'tcx>) {
1765 self.tables.borrow_mut().type_dependent_defs.insert(node_id, Def::Method(method.def_id));
1766 self.write_substs(node_id, method.substs);
1769 pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) {
1770 if !substs.is_noop() {
1771 debug!("write_substs({}, {:?}) in fcx {}",
1776 self.tables.borrow_mut().node_substs.insert(node_id, substs);
1780 pub fn apply_adjustments(&self, expr: &hir::Expr, adj: Vec<Adjustment<'tcx>>) {
1781 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
1787 match self.tables.borrow_mut().adjustments.entry(expr.id) {
1788 Entry::Vacant(entry) => { entry.insert(adj); },
1789 Entry::Occupied(mut entry) => {
1790 debug!(" - composing on top of {:?}", entry.get());
1791 match (&entry.get()[..], &adj[..]) {
1792 // Applying any adjustment on top of a NeverToAny
1793 // is a valid NeverToAny adjustment, because it can't
1795 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
1797 Adjustment { kind: Adjust::Deref(_), .. },
1798 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
1800 Adjustment { kind: Adjust::Deref(_), .. },
1801 .. // Any following adjustments are allowed.
1803 // A reborrow has no effect before a dereference.
1805 // FIXME: currently we never try to compose autoderefs
1806 // and ReifyFnPointer/UnsafeFnPointer, but we could.
1808 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
1809 expr, entry.get(), adj)
1811 *entry.get_mut() = adj;
1816 /// Basically whenever we are converting from a type scheme into
1817 /// the fn body space, we always want to normalize associated
1818 /// types as well. This function combines the two.
1819 fn instantiate_type_scheme<T>(&self,
1821 substs: &Substs<'tcx>,
1824 where T : TypeFoldable<'tcx>
1826 let value = value.subst(self.tcx, substs);
1827 let result = self.normalize_associated_types_in(span, &value);
1828 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1835 /// As `instantiate_type_scheme`, but for the bounds found in a
1836 /// generic type scheme.
1837 fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: &Substs<'tcx>)
1838 -> ty::InstantiatedPredicates<'tcx> {
1839 let bounds = self.tcx.predicates_of(def_id);
1840 let result = bounds.instantiate(self.tcx, substs);
1841 let result = self.normalize_associated_types_in(span, &result);
1842 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1849 /// Replace all anonymized types with fresh inference variables
1850 /// and record them for writeback.
1851 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1852 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1853 if let ty::TyAnon(def_id, substs) = ty.sty {
1854 // Use the same type variable if the exact same TyAnon appears more
1855 // than once in the return type (e.g. if it's pased to a type alias).
1856 let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
1857 if let Some(ty_var) = self.anon_types.borrow().get(&id) {
1860 let span = self.tcx.def_span(def_id);
1861 let ty_var = self.next_ty_var(TypeVariableOrigin::TypeInference(span));
1862 self.anon_types.borrow_mut().insert(id, ty_var);
1864 let predicates_of = self.tcx.predicates_of(def_id);
1865 let bounds = predicates_of.instantiate(self.tcx, substs);
1867 for predicate in bounds.predicates {
1868 // Change the predicate to refer to the type variable,
1869 // which will be the concrete type, instead of the TyAnon.
1870 // This also instantiates nested `impl Trait`.
1871 let predicate = self.instantiate_anon_types(&predicate);
1873 // Require that the predicate holds for the concrete type.
1874 let cause = traits::ObligationCause::new(span, self.body_id,
1875 traits::ReturnType);
1876 self.register_predicate(traits::Obligation::new(cause,
1888 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1889 where T : TypeFoldable<'tcx>
1891 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
1894 fn normalize_associated_types_in_as_infer_ok<T>(&self, span: Span, value: &T)
1896 where T : TypeFoldable<'tcx>
1898 self.inh.normalize_associated_types_in_as_infer_ok(span,
1904 pub fn require_type_meets(&self,
1907 code: traits::ObligationCauseCode<'tcx>,
1910 self.register_bound(
1913 traits::ObligationCause::new(span, self.body_id, code));
1916 pub fn require_type_is_sized(&self,
1919 code: traits::ObligationCauseCode<'tcx>)
1921 let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
1922 self.require_type_meets(ty, span, code, lang_item);
1925 pub fn register_bound(&self,
1928 cause: traits::ObligationCause<'tcx>)
1930 self.fulfillment_cx.borrow_mut()
1931 .register_bound(self, self.param_env, ty, def_id, cause);
1934 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1935 let t = AstConv::ast_ty_to_ty(self, ast_t);
1936 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1940 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1941 match self.tables.borrow().node_types.get(&id) {
1943 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1945 bug!("no type for node {}: {} in fcx {}",
1946 id, self.tcx.hir.node_to_string(id),
1952 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1953 /// outlive the region `r`.
1954 pub fn register_region_obligation(&self,
1956 region: ty::Region<'tcx>,
1957 cause: traits::ObligationCause<'tcx>)
1959 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1960 fulfillment_cx.register_region_obligation(ty, region, cause);
1963 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1964 /// outlive the region `r`.
1965 pub fn register_wf_obligation(&self,
1968 code: traits::ObligationCauseCode<'tcx>)
1970 // WF obligations never themselves fail, so no real need to give a detailed cause:
1971 let cause = traits::ObligationCause::new(span, self.body_id, code);
1972 self.register_predicate(traits::Obligation::new(cause,
1974 ty::Predicate::WellFormed(ty)));
1977 pub fn register_old_wf_obligation(&self,
1980 code: traits::ObligationCauseCode<'tcx>)
1982 // Registers an "old-style" WF obligation that uses the
1983 // implicator code. This is basically a buggy version of
1984 // `register_wf_obligation` that is being kept around
1985 // temporarily just to help with phasing in the newer rules.
1987 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1988 let cause = traits::ObligationCause::new(span, self.body_id, code);
1989 self.register_region_obligation(ty, self.tcx.types.re_empty, cause);
1992 /// Registers obligations that all types appearing in `substs` are well-formed.
1993 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1995 for ty in substs.types() {
1996 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2000 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
2001 /// type/region parameter was instantiated (`substs`), creates and registers suitable
2002 /// trait/region obligations.
2004 /// For example, if there is a function:
2007 /// fn foo<'a,T:'a>(...)
2010 /// and a reference:
2016 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
2017 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
2018 pub fn add_obligations_for_parameters(&self,
2019 cause: traits::ObligationCause<'tcx>,
2020 predicates: &ty::InstantiatedPredicates<'tcx>)
2022 assert!(!predicates.has_escaping_regions());
2024 debug!("add_obligations_for_parameters(predicates={:?})",
2027 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
2028 self.register_predicate(obligation);
2032 // FIXME(arielb1): use this instead of field.ty everywhere
2033 // Only for fields! Returns <none> for methods>
2034 // Indifferent to privacy flags
2035 pub fn field_ty(&self,
2037 field: &'tcx ty::FieldDef,
2038 substs: &Substs<'tcx>)
2041 self.normalize_associated_types_in(span,
2042 &field.ty(self.tcx, substs))
2045 fn check_casts(&self) {
2046 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
2047 for cast in deferred_cast_checks.drain(..) {
2052 /// Apply "fallbacks" to some types
2053 /// unconstrained types get replaced with ! or () (depending on whether
2054 /// feature(never_type) is enabled), unconstrained ints with i32, and
2055 /// unconstrained floats with f64.
2056 fn default_type_parameters(&self) {
2057 use rustc::ty::error::UnconstrainedNumeric::Neither;
2058 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2060 // Defaulting inference variables becomes very dubious if we have
2061 // encountered type-checking errors. Therefore, if we think we saw
2062 // some errors in this function, just resolve all uninstanted type
2063 // varibles to TyError.
2064 if self.is_tainted_by_errors() {
2065 for ty in &self.unsolved_variables() {
2066 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
2067 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2068 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2074 for ty in &self.unsolved_variables() {
2075 let resolved = self.resolve_type_vars_if_possible(ty);
2076 if self.type_var_diverges(resolved) {
2077 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
2079 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2080 self.tcx.mk_diverging_default());
2082 match self.type_is_unconstrained_numeric(resolved) {
2083 UnconstrainedInt => {
2084 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
2086 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2088 UnconstrainedFloat => {
2089 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
2091 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2099 // Implements type inference fallback algorithm
2100 fn select_all_obligations_and_apply_defaults(&self) {
2101 self.select_obligations_where_possible();
2102 self.default_type_parameters();
2103 self.select_obligations_where_possible();
2106 fn select_all_obligations_or_error(&self) {
2107 debug!("select_all_obligations_or_error");
2109 // upvar inference should have ensured that all deferred call
2110 // resolutions are handled by now.
2111 assert!(self.deferred_call_resolutions.borrow().is_empty());
2113 self.select_all_obligations_and_apply_defaults();
2115 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2117 match fulfillment_cx.select_all_or_error(self) {
2119 Err(errors) => { self.report_fulfillment_errors(&errors); }
2123 /// Select as many obligations as we can at present.
2124 fn select_obligations_where_possible(&self) {
2125 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2127 Err(errors) => { self.report_fulfillment_errors(&errors); }
2131 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2132 /// returns a type of `&T`, but the actual type we assign to the
2133 /// *expression* is `T`. So this function just peels off the return
2134 /// type by one layer to yield `T`.
2135 fn make_overloaded_lvalue_return_type(&self,
2136 method: MethodCallee<'tcx>)
2137 -> ty::TypeAndMut<'tcx>
2139 // extract method return type, which will be &T;
2140 // all LB regions should have been instantiated during method lookup
2141 let ret_ty = method.sig.output();
2143 // method returns &T, but the type as visible to user is T, so deref
2144 ret_ty.builtin_deref(true, NoPreference).unwrap()
2147 fn lookup_indexing(&self,
2149 base_expr: &'gcx hir::Expr,
2152 lvalue_pref: LvaluePreference)
2153 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2155 // FIXME(#18741) -- this is almost but not quite the same as the
2156 // autoderef that normal method probing does. They could likely be
2159 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2160 let mut result = None;
2161 while result.is_none() && autoderef.next().is_some() {
2162 result = self.try_index_step(expr, base_expr, &autoderef, lvalue_pref, idx_ty);
2164 autoderef.finalize();
2168 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2169 /// (and otherwise adjust) `base_expr`, looking for a type which either
2170 /// supports builtin indexing or overloaded indexing.
2171 /// This loop implements one step in that search; the autoderef loop
2172 /// is implemented by `lookup_indexing`.
2173 fn try_index_step(&self,
2175 base_expr: &hir::Expr,
2176 autoderef: &Autoderef<'a, 'gcx, 'tcx>,
2177 lvalue_pref: LvaluePreference,
2179 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2181 let adjusted_ty = autoderef.unambiguous_final_ty();
2182 debug!("try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
2190 // First, try built-in indexing.
2191 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2192 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2193 debug!("try_index_step: success, using built-in indexing");
2194 let adjustments = autoderef.adjust_steps(lvalue_pref);
2195 self.apply_adjustments(base_expr, adjustments);
2196 return Some((self.tcx.types.usize, ty));
2201 for &unsize in &[false, true] {
2202 let mut self_ty = adjusted_ty;
2204 // We only unsize arrays here.
2205 if let ty::TyArray(element_ty, _) = adjusted_ty.sty {
2206 self_ty = self.tcx.mk_slice(element_ty);
2212 // If some lookup succeeds, write callee into table and extract index/element
2213 // type from the method signature.
2214 // If some lookup succeeded, install method in table
2215 let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
2216 let method = self.try_overloaded_lvalue_op(
2217 expr.span, self_ty, &[input_ty], lvalue_pref, LvalueOp::Index);
2219 let result = method.map(|ok| {
2220 debug!("try_index_step: success, using overloaded indexing");
2221 let method = self.register_infer_ok_obligations(ok);
2223 let mut adjustments = autoderef.adjust_steps(lvalue_pref);
2224 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
2225 adjustments.push(Adjustment {
2226 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
2227 target: self.tcx.mk_ref(region, ty::TypeAndMut {
2234 adjustments.push(Adjustment {
2235 kind: Adjust::Unsize,
2236 target: method.sig.inputs()[0]
2239 self.apply_adjustments(base_expr, adjustments);
2241 self.write_method_call(expr.id, method);
2242 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2244 if result.is_some() {
2252 fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
2253 let (tr, name) = match (op, is_mut) {
2254 (LvalueOp::Deref, false) =>
2255 (self.tcx.lang_items.deref_trait(), "deref"),
2256 (LvalueOp::Deref, true) =>
2257 (self.tcx.lang_items.deref_mut_trait(), "deref_mut"),
2258 (LvalueOp::Index, false) =>
2259 (self.tcx.lang_items.index_trait(), "index"),
2260 (LvalueOp::Index, true) =>
2261 (self.tcx.lang_items.index_mut_trait(), "index_mut"),
2263 (tr, Symbol::intern(name))
2266 fn try_overloaded_lvalue_op(&self,
2269 arg_tys: &[Ty<'tcx>],
2270 lvalue_pref: LvaluePreference,
2272 -> Option<InferOk<'tcx, MethodCallee<'tcx>>>
2274 debug!("try_overloaded_lvalue_op({:?},{:?},{:?},{:?})",
2280 // Try Mut first, if preferred.
2281 let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
2282 let method = match (lvalue_pref, mut_tr) {
2283 (PreferMutLvalue, Some(trait_did)) => {
2284 self.lookup_method_in_trait(span, mut_op, trait_did, base_ty, Some(arg_tys))
2289 // Otherwise, fall back to the immutable version.
2290 let (imm_tr, imm_op) = self.resolve_lvalue_op(op, false);
2291 let method = match (method, imm_tr) {
2292 (None, Some(trait_did)) => {
2293 self.lookup_method_in_trait(span, imm_op, trait_did, base_ty, Some(arg_tys))
2295 (method, _) => method,
2301 fn check_method_argument_types(&self,
2303 method: Result<MethodCallee<'tcx>, ()>,
2304 args_no_rcvr: &'gcx [hir::Expr],
2305 tuple_arguments: TupleArgumentsFlag,
2306 expected: Expectation<'tcx>)
2308 let has_error = match method {
2310 method.substs.references_error() || method.sig.references_error()
2315 let err_inputs = self.err_args(args_no_rcvr.len());
2317 let err_inputs = match tuple_arguments {
2318 DontTupleArguments => err_inputs,
2319 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
2322 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2323 false, tuple_arguments, None);
2324 return self.tcx.types.err;
2327 let method = method.unwrap();
2328 // HACK(eddyb) ignore self in the definition (see above).
2329 let expected_arg_tys = self.expected_inputs_for_expected_output(
2332 method.sig.output(),
2333 &method.sig.inputs()[1..]
2335 self.check_argument_types(sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
2336 args_no_rcvr, method.sig.variadic, tuple_arguments,
2337 self.tcx.hir.span_if_local(method.def_id));
2341 /// Generic function that factors out common logic from function calls,
2342 /// method calls and overloaded operators.
2343 fn check_argument_types(&self,
2345 fn_inputs: &[Ty<'tcx>],
2346 expected_arg_tys: &[Ty<'tcx>],
2347 args: &'gcx [hir::Expr],
2349 tuple_arguments: TupleArgumentsFlag,
2350 def_span: Option<Span>) {
2353 // Grab the argument types, supplying fresh type variables
2354 // if the wrong number of arguments were supplied
2355 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2361 // All the input types from the fn signature must outlive the call
2362 // so as to validate implied bounds.
2363 for &fn_input_ty in fn_inputs {
2364 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2367 let mut expected_arg_tys = expected_arg_tys;
2368 let expected_arg_count = fn_inputs.len();
2370 let sp_args = if args.len() > 0 {
2371 let (first, args) = args.split_at(1);
2372 let mut sp_tmp = first[0].span;
2374 let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2375 if ! sp_opt.is_some() {
2378 sp_tmp = sp_opt.unwrap();
2385 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2386 arg_count: usize, error_code: &str, variadic: bool,
2387 def_span: Option<Span>) {
2388 let mut err = sess.struct_span_err_with_code(sp,
2389 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2390 if variadic {"at least "} else {""},
2392 if expected_count == 1 {""} else {"s"},
2394 if arg_count == 1 {" was"} else {"s were"}),
2397 err.span_label(sp, format!("expected {}{} parameter{}",
2398 if variadic {"at least "} else {""},
2400 if expected_count == 1 {""} else {"s"}));
2401 if let Some(def_s) = def_span {
2402 err.span_label(def_s, "defined here");
2407 let formal_tys = if tuple_arguments == TupleArguments {
2408 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2409 match tuple_type.sty {
2410 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2411 parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2412 "E0057", false, def_span);
2413 expected_arg_tys = &[];
2414 self.err_args(args.len())
2416 ty::TyTuple(arg_types, _) => {
2417 expected_arg_tys = match expected_arg_tys.get(0) {
2418 Some(&ty) => match ty.sty {
2419 ty::TyTuple(ref tys, _) => &tys,
2427 span_err!(tcx.sess, sp, E0059,
2428 "cannot use call notation; the first type parameter \
2429 for the function trait is neither a tuple nor unit");
2430 expected_arg_tys = &[];
2431 self.err_args(args.len())
2434 } else if expected_arg_count == supplied_arg_count {
2436 } else if variadic {
2437 if supplied_arg_count >= expected_arg_count {
2440 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2441 supplied_arg_count, "E0060", true, def_span);
2442 expected_arg_tys = &[];
2443 self.err_args(supplied_arg_count)
2446 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2447 supplied_arg_count, "E0061", false, def_span);
2448 expected_arg_tys = &[];
2449 self.err_args(supplied_arg_count)
2452 debug!("check_argument_types: formal_tys={:?}",
2453 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2455 // Check the arguments.
2456 // We do this in a pretty awful way: first we typecheck any arguments
2457 // that are not closures, then we typecheck the closures. This is so
2458 // that we have more information about the types of arguments when we
2459 // typecheck the functions. This isn't really the right way to do this.
2460 for &check_closures in &[false, true] {
2461 debug!("check_closures={}", check_closures);
2463 // More awful hacks: before we check argument types, try to do
2464 // an "opportunistic" vtable resolution of any trait bounds on
2465 // the call. This helps coercions.
2467 self.select_obligations_where_possible();
2470 // For variadic functions, we don't have a declared type for all of
2471 // the arguments hence we only do our usual type checking with
2472 // the arguments who's types we do know.
2473 let t = if variadic {
2475 } else if tuple_arguments == TupleArguments {
2480 for (i, arg) in args.iter().take(t).enumerate() {
2481 // Warn only for the first loop (the "no closures" one).
2482 // Closure arguments themselves can't be diverging, but
2483 // a previous argument can, e.g. `foo(panic!(), || {})`.
2484 if !check_closures {
2485 self.warn_if_unreachable(arg.id, arg.span, "expression");
2488 let is_closure = match arg.node {
2489 hir::ExprClosure(..) => true,
2493 if is_closure != check_closures {
2497 debug!("checking the argument");
2498 let formal_ty = formal_tys[i];
2500 // The special-cased logic below has three functions:
2501 // 1. Provide as good of an expected type as possible.
2502 let expected = expected_arg_tys.get(i).map(|&ty| {
2503 Expectation::rvalue_hint(self, ty)
2506 let checked_ty = self.check_expr_with_expectation(
2508 expected.unwrap_or(ExpectHasType(formal_ty)));
2510 // 2. Coerce to the most detailed type that could be coerced
2511 // to, which is `expected_ty` if `rvalue_hint` returns an
2512 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2513 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2514 self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2516 // 3. Relate the expected type and the formal one,
2517 // if the expected type was used for the coercion.
2518 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2522 // We also need to make sure we at least write the ty of the other
2523 // arguments which we skipped above.
2525 for arg in args.iter().skip(expected_arg_count) {
2526 let arg_ty = self.check_expr(&arg);
2528 // There are a few types which get autopromoted when passed via varargs
2529 // in C but we just error out instead and require explicit casts.
2530 let arg_ty = self.structurally_resolved_type(arg.span,
2533 ty::TyFloat(ast::FloatTy::F32) => {
2534 self.type_error_message(arg.span, |t| {
2535 format!("can't pass an `{}` to variadic \
2536 function, cast to `c_double`", t)
2539 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2540 self.type_error_message(arg.span, |t| {
2541 format!("can't pass `{}` to variadic \
2542 function, cast to `c_int`",
2546 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2547 self.type_error_message(arg.span, |t| {
2548 format!("can't pass `{}` to variadic \
2549 function, cast to `c_uint`",
2553 ty::TyFnDef(.., f) => {
2554 let ptr_ty = self.tcx.mk_fn_ptr(f);
2555 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2556 self.type_error_message(arg.span,
2558 format!("can't pass `{}` to variadic \
2559 function, cast to `{}`", t, ptr_ty)
2568 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2569 (0..len).map(|_| self.tcx.types.err).collect()
2572 // AST fragment checking
2575 expected: Expectation<'tcx>)
2581 ast::LitKind::Str(..) => tcx.mk_static_str(),
2582 ast::LitKind::ByteStr(ref v) => {
2583 tcx.mk_imm_ref(tcx.types.re_static,
2584 tcx.mk_array(tcx.types.u8, v.len()))
2586 ast::LitKind::Byte(_) => tcx.types.u8,
2587 ast::LitKind::Char(_) => tcx.types.char,
2588 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2589 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2590 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2591 let opt_ty = expected.to_option(self).and_then(|ty| {
2593 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2594 ty::TyChar => Some(tcx.types.u8),
2595 ty::TyRawPtr(..) => Some(tcx.types.usize),
2596 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2600 opt_ty.unwrap_or_else(
2601 || tcx.mk_int_var(self.next_int_var_id()))
2603 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2604 ast::LitKind::FloatUnsuffixed(_) => {
2605 let opt_ty = expected.to_option(self).and_then(|ty| {
2607 ty::TyFloat(_) => Some(ty),
2611 opt_ty.unwrap_or_else(
2612 || tcx.mk_float_var(self.next_float_var_id()))
2614 ast::LitKind::Bool(_) => tcx.types.bool
2618 fn check_expr_eq_type(&self,
2619 expr: &'gcx hir::Expr,
2620 expected: Ty<'tcx>) {
2621 let ty = self.check_expr_with_hint(expr, expected);
2622 self.demand_eqtype(expr.span, expected, ty);
2625 pub fn check_expr_has_type(&self,
2626 expr: &'gcx hir::Expr,
2627 expected: Ty<'tcx>) -> Ty<'tcx> {
2628 let mut ty = self.check_expr_with_hint(expr, expected);
2630 // While we don't allow *arbitrary* coercions here, we *do* allow
2631 // coercions from ! to `expected`.
2633 assert!(!self.tables.borrow().adjustments.contains_key(&expr.id),
2634 "expression with never type wound up being adjusted");
2635 let adj_ty = self.next_diverging_ty_var(
2636 TypeVariableOrigin::AdjustmentType(expr.span));
2637 self.apply_adjustments(expr, vec![Adjustment {
2638 kind: Adjust::NeverToAny,
2644 self.demand_suptype(expr.span, expected, ty);
2648 fn check_expr_coercable_to_type(&self,
2649 expr: &'gcx hir::Expr,
2650 expected: Ty<'tcx>) -> Ty<'tcx> {
2651 let ty = self.check_expr_with_hint(expr, expected);
2652 self.demand_coerce(expr, ty, expected);
2656 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2657 expected: Ty<'tcx>) -> Ty<'tcx> {
2658 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2661 fn check_expr_with_expectation(&self,
2662 expr: &'gcx hir::Expr,
2663 expected: Expectation<'tcx>) -> Ty<'tcx> {
2664 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2667 fn check_expr(&self, expr: &'gcx hir::Expr) -> Ty<'tcx> {
2668 self.check_expr_with_expectation(expr, NoExpectation)
2671 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2672 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2673 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2676 // determine the `self` type, using fresh variables for all variables
2677 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2678 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2680 pub fn impl_self_ty(&self,
2681 span: Span, // (potential) receiver for this impl
2683 -> TypeAndSubsts<'tcx> {
2684 let ity = self.tcx.type_of(did);
2685 debug!("impl_self_ty: ity={:?}", ity);
2687 let substs = self.fresh_substs_for_item(span, did);
2688 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
2690 TypeAndSubsts { substs: substs, ty: substd_ty }
2693 /// Unifies the output type with the expected type early, for more coercions
2694 /// and forward type information on the input expressions.
2695 fn expected_inputs_for_expected_output(&self,
2697 expected_ret: Expectation<'tcx>,
2698 formal_ret: Ty<'tcx>,
2699 formal_args: &[Ty<'tcx>])
2701 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2702 self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2703 // Attempt to apply a subtyping relationship between the formal
2704 // return type (likely containing type variables if the function
2705 // is polymorphic) and the expected return type.
2706 // No argument expectations are produced if unification fails.
2707 let origin = self.misc(call_span);
2708 let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
2710 // FIXME(#15760) can't use try! here, FromError doesn't default
2711 // to identity so the resulting type is not constrained.
2714 // Process any obligations locally as much as
2715 // we can. We don't care if some things turn
2716 // out unconstrained or ambiguous, as we're
2717 // just trying to get hints here.
2718 let result = self.save_and_restore_in_snapshot_flag(|_| {
2719 let mut fulfill = FulfillmentContext::new();
2720 let ok = ok; // FIXME(#30046)
2721 for obligation in ok.obligations {
2722 fulfill.register_predicate_obligation(self, obligation);
2724 fulfill.select_where_possible(self)
2729 Err(_) => return Err(()),
2732 Err(_) => return Err(()),
2735 // Record all the argument types, with the substitutions
2736 // produced from the above subtyping unification.
2737 Ok(formal_args.iter().map(|ty| {
2738 self.resolve_type_vars_if_possible(ty)
2741 }).unwrap_or(vec![]);
2742 debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
2743 formal_args, formal_ret,
2744 expected_args, expected_ret);
2748 // Checks a method call.
2749 fn check_method_call(&self,
2750 expr: &'gcx hir::Expr,
2751 method_name: Spanned<ast::Name>,
2752 args: &'gcx [hir::Expr],
2754 expected: Expectation<'tcx>,
2755 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
2756 let rcvr = &args[0];
2757 let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2759 // no need to check for bot/err -- callee does that
2760 let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2762 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2763 let method = match self.lookup_method(method_name.span,
2770 self.write_method_call(expr.id, method);
2774 if method_name.node != keywords::Invalid.name() {
2775 self.report_method_error(method_name.span,
2786 // Call the generic checker.
2787 self.check_method_argument_types(method_name.span, method,
2793 fn check_return_expr(&self, return_expr: &'gcx hir::Expr) {
2797 .unwrap_or_else(|| span_bug!(return_expr.span,
2798 "check_return_expr called outside fn body"));
2800 let ret_ty = ret_coercion.borrow().expected_ty();
2801 let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
2802 ret_coercion.borrow_mut()
2804 &self.misc(return_expr.span),
2807 self.diverges.get());
2811 // A generic function for checking the then and else in an if
2813 fn check_then_else(&self,
2814 cond_expr: &'gcx hir::Expr,
2815 then_expr: &'gcx hir::Expr,
2816 opt_else_expr: Option<&'gcx hir::Expr>,
2818 expected: Expectation<'tcx>) -> Ty<'tcx> {
2819 let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2820 let cond_diverges = self.diverges.get();
2821 self.diverges.set(Diverges::Maybe);
2823 let expected = expected.adjust_for_branches(self);
2824 let then_ty = self.check_expr_with_expectation(then_expr, expected);
2825 let then_diverges = self.diverges.get();
2826 self.diverges.set(Diverges::Maybe);
2828 // We've already taken the expected type's preferences
2829 // into account when typing the `then` branch. To figure
2830 // out the initial shot at a LUB, we thus only consider
2831 // `expected` if it represents a *hard* constraint
2832 // (`only_has_type`); otherwise, we just go with a
2833 // fresh type variable.
2834 let coerce_to_ty = expected.coercion_target_type(self, sp);
2835 let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
2837 let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
2838 coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
2840 if let Some(else_expr) = opt_else_expr {
2841 let else_ty = self.check_expr_with_expectation(else_expr, expected);
2842 let else_diverges = self.diverges.get();
2844 coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
2846 // We won't diverge unless both branches do (or the condition does).
2847 self.diverges.set(cond_diverges | then_diverges & else_diverges);
2849 let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
2850 coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
2852 // If the condition is false we can't diverge.
2853 self.diverges.set(cond_diverges);
2856 let result_ty = coerce.complete(self);
2857 if cond_ty.references_error() {
2864 // Check field access expressions
2865 fn check_field(&self,
2866 expr: &'gcx hir::Expr,
2867 lvalue_pref: LvaluePreference,
2868 base: &'gcx hir::Expr,
2869 field: &Spanned<ast::Name>) -> Ty<'tcx> {
2870 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2871 let expr_t = self.structurally_resolved_type(expr.span,
2873 let mut private_candidate = None;
2874 let mut autoderef = self.autoderef(expr.span, expr_t);
2875 while let Some((base_t, _)) = autoderef.next() {
2877 ty::TyAdt(base_def, substs) if !base_def.is_enum() => {
2878 debug!("struct named {:?}", base_t);
2879 let (ident, def_scope) =
2880 self.tcx.adjust(field.node, base_def.did, self.body_id);
2881 let fields = &base_def.struct_variant().fields;
2882 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
2883 let field_ty = self.field_ty(expr.span, field, substs);
2884 if field.vis.is_accessible_from(def_scope, self.tcx) {
2885 let adjustments = autoderef.adjust_steps(lvalue_pref);
2886 self.apply_adjustments(base, adjustments);
2887 autoderef.finalize();
2889 self.tcx.check_stability(field.did, expr.id, expr.span);
2893 private_candidate = Some((base_def.did, field_ty));
2899 autoderef.unambiguous_final_ty();
2901 if let Some((did, field_ty)) = private_candidate {
2902 let struct_path = self.tcx().item_path_str(did);
2903 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2904 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2905 // Also check if an accessible method exists, which is often what is meant.
2906 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2907 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2912 } else if field.node == keywords::Invalid.name() {
2913 self.tcx().types.err
2914 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2915 self.type_error_struct(field.span, |actual| {
2916 format!("attempted to take value of method `{}` on type \
2917 `{}`", field.node, actual)
2919 .help("maybe a `()` to call it is missing? \
2920 If not, try an anonymous function")
2922 self.tcx().types.err
2924 let mut err = self.type_error_struct(field.span, |actual| {
2925 format!("no field `{}` on type `{}`",
2929 ty::TyAdt(def, _) if !def.is_enum() => {
2930 if let Some(suggested_field_name) =
2931 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2932 err.span_label(field.span,
2933 format!("did you mean `{}`?", suggested_field_name));
2935 err.span_label(field.span,
2939 ty::TyRawPtr(..) => {
2940 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2942 self.tcx.hir.node_to_pretty_string(base.id),
2948 self.tcx().types.err
2952 // Return an hint about the closest match in field names
2953 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2954 field: &Spanned<ast::Name>,
2955 skip : Vec<InternedString>)
2957 let name = field.node.as_str();
2958 let names = variant.fields.iter().filter_map(|field| {
2959 // ignore already set fields and private fields from non-local crates
2960 if skip.iter().any(|x| *x == field.name.as_str()) ||
2961 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2968 // only find fits with at least one matching letter
2969 find_best_match_for_name(names, &name, Some(name.len()))
2972 // Check tuple index expressions
2973 fn check_tup_field(&self,
2974 expr: &'gcx hir::Expr,
2975 lvalue_pref: LvaluePreference,
2976 base: &'gcx hir::Expr,
2977 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2978 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2979 let expr_t = self.structurally_resolved_type(expr.span,
2981 let mut private_candidate = None;
2982 let mut tuple_like = false;
2983 let mut autoderef = self.autoderef(expr.span, expr_t);
2984 while let Some((base_t, _)) = autoderef.next() {
2985 let field = match base_t.sty {
2986 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2987 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2988 if !tuple_like { continue }
2990 debug!("tuple struct named {:?}", base_t);
2991 let ident = ast::Ident {
2992 name: Symbol::intern(&idx.node.to_string()),
2993 ctxt: idx.span.ctxt.modern(),
2995 let (ident, def_scope) =
2996 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
2997 let fields = &base_def.struct_variant().fields;
2998 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
2999 let field_ty = self.field_ty(expr.span, field, substs);
3000 if field.vis.is_accessible_from(def_scope, self.tcx) {
3001 self.tcx.check_stability(field.did, expr.id, expr.span);
3004 private_candidate = Some((base_def.did, field_ty));
3011 ty::TyTuple(ref v, _) => {
3013 v.get(idx.node).cloned()
3018 if let Some(field_ty) = field {
3019 let adjustments = autoderef.adjust_steps(lvalue_pref);
3020 self.apply_adjustments(base, adjustments);
3021 autoderef.finalize();
3025 autoderef.unambiguous_final_ty();
3027 if let Some((did, field_ty)) = private_candidate {
3028 let struct_path = self.tcx().item_path_str(did);
3029 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3030 self.tcx().sess.span_err(expr.span, &msg);
3034 self.type_error_message(
3038 format!("attempted out-of-bounds tuple index `{}` on \
3043 format!("attempted tuple index `{}` on type `{}`, but the \
3044 type was not a tuple or tuple struct",
3051 self.tcx().types.err
3054 fn report_unknown_field(&self,
3056 variant: &'tcx ty::VariantDef,
3058 skip_fields: &[hir::Field],
3060 let mut err = self.type_error_struct_with_diag(
3062 |actual| match ty.sty {
3063 ty::TyAdt(adt, ..) if adt.is_enum() => {
3064 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3065 "{} `{}::{}` has no field named `{}`",
3066 kind_name, actual, variant.name, field.name.node)
3069 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3070 "{} `{}` has no field named `{}`",
3071 kind_name, actual, field.name.node)
3075 // prevent all specified fields from being suggested
3076 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3077 if let Some(field_name) = Self::suggest_field_name(variant,
3079 skip_fields.collect()) {
3080 err.span_label(field.name.span,
3081 format!("field does not exist - did you mean `{}`?", field_name));
3084 ty::TyAdt(adt, ..) if adt.is_enum() => {
3085 err.span_label(field.name.span, format!("`{}::{}` does not have this field",
3089 err.span_label(field.name.span, format!("`{}` does not have this field", ty));
3096 fn check_expr_struct_fields(&self,
3098 expected: Expectation<'tcx>,
3099 expr_id: ast::NodeId,
3101 variant: &'tcx ty::VariantDef,
3102 ast_fields: &'gcx [hir::Field],
3103 check_completeness: bool) {
3107 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3108 .get(0).cloned().unwrap_or(adt_ty);
3110 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3111 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3112 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3114 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3117 let mut remaining_fields = FxHashMap();
3118 for field in &variant.fields {
3119 remaining_fields.insert(field.name.to_ident(), field);
3122 let mut seen_fields = FxHashMap();
3124 let mut error_happened = false;
3126 // Typecheck each field.
3127 for field in ast_fields {
3128 let final_field_type;
3129 let field_type_hint;
3131 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3132 if let Some(v_field) = remaining_fields.remove(&ident) {
3133 final_field_type = self.field_ty(field.span, v_field, substs);
3134 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3136 seen_fields.insert(field.name.node, field.span);
3138 // we don't look at stability attributes on
3139 // struct-like enums (yet...), but it's definitely not
3140 // a bug to have construct one.
3141 if adt_kind != ty::AdtKind::Enum {
3142 tcx.check_stability(v_field.did, expr_id, field.span);
3145 error_happened = true;
3146 final_field_type = tcx.types.err;
3147 field_type_hint = tcx.types.err;
3148 if let Some(_) = variant.find_field_named(field.name.node) {
3149 let mut err = struct_span_err!(self.tcx.sess,
3152 "field `{}` specified more than once",
3155 err.span_label(field.name.span, "used more than once");
3157 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3158 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3163 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3167 // Make sure to give a type to the field even if there's
3168 // an error, so we can continue typechecking
3169 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3170 self.demand_coerce(&field.expr, ty, final_field_type);
3173 // Make sure the programmer specified correct number of fields.
3174 if kind_name == "union" {
3175 if ast_fields.len() != 1 {
3176 tcx.sess.span_err(span, "union expressions should have exactly one field");
3178 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3179 let len = remaining_fields.len();
3181 let mut displayable_field_names = remaining_fields
3183 .map(|ident| ident.name.as_str())
3184 .collect::<Vec<_>>();
3186 displayable_field_names.sort();
3188 let truncated_fields_error = if len <= 3 {
3191 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3194 let remaining_fields_names = displayable_field_names.iter().take(3)
3195 .map(|n| format!("`{}`", n))
3196 .collect::<Vec<_>>()
3199 struct_span_err!(tcx.sess, span, E0063,
3200 "missing field{} {}{} in initializer of `{}`",
3201 if remaining_fields.len() == 1 {""} else {"s"},
3202 remaining_fields_names,
3203 truncated_fields_error,
3205 .span_label(span, format!("missing {}{}",
3206 remaining_fields_names,
3207 truncated_fields_error))
3212 fn check_struct_fields_on_error(&self,
3213 fields: &'gcx [hir::Field],
3214 base_expr: &'gcx Option<P<hir::Expr>>) {
3215 for field in fields {
3216 self.check_expr(&field.expr);
3220 self.check_expr(&base);
3226 pub fn check_struct_path(&self,
3228 node_id: ast::NodeId)
3229 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3230 let path_span = match *qpath {
3231 hir::QPath::Resolved(_, ref path) => path.span,
3232 hir::QPath::TypeRelative(ref qself, _) => qself.span
3234 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3235 let variant = match def {
3237 self.set_tainted_by_errors();
3240 Def::Variant(..) => {
3242 ty::TyAdt(adt, substs) => {
3243 Some((adt.variant_of_def(def), adt.did, substs))
3245 _ => bug!("unexpected type: {:?}", ty.sty)
3248 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3249 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3251 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3252 Some((adt.struct_variant(), adt.did, substs))
3257 _ => bug!("unexpected definition: {:?}", def)
3260 if let Some((variant, did, substs)) = variant {
3261 // Check bounds on type arguments used in the path.
3262 let bounds = self.instantiate_bounds(path_span, did, substs);
3263 let cause = traits::ObligationCause::new(path_span, self.body_id,
3264 traits::ItemObligation(did));
3265 self.add_obligations_for_parameters(cause, &bounds);
3269 struct_span_err!(self.tcx.sess, path_span, E0071,
3270 "expected struct, variant or union type, found {}",
3271 ty.sort_string(self.tcx))
3272 .span_label(path_span, "not a struct")
3278 fn check_expr_struct(&self,
3280 expected: Expectation<'tcx>,
3282 fields: &'gcx [hir::Field],
3283 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3285 // Find the relevant variant
3286 let (variant, struct_ty) =
3287 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3290 self.check_struct_fields_on_error(fields, base_expr);
3291 return self.tcx.types.err;
3294 let path_span = match *qpath {
3295 hir::QPath::Resolved(_, ref path) => path.span,
3296 hir::QPath::TypeRelative(ref qself, _) => qself.span
3299 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3300 base_expr.is_none());
3301 if let &Some(ref base_expr) = base_expr {
3302 self.check_expr_has_type(base_expr, struct_ty);
3303 match struct_ty.sty {
3304 ty::TyAdt(adt, substs) if adt.is_struct() => {
3305 self.tables.borrow_mut().fru_field_types.insert(
3307 adt.struct_variant().fields.iter().map(|f| {
3308 self.normalize_associated_types_in(
3309 expr.span, &f.ty(self.tcx, substs)
3315 span_err!(self.tcx.sess, base_expr.span, E0436,
3316 "functional record update syntax requires a struct");
3320 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3326 /// If an expression has any sub-expressions that result in a type error,
3327 /// inspecting that expression's type with `ty.references_error()` will return
3328 /// true. Likewise, if an expression is known to diverge, inspecting its
3329 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3330 /// strict, _|_ can appear in the type of an expression that does not,
3331 /// itself, diverge: for example, fn() -> _|_.)
3332 /// Note that inspecting a type's structure *directly* may expose the fact
3333 /// that there are actually multiple representations for `TyError`, so avoid
3334 /// that when err needs to be handled differently.
3335 fn check_expr_with_expectation_and_lvalue_pref(&self,
3336 expr: &'gcx hir::Expr,
3337 expected: Expectation<'tcx>,
3338 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3339 debug!(">> typechecking: expr={:?} expected={:?}",
3342 // Warn for expressions after diverging siblings.
3343 self.warn_if_unreachable(expr.id, expr.span, "expression");
3345 // Hide the outer diverging and has_errors flags.
3346 let old_diverges = self.diverges.get();
3347 let old_has_errors = self.has_errors.get();
3348 self.diverges.set(Diverges::Maybe);
3349 self.has_errors.set(false);
3351 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3353 // Warn for non-block expressions with diverging children.
3356 hir::ExprLoop(..) | hir::ExprWhile(..) |
3357 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3359 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3362 // Any expression that produces a value of type `!` must have diverged
3364 self.diverges.set(self.diverges.get() | Diverges::Always);
3367 // Record the type, which applies it effects.
3368 // We need to do this after the warning above, so that
3369 // we don't warn for the diverging expression itself.
3370 self.write_ty(expr.id, ty);
3372 // Combine the diverging and has_error flags.
3373 self.diverges.set(self.diverges.get() | old_diverges);
3374 self.has_errors.set(self.has_errors.get() | old_has_errors);
3376 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3377 debug!("... {:?}, expected is {:?}", ty, expected);
3382 fn check_expr_kind(&self,
3383 expr: &'gcx hir::Expr,
3384 expected: Expectation<'tcx>,
3385 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3389 hir::ExprBox(ref subexpr) => {
3390 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3392 ty::TyAdt(def, _) if def.is_box()
3393 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3397 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3398 tcx.mk_box(referent_ty)
3401 hir::ExprLit(ref lit) => {
3402 self.check_lit(&lit, expected)
3404 hir::ExprBinary(op, ref lhs, ref rhs) => {
3405 self.check_binop(expr, op, lhs, rhs)
3407 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3408 self.check_binop_assign(expr, op, lhs, rhs)
3410 hir::ExprUnary(unop, ref oprnd) => {
3411 let expected_inner = match unop {
3412 hir::UnNot | hir::UnNeg => {
3419 let lvalue_pref = match unop {
3420 hir::UnDeref => lvalue_pref,
3423 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3427 if !oprnd_t.references_error() {
3428 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3431 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3433 } else if let Some(ok) = self.try_overloaded_deref(
3434 expr.span, oprnd_t, lvalue_pref) {
3435 let method = self.register_infer_ok_obligations(ok);
3436 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3437 self.apply_adjustments(oprnd, vec![Adjustment {
3438 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
3439 target: method.sig.inputs()[0]
3442 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3443 self.write_method_call(expr.id, method);
3445 self.type_error_message(expr.span, |actual| {
3446 format!("type `{}` cannot be \
3447 dereferenced", actual)
3449 oprnd_t = tcx.types.err;
3453 let result = self.check_user_unop(expr, oprnd_t, unop);
3454 // If it's builtin, we can reuse the type, this helps inference.
3455 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3460 let result = self.check_user_unop(expr, oprnd_t, unop);
3461 // If it's builtin, we can reuse the type, this helps inference.
3462 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3470 hir::ExprAddrOf(mutbl, ref oprnd) => {
3471 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3473 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3474 if self.tcx.expr_is_lval(&oprnd) {
3475 // Lvalues may legitimately have unsized types.
3476 // For example, dereferences of a fat pointer and
3477 // the last field of a struct can be unsized.
3478 ExpectHasType(mt.ty)
3480 Expectation::rvalue_hint(self, mt.ty)
3486 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3487 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3489 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3490 if tm.ty.references_error() {
3493 // Note: at this point, we cannot say what the best lifetime
3494 // is to use for resulting pointer. We want to use the
3495 // shortest lifetime possible so as to avoid spurious borrowck
3496 // errors. Moreover, the longest lifetime will depend on the
3497 // precise details of the value whose address is being taken
3498 // (and how long it is valid), which we don't know yet until type
3499 // inference is complete.
3501 // Therefore, here we simply generate a region variable. The
3502 // region inferencer will then select the ultimate value.
3503 // Finally, borrowck is charged with guaranteeing that the
3504 // value whose address was taken can actually be made to live
3505 // as long as it needs to live.
3506 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3507 tcx.mk_ref(region, tm)
3510 hir::ExprPath(ref qpath) => {
3511 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3512 expr.id, expr.span);
3513 let ty = if def != Def::Err {
3514 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3516 self.set_tainted_by_errors();
3520 // We always require that the type provided as the value for
3521 // a type parameter outlives the moment of instantiation.
3522 let substs = self.tables.borrow().node_substs(expr.id);
3523 self.add_wf_bounds(substs, expr);
3527 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3528 for output in outputs {
3529 self.check_expr(output);
3531 for input in inputs {
3532 self.check_expr(input);
3536 hir::ExprBreak(destination, ref expr_opt) => {
3537 if let Some(target_id) = destination.target_id.opt_id() {
3538 let (e_ty, e_diverges, cause);
3539 if let Some(ref e) = *expr_opt {
3540 // If this is a break with a value, we need to type-check
3541 // the expression. Get an expected type from the loop context.
3542 let opt_coerce_to = {
3543 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3544 enclosing_breakables.find_breakable(target_id)
3547 .map(|coerce| coerce.expected_ty())
3550 // If the loop context is not a `loop { }`, then break with
3551 // a value is illegal, and `opt_coerce_to` will be `None`.
3552 // Just set expectation to error in that case.
3553 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3555 // Recurse without `enclosing_breakables` borrowed.
3556 e_ty = self.check_expr_with_hint(e, coerce_to);
3557 e_diverges = self.diverges.get();
3558 cause = self.misc(e.span);
3560 // Otherwise, this is a break *without* a value. That's
3561 // always legal, and is equivalent to `break ()`.
3562 e_ty = tcx.mk_nil();
3563 e_diverges = Diverges::Maybe;
3564 cause = self.misc(expr.span);
3567 // Now that we have type-checked `expr_opt`, borrow
3568 // the `enclosing_loops` field and let's coerce the
3569 // type of `expr_opt` into what is expected.
3570 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3571 let ctxt = enclosing_breakables.find_breakable(target_id);
3572 if let Some(ref mut coerce) = ctxt.coerce {
3573 if let Some(ref e) = *expr_opt {
3574 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3576 assert!(e_ty.is_nil());
3577 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3580 // If `ctxt.coerce` is `None`, we can just ignore
3581 // the type of the expresison. This is because
3582 // either this was a break *without* a value, in
3583 // which case it is always a legal type (`()`), or
3584 // else an error would have been flagged by the
3585 // `loops` pass for using break with an expression
3586 // where you are not supposed to.
3587 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3590 ctxt.may_break = true;
3592 // Otherwise, we failed to find the enclosing loop;
3593 // this can only happen if the `break` was not
3594 // inside a loop at all, which is caught by the
3595 // loop-checking pass.
3596 assert!(self.tcx.sess.err_count() > 0);
3599 // the type of a `break` is always `!`, since it diverges
3602 hir::ExprAgain(_) => { tcx.types.never }
3603 hir::ExprRet(ref expr_opt) => {
3604 if self.ret_coercion.is_none() {
3605 struct_span_err!(self.tcx.sess, expr.span, E0572,
3606 "return statement outside of function body").emit();
3607 } else if let Some(ref e) = *expr_opt {
3608 self.check_return_expr(e);
3610 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3611 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3612 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3616 hir::ExprAssign(ref lhs, ref rhs) => {
3617 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3620 if !tcx.expr_is_lval(&lhs) {
3622 tcx.sess, expr.span, E0070,
3623 "invalid left-hand side expression")
3626 "left-hand of expression not valid")
3630 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3632 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3634 if lhs_ty.references_error() || rhs_ty.references_error() {
3640 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3641 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3642 expr.span, expected)
3644 hir::ExprWhile(ref cond, ref body, _) => {
3645 let ctxt = BreakableCtxt {
3646 // cannot use break with a value from a while loop
3651 self.with_breakable_ctxt(expr.id, ctxt, || {
3652 self.check_expr_has_type(&cond, tcx.types.bool);
3653 let cond_diverging = self.diverges.get();
3654 self.check_block_no_value(&body);
3656 // We may never reach the body so it diverging means nothing.
3657 self.diverges.set(cond_diverging);
3662 hir::ExprLoop(ref body, _, source) => {
3663 let coerce = match source {
3664 // you can only use break with a value from a normal `loop { }`
3665 hir::LoopSource::Loop => {
3666 let coerce_to = expected.coercion_target_type(self, body.span);
3667 Some(CoerceMany::new(coerce_to))
3670 hir::LoopSource::WhileLet |
3671 hir::LoopSource::ForLoop => {
3676 let ctxt = BreakableCtxt {
3678 may_break: false, // will get updated if/when we find a `break`
3681 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3682 self.check_block_no_value(&body);
3686 // No way to know whether it's diverging because
3687 // of a `break` or an outer `break` or `return.
3688 self.diverges.set(Diverges::Maybe);
3691 // If we permit break with a value, then result type is
3692 // the LUB of the breaks (possibly ! if none); else, it
3693 // is nil. This makes sense because infinite loops
3694 // (which would have type !) are only possible iff we
3695 // permit break with a value [1].
3696 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3697 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3699 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3700 self.check_match(expr, &discrim, arms, expected, match_src)
3702 hir::ExprClosure(capture, ref decl, body_id, _) => {
3703 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3705 hir::ExprBlock(ref body) => {
3706 self.check_block_with_expected(&body, expected)
3708 hir::ExprCall(ref callee, ref args) => {
3709 self.check_call(expr, &callee, args, expected)
3711 hir::ExprMethodCall(name, ref tps, ref args) => {
3712 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3714 hir::ExprCast(ref e, ref t) => {
3715 // Find the type of `e`. Supply hints based on the type we are casting to,
3717 let t_cast = self.to_ty(t);
3718 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3719 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3720 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3721 let diverges = self.diverges.get();
3723 // Eagerly check for some obvious errors.
3724 if t_expr.references_error() || t_cast.references_error() {
3727 // Defer other checks until we're done type checking.
3728 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3729 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3731 deferred_cast_checks.push(cast_check);
3734 Err(ErrorReported) => {
3740 hir::ExprType(ref e, ref t) => {
3741 let typ = self.to_ty(&t);
3742 self.check_expr_eq_type(&e, typ);
3745 hir::ExprArray(ref args) => {
3746 let uty = expected.to_option(self).and_then(|uty| {
3748 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3753 let element_ty = if !args.is_empty() {
3754 let coerce_to = uty.unwrap_or_else(
3755 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3756 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3757 assert_eq!(self.diverges.get(), Diverges::Maybe);
3759 let e_ty = self.check_expr_with_hint(e, coerce_to);
3760 let cause = self.misc(e.span);
3761 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3763 coerce.complete(self)
3765 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3767 tcx.mk_array(element_ty, args.len())
3769 hir::ExprRepeat(ref element, count) => {
3770 let count = eval_length(self.tcx, count, "repeat count")
3773 let uty = match expected {
3774 ExpectHasType(uty) => {
3776 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3783 let (element_ty, t) = match uty {
3785 self.check_expr_coercable_to_type(&element, uty);
3789 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3790 let element_ty = self.check_expr_has_type(&element, t);
3796 // For [foo, ..n] where n > 1, `foo` must have
3798 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3799 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3802 if element_ty.references_error() {
3805 tcx.mk_array(t, count)
3808 hir::ExprTup(ref elts) => {
3809 let flds = expected.only_has_type(self).and_then(|ty| {
3811 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3816 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3817 let t = match flds {
3818 Some(ref fs) if i < fs.len() => {
3820 self.check_expr_coercable_to_type(&e, ety);
3824 self.check_expr_with_expectation(&e, NoExpectation)
3829 let tuple = tcx.mk_tup(elt_ts_iter, false);
3830 if tuple.references_error() {
3836 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3837 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3839 hir::ExprField(ref base, ref field) => {
3840 self.check_field(expr, lvalue_pref, &base, field)
3842 hir::ExprTupField(ref base, idx) => {
3843 self.check_tup_field(expr, lvalue_pref, &base, idx)
3845 hir::ExprIndex(ref base, ref idx) => {
3846 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3847 let idx_t = self.check_expr(&idx);
3849 if base_t.references_error() {
3851 } else if idx_t.references_error() {
3854 let base_t = self.structurally_resolved_type(expr.span, base_t);
3855 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3856 Some((index_ty, element_ty)) => {
3857 self.demand_coerce(idx, idx_t, index_ty);
3861 let mut err = self.type_error_struct(
3864 format!("cannot index a value of type `{}`",
3868 // Try to give some advice about indexing tuples.
3869 if let ty::TyTuple(..) = base_t.sty {
3870 let mut needs_note = true;
3871 // If the index is an integer, we can show the actual
3872 // fixed expression:
3873 if let hir::ExprLit(ref lit) = idx.node {
3874 if let ast::LitKind::Int(i,
3875 ast::LitIntType::Unsuffixed) = lit.node {
3876 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3877 if let Ok(snip) = snip {
3878 err.span_suggestion(expr.span,
3879 "to access tuple elements, use",
3880 format!("{}.{}", snip, i));
3886 err.help("to access tuple elements, use tuple indexing \
3887 syntax (e.g. `tuple.0`)");
3899 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3900 // The newly resolved definition is written into `type_dependent_defs`.
3901 fn finish_resolving_struct_path(&self,
3904 node_id: ast::NodeId)
3908 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3909 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3910 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3913 hir::QPath::TypeRelative(ref qself, ref segment) => {
3914 let ty = self.to_ty(qself);
3916 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3921 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3924 // Write back the new resolution.
3925 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3932 // Resolve associated value path into a base type and associated constant or method definition.
3933 // The newly resolved definition is written into `type_dependent_defs`.
3934 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3935 qpath: &'b hir::QPath,
3936 node_id: ast::NodeId,
3938 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3940 let (ty, item_segment) = match *qpath {
3941 hir::QPath::Resolved(ref opt_qself, ref path) => {
3943 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3944 &path.segments[..]);
3946 hir::QPath::TypeRelative(ref qself, ref segment) => {
3947 (self.to_ty(qself), segment)
3950 let item_name = item_segment.name;
3951 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3954 let def = match error {
3955 method::MethodError::PrivateMatch(def) => def,
3958 if item_name != keywords::Invalid.name() {
3959 self.report_method_error(span, ty, item_name, None, error, None);
3965 // Write back the new resolution.
3966 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3967 (def, Some(ty), slice::ref_slice(&**item_segment))
3970 pub fn check_decl_initializer(&self,
3971 local: &'gcx hir::Local,
3972 init: &'gcx hir::Expr) -> Ty<'tcx>
3974 let ref_bindings = local.pat.contains_ref_binding();
3976 let local_ty = self.local_ty(init.span, local.id);
3977 if let Some(m) = ref_bindings {
3978 // Somewhat subtle: if we have a `ref` binding in the pattern,
3979 // we want to avoid introducing coercions for the RHS. This is
3980 // both because it helps preserve sanity and, in the case of
3981 // ref mut, for soundness (issue #23116). In particular, in
3982 // the latter case, we need to be clear that the type of the
3983 // referent for the reference that results is *equal to* the
3984 // type of the lvalue it is referencing, and not some
3985 // supertype thereof.
3986 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3987 self.demand_eqtype(init.span, init_ty, local_ty);
3990 self.check_expr_coercable_to_type(init, local_ty)
3994 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3995 let t = self.local_ty(local.span, local.id);
3996 self.write_ty(local.id, t);
3998 if let Some(ref init) = local.init {
3999 let init_ty = self.check_decl_initializer(local, &init);
4000 if init_ty.references_error() {
4001 self.write_ty(local.id, init_ty);
4005 self.check_pat(&local.pat, t);
4006 let pat_ty = self.node_ty(local.pat.id);
4007 if pat_ty.references_error() {
4008 self.write_ty(local.id, pat_ty);
4012 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4013 // Don't do all the complex logic below for DeclItem.
4015 hir::StmtDecl(ref decl, _) => {
4017 hir::DeclLocal(_) => {}
4018 hir::DeclItem(_) => {
4023 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4026 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4028 // Hide the outer diverging and has_errors flags.
4029 let old_diverges = self.diverges.get();
4030 let old_has_errors = self.has_errors.get();
4031 self.diverges.set(Diverges::Maybe);
4032 self.has_errors.set(false);
4035 hir::StmtDecl(ref decl, _) => {
4037 hir::DeclLocal(ref l) => {
4038 self.check_decl_local(&l);
4040 hir::DeclItem(_) => {/* ignore for now */}
4043 hir::StmtExpr(ref expr, _) => {
4044 // Check with expected type of ()
4045 self.check_expr_has_type(&expr, self.tcx.mk_nil());
4047 hir::StmtSemi(ref expr, _) => {
4048 self.check_expr(&expr);
4052 // Combine the diverging and has_error flags.
4053 self.diverges.set(self.diverges.get() | old_diverges);
4054 self.has_errors.set(self.has_errors.get() | old_has_errors);
4057 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4058 let unit = self.tcx.mk_nil();
4059 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4061 // if the block produces a `!` value, that can always be
4062 // (effectively) coerced to unit.
4064 self.demand_suptype(blk.span, unit, ty);
4068 fn check_block_with_expected(&self,
4069 blk: &'gcx hir::Block,
4070 expected: Expectation<'tcx>) -> Ty<'tcx> {
4072 let mut fcx_ps = self.ps.borrow_mut();
4073 let unsafety_state = fcx_ps.recurse(blk);
4074 replace(&mut *fcx_ps, unsafety_state)
4077 // In some cases, blocks have just one exit, but other blocks
4078 // can be targeted by multiple breaks. This cannot happen in
4079 // normal Rust syntax today, but it can happen when we desugar
4080 // a `do catch { ... }` expression.
4084 // 'a: { if true { break 'a Err(()); } Ok(()) }
4086 // Here we would wind up with two coercions, one from
4087 // `Err(())` and the other from the tail expression
4088 // `Ok(())`. If the tail expression is omitted, that's a
4089 // "forced unit" -- unless the block diverges, in which
4090 // case we can ignore the tail expression (e.g., `'a: {
4091 // break 'a 22; }` would not force the type of the block
4093 let tail_expr = blk.expr.as_ref();
4094 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4095 let coerce = if blk.targeted_by_break {
4096 CoerceMany::new(coerce_to_ty)
4098 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4099 Some(e) => ref_slice(e),
4102 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4105 let ctxt = BreakableCtxt {
4106 coerce: Some(coerce),
4110 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4111 for s in &blk.stmts {
4115 // check the tail expression **without** holding the
4116 // `enclosing_breakables` lock below.
4117 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4119 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4120 let mut ctxt = enclosing_breakables.find_breakable(blk.id);
4121 let mut coerce = ctxt.coerce.as_mut().unwrap();
4122 if let Some(tail_expr_ty) = tail_expr_ty {
4123 let tail_expr = tail_expr.unwrap();
4125 &self.misc(tail_expr.span),
4128 self.diverges.get());
4130 // Subtle: if there is no explicit tail expression,
4131 // that is typically equivalent to a tail expression
4132 // of `()` -- except if the block diverges. In that
4133 // case, there is no value supplied from the tail
4134 // expression (assuming there are no other breaks,
4135 // this implies that the type of the block will be
4138 // #41425 -- label the implicit `()` as being the
4139 // "found type" here, rather than the "expected type".
4140 if !self.diverges.get().always() {
4141 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4142 if let Some(expected_ty) = expected.only_has_type(self) {
4143 self.consider_hint_about_removing_semicolon(blk,
4152 let mut ty = ctxt.coerce.unwrap().complete(self);
4154 if self.has_errors.get() || ty.references_error() {
4155 ty = self.tcx.types.err
4158 self.write_ty(blk.id, ty);
4160 *self.ps.borrow_mut() = prev;
4164 /// A common error is to add an extra semicolon:
4167 /// fn foo() -> usize {
4172 /// This routine checks if the final statement in a block is an
4173 /// expression with an explicit semicolon whose type is compatible
4174 /// with `expected_ty`. If so, it suggests removing the semicolon.
4175 fn consider_hint_about_removing_semicolon(&self,
4176 blk: &'gcx hir::Block,
4177 expected_ty: Ty<'tcx>,
4178 err: &mut DiagnosticBuilder) {
4179 // Be helpful when the user wrote `{... expr;}` and
4180 // taking the `;` off is enough to fix the error.
4181 let last_stmt = match blk.stmts.last() {
4185 let last_expr = match last_stmt.node {
4186 hir::StmtSemi(ref e, _) => e,
4189 let last_expr_ty = self.node_ty(last_expr.id);
4190 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4193 let original_span = original_sp(last_stmt.span, blk.span);
4194 let span_semi = Span {
4195 lo: original_span.hi - BytePos(1),
4196 hi: original_span.hi,
4197 ctxt: original_span.ctxt,
4199 err.span_help(span_semi, "consider removing this semicolon:");
4202 // Instantiates the given path, which must refer to an item with the given
4203 // number of type parameters and type.
4204 pub fn instantiate_value_path(&self,
4205 segments: &[hir::PathSegment],
4206 opt_self_ty: Option<Ty<'tcx>>,
4209 node_id: ast::NodeId)
4211 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4216 // We need to extract the type parameters supplied by the user in
4217 // the path `path`. Due to the current setup, this is a bit of a
4218 // tricky-process; the problem is that resolve only tells us the
4219 // end-point of the path resolution, and not the intermediate steps.
4220 // Luckily, we can (at least for now) deduce the intermediate steps
4221 // just from the end-point.
4223 // There are basically four cases to consider:
4225 // 1. Reference to a constructor of enum variant or struct:
4227 // struct Foo<T>(...)
4228 // enum E<T> { Foo(...) }
4230 // In these cases, the parameters are declared in the type
4233 // 2. Reference to a fn item or a free constant:
4237 // In this case, the path will again always have the form
4238 // `a::b::foo::<T>` where only the final segment should have
4239 // type parameters. However, in this case, those parameters are
4240 // declared on a value, and hence are in the `FnSpace`.
4242 // 3. Reference to a method or an associated constant:
4244 // impl<A> SomeStruct<A> {
4248 // Here we can have a path like
4249 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4250 // may appear in two places. The penultimate segment,
4251 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4252 // final segment, `foo::<B>` contains parameters in fn space.
4254 // 4. Reference to a local variable
4256 // Local variables can't have any type parameters.
4258 // The first step then is to categorize the segments appropriately.
4260 assert!(!segments.is_empty());
4262 let mut ufcs_associated = None;
4263 let mut type_segment = None;
4264 let mut fn_segment = None;
4266 // Case 1. Reference to a struct/variant constructor.
4267 Def::StructCtor(def_id, ..) |
4268 Def::VariantCtor(def_id, ..) => {
4269 // Everything but the final segment should have no
4270 // parameters at all.
4271 let mut generics = self.tcx.generics_of(def_id);
4272 if let Some(def_id) = generics.parent {
4273 // Variant and struct constructors use the
4274 // generics of their parent type definition.
4275 generics = self.tcx.generics_of(def_id);
4277 type_segment = Some((segments.last().unwrap(), generics));
4280 // Case 2. Reference to a top-level value.
4282 Def::Const(def_id) |
4283 Def::Static(def_id, _) => {
4284 fn_segment = Some((segments.last().unwrap(),
4285 self.tcx.generics_of(def_id)));
4288 // Case 3. Reference to a method or associated const.
4289 Def::Method(def_id) |
4290 Def::AssociatedConst(def_id) => {
4291 let container = self.tcx.associated_item(def_id).container;
4293 ty::TraitContainer(trait_did) => {
4294 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4296 ty::ImplContainer(_) => {}
4299 let generics = self.tcx.generics_of(def_id);
4300 if segments.len() >= 2 {
4301 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4302 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4304 // `<T>::assoc` will end up here, and so can `T::assoc`.
4305 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4306 ufcs_associated = Some((container, self_ty));
4308 fn_segment = Some((segments.last().unwrap(), generics));
4311 // Case 4. Local variable, no generics.
4312 Def::Local(..) | Def::Upvar(..) => {}
4314 _ => bug!("unexpected definition: {:?}", def),
4317 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4319 // Now that we have categorized what space the parameters for each
4320 // segment belong to, let's sort out the parameters that the user
4321 // provided (if any) into their appropriate spaces. We'll also report
4322 // errors if type parameters are provided in an inappropriate place.
4323 let poly_segments = type_segment.is_some() as usize +
4324 fn_segment.is_some() as usize;
4325 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4328 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4329 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4330 let ty = self.local_ty(span, nid);
4331 let ty = self.normalize_associated_types_in(span, &ty);
4332 self.write_ty(node_id, ty);
4338 // Now we have to compare the types that the user *actually*
4339 // provided against the types that were *expected*. If the user
4340 // did not provide any types, then we want to substitute inference
4341 // variables. If the user provided some types, we may still need
4342 // to add defaults. If the user provided *too many* types, that's
4344 self.check_path_parameter_count(span, &mut type_segment);
4345 self.check_path_parameter_count(span, &mut fn_segment);
4347 let (fn_start, has_self) = match (type_segment, fn_segment) {
4348 (_, Some((_, generics))) => {
4349 (generics.parent_count(), generics.has_self)
4351 (Some((_, generics)), None) => {
4352 (generics.own_count(), generics.has_self)
4354 (None, None) => (0, false)
4356 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4357 let mut i = def.index as usize;
4359 let segment = if i < fn_start {
4360 i -= has_self as usize;
4366 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4367 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4368 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4372 if let Some(lifetime) = lifetimes.get(i) {
4373 AstConv::ast_region_to_region(self, lifetime, Some(def))
4375 self.re_infer(span, Some(def)).unwrap()
4378 let mut i = def.index as usize;
4380 let segment = if i < fn_start {
4381 // Handle Self first, so we can adjust the index to match the AST.
4382 if has_self && i == 0 {
4383 return opt_self_ty.unwrap_or_else(|| {
4384 self.type_var_for_def(span, def, substs)
4387 i -= has_self as usize;
4393 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4394 Some(&hir::AngleBracketedParameters(ref data)) => {
4395 (&data.types[..], data.infer_types)
4397 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4398 None => (&[][..], true)
4401 // Skip over the lifetimes in the same segment.
4402 if let Some((_, generics)) = segment {
4403 i -= generics.regions.len();
4406 if let Some(ast_ty) = types.get(i) {
4407 // A provided type parameter.
4409 } else if !infer_types && def.has_default {
4410 // No type parameter provided, but a default exists.
4411 let default = self.tcx.type_of(def.def_id);
4414 default.subst_spanned(self.tcx, substs, Some(span))
4417 // No type parameters were provided, we can infer all.
4418 // This can also be reached in some error cases:
4419 // We prefer to use inference variables instead of
4420 // TyError to let type inference recover somewhat.
4421 self.type_var_for_def(span, def, substs)
4425 // The things we are substituting into the type should not contain
4426 // escaping late-bound regions, and nor should the base type scheme.
4427 let ty = self.tcx.type_of(def.def_id());
4428 assert!(!substs.has_escaping_regions());
4429 assert!(!ty.has_escaping_regions());
4431 // Add all the obligations that are required, substituting and
4432 // normalized appropriately.
4433 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4434 self.add_obligations_for_parameters(
4435 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4438 // Substitute the values for the type parameters into the type of
4439 // the referenced item.
4440 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4442 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4443 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4444 // is inherent, there is no `Self` parameter, instead, the impl needs
4445 // type parameters, which we can infer by unifying the provided `Self`
4446 // with the substituted impl type.
4447 let ty = self.tcx.type_of(impl_def_id);
4449 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4450 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4451 Ok(ok) => self.register_infer_ok_obligations(ok),
4454 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4461 debug!("instantiate_value_path: type of {:?} is {:?}",
4464 self.write_substs(node_id, substs);
4468 /// Report errors if the provided parameters are too few or too many.
4469 fn check_path_parameter_count(&self,
4471 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4472 let (lifetimes, types, infer_types, bindings) = {
4473 match segment.map(|(s, _)| &s.parameters) {
4474 Some(&hir::AngleBracketedParameters(ref data)) => {
4475 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4477 Some(&hir::ParenthesizedParameters(_)) => {
4478 AstConv::prohibit_parenthesized_params(self, &segment.as_ref().unwrap().0,
4480 (&[][..], &[][..], true, &[][..])
4482 None => (&[][..], &[][..], true, &[][..])
4486 let count_lifetime_params = |n| {
4487 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4489 let count_type_params = |n| {
4490 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4493 // Check provided lifetime parameters.
4494 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4495 if lifetimes.len() > lifetime_defs.len() {
4496 let expected_text = count_lifetime_params(lifetime_defs.len());
4497 let actual_text = count_lifetime_params(lifetimes.len());
4498 struct_span_err!(self.tcx.sess, span, E0088,
4499 "too many lifetime parameters provided: \
4500 expected at most {}, found {}",
4501 expected_text, actual_text)
4502 .span_label(span, format!("expected {}", expected_text))
4504 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4505 let expected_text = count_lifetime_params(lifetime_defs.len());
4506 let actual_text = count_lifetime_params(lifetimes.len());
4507 struct_span_err!(self.tcx.sess, span, E0090,
4508 "too few lifetime parameters provided: \
4509 expected {}, found {}",
4510 expected_text, actual_text)
4511 .span_label(span, format!("expected {}", expected_text))
4515 // The case where there is not enough lifetime parameters is not checked,
4516 // because this is not possible - a function never takes lifetime parameters.
4517 // See discussion for Pull Request 36208.
4519 // Check provided type parameters.
4520 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4521 if generics.parent.is_none() {
4522 &generics.types[generics.has_self as usize..]
4527 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4528 if types.len() > type_defs.len() {
4529 let span = types[type_defs.len()].span;
4530 let expected_text = count_type_params(type_defs.len());
4531 let actual_text = count_type_params(types.len());
4532 struct_span_err!(self.tcx.sess, span, E0087,
4533 "too many type parameters provided: \
4534 expected at most {}, found {}",
4535 expected_text, actual_text)
4536 .span_label(span, format!("expected {}", expected_text))
4539 // To prevent derived errors to accumulate due to extra
4540 // type parameters, we force instantiate_value_path to
4541 // use inference variables instead of the provided types.
4543 } else if !infer_types && types.len() < required_len {
4544 let expected_text = count_type_params(required_len);
4545 let actual_text = count_type_params(types.len());
4546 struct_span_err!(self.tcx.sess, span, E0089,
4547 "too few type parameters provided: \
4548 expected {}, found {}",
4549 expected_text, actual_text)
4550 .span_label(span, format!("expected {}", expected_text))
4554 if !bindings.is_empty() {
4555 span_err!(self.tcx.sess, bindings[0].span, E0182,
4556 "unexpected binding of associated item in expression path \
4557 (only allowed in type paths)");
4561 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4563 where F: Fn() -> Ty<'tcx>
4565 let mut ty = self.resolve_type_vars_with_obligations(ty);
4568 let alternative = f();
4571 if alternative.is_ty_var() || alternative.references_error() {
4572 if !self.is_tainted_by_errors() {
4573 self.type_error_message(sp, |_actual| {
4574 "the type of this value must be known in this context".to_string()
4577 self.demand_suptype(sp, self.tcx.types.err, ty);
4578 ty = self.tcx.types.err;
4580 self.demand_suptype(sp, alternative, ty);
4588 // Resolves `typ` by a single level if `typ` is a type variable. If no
4589 // resolution is possible, then an error is reported.
4590 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4591 self.structurally_resolve_type_or_else(sp, ty, || {
4596 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4597 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4598 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4601 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4602 index = enclosing_breakables.stack.len();
4603 enclosing_breakables.by_id.insert(id, index);
4604 enclosing_breakables.stack.push(ctxt);
4608 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4609 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4610 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4611 enclosing_breakables.stack.pop().expect("missing breakable context")
4617 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4618 generics: &hir::Generics,
4620 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4621 generics.ty_params.len(), ty);
4623 // make a vector of booleans initially false, set to true when used
4624 if generics.ty_params.is_empty() { return; }
4625 let mut tps_used = vec![false; generics.ty_params.len()];
4627 for leaf_ty in ty.walk() {
4628 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4629 debug!("Found use of ty param num {}", idx);
4630 tps_used[idx as usize - generics.lifetimes.len()] = true;
4634 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4636 struct_span_err!(tcx.sess, param.span, E0091,
4637 "type parameter `{}` is unused",
4639 .span_label(param.span, "unused type parameter")