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 = type_error_struct!(self.tcx().sess, field.span, expr_t, E0609,
2925 "no field `{}` on type `{}`",
2926 field.node, expr_t);
2928 ty::TyAdt(def, _) if !def.is_enum() => {
2929 if let Some(suggested_field_name) =
2930 Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2931 err.span_label(field.span,
2932 format!("did you mean `{}`?", suggested_field_name));
2934 err.span_label(field.span,
2938 ty::TyRawPtr(..) => {
2939 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2941 self.tcx.hir.node_to_pretty_string(base.id),
2947 self.tcx().types.err
2951 // Return an hint about the closest match in field names
2952 fn suggest_field_name(variant: &'tcx ty::VariantDef,
2953 field: &Spanned<ast::Name>,
2954 skip : Vec<InternedString>)
2956 let name = field.node.as_str();
2957 let names = variant.fields.iter().filter_map(|field| {
2958 // ignore already set fields and private fields from non-local crates
2959 if skip.iter().any(|x| *x == field.name.as_str()) ||
2960 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2967 // only find fits with at least one matching letter
2968 find_best_match_for_name(names, &name, Some(name.len()))
2971 // Check tuple index expressions
2972 fn check_tup_field(&self,
2973 expr: &'gcx hir::Expr,
2974 lvalue_pref: LvaluePreference,
2975 base: &'gcx hir::Expr,
2976 idx: codemap::Spanned<usize>) -> Ty<'tcx> {
2977 let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
2978 let expr_t = self.structurally_resolved_type(expr.span,
2980 let mut private_candidate = None;
2981 let mut tuple_like = false;
2982 let mut autoderef = self.autoderef(expr.span, expr_t);
2983 while let Some((base_t, _)) = autoderef.next() {
2984 let field = match base_t.sty {
2985 ty::TyAdt(base_def, substs) if base_def.is_struct() => {
2986 tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
2987 if !tuple_like { continue }
2989 debug!("tuple struct named {:?}", base_t);
2990 let ident = ast::Ident {
2991 name: Symbol::intern(&idx.node.to_string()),
2992 ctxt: idx.span.ctxt.modern(),
2994 let (ident, def_scope) =
2995 self.tcx.adjust_ident(ident, base_def.did, self.body_id);
2996 let fields = &base_def.struct_variant().fields;
2997 if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
2998 let field_ty = self.field_ty(expr.span, field, substs);
2999 if field.vis.is_accessible_from(def_scope, self.tcx) {
3000 self.tcx.check_stability(field.did, expr.id, expr.span);
3003 private_candidate = Some((base_def.did, field_ty));
3010 ty::TyTuple(ref v, _) => {
3012 v.get(idx.node).cloned()
3017 if let Some(field_ty) = field {
3018 let adjustments = autoderef.adjust_steps(lvalue_pref);
3019 self.apply_adjustments(base, adjustments);
3020 autoderef.finalize();
3024 autoderef.unambiguous_final_ty();
3026 if let Some((did, field_ty)) = private_candidate {
3027 let struct_path = self.tcx().item_path_str(did);
3028 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3029 self.tcx().sess.span_err(expr.span, &msg);
3033 self.type_error_message(
3037 format!("attempted out-of-bounds tuple index `{}` on \
3042 format!("attempted tuple index `{}` on type `{}`, but the \
3043 type was not a tuple or tuple struct",
3050 self.tcx().types.err
3053 fn report_unknown_field(&self,
3055 variant: &'tcx ty::VariantDef,
3057 skip_fields: &[hir::Field],
3059 let mut err = self.type_error_struct_with_diag(
3061 |actual| match ty.sty {
3062 ty::TyAdt(adt, ..) if adt.is_enum() => {
3063 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3064 "{} `{}::{}` has no field named `{}`",
3065 kind_name, actual, variant.name, field.name.node)
3068 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3069 "{} `{}` has no field named `{}`",
3070 kind_name, actual, field.name.node)
3074 // prevent all specified fields from being suggested
3075 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3076 if let Some(field_name) = Self::suggest_field_name(variant,
3078 skip_fields.collect()) {
3079 err.span_label(field.name.span,
3080 format!("field does not exist - did you mean `{}`?", field_name));
3083 ty::TyAdt(adt, ..) if adt.is_enum() => {
3084 err.span_label(field.name.span, format!("`{}::{}` does not have this field",
3088 err.span_label(field.name.span, format!("`{}` does not have this field", ty));
3095 fn check_expr_struct_fields(&self,
3097 expected: Expectation<'tcx>,
3098 expr_id: ast::NodeId,
3100 variant: &'tcx ty::VariantDef,
3101 ast_fields: &'gcx [hir::Field],
3102 check_completeness: bool) {
3106 self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
3107 .get(0).cloned().unwrap_or(adt_ty);
3109 let (substs, hint_substs, adt_kind, kind_name) = match (&adt_ty.sty, &adt_ty_hint.sty) {
3110 (&ty::TyAdt(adt, substs), &ty::TyAdt(_, hint_substs)) => {
3111 (substs, hint_substs, adt.adt_kind(), adt.variant_descr())
3113 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3116 let mut remaining_fields = FxHashMap();
3117 for field in &variant.fields {
3118 remaining_fields.insert(field.name.to_ident(), field);
3121 let mut seen_fields = FxHashMap();
3123 let mut error_happened = false;
3125 // Typecheck each field.
3126 for field in ast_fields {
3127 let final_field_type;
3128 let field_type_hint;
3130 let ident = tcx.adjust(field.name.node, variant.did, self.body_id).0;
3131 if let Some(v_field) = remaining_fields.remove(&ident) {
3132 final_field_type = self.field_ty(field.span, v_field, substs);
3133 field_type_hint = self.field_ty(field.span, v_field, hint_substs);
3135 seen_fields.insert(field.name.node, field.span);
3137 // we don't look at stability attributes on
3138 // struct-like enums (yet...), but it's definitely not
3139 // a bug to have construct one.
3140 if adt_kind != ty::AdtKind::Enum {
3141 tcx.check_stability(v_field.did, expr_id, field.span);
3144 error_happened = true;
3145 final_field_type = tcx.types.err;
3146 field_type_hint = tcx.types.err;
3147 if let Some(_) = variant.find_field_named(field.name.node) {
3148 let mut err = struct_span_err!(self.tcx.sess,
3151 "field `{}` specified more than once",
3154 err.span_label(field.name.span, "used more than once");
3156 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3157 err.span_label(*prev_span, format!("first use of `{}`", field.name.node));
3162 self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name);
3166 // Make sure to give a type to the field even if there's
3167 // an error, so we can continue typechecking
3168 let ty = self.check_expr_with_hint(&field.expr, field_type_hint);
3169 self.demand_coerce(&field.expr, ty, final_field_type);
3172 // Make sure the programmer specified correct number of fields.
3173 if kind_name == "union" {
3174 if ast_fields.len() != 1 {
3175 tcx.sess.span_err(span, "union expressions should have exactly one field");
3177 } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
3178 let len = remaining_fields.len();
3180 let mut displayable_field_names = remaining_fields
3182 .map(|ident| ident.name.as_str())
3183 .collect::<Vec<_>>();
3185 displayable_field_names.sort();
3187 let truncated_fields_error = if len <= 3 {
3190 format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
3193 let remaining_fields_names = displayable_field_names.iter().take(3)
3194 .map(|n| format!("`{}`", n))
3195 .collect::<Vec<_>>()
3198 struct_span_err!(tcx.sess, span, E0063,
3199 "missing field{} {}{} in initializer of `{}`",
3200 if remaining_fields.len() == 1 {""} else {"s"},
3201 remaining_fields_names,
3202 truncated_fields_error,
3204 .span_label(span, format!("missing {}{}",
3205 remaining_fields_names,
3206 truncated_fields_error))
3211 fn check_struct_fields_on_error(&self,
3212 fields: &'gcx [hir::Field],
3213 base_expr: &'gcx Option<P<hir::Expr>>) {
3214 for field in fields {
3215 self.check_expr(&field.expr);
3219 self.check_expr(&base);
3225 pub fn check_struct_path(&self,
3227 node_id: ast::NodeId)
3228 -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
3229 let path_span = match *qpath {
3230 hir::QPath::Resolved(_, ref path) => path.span,
3231 hir::QPath::TypeRelative(ref qself, _) => qself.span
3233 let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id);
3234 let variant = match def {
3236 self.set_tainted_by_errors();
3239 Def::Variant(..) => {
3241 ty::TyAdt(adt, substs) => {
3242 Some((adt.variant_of_def(def), adt.did, substs))
3244 _ => bug!("unexpected type: {:?}", ty.sty)
3247 Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3248 Def::AssociatedTy(..) | Def::SelfTy(..) => {
3250 ty::TyAdt(adt, substs) if !adt.is_enum() => {
3251 Some((adt.struct_variant(), adt.did, substs))
3256 _ => bug!("unexpected definition: {:?}", def)
3259 if let Some((variant, did, substs)) = variant {
3260 // Check bounds on type arguments used in the path.
3261 let bounds = self.instantiate_bounds(path_span, did, substs);
3262 let cause = traits::ObligationCause::new(path_span, self.body_id,
3263 traits::ItemObligation(did));
3264 self.add_obligations_for_parameters(cause, &bounds);
3268 struct_span_err!(self.tcx.sess, path_span, E0071,
3269 "expected struct, variant or union type, found {}",
3270 ty.sort_string(self.tcx))
3271 .span_label(path_span, "not a struct")
3277 fn check_expr_struct(&self,
3279 expected: Expectation<'tcx>,
3281 fields: &'gcx [hir::Field],
3282 base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
3284 // Find the relevant variant
3285 let (variant, struct_ty) =
3286 if let Some(variant_ty) = self.check_struct_path(qpath, expr.id) {
3289 self.check_struct_fields_on_error(fields, base_expr);
3290 return self.tcx.types.err;
3293 let path_span = match *qpath {
3294 hir::QPath::Resolved(_, ref path) => path.span,
3295 hir::QPath::TypeRelative(ref qself, _) => qself.span
3298 self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
3299 base_expr.is_none());
3300 if let &Some(ref base_expr) = base_expr {
3301 self.check_expr_has_type(base_expr, struct_ty);
3302 match struct_ty.sty {
3303 ty::TyAdt(adt, substs) if adt.is_struct() => {
3304 self.tables.borrow_mut().fru_field_types.insert(
3306 adt.struct_variant().fields.iter().map(|f| {
3307 self.normalize_associated_types_in(
3308 expr.span, &f.ty(self.tcx, substs)
3314 span_err!(self.tcx.sess, base_expr.span, E0436,
3315 "functional record update syntax requires a struct");
3319 self.require_type_is_sized(struct_ty, expr.span, traits::StructInitializerSized);
3325 /// If an expression has any sub-expressions that result in a type error,
3326 /// inspecting that expression's type with `ty.references_error()` will return
3327 /// true. Likewise, if an expression is known to diverge, inspecting its
3328 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3329 /// strict, _|_ can appear in the type of an expression that does not,
3330 /// itself, diverge: for example, fn() -> _|_.)
3331 /// Note that inspecting a type's structure *directly* may expose the fact
3332 /// that there are actually multiple representations for `TyError`, so avoid
3333 /// that when err needs to be handled differently.
3334 fn check_expr_with_expectation_and_lvalue_pref(&self,
3335 expr: &'gcx hir::Expr,
3336 expected: Expectation<'tcx>,
3337 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3338 debug!(">> typechecking: expr={:?} expected={:?}",
3341 // Warn for expressions after diverging siblings.
3342 self.warn_if_unreachable(expr.id, expr.span, "expression");
3344 // Hide the outer diverging and has_errors flags.
3345 let old_diverges = self.diverges.get();
3346 let old_has_errors = self.has_errors.get();
3347 self.diverges.set(Diverges::Maybe);
3348 self.has_errors.set(false);
3350 let ty = self.check_expr_kind(expr, expected, lvalue_pref);
3352 // Warn for non-block expressions with diverging children.
3355 hir::ExprLoop(..) | hir::ExprWhile(..) |
3356 hir::ExprIf(..) | hir::ExprMatch(..) => {}
3358 _ => self.warn_if_unreachable(expr.id, expr.span, "expression")
3361 // Any expression that produces a value of type `!` must have diverged
3363 self.diverges.set(self.diverges.get() | Diverges::Always);
3366 // Record the type, which applies it effects.
3367 // We need to do this after the warning above, so that
3368 // we don't warn for the diverging expression itself.
3369 self.write_ty(expr.id, ty);
3371 // Combine the diverging and has_error flags.
3372 self.diverges.set(self.diverges.get() | old_diverges);
3373 self.has_errors.set(self.has_errors.get() | old_has_errors);
3375 debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id));
3376 debug!("... {:?}, expected is {:?}", ty, expected);
3381 fn check_expr_kind(&self,
3382 expr: &'gcx hir::Expr,
3383 expected: Expectation<'tcx>,
3384 lvalue_pref: LvaluePreference) -> Ty<'tcx> {
3388 hir::ExprBox(ref subexpr) => {
3389 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3391 ty::TyAdt(def, _) if def.is_box()
3392 => Expectation::rvalue_hint(self, ty.boxed_ty()),
3396 let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
3397 tcx.mk_box(referent_ty)
3400 hir::ExprLit(ref lit) => {
3401 self.check_lit(&lit, expected)
3403 hir::ExprBinary(op, ref lhs, ref rhs) => {
3404 self.check_binop(expr, op, lhs, rhs)
3406 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3407 self.check_binop_assign(expr, op, lhs, rhs)
3409 hir::ExprUnary(unop, ref oprnd) => {
3410 let expected_inner = match unop {
3411 hir::UnNot | hir::UnNeg => {
3418 let lvalue_pref = match unop {
3419 hir::UnDeref => lvalue_pref,
3422 let mut oprnd_t = self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3426 if !oprnd_t.references_error() {
3427 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3430 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3432 } else if let Some(ok) = self.try_overloaded_deref(
3433 expr.span, oprnd_t, lvalue_pref) {
3434 let method = self.register_infer_ok_obligations(ok);
3435 if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
3436 self.apply_adjustments(oprnd, vec![Adjustment {
3437 kind: Adjust::Borrow(AutoBorrow::Ref(region, mt.mutbl)),
3438 target: method.sig.inputs()[0]
3441 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3442 self.write_method_call(expr.id, method);
3444 self.type_error_message(expr.span, |actual| {
3445 format!("type `{}` cannot be \
3446 dereferenced", actual)
3448 oprnd_t = tcx.types.err;
3452 let result = self.check_user_unop(expr, oprnd_t, unop);
3453 // If it's builtin, we can reuse the type, this helps inference.
3454 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3459 let result = self.check_user_unop(expr, oprnd_t, unop);
3460 // If it's builtin, we can reuse the type, this helps inference.
3461 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3469 hir::ExprAddrOf(mutbl, ref oprnd) => {
3470 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3472 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3473 if self.tcx.expr_is_lval(&oprnd) {
3474 // Lvalues may legitimately have unsized types.
3475 // For example, dereferences of a fat pointer and
3476 // the last field of a struct can be unsized.
3477 ExpectHasType(mt.ty)
3479 Expectation::rvalue_hint(self, mt.ty)
3485 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3486 let ty = self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3488 let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
3489 if tm.ty.references_error() {
3492 // Note: at this point, we cannot say what the best lifetime
3493 // is to use for resulting pointer. We want to use the
3494 // shortest lifetime possible so as to avoid spurious borrowck
3495 // errors. Moreover, the longest lifetime will depend on the
3496 // precise details of the value whose address is being taken
3497 // (and how long it is valid), which we don't know yet until type
3498 // inference is complete.
3500 // Therefore, here we simply generate a region variable. The
3501 // region inferencer will then select the ultimate value.
3502 // Finally, borrowck is charged with guaranteeing that the
3503 // value whose address was taken can actually be made to live
3504 // as long as it needs to live.
3505 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3506 tcx.mk_ref(region, tm)
3509 hir::ExprPath(ref qpath) => {
3510 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath,
3511 expr.id, expr.span);
3512 let ty = if def != Def::Err {
3513 self.instantiate_value_path(segments, opt_ty, def, expr.span, id)
3515 self.set_tainted_by_errors();
3519 // We always require that the type provided as the value for
3520 // a type parameter outlives the moment of instantiation.
3521 let substs = self.tables.borrow().node_substs(expr.id);
3522 self.add_wf_bounds(substs, expr);
3526 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3527 for output in outputs {
3528 self.check_expr(output);
3530 for input in inputs {
3531 self.check_expr(input);
3535 hir::ExprBreak(destination, ref expr_opt) => {
3536 if let Some(target_id) = destination.target_id.opt_id() {
3537 let (e_ty, e_diverges, cause);
3538 if let Some(ref e) = *expr_opt {
3539 // If this is a break with a value, we need to type-check
3540 // the expression. Get an expected type from the loop context.
3541 let opt_coerce_to = {
3542 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3543 enclosing_breakables.find_breakable(target_id)
3546 .map(|coerce| coerce.expected_ty())
3549 // If the loop context is not a `loop { }`, then break with
3550 // a value is illegal, and `opt_coerce_to` will be `None`.
3551 // Just set expectation to error in that case.
3552 let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err);
3554 // Recurse without `enclosing_breakables` borrowed.
3555 e_ty = self.check_expr_with_hint(e, coerce_to);
3556 e_diverges = self.diverges.get();
3557 cause = self.misc(e.span);
3559 // Otherwise, this is a break *without* a value. That's
3560 // always legal, and is equivalent to `break ()`.
3561 e_ty = tcx.mk_nil();
3562 e_diverges = Diverges::Maybe;
3563 cause = self.misc(expr.span);
3566 // Now that we have type-checked `expr_opt`, borrow
3567 // the `enclosing_loops` field and let's coerce the
3568 // type of `expr_opt` into what is expected.
3569 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
3570 let ctxt = enclosing_breakables.find_breakable(target_id);
3571 if let Some(ref mut coerce) = ctxt.coerce {
3572 if let Some(ref e) = *expr_opt {
3573 coerce.coerce(self, &cause, e, e_ty, e_diverges);
3575 assert!(e_ty.is_nil());
3576 coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
3579 // If `ctxt.coerce` is `None`, we can just ignore
3580 // the type of the expresison. This is because
3581 // either this was a break *without* a value, in
3582 // which case it is always a legal type (`()`), or
3583 // else an error would have been flagged by the
3584 // `loops` pass for using break with an expression
3585 // where you are not supposed to.
3586 assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
3589 ctxt.may_break = true;
3591 // Otherwise, we failed to find the enclosing loop;
3592 // this can only happen if the `break` was not
3593 // inside a loop at all, which is caught by the
3594 // loop-checking pass.
3595 assert!(self.tcx.sess.err_count() > 0);
3598 // the type of a `break` is always `!`, since it diverges
3601 hir::ExprAgain(_) => { tcx.types.never }
3602 hir::ExprRet(ref expr_opt) => {
3603 if self.ret_coercion.is_none() {
3604 struct_span_err!(self.tcx.sess, expr.span, E0572,
3605 "return statement outside of function body").emit();
3606 } else if let Some(ref e) = *expr_opt {
3607 self.check_return_expr(e);
3609 let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
3610 let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
3611 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
3615 hir::ExprAssign(ref lhs, ref rhs) => {
3616 let lhs_ty = self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3619 if !tcx.expr_is_lval(&lhs) {
3621 tcx.sess, expr.span, E0070,
3622 "invalid left-hand side expression")
3625 "left-hand of expression not valid")
3629 let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3631 self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
3633 if lhs_ty.references_error() || rhs_ty.references_error() {
3639 hir::ExprIf(ref cond, ref then_expr, ref opt_else_expr) => {
3640 self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e),
3641 expr.span, expected)
3643 hir::ExprWhile(ref cond, ref body, _) => {
3644 let ctxt = BreakableCtxt {
3645 // cannot use break with a value from a while loop
3650 self.with_breakable_ctxt(expr.id, ctxt, || {
3651 self.check_expr_has_type(&cond, tcx.types.bool);
3652 let cond_diverging = self.diverges.get();
3653 self.check_block_no_value(&body);
3655 // We may never reach the body so it diverging means nothing.
3656 self.diverges.set(cond_diverging);
3661 hir::ExprLoop(ref body, _, source) => {
3662 let coerce = match source {
3663 // you can only use break with a value from a normal `loop { }`
3664 hir::LoopSource::Loop => {
3665 let coerce_to = expected.coercion_target_type(self, body.span);
3666 Some(CoerceMany::new(coerce_to))
3669 hir::LoopSource::WhileLet |
3670 hir::LoopSource::ForLoop => {
3675 let ctxt = BreakableCtxt {
3677 may_break: false, // will get updated if/when we find a `break`
3680 let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
3681 self.check_block_no_value(&body);
3685 // No way to know whether it's diverging because
3686 // of a `break` or an outer `break` or `return.
3687 self.diverges.set(Diverges::Maybe);
3690 // If we permit break with a value, then result type is
3691 // the LUB of the breaks (possibly ! if none); else, it
3692 // is nil. This makes sense because infinite loops
3693 // (which would have type !) are only possible iff we
3694 // permit break with a value [1].
3695 assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
3696 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
3698 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3699 self.check_match(expr, &discrim, arms, expected, match_src)
3701 hir::ExprClosure(capture, ref decl, body_id, _) => {
3702 self.check_expr_closure(expr, capture, &decl, body_id, expected)
3704 hir::ExprBlock(ref body) => {
3705 self.check_block_with_expected(&body, expected)
3707 hir::ExprCall(ref callee, ref args) => {
3708 self.check_call(expr, &callee, args, expected)
3710 hir::ExprMethodCall(name, ref tps, ref args) => {
3711 self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3713 hir::ExprCast(ref e, ref t) => {
3714 // Find the type of `e`. Supply hints based on the type we are casting to,
3716 let t_cast = self.to_ty(t);
3717 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3718 let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3719 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3720 let diverges = self.diverges.get();
3722 // Eagerly check for some obvious errors.
3723 if t_expr.references_error() || t_cast.references_error() {
3726 // Defer other checks until we're done type checking.
3727 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3728 match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3730 deferred_cast_checks.push(cast_check);
3733 Err(ErrorReported) => {
3739 hir::ExprType(ref e, ref t) => {
3740 let typ = self.to_ty(&t);
3741 self.check_expr_eq_type(&e, typ);
3744 hir::ExprArray(ref args) => {
3745 let uty = expected.to_option(self).and_then(|uty| {
3747 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3752 let element_ty = if !args.is_empty() {
3753 let coerce_to = uty.unwrap_or_else(
3754 || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
3755 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
3756 assert_eq!(self.diverges.get(), Diverges::Maybe);
3758 let e_ty = self.check_expr_with_hint(e, coerce_to);
3759 let cause = self.misc(e.span);
3760 coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3762 coerce.complete(self)
3764 self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
3766 tcx.mk_array(element_ty, args.len())
3768 hir::ExprRepeat(ref element, count) => {
3769 let count = eval_length(self.tcx, count, "repeat count")
3772 let uty = match expected {
3773 ExpectHasType(uty) => {
3775 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3782 let (element_ty, t) = match uty {
3784 self.check_expr_coercable_to_type(&element, uty);
3788 let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
3789 let element_ty = self.check_expr_has_type(&element, t);
3795 // For [foo, ..n] where n > 1, `foo` must have
3797 let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
3798 self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item);
3801 if element_ty.references_error() {
3804 tcx.mk_array(t, count)
3807 hir::ExprTup(ref elts) => {
3808 let flds = expected.only_has_type(self).and_then(|ty| {
3810 ty::TyTuple(ref flds, _) => Some(&flds[..]),
3815 let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
3816 let t = match flds {
3817 Some(ref fs) if i < fs.len() => {
3819 self.check_expr_coercable_to_type(&e, ety);
3823 self.check_expr_with_expectation(&e, NoExpectation)
3828 let tuple = tcx.mk_tup(elt_ts_iter, false);
3829 if tuple.references_error() {
3835 hir::ExprStruct(ref qpath, ref fields, ref base_expr) => {
3836 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
3838 hir::ExprField(ref base, ref field) => {
3839 self.check_field(expr, lvalue_pref, &base, field)
3841 hir::ExprTupField(ref base, idx) => {
3842 self.check_tup_field(expr, lvalue_pref, &base, idx)
3844 hir::ExprIndex(ref base, ref idx) => {
3845 let base_t = self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3846 let idx_t = self.check_expr(&idx);
3848 if base_t.references_error() {
3850 } else if idx_t.references_error() {
3853 let base_t = self.structurally_resolved_type(expr.span, base_t);
3854 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3855 Some((index_ty, element_ty)) => {
3856 self.demand_coerce(idx, idx_t, index_ty);
3860 let mut err = self.type_error_struct(
3863 format!("cannot index a value of type `{}`",
3867 // Try to give some advice about indexing tuples.
3868 if let ty::TyTuple(..) = base_t.sty {
3869 let mut needs_note = true;
3870 // If the index is an integer, we can show the actual
3871 // fixed expression:
3872 if let hir::ExprLit(ref lit) = idx.node {
3873 if let ast::LitKind::Int(i,
3874 ast::LitIntType::Unsuffixed) = lit.node {
3875 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3876 if let Ok(snip) = snip {
3877 err.span_suggestion(expr.span,
3878 "to access tuple elements, use",
3879 format!("{}.{}", snip, i));
3885 err.help("to access tuple elements, use tuple indexing \
3886 syntax (e.g. `tuple.0`)");
3898 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3899 // The newly resolved definition is written into `type_dependent_defs`.
3900 fn finish_resolving_struct_path(&self,
3903 node_id: ast::NodeId)
3907 hir::QPath::Resolved(ref maybe_qself, ref path) => {
3908 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
3909 let ty = AstConv::def_to_ty(self, opt_self_ty, path, true);
3912 hir::QPath::TypeRelative(ref qself, ref segment) => {
3913 let ty = self.to_ty(qself);
3915 let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
3920 let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span,
3923 // Write back the new resolution.
3924 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3931 // Resolve associated value path into a base type and associated constant or method definition.
3932 // The newly resolved definition is written into `type_dependent_defs`.
3933 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3934 qpath: &'b hir::QPath,
3935 node_id: ast::NodeId,
3937 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3939 let (ty, item_segment) = match *qpath {
3940 hir::QPath::Resolved(ref opt_qself, ref path) => {
3942 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
3943 &path.segments[..]);
3945 hir::QPath::TypeRelative(ref qself, ref segment) => {
3946 (self.to_ty(qself), segment)
3949 let item_name = item_segment.name;
3950 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3953 let def = match error {
3954 method::MethodError::PrivateMatch(def) => def,
3957 if item_name != keywords::Invalid.name() {
3958 self.report_method_error(span, ty, item_name, None, error, None);
3964 // Write back the new resolution.
3965 self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
3966 (def, Some(ty), slice::ref_slice(&**item_segment))
3969 pub fn check_decl_initializer(&self,
3970 local: &'gcx hir::Local,
3971 init: &'gcx hir::Expr) -> Ty<'tcx>
3973 let ref_bindings = local.pat.contains_ref_binding();
3975 let local_ty = self.local_ty(init.span, local.id);
3976 if let Some(m) = ref_bindings {
3977 // Somewhat subtle: if we have a `ref` binding in the pattern,
3978 // we want to avoid introducing coercions for the RHS. This is
3979 // both because it helps preserve sanity and, in the case of
3980 // ref mut, for soundness (issue #23116). In particular, in
3981 // the latter case, we need to be clear that the type of the
3982 // referent for the reference that results is *equal to* the
3983 // type of the lvalue it is referencing, and not some
3984 // supertype thereof.
3985 let init_ty = self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3986 self.demand_eqtype(init.span, init_ty, local_ty);
3989 self.check_expr_coercable_to_type(init, local_ty)
3993 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3994 let t = self.local_ty(local.span, local.id);
3995 self.write_ty(local.id, t);
3997 if let Some(ref init) = local.init {
3998 let init_ty = self.check_decl_initializer(local, &init);
3999 if init_ty.references_error() {
4000 self.write_ty(local.id, init_ty);
4004 self.check_pat(&local.pat, t);
4005 let pat_ty = self.node_ty(local.pat.id);
4006 if pat_ty.references_error() {
4007 self.write_ty(local.id, pat_ty);
4011 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
4012 // Don't do all the complex logic below for DeclItem.
4014 hir::StmtDecl(ref decl, _) => {
4016 hir::DeclLocal(_) => {}
4017 hir::DeclItem(_) => {
4022 hir::StmtExpr(..) | hir::StmtSemi(..) => {}
4025 self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
4027 // Hide the outer diverging and has_errors flags.
4028 let old_diverges = self.diverges.get();
4029 let old_has_errors = self.has_errors.get();
4030 self.diverges.set(Diverges::Maybe);
4031 self.has_errors.set(false);
4034 hir::StmtDecl(ref decl, _) => {
4036 hir::DeclLocal(ref l) => {
4037 self.check_decl_local(&l);
4039 hir::DeclItem(_) => {/* ignore for now */}
4042 hir::StmtExpr(ref expr, _) => {
4043 // Check with expected type of ()
4044 self.check_expr_has_type(&expr, self.tcx.mk_nil());
4046 hir::StmtSemi(ref expr, _) => {
4047 self.check_expr(&expr);
4051 // Combine the diverging and has_error flags.
4052 self.diverges.set(self.diverges.get() | old_diverges);
4053 self.has_errors.set(self.has_errors.get() | old_has_errors);
4056 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
4057 let unit = self.tcx.mk_nil();
4058 let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
4060 // if the block produces a `!` value, that can always be
4061 // (effectively) coerced to unit.
4063 self.demand_suptype(blk.span, unit, ty);
4067 fn check_block_with_expected(&self,
4068 blk: &'gcx hir::Block,
4069 expected: Expectation<'tcx>) -> Ty<'tcx> {
4071 let mut fcx_ps = self.ps.borrow_mut();
4072 let unsafety_state = fcx_ps.recurse(blk);
4073 replace(&mut *fcx_ps, unsafety_state)
4076 // In some cases, blocks have just one exit, but other blocks
4077 // can be targeted by multiple breaks. This cannot happen in
4078 // normal Rust syntax today, but it can happen when we desugar
4079 // a `do catch { ... }` expression.
4083 // 'a: { if true { break 'a Err(()); } Ok(()) }
4085 // Here we would wind up with two coercions, one from
4086 // `Err(())` and the other from the tail expression
4087 // `Ok(())`. If the tail expression is omitted, that's a
4088 // "forced unit" -- unless the block diverges, in which
4089 // case we can ignore the tail expression (e.g., `'a: {
4090 // break 'a 22; }` would not force the type of the block
4092 let tail_expr = blk.expr.as_ref();
4093 let coerce_to_ty = expected.coercion_target_type(self, blk.span);
4094 let coerce = if blk.targeted_by_break {
4095 CoerceMany::new(coerce_to_ty)
4097 let tail_expr: &[P<hir::Expr>] = match tail_expr {
4098 Some(e) => ref_slice(e),
4101 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
4104 let ctxt = BreakableCtxt {
4105 coerce: Some(coerce),
4109 let (ctxt, ()) = self.with_breakable_ctxt(blk.id, ctxt, || {
4110 for s in &blk.stmts {
4114 // check the tail expression **without** holding the
4115 // `enclosing_breakables` lock below.
4116 let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
4118 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4119 let mut ctxt = enclosing_breakables.find_breakable(blk.id);
4120 let mut coerce = ctxt.coerce.as_mut().unwrap();
4121 if let Some(tail_expr_ty) = tail_expr_ty {
4122 let tail_expr = tail_expr.unwrap();
4124 &self.misc(tail_expr.span),
4127 self.diverges.get());
4129 // Subtle: if there is no explicit tail expression,
4130 // that is typically equivalent to a tail expression
4131 // of `()` -- except if the block diverges. In that
4132 // case, there is no value supplied from the tail
4133 // expression (assuming there are no other breaks,
4134 // this implies that the type of the block will be
4137 // #41425 -- label the implicit `()` as being the
4138 // "found type" here, rather than the "expected type".
4139 if !self.diverges.get().always() {
4140 coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| {
4141 if let Some(expected_ty) = expected.only_has_type(self) {
4142 self.consider_hint_about_removing_semicolon(blk,
4151 let mut ty = ctxt.coerce.unwrap().complete(self);
4153 if self.has_errors.get() || ty.references_error() {
4154 ty = self.tcx.types.err
4157 self.write_ty(blk.id, ty);
4159 *self.ps.borrow_mut() = prev;
4163 /// A common error is to add an extra semicolon:
4166 /// fn foo() -> usize {
4171 /// This routine checks if the final statement in a block is an
4172 /// expression with an explicit semicolon whose type is compatible
4173 /// with `expected_ty`. If so, it suggests removing the semicolon.
4174 fn consider_hint_about_removing_semicolon(&self,
4175 blk: &'gcx hir::Block,
4176 expected_ty: Ty<'tcx>,
4177 err: &mut DiagnosticBuilder) {
4178 // Be helpful when the user wrote `{... expr;}` and
4179 // taking the `;` off is enough to fix the error.
4180 let last_stmt = match blk.stmts.last() {
4184 let last_expr = match last_stmt.node {
4185 hir::StmtSemi(ref e, _) => e,
4188 let last_expr_ty = self.expr_ty(last_expr);
4189 if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
4192 let original_span = original_sp(last_stmt.span, blk.span);
4193 let span_semi = Span {
4194 lo: original_span.hi - BytePos(1),
4195 hi: original_span.hi,
4196 ctxt: original_span.ctxt,
4198 err.span_help(span_semi, "consider removing this semicolon:");
4201 // Instantiates the given path, which must refer to an item with the given
4202 // number of type parameters and type.
4203 pub fn instantiate_value_path(&self,
4204 segments: &[hir::PathSegment],
4205 opt_self_ty: Option<Ty<'tcx>>,
4208 node_id: ast::NodeId)
4210 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4215 // We need to extract the type parameters supplied by the user in
4216 // the path `path`. Due to the current setup, this is a bit of a
4217 // tricky-process; the problem is that resolve only tells us the
4218 // end-point of the path resolution, and not the intermediate steps.
4219 // Luckily, we can (at least for now) deduce the intermediate steps
4220 // just from the end-point.
4222 // There are basically four cases to consider:
4224 // 1. Reference to a constructor of enum variant or struct:
4226 // struct Foo<T>(...)
4227 // enum E<T> { Foo(...) }
4229 // In these cases, the parameters are declared in the type
4232 // 2. Reference to a fn item or a free constant:
4236 // In this case, the path will again always have the form
4237 // `a::b::foo::<T>` where only the final segment should have
4238 // type parameters. However, in this case, those parameters are
4239 // declared on a value, and hence are in the `FnSpace`.
4241 // 3. Reference to a method or an associated constant:
4243 // impl<A> SomeStruct<A> {
4247 // Here we can have a path like
4248 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4249 // may appear in two places. The penultimate segment,
4250 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4251 // final segment, `foo::<B>` contains parameters in fn space.
4253 // 4. Reference to a local variable
4255 // Local variables can't have any type parameters.
4257 // The first step then is to categorize the segments appropriately.
4259 assert!(!segments.is_empty());
4261 let mut ufcs_associated = None;
4262 let mut type_segment = None;
4263 let mut fn_segment = None;
4265 // Case 1. Reference to a struct/variant constructor.
4266 Def::StructCtor(def_id, ..) |
4267 Def::VariantCtor(def_id, ..) => {
4268 // Everything but the final segment should have no
4269 // parameters at all.
4270 let mut generics = self.tcx.generics_of(def_id);
4271 if let Some(def_id) = generics.parent {
4272 // Variant and struct constructors use the
4273 // generics of their parent type definition.
4274 generics = self.tcx.generics_of(def_id);
4276 type_segment = Some((segments.last().unwrap(), generics));
4279 // Case 2. Reference to a top-level value.
4281 Def::Const(def_id) |
4282 Def::Static(def_id, _) => {
4283 fn_segment = Some((segments.last().unwrap(),
4284 self.tcx.generics_of(def_id)));
4287 // Case 3. Reference to a method or associated const.
4288 Def::Method(def_id) |
4289 Def::AssociatedConst(def_id) => {
4290 let container = self.tcx.associated_item(def_id).container;
4292 ty::TraitContainer(trait_did) => {
4293 callee::check_legal_trait_for_method_call(self.tcx, span, trait_did)
4295 ty::ImplContainer(_) => {}
4298 let generics = self.tcx.generics_of(def_id);
4299 if segments.len() >= 2 {
4300 let parent_generics = self.tcx.generics_of(generics.parent.unwrap());
4301 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4303 // `<T>::assoc` will end up here, and so can `T::assoc`.
4304 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4305 ufcs_associated = Some((container, self_ty));
4307 fn_segment = Some((segments.last().unwrap(), generics));
4310 // Case 4. Local variable, no generics.
4311 Def::Local(..) | Def::Upvar(..) => {}
4313 _ => bug!("unexpected definition: {:?}", def),
4316 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4318 // Now that we have categorized what space the parameters for each
4319 // segment belong to, let's sort out the parameters that the user
4320 // provided (if any) into their appropriate spaces. We'll also report
4321 // errors if type parameters are provided in an inappropriate place.
4322 let poly_segments = type_segment.is_some() as usize +
4323 fn_segment.is_some() as usize;
4324 AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
4327 Def::Local(def_id) | Def::Upvar(def_id, ..) => {
4328 let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
4329 let ty = self.local_ty(span, nid);
4330 let ty = self.normalize_associated_types_in(span, &ty);
4331 self.write_ty(node_id, ty);
4337 // Now we have to compare the types that the user *actually*
4338 // provided against the types that were *expected*. If the user
4339 // did not provide any types, then we want to substitute inference
4340 // variables. If the user provided some types, we may still need
4341 // to add defaults. If the user provided *too many* types, that's
4343 self.check_path_parameter_count(span, &mut type_segment);
4344 self.check_path_parameter_count(span, &mut fn_segment);
4346 let (fn_start, has_self) = match (type_segment, fn_segment) {
4347 (_, Some((_, generics))) => {
4348 (generics.parent_count(), generics.has_self)
4350 (Some((_, generics)), None) => {
4351 (generics.own_count(), generics.has_self)
4353 (None, None) => (0, false)
4355 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4356 let mut i = def.index as usize;
4358 let segment = if i < fn_start {
4359 i -= has_self as usize;
4365 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4366 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4367 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4371 if let Some(lifetime) = lifetimes.get(i) {
4372 AstConv::ast_region_to_region(self, lifetime, Some(def))
4374 self.re_infer(span, Some(def)).unwrap()
4377 let mut i = def.index as usize;
4379 let segment = if i < fn_start {
4380 // Handle Self first, so we can adjust the index to match the AST.
4381 if has_self && i == 0 {
4382 return opt_self_ty.unwrap_or_else(|| {
4383 self.type_var_for_def(span, def, substs)
4386 i -= has_self as usize;
4392 let (types, infer_types) = match segment.map(|(s, _)| &s.parameters) {
4393 Some(&hir::AngleBracketedParameters(ref data)) => {
4394 (&data.types[..], data.infer_types)
4396 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4397 None => (&[][..], true)
4400 // Skip over the lifetimes in the same segment.
4401 if let Some((_, generics)) = segment {
4402 i -= generics.regions.len();
4405 if let Some(ast_ty) = types.get(i) {
4406 // A provided type parameter.
4408 } else if !infer_types && def.has_default {
4409 // No type parameter provided, but a default exists.
4410 let default = self.tcx.type_of(def.def_id);
4413 default.subst_spanned(self.tcx, substs, Some(span))
4416 // No type parameters were provided, we can infer all.
4417 // This can also be reached in some error cases:
4418 // We prefer to use inference variables instead of
4419 // TyError to let type inference recover somewhat.
4420 self.type_var_for_def(span, def, substs)
4424 // The things we are substituting into the type should not contain
4425 // escaping late-bound regions, and nor should the base type scheme.
4426 let ty = self.tcx.type_of(def.def_id());
4427 assert!(!substs.has_escaping_regions());
4428 assert!(!ty.has_escaping_regions());
4430 // Add all the obligations that are required, substituting and
4431 // normalized appropriately.
4432 let bounds = self.instantiate_bounds(span, def.def_id(), &substs);
4433 self.add_obligations_for_parameters(
4434 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4437 // Substitute the values for the type parameters into the type of
4438 // the referenced item.
4439 let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty);
4441 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4442 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4443 // is inherent, there is no `Self` parameter, instead, the impl needs
4444 // type parameters, which we can infer by unifying the provided `Self`
4445 // with the substituted impl type.
4446 let ty = self.tcx.type_of(impl_def_id);
4448 let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
4449 match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
4450 Ok(ok) => self.register_infer_ok_obligations(ok),
4453 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4460 debug!("instantiate_value_path: type of {:?} is {:?}",
4463 self.write_substs(node_id, substs);
4467 /// Report errors if the provided parameters are too few or too many.
4468 fn check_path_parameter_count(&self,
4470 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4471 let (lifetimes, types, infer_types, bindings) = {
4472 match segment.map(|(s, _)| &s.parameters) {
4473 Some(&hir::AngleBracketedParameters(ref data)) => {
4474 (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
4476 Some(&hir::ParenthesizedParameters(_)) => {
4477 AstConv::prohibit_parenthesized_params(self, &segment.as_ref().unwrap().0,
4479 (&[][..], &[][..], true, &[][..])
4481 None => (&[][..], &[][..], true, &[][..])
4485 let count_lifetime_params = |n| {
4486 format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4488 let count_type_params = |n| {
4489 format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4492 // Check provided lifetime parameters.
4493 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4494 if lifetimes.len() > lifetime_defs.len() {
4495 let expected_text = count_lifetime_params(lifetime_defs.len());
4496 let actual_text = count_lifetime_params(lifetimes.len());
4497 struct_span_err!(self.tcx.sess, span, E0088,
4498 "too many lifetime parameters provided: \
4499 expected at most {}, found {}",
4500 expected_text, actual_text)
4501 .span_label(span, format!("expected {}", expected_text))
4503 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4504 let expected_text = count_lifetime_params(lifetime_defs.len());
4505 let actual_text = count_lifetime_params(lifetimes.len());
4506 struct_span_err!(self.tcx.sess, span, E0090,
4507 "too few lifetime parameters provided: \
4508 expected {}, found {}",
4509 expected_text, actual_text)
4510 .span_label(span, format!("expected {}", expected_text))
4514 // The case where there is not enough lifetime parameters is not checked,
4515 // because this is not possible - a function never takes lifetime parameters.
4516 // See discussion for Pull Request 36208.
4518 // Check provided type parameters.
4519 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4520 if generics.parent.is_none() {
4521 &generics.types[generics.has_self as usize..]
4526 let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
4527 if types.len() > type_defs.len() {
4528 let span = types[type_defs.len()].span;
4529 let expected_text = count_type_params(type_defs.len());
4530 let actual_text = count_type_params(types.len());
4531 struct_span_err!(self.tcx.sess, span, E0087,
4532 "too many type parameters provided: \
4533 expected at most {}, found {}",
4534 expected_text, actual_text)
4535 .span_label(span, format!("expected {}", expected_text))
4538 // To prevent derived errors to accumulate due to extra
4539 // type parameters, we force instantiate_value_path to
4540 // use inference variables instead of the provided types.
4542 } else if !infer_types && types.len() < required_len {
4543 let expected_text = count_type_params(required_len);
4544 let actual_text = count_type_params(types.len());
4545 struct_span_err!(self.tcx.sess, span, E0089,
4546 "too few type parameters provided: \
4547 expected {}, found {}",
4548 expected_text, actual_text)
4549 .span_label(span, format!("expected {}", expected_text))
4553 if !bindings.is_empty() {
4554 span_err!(self.tcx.sess, bindings[0].span, E0182,
4555 "unexpected binding of associated item in expression path \
4556 (only allowed in type paths)");
4560 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4562 where F: Fn() -> Ty<'tcx>
4564 let mut ty = self.resolve_type_vars_with_obligations(ty);
4567 let alternative = f();
4570 if alternative.is_ty_var() || alternative.references_error() {
4571 if !self.is_tainted_by_errors() {
4572 self.type_error_message(sp, |_actual| {
4573 "the type of this value must be known in this context".to_string()
4576 self.demand_suptype(sp, self.tcx.types.err, ty);
4577 ty = self.tcx.types.err;
4579 self.demand_suptype(sp, alternative, ty);
4587 // Resolves `typ` by a single level if `typ` is a type variable. If no
4588 // resolution is possible, then an error is reported.
4589 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4590 self.structurally_resolve_type_or_else(sp, ty, || {
4595 fn with_breakable_ctxt<F: FnOnce() -> R, R>(&self, id: ast::NodeId,
4596 ctxt: BreakableCtxt<'gcx, 'tcx>, f: F)
4597 -> (BreakableCtxt<'gcx, 'tcx>, R) {
4600 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4601 index = enclosing_breakables.stack.len();
4602 enclosing_breakables.by_id.insert(id, index);
4603 enclosing_breakables.stack.push(ctxt);
4607 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
4608 debug_assert!(enclosing_breakables.stack.len() == index + 1);
4609 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
4610 enclosing_breakables.stack.pop().expect("missing breakable context")
4616 pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4617 generics: &hir::Generics,
4619 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4620 generics.ty_params.len(), ty);
4622 // make a vector of booleans initially false, set to true when used
4623 if generics.ty_params.is_empty() { return; }
4624 let mut tps_used = vec![false; generics.ty_params.len()];
4626 for leaf_ty in ty.walk() {
4627 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4628 debug!("Found use of ty param num {}", idx);
4629 tps_used[idx as usize - generics.lifetimes.len()] = true;
4633 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4635 struct_span_err!(tcx.sess, param.span, E0091,
4636 "type parameter `{}` is unused",
4638 .span_label(param.span, "unused type parameter")