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.item_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 `ccx.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 pub use self::compare_method::{compare_impl_method, compare_const_impl};
81 use self::TupleArgumentsFlag::*;
83 use astconv::{AstConv, ast_region_to_region, PathParamMode};
84 use dep_graph::DepNode;
85 use fmt_macros::{Parser, Piece, Position};
86 use middle::cstore::LOCAL_CRATE;
87 use hir::def::{self, Def};
88 use hir::def_id::DefId;
90 use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
91 use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
92 use rustc::traits::{self, ProjectionMode};
93 use rustc::ty::{GenericPredicates, TypeScheme};
94 use rustc::ty::{ParamTy, ParameterEnvironment};
95 use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
96 use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
97 use rustc::ty::{MethodCall, MethodCallee};
98 use rustc::ty::adjustment;
99 use rustc::ty::fold::TypeFoldable;
100 use rustc::ty::util::{Representability, IntTypeExt};
101 use require_c_abi_if_variadic;
102 use rscope::{ElisionFailureInfo, RegionScope};
103 use session::{Session, CompileResult};
107 use util::common::{block_query, ErrorReported, indenter, loop_query};
108 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
110 use std::cell::{Cell, Ref, RefCell};
111 use std::collections::{HashSet};
112 use std::mem::replace;
114 use syntax::abi::Abi;
117 use syntax::attr::AttrMetaMethods;
118 use syntax::codemap::{self, Span, Spanned};
119 use syntax::errors::DiagnosticBuilder;
120 use syntax::parse::token::{self, InternedString, keywords};
122 use syntax::util::lev_distance::find_best_match_for_name;
124 use rustc::hir::intravisit::{self, Visitor};
125 use rustc::hir::{self, PatKind};
126 use rustc::hir::print as pprust;
127 use rustc_back::slice;
128 use rustc_const_eval::eval_repeat_count;
148 /// closures defined within the function. For example:
151 /// bar(move|| { ... })
154 /// Here, the function `foo()` and the closure passed to
155 /// `bar()` will each have their own `FnCtxt`, but they will
156 /// share the inherited fields.
157 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
158 ccx: &'a CrateCtxt<'a, 'gcx>,
159 infcx: InferCtxt<'a, 'gcx, 'tcx>,
160 locals: RefCell<NodeMap<Ty<'tcx>>>,
162 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
164 // When we process a call like `c()` where `c` is a closure type,
165 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
166 // `FnOnce` closure. In that case, we defer full resolution of the
167 // call until upvar inference can kick in and make the
168 // decision. We keep these deferred resolutions grouped by the
169 // def-id of the closure, so that once we decide, we can easily go
170 // back and process them.
171 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
173 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
176 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
177 type Target = InferCtxt<'a, 'gcx, 'tcx>;
178 fn deref(&self) -> &Self::Target {
183 trait DeferredCallResolution<'gcx, 'tcx> {
184 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
187 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
189 /// When type-checking an expression, we propagate downward
190 /// whatever type hint we are able in the form of an `Expectation`.
191 #[derive(Copy, Clone, Debug)]
192 pub enum Expectation<'tcx> {
193 /// We know nothing about what type this expression should have.
196 /// This expression should have the type given (or some subtype)
197 ExpectHasType(Ty<'tcx>),
199 /// This expression will be cast to the `Ty`
200 ExpectCastableToType(Ty<'tcx>),
202 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
203 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
204 ExpectRvalueLikeUnsized(Ty<'tcx>),
207 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
208 // Disregard "castable to" expectations because they
209 // can lead us astray. Consider for example `if cond
210 // {22} else {c} as u8` -- if we propagate the
211 // "castable to u8" constraint to 22, it will pick the
212 // type 22u8, which is overly constrained (c might not
213 // be a u8). In effect, the problem is that the
214 // "castable to" expectation is not the tightest thing
215 // we can say, so we want to drop it in this case.
216 // The tightest thing we can say is "must unify with
217 // else branch". Note that in the case of a "has type"
218 // constraint, this limitation does not hold.
220 // If the expected type is just a type variable, then don't use
221 // an expected type. Otherwise, we might write parts of the type
222 // when checking the 'then' block which are incompatible with the
224 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
226 ExpectHasType(ety) => {
227 let ety = fcx.shallow_resolve(ety);
228 if !ety.is_ty_var() {
234 ExpectRvalueLikeUnsized(ety) => {
235 ExpectRvalueLikeUnsized(ety)
241 /// Provide an expectation for an rvalue expression given an *optional*
242 /// hint, which is not required for type safety (the resulting type might
243 /// be checked higher up, as is the case with `&expr` and `box expr`), but
244 /// is useful in determining the concrete type.
246 /// The primary use case is where the expected type is a fat pointer,
247 /// like `&[isize]`. For example, consider the following statement:
249 /// let x: &[isize] = &[1, 2, 3];
251 /// In this case, the expected type for the `&[1, 2, 3]` expression is
252 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
253 /// expectation `ExpectHasType([isize])`, that would be too strong --
254 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
255 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
256 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
257 /// which still is useful, because it informs integer literals and the like.
258 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
259 /// for examples of where this comes up,.
260 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
261 match fcx.tcx.struct_tail(ty).sty {
262 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
263 ExpectRvalueLikeUnsized(ty)
265 _ => ExpectHasType(ty)
269 // Resolves `expected` by a single level if it is a variable. If
270 // there is no expected type or resolution is not possible (e.g.,
271 // no constraints yet present), just returns `None`.
272 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
277 ExpectCastableToType(t) => {
278 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
280 ExpectHasType(t) => {
281 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
283 ExpectRvalueLikeUnsized(t) => {
284 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
289 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
290 match self.resolve(fcx) {
291 NoExpectation => None,
292 ExpectCastableToType(ty) |
294 ExpectRvalueLikeUnsized(ty) => Some(ty),
298 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
299 match self.resolve(fcx) {
300 ExpectHasType(ty) => Some(ty),
306 #[derive(Copy, Clone)]
307 pub struct UnsafetyState {
308 pub def: ast::NodeId,
309 pub unsafety: hir::Unsafety,
310 pub unsafe_push_count: u32,
315 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
316 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
319 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
320 match self.unsafety {
321 // If this unsafe, then if the outer function was already marked as
322 // unsafe we shouldn't attribute the unsafe'ness to the block. This
323 // way the block can be warned about instead of ignoring this
324 // extraneous block (functions are never warned about).
325 hir::Unsafety::Unsafe if self.from_fn => *self,
328 let (unsafety, def, count) = match blk.rules {
329 hir::PushUnsafeBlock(..) =>
330 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
331 hir::PopUnsafeBlock(..) =>
332 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
333 hir::UnsafeBlock(..) =>
334 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
335 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
336 (unsafety, self.def, self.unsafe_push_count),
338 UnsafetyState{ def: def,
340 unsafe_push_count: count,
348 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
349 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
351 body_id: ast::NodeId,
353 // This flag is set to true if, during the writeback phase, we encounter
354 // a type error in this function.
355 writeback_errors: Cell<bool>,
357 // Number of errors that had been reported when we started
358 // checking this function. On exit, if we find that *more* errors
359 // have been reported, we will skip regionck and other work that
360 // expects the types within the function to be consistent.
361 err_count_on_creation: usize,
363 ret_ty: ty::FnOutput<'tcx>,
365 ps: RefCell<UnsafetyState>,
367 inh: &'a Inherited<'a, 'gcx, 'tcx>,
370 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
371 type Target = Inherited<'a, 'gcx, 'tcx>;
372 fn deref(&self) -> &Self::Target {
377 /// Helper type of a temporary returned by ccx.inherited(...).
378 /// Necessary because we can't write the following bound:
379 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
380 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
381 ccx: &'a CrateCtxt<'a, 'gcx>,
382 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
385 impl<'a, 'gcx, 'tcx> CrateCtxt<'a, 'gcx> {
386 pub fn inherited(&'a self, param_env: Option<ty::ParameterEnvironment<'gcx>>)
387 -> InheritedBuilder<'a, 'gcx, 'tcx> {
390 infcx: self.tcx.infer_ctxt(Some(ty::Tables::empty()),
392 ProjectionMode::AnyFinal)
397 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
398 fn enter<F, R>(&'tcx mut self, f: F) -> R
399 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
402 self.infcx.enter(|infcx| {
406 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
407 locals: RefCell::new(NodeMap()),
408 deferred_call_resolutions: RefCell::new(DefIdMap()),
409 deferred_cast_checks: RefCell::new(Vec::new()),
415 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
416 fn normalize_associated_types_in<T>(&self,
418 body_id: ast::NodeId,
421 where T : TypeFoldable<'tcx>
423 assoc::normalize_associated_types_in(self,
424 &mut self.fulfillment_cx.borrow_mut(),
432 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
433 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
435 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
436 fn visit_item(&mut self, i: &'tcx hir::Item) {
437 check_item_type(self.ccx, i);
438 intravisit::walk_item(self, i);
441 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
443 hir::TyFixedLengthVec(_, ref expr) => {
444 check_const_in_type(self.ccx, &expr, self.ccx.tcx.types.usize);
449 intravisit::walk_ty(self, t);
453 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
454 fn visit_item(&mut self, i: &'tcx hir::Item) {
455 check_item_body(self.ccx, i);
459 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
460 ccx.tcx.sess.track_errors(|| {
461 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
462 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
466 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
467 ccx.tcx.sess.track_errors(|| {
468 let mut visit = CheckItemTypesVisitor { ccx: ccx };
469 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
473 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
474 ccx.tcx.sess.track_errors(|| {
475 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
476 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
480 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
481 ccx.tcx.sess.track_errors(|| {
482 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
483 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
484 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
486 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
487 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
488 if drop_impl_did.is_local() {
489 match dropck::check_drop_impl(ccx, drop_impl_did) {
492 assert!(ccx.tcx.sess.has_errors());
500 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
501 decl: &'tcx hir::FnDecl,
502 body: &'tcx hir::Block,
506 param_env: ty::ParameterEnvironment<'tcx>)
508 let fn_ty = match raw_fty.sty {
509 ty::TyFnDef(_, _, f) => f,
510 _ => span_bug!(body.span, "check_bare_fn: function type expected")
513 ccx.inherited(Some(param_env)).enter(|inh| {
514 // Compute the fty from point of view of inside fn.
515 let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body.id);
517 fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
519 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
521 inh.normalize_associated_types_in(body.span, body.id, &fn_sig);
523 let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
525 fcx.select_all_obligations_and_apply_defaults();
526 fcx.closure_analyze_fn(body);
527 fcx.select_obligations_where_possible();
529 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
531 fcx.regionck_fn(fn_id, fn_span, decl, body);
532 fcx.resolve_type_vars_in_fn(decl, body);
536 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
537 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
540 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
541 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
544 // infer the variable's type
545 let var_ty = self.fcx.next_ty_var();
546 self.fcx.locals.borrow_mut().insert(nid, var_ty);
550 // take type that the user specified
551 self.fcx.locals.borrow_mut().insert(nid, typ);
558 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
559 // Add explicitly-declared locals.
560 fn visit_local(&mut self, local: &'gcx hir::Local) {
561 let o_ty = match local.ty {
562 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
565 self.assign(local.span, local.id, o_ty);
566 debug!("Local variable {:?} is assigned type {}",
568 self.fcx.ty_to_string(
569 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
570 intravisit::walk_local(self, local);
573 // Add pattern bindings.
574 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
575 if let PatKind::Binding(_, ref path1, _) = p.node {
576 let var_ty = self.assign(p.span, p.id, None);
578 self.fcx.require_type_is_sized(var_ty, p.span,
579 traits::VariableType(p.id));
581 debug!("Pattern binding {} is assigned to {} with type {:?}",
583 self.fcx.ty_to_string(
584 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
587 intravisit::walk_pat(self, p);
590 fn visit_block(&mut self, b: &'gcx hir::Block) {
591 // non-obvious: the `blk` variable maps to region lb, so
592 // we have to keep this up-to-date. This
593 // is... unfortunate. It'd be nice to not need this.
594 intravisit::walk_block(self, b);
597 // Since an expr occurs as part of the type fixed size arrays we
598 // need to record the type for that node
599 fn visit_ty(&mut self, t: &'gcx hir::Ty) {
601 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
603 self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize);
605 hir::TyBareFn(ref function_declaration) => {
606 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
607 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
609 _ => intravisit::walk_ty(self, t)
613 // Don't descend into the bodies of nested closures
614 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
615 _: &'gcx hir::Block, _: Span, _: ast::NodeId) { }
618 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
619 /// body and returns the function context used for that purpose, since in the case of a fn item
620 /// there is still a bit more to do.
623 /// * inherited: other fields inherited from the enclosing fn (if any)
624 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
625 unsafety: hir::Unsafety,
626 unsafety_id: ast::NodeId,
627 fn_sig: &ty::FnSig<'tcx>,
628 decl: &'gcx hir::FnDecl,
630 body: &'gcx hir::Block)
631 -> FnCtxt<'a, 'gcx, 'tcx>
633 let arg_tys = &fn_sig.inputs;
634 let ret_ty = fn_sig.output;
636 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
641 // Create the function context. This is either derived from scratch or,
642 // in the case of function expressions, based on the outer context.
643 let fcx = FnCtxt::new(inherited, ret_ty, body.id);
644 *fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id);
646 if let ty::FnConverging(ret_ty) = ret_ty {
647 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
650 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
652 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
655 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
657 // Add formal parameters.
658 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
659 // The type of the argument must be well-formed.
661 // NB -- this is now checked in wfcheck, but that
662 // currently only results in warnings, so we issue an
663 // old-style WF obligation here so that we still get the
664 // errors that we used to get.
665 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
667 // Create type variables for each argument.
668 pat_util::pat_bindings(&input.pat, |_bm, pat_id, sp, _path| {
669 let var_ty = visit.assign(sp, pat_id, None);
670 fcx.require_type_is_sized(var_ty, sp, traits::VariableType(pat_id));
673 // Check the pattern.
674 fcx.check_pat(&input.pat, *arg_ty);
677 visit.visit_block(body);
680 fcx.check_block_with_expected(body, match ret_ty {
681 ty::FnConverging(result_type) => ExpectHasType(result_type),
682 ty::FnDiverging => NoExpectation
685 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
686 fcx.write_ty(input.id, arg);
692 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
695 check_representable(tcx, span, id, "struct");
697 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
698 check_simd(tcx, span, id);
702 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
703 debug!("check_item_type(it.id={}, it.name={})",
705 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
706 let _indenter = indenter();
708 // Consts can play a role in type-checking, so they are included here.
709 hir::ItemStatic(_, _, ref e) |
710 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &e, it.id),
711 hir::ItemEnum(ref enum_definition, _) => {
712 check_enum_variants(ccx,
714 &enum_definition.variants,
717 hir::ItemFn(..) => {} // entirely within check_item_body
718 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
719 debug!("ItemImpl {} with id {}", it.name, it.id);
720 let impl_def_id = ccx.tcx.map.local_def_id(it.id);
721 match ccx.tcx.impl_trait_ref(impl_def_id) {
722 Some(impl_trait_ref) => {
723 let trait_def_id = impl_trait_ref.def_id;
725 check_impl_items_against_trait(ccx,
730 check_on_unimplemented(
732 &ccx.tcx.lookup_trait_def(trait_def_id).generics,
734 ccx.tcx.item_name(trait_def_id));
739 hir::ItemTrait(..) => {
740 let def_id = ccx.tcx.map.local_def_id(it.id);
741 let generics = &ccx.tcx.lookup_trait_def(def_id).generics;
742 check_on_unimplemented(ccx, generics, it, it.name);
744 hir::ItemStruct(..) => {
745 check_struct(ccx, it.id, it.span);
747 hir::ItemTy(_, ref generics) => {
748 let pty_ty = ccx.tcx.node_id_to_type(it.id);
749 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
751 hir::ItemForeignMod(ref m) => {
752 if m.abi == Abi::RustIntrinsic {
753 for item in &m.items {
754 intrinsic::check_intrinsic_type(ccx, item);
756 } else if m.abi == Abi::PlatformIntrinsic {
757 for item in &m.items {
758 intrinsic::check_platform_intrinsic_type(ccx, item);
761 for item in &m.items {
762 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
763 if !pty.generics.types.is_empty() {
764 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
765 "foreign items may not have type parameters");
766 span_help!(&mut err, item.span,
767 "consider using specialization instead of \
772 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
773 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
778 _ => {/* nothing to do */ }
782 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
783 debug!("check_item_body(it.id={}, it.name={})",
785 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
786 let _indenter = indenter();
788 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
789 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
790 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
791 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
793 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
794 debug!("ItemImpl {} with id {}", it.name, it.id);
796 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
798 for impl_item in impl_items {
799 match impl_item.node {
800 hir::ImplItemKind::Const(_, ref expr) => {
801 check_const(ccx, impl_item.span, &expr, impl_item.id)
803 hir::ImplItemKind::Method(ref sig, ref body) => {
804 check_method_body(ccx, &impl_pty.generics, sig, body,
805 impl_item.id, impl_item.span);
807 hir::ImplItemKind::Type(_) => {
808 // Nothing to do here.
813 hir::ItemTrait(_, _, _, ref trait_items) => {
814 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
815 for trait_item in trait_items {
816 match trait_item.node {
817 hir::ConstTraitItem(_, Some(ref expr)) => {
818 check_const(ccx, trait_item.span, &expr, trait_item.id)
820 hir::MethodTraitItem(ref sig, Some(ref body)) => {
821 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
823 check_method_body(ccx, &trait_def.generics, sig, body,
824 trait_item.id, trait_item.span);
826 hir::MethodTraitItem(ref sig, None) => {
827 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
829 hir::ConstTraitItem(_, None) |
830 hir::TypeTraitItem(..) => {
836 _ => {/* nothing to do */ }
840 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
842 constness: hir::Constness)
845 hir::Constness::NotConst => {
848 hir::Constness::Const => {
849 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
854 fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
855 generics: &ty::Generics,
858 if let Some(ref attr) = item.attrs.iter().find(|a| {
859 a.check_name("rustc_on_unimplemented")
861 if let Some(ref istring) = attr.value_str() {
862 let parser = Parser::new(&istring);
863 let types = &generics.types;
864 for token in parser {
866 Piece::String(_) => (), // Normal string, no need to check it
867 Piece::NextArgument(a) => match a.position {
868 // `{Self}` is allowed
869 Position::ArgumentNamed(s) if s == "Self" => (),
870 // So is `{A}` if A is a type parameter
871 Position::ArgumentNamed(s) => match types.iter().find(|t| {
876 span_err!(ccx.tcx.sess, attr.span, E0230,
877 "there is no type parameter \
882 // `{:1}` and `{}` are not to be used
883 Position::ArgumentIs(_) | Position::ArgumentNext => {
884 span_err!(ccx.tcx.sess, attr.span, E0231,
885 "only named substitution \
886 parameters are allowed");
892 span_err!(ccx.tcx.sess, attr.span, E0232,
893 "this attribute must have a value, \
894 eg `#[rustc_on_unimplemented = \"foo\"]`")
899 /// Type checks a method body.
903 /// * `item_generics`: generics defined on the impl/trait that contains
905 /// * `self_bound`: bound for the `Self` type parameter, if any
906 /// * `method`: the method definition
907 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
908 item_generics: &ty::Generics<'tcx>,
909 sig: &'tcx hir::MethodSig,
910 body: &'tcx hir::Block,
911 id: ast::NodeId, span: Span) {
912 debug!("check_method_body(item_generics={:?}, id={})",
914 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
916 let fty = ccx.tcx.node_id_to_type(id);
917 debug!("check_method_body: fty={:?}", fty);
919 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
922 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
923 impl_item: &hir::ImplItem,
926 let mut err = struct_span_err!(
927 tcx.sess, impl_item.span, E0520,
928 "item `{}` is provided by an `impl` that specializes \
929 another, but the item in the parent `impl` is not \
930 marked `default` and so it cannot be specialized.",
933 match tcx.span_of_impl(parent_impl) {
935 err.span_note(span, "parent implementation is here:");
938 err.note(&format!("parent implementation is in crate `{}`", cname));
945 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
946 trait_def: &ty::TraitDef<'tcx>,
948 impl_item: &hir::ImplItem)
950 let ancestors = trait_def.ancestors(impl_id);
952 let parent = match impl_item.node {
953 hir::ImplItemKind::Const(..) => {
954 ancestors.const_defs(tcx, impl_item.name).skip(1).next()
955 .map(|node_item| node_item.map(|parent| parent.defaultness))
957 hir::ImplItemKind::Method(..) => {
958 ancestors.fn_defs(tcx, impl_item.name).skip(1).next()
959 .map(|node_item| node_item.map(|parent| parent.defaultness))
962 hir::ImplItemKind::Type(_) => {
963 ancestors.type_defs(tcx, impl_item.name).skip(1).next()
964 .map(|node_item| node_item.map(|parent| parent.defaultness))
968 if let Some(parent) = parent {
969 if parent.item.is_final() {
970 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
976 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
979 impl_trait_ref: &ty::TraitRef<'tcx>,
980 impl_items: &[hir::ImplItem]) {
981 // If the trait reference itself is erroneous (so the compilation is going
982 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
983 // isn't populated for such impls.
984 if impl_trait_ref.references_error() { return; }
986 // Locate trait definition and items
988 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
989 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
990 let mut overridden_associated_type = None;
992 // Check existing impl methods to see if they are both present in trait
993 // and compatible with trait signature
994 for impl_item in impl_items {
995 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
996 let ty_trait_item = trait_items.iter()
997 .find(|ac| ac.name() == ty_impl_item.name());
999 // Check that impl definition matches trait definition
1000 if let Some(ty_trait_item) = ty_trait_item {
1001 match impl_item.node {
1002 hir::ImplItemKind::Const(..) => {
1003 let impl_const = match ty_impl_item {
1004 ty::ConstTraitItem(ref cti) => cti,
1005 _ => span_bug!(impl_item.span, "non-const impl-item for const")
1008 // Find associated const definition.
1009 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
1010 compare_const_impl(ccx,
1016 span_err!(tcx.sess, impl_item.span, E0323,
1017 "item `{}` is an associated const, \
1018 which doesn't match its trait `{:?}`",
1023 hir::ImplItemKind::Method(ref sig, ref body) => {
1024 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
1026 let impl_method = match ty_impl_item {
1027 ty::MethodTraitItem(ref mti) => mti,
1028 _ => span_bug!(impl_item.span, "non-method impl-item for method")
1031 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
1032 compare_impl_method(ccx,
1039 span_err!(tcx.sess, impl_item.span, E0324,
1040 "item `{}` is an associated method, \
1041 which doesn't match its trait `{:?}`",
1046 hir::ImplItemKind::Type(_) => {
1047 let impl_type = match ty_impl_item {
1048 ty::TypeTraitItem(ref tti) => tti,
1049 _ => span_bug!(impl_item.span, "non-type impl-item for type")
1052 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
1053 if let Some(_) = at.ty {
1054 overridden_associated_type = Some(impl_item);
1057 span_err!(tcx.sess, impl_item.span, E0325,
1058 "item `{}` is an associated type, \
1059 which doesn't match its trait `{:?}`",
1067 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1070 // Check for missing items from trait
1071 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
1072 let mut missing_items = Vec::new();
1073 let mut invalidated_items = Vec::new();
1074 let associated_type_overridden = overridden_associated_type.is_some();
1075 for trait_item in trait_items.iter() {
1080 ty::ConstTraitItem(ref associated_const) => {
1081 is_provided = associated_const.has_value;
1082 is_implemented = impl_items.iter().any(|ii| {
1084 hir::ImplItemKind::Const(..) => {
1085 ii.name == associated_const.name
1091 ty::MethodTraitItem(ref trait_method) => {
1092 is_provided = provided_methods.iter().any(|m| m.name == trait_method.name);
1093 is_implemented = trait_def.ancestors(impl_id)
1094 .fn_defs(tcx, trait_method.name)
1096 .map(|node_item| !node_item.node.is_from_trait())
1099 ty::TypeTraitItem(ref trait_assoc_ty) => {
1100 is_provided = trait_assoc_ty.ty.is_some();
1101 is_implemented = trait_def.ancestors(impl_id)
1102 .type_defs(tcx, trait_assoc_ty.name)
1104 .map(|node_item| !node_item.node.is_from_trait())
1109 if !is_implemented {
1111 missing_items.push(trait_item.name());
1112 } else if associated_type_overridden {
1113 invalidated_items.push(trait_item.name());
1118 if !missing_items.is_empty() {
1119 span_err!(tcx.sess, impl_span, E0046,
1120 "not all trait items implemented, missing: `{}`",
1121 missing_items.iter()
1122 .map(|name| name.to_string())
1123 .collect::<Vec<_>>().join("`, `"))
1126 if !invalidated_items.is_empty() {
1127 let invalidator = overridden_associated_type.unwrap();
1128 span_err!(tcx.sess, invalidator.span, E0399,
1129 "the following trait items need to be reimplemented \
1130 as `{}` was overridden: `{}`",
1132 invalidated_items.iter()
1133 .map(|name| name.to_string())
1134 .collect::<Vec<_>>().join("`, `"))
1138 /// Checks a constant appearing in a type. At the moment this is just the
1139 /// length expression in a fixed-length vector, but someday it might be
1140 /// extended to type-level numeric literals.
1141 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
1142 expr: &'tcx hir::Expr,
1143 expected_type: Ty<'tcx>) {
1144 ccx.inherited(None).enter(|inh| {
1145 let fcx = FnCtxt::new(&inh, ty::FnConverging(expected_type), expr.id);
1146 fcx.check_const_with_ty(expr.span, expr, expected_type);
1150 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1154 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
1155 ccx.inherited(Some(param_env)).enter(|inh| {
1156 let rty = ccx.tcx.node_id_to_type(id);
1157 let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), e.id);
1158 let declty = fcx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
1159 fcx.check_const_with_ty(sp, e, declty);
1163 /// Checks whether a type can be represented in memory. In particular, it
1164 /// identifies types that contain themselves without indirection through a
1165 /// pointer, which would mean their size is unbounded.
1166 pub fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1168 item_id: ast::NodeId,
1169 _designation: &str) -> bool {
1170 let rty = tcx.node_id_to_type(item_id);
1172 // Check that it is possible to represent this type. This call identifies
1173 // (1) types that contain themselves and (2) types that contain a different
1174 // recursive type. It is only necessary to throw an error on those that
1175 // contain themselves. For case 2, there must be an inner type that will be
1176 // caught by case 1.
1177 match rty.is_representable(tcx, sp) {
1178 Representability::SelfRecursive => {
1179 let item_def_id = tcx.map.local_def_id(item_id);
1180 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1183 Representability::Representable | Representability::ContainsRecursive => (),
1188 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) {
1189 let t = tcx.node_id_to_type(id);
1191 ty::TyStruct(def, substs) => {
1192 let fields = &def.struct_variant().fields;
1193 if fields.is_empty() {
1194 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1197 let e = fields[0].ty(tcx, substs);
1198 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1199 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
1203 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1204 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1206 span_err!(tcx.sess, sp, E0077,
1207 "SIMD vector element type should be machine type");
1216 #[allow(trivial_numeric_casts)]
1217 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1219 vs: &'tcx [hir::Variant],
1221 let def_id = ccx.tcx.map.local_def_id(id);
1222 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
1224 if hint != attr::ReprAny && vs.is_empty() {
1225 span_err!(ccx.tcx.sess, sp, E0084,
1226 "unsupported representation for zero-variant enum");
1229 ccx.inherited(None).enter(|inh| {
1230 let rty = ccx.tcx.node_id_to_type(id);
1231 let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), id);
1233 let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx);
1235 if let Some(ref e) = v.node.disr_expr {
1236 fcx.check_const_with_ty(e.span, e, repr_type_ty);
1240 let def_id = ccx.tcx.map.local_def_id(id);
1242 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
1243 let mut disr_vals: Vec<ty::Disr> = Vec::new();
1244 for (v, variant) in vs.iter().zip(variants.iter()) {
1245 let current_disr_val = variant.disr_val;
1247 // Check for duplicate discriminant values
1248 if let Some(i) = disr_vals.iter().position(|&x| x == current_disr_val) {
1249 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
1250 "discriminant value `{}` already exists", disr_vals[i]);
1251 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
1252 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
1253 "conflicting discriminant here");
1256 disr_vals.push(current_disr_val);
1260 check_representable(ccx.tcx, sp, id, "enum");
1263 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1264 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1266 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1267 &self.ast_ty_to_ty_cache
1270 fn get_item_type_scheme(&self, _: Span, id: DefId)
1271 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1273 Ok(self.tcx().lookup_item_type(id))
1276 fn get_trait_def(&self, _: Span, id: DefId)
1277 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1279 Ok(self.tcx().lookup_trait_def(id))
1282 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1283 // all super predicates are ensured during collect pass
1287 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1288 Some(&self.parameter_environment.free_substs)
1291 fn get_type_parameter_bounds(&self,
1293 node_id: ast::NodeId)
1294 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1296 let def = self.tcx.type_parameter_def(node_id);
1297 let r = self.parameter_environment
1300 .filter_map(|predicate| {
1302 ty::Predicate::Trait(ref data) => {
1303 if data.0.self_ty().is_param(def.space, def.index) {
1304 Some(data.to_poly_trait_ref())
1318 fn trait_defines_associated_type_named(&self,
1319 trait_def_id: DefId,
1320 assoc_name: ast::Name)
1323 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
1324 trait_def.associated_type_names.contains(&assoc_name)
1328 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1329 substs: Option<&mut subst::Substs<'tcx>>,
1330 space: Option<subst::ParamSpace>,
1331 span: Span) -> Ty<'tcx> {
1332 // Grab the default doing subsitution
1333 let default = ty_param_def.and_then(|def| {
1334 def.default.map(|ty| type_variable::Default {
1335 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1337 def_id: def.default_def_id
1341 let ty_var = self.next_ty_var_with_default(default);
1343 // Finally we add the type variable to the substs
1346 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1350 fn projected_ty_from_poly_trait_ref(&self,
1352 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1353 item_name: ast::Name)
1356 let (trait_ref, _) =
1357 self.replace_late_bound_regions_with_fresh_var(
1359 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1362 self.normalize_associated_type(span, trait_ref, item_name)
1365 fn projected_ty(&self,
1367 trait_ref: ty::TraitRef<'tcx>,
1368 item_name: ast::Name)
1371 self.normalize_associated_type(span, trait_ref, item_name)
1374 fn set_tainted_by_errors(&self) {
1375 self.infcx.set_tainted_by_errors()
1379 impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> {
1380 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1381 Some(self.base_object_lifetime_default(span))
1384 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1385 // RFC #599 specifies that object lifetime defaults take
1386 // precedence over other defaults. But within a fn body we
1387 // don't have a *default* region, rather we use inference to
1388 // find the *correct* region, which is strictly more general
1389 // (and anyway, within a fn body the right region may not even
1390 // be something the user can write explicitly, since it might
1391 // be some expression).
1392 self.next_region_var(infer::MiscVariable(span))
1395 fn anon_regions(&self, span: Span, count: usize)
1396 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1397 Ok((0..count).map(|_| {
1398 self.next_region_var(infer::MiscVariable(span))
1403 /// Controls whether the arguments are tupled. This is used for the call
1406 /// Tupling means that all call-side arguments are packed into a tuple and
1407 /// passed as a single parameter. For example, if tupling is enabled, this
1410 /// fn f(x: (isize, isize))
1412 /// Can be called as:
1419 #[derive(Clone, Eq, PartialEq)]
1420 enum TupleArgumentsFlag {
1425 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1426 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1427 rty: ty::FnOutput<'tcx>,
1428 body_id: ast::NodeId)
1429 -> FnCtxt<'a, 'gcx, 'tcx> {
1431 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1433 writeback_errors: Cell::new(false),
1434 err_count_on_creation: inh.tcx.sess.err_count(),
1436 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
1441 pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> {
1442 &self.parameter_environment
1445 pub fn sess(&self) -> &Session {
1449 pub fn err_count_since_creation(&self) -> usize {
1450 self.tcx.sess.err_count() - self.err_count_on_creation
1453 /// Resolves type variables in `ty` if possible. Unlike the infcx
1454 /// version (resolve_type_vars_if_possible), this version will
1455 /// also select obligations if it seems useful, in an effort
1456 /// to get more type information.
1457 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1458 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1460 // No TyInfer()? Nothing needs doing.
1461 if !ty.has_infer_types() {
1462 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1466 // If `ty` is a type variable, see whether we already know what it is.
1467 ty = self.resolve_type_vars_if_possible(&ty);
1468 if !ty.has_infer_types() {
1469 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1473 // If not, try resolving pending obligations as much as
1474 // possible. This can help substantially when there are
1475 // indirect dependencies that don't seem worth tracking
1477 self.select_obligations_where_possible();
1478 ty = self.resolve_type_vars_if_possible(&ty);
1480 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1484 fn record_deferred_call_resolution(&self,
1485 closure_def_id: DefId,
1486 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1487 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1488 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1491 fn remove_deferred_call_resolutions(&self,
1492 closure_def_id: DefId)
1493 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1495 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1496 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1499 pub fn tag(&self) -> String {
1500 let self_ptr: *const FnCtxt = self;
1501 format!("{:?}", self_ptr)
1504 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1505 match self.locals.borrow().get(&nid) {
1508 span_err!(self.tcx.sess, span, E0513,
1509 "no type for local variable {}",
1517 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1518 debug!("write_ty({}, {:?}) in fcx {}",
1519 node_id, ty, self.tag());
1520 self.tables.borrow_mut().node_types.insert(node_id, ty);
1523 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1524 if !substs.substs.is_noop() {
1525 debug!("write_substs({}, {:?}) in fcx {}",
1530 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1534 pub fn write_autoderef_adjustment(&self,
1535 node_id: ast::NodeId,
1537 self.write_adjustment(
1539 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1547 pub fn write_adjustment(&self,
1548 node_id: ast::NodeId,
1549 adj: adjustment::AutoAdjustment<'tcx>) {
1550 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1552 if adj.is_identity() {
1556 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1559 /// Basically whenever we are converting from a type scheme into
1560 /// the fn body space, we always want to normalize associated
1561 /// types as well. This function combines the two.
1562 fn instantiate_type_scheme<T>(&self,
1564 substs: &Substs<'tcx>,
1567 where T : TypeFoldable<'tcx>
1569 let value = value.subst(self.tcx, substs);
1570 let result = self.normalize_associated_types_in(span, &value);
1571 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1578 /// As `instantiate_type_scheme`, but for the bounds found in a
1579 /// generic type scheme.
1580 fn instantiate_bounds(&self,
1582 substs: &Substs<'tcx>,
1583 bounds: &ty::GenericPredicates<'tcx>)
1584 -> ty::InstantiatedPredicates<'tcx>
1586 ty::InstantiatedPredicates {
1587 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1592 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1593 where T : TypeFoldable<'tcx>
1595 self.inh.normalize_associated_types_in(span, self.body_id, value)
1598 fn normalize_associated_type(&self,
1600 trait_ref: ty::TraitRef<'tcx>,
1601 item_name: ast::Name)
1604 let cause = traits::ObligationCause::new(span,
1606 traits::ObligationCauseCode::MiscObligation);
1609 .normalize_projection_type(self,
1611 trait_ref: trait_ref,
1612 item_name: item_name,
1617 /// Instantiates the type in `did` with the generics in `path` and returns
1618 /// it (registering the necessary trait obligations along the way).
1620 /// Note that this function is only intended to be used with type-paths,
1621 /// not with value-paths.
1622 pub fn instantiate_type(&self,
1627 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1629 self.tcx.lookup_item_type(did);
1630 let type_predicates =
1631 self.tcx.lookup_predicates(did);
1632 let substs = AstConv::ast_path_substs_for_ty(self, self,
1634 PathParamMode::Optional,
1635 &type_scheme.generics,
1636 path.segments.last().unwrap());
1637 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1639 self.instantiate_bounds(path.span, &substs, &type_predicates);
1640 self.add_obligations_for_parameters(
1641 traits::ObligationCause::new(
1644 traits::ItemObligation(did)),
1647 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1650 /// Return the dict-like variant corresponding to a given `Def`.
1651 pub fn def_struct_variant(&self,
1654 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1656 let (adt, variant) = match def {
1657 Def::Variant(enum_id, variant_id) => {
1658 let adt = self.tcx.lookup_adt_def(enum_id);
1659 (adt, adt.variant_with_id(variant_id))
1661 Def::Struct(did) | Def::TyAlias(did) => {
1662 let typ = self.tcx.lookup_item_type(did);
1663 if let ty::TyStruct(adt, _) = typ.ty.sty {
1664 (adt, adt.struct_variant())
1672 let var_kind = variant.kind();
1673 if var_kind == ty::VariantKind::Struct {
1674 Some((adt, variant))
1675 } else if var_kind == ty::VariantKind::Unit {
1676 Some((adt, variant))
1682 pub fn write_nil(&self, node_id: ast::NodeId) {
1683 self.write_ty(node_id, self.tcx.mk_nil());
1685 pub fn write_error(&self, node_id: ast::NodeId) {
1686 self.write_ty(node_id, self.tcx.types.err);
1689 pub fn require_type_meets(&self,
1692 code: traits::ObligationCauseCode<'tcx>,
1693 bound: ty::BuiltinBound)
1695 self.register_builtin_bound(
1698 traits::ObligationCause::new(span, self.body_id, code));
1701 pub fn require_type_is_sized(&self,
1704 code: traits::ObligationCauseCode<'tcx>)
1706 self.require_type_meets(ty, span, code, ty::BoundSized);
1709 pub fn require_expr_have_sized_type(&self,
1711 code: traits::ObligationCauseCode<'tcx>)
1713 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1716 pub fn register_builtin_bound(&self,
1718 builtin_bound: ty::BuiltinBound,
1719 cause: traits::ObligationCause<'tcx>)
1721 self.fulfillment_cx.borrow_mut()
1722 .register_builtin_bound(self, ty, builtin_bound, cause);
1725 pub fn register_predicate(&self,
1726 obligation: traits::PredicateObligation<'tcx>)
1728 debug!("register_predicate({:?})",
1732 .register_predicate_obligation(self, obligation);
1735 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1736 let t = AstConv::ast_ty_to_ty(self, self, ast_t);
1737 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1741 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1742 match self.tables.borrow().node_types.get(&ex.id) {
1745 bug!("no type for expr in fcx {}", self.tag());
1750 /// Apply `adjustment` to the type of `expr`
1751 pub fn adjust_expr_ty(&self,
1753 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1756 let raw_ty = self.expr_ty(expr);
1757 let raw_ty = self.shallow_resolve(raw_ty);
1758 let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1759 raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| {
1760 self.tables.borrow().method_map.get(&method_call)
1761 .map(|method| resolve_ty(method.ty))
1765 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1766 match self.tables.borrow().node_types.get(&id) {
1768 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1770 bug!("no type for node {}: {} in fcx {}",
1771 id, self.tcx.map.node_to_string(id),
1777 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1778 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1779 // it changes when we upgrade the snapshot compiler
1780 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1781 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1785 Ref::map(self.tables.borrow(), project_item_susbts)
1788 pub fn opt_node_ty_substs<F>(&self,
1791 F: FnOnce(&ty::ItemSubsts<'tcx>),
1793 match self.tables.borrow().item_substs.get(&id) {
1799 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1800 /// outlive the region `r`.
1801 pub fn register_region_obligation(&self,
1804 cause: traits::ObligationCause<'tcx>)
1806 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1807 fulfillment_cx.register_region_obligation(ty, region, cause);
1810 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1811 /// outlive the region `r`.
1812 pub fn register_wf_obligation(&self,
1815 code: traits::ObligationCauseCode<'tcx>)
1817 // WF obligations never themselves fail, so no real need to give a detailed cause:
1818 let cause = traits::ObligationCause::new(span, self.body_id, code);
1819 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1822 pub fn register_old_wf_obligation(&self,
1825 code: traits::ObligationCauseCode<'tcx>)
1827 // Registers an "old-style" WF obligation that uses the
1828 // implicator code. This is basically a buggy version of
1829 // `register_wf_obligation` that is being kept around
1830 // temporarily just to help with phasing in the newer rules.
1832 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1833 let cause = traits::ObligationCause::new(span, self.body_id, code);
1834 self.register_region_obligation(ty, ty::ReEmpty, cause);
1837 /// Registers obligations that all types appearing in `substs` are well-formed.
1838 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1840 for &ty in &substs.types {
1841 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1845 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1846 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1847 /// trait/region obligations.
1849 /// For example, if there is a function:
1852 /// fn foo<'a,T:'a>(...)
1855 /// and a reference:
1861 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1862 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1863 pub fn add_obligations_for_parameters(&self,
1864 cause: traits::ObligationCause<'tcx>,
1865 predicates: &ty::InstantiatedPredicates<'tcx>)
1867 assert!(!predicates.has_escaping_regions());
1869 debug!("add_obligations_for_parameters(predicates={:?})",
1872 for obligation in traits::predicates_for_generics(cause, predicates) {
1873 self.register_predicate(obligation);
1877 // FIXME(arielb1): use this instead of field.ty everywhere
1878 // Only for fields! Returns <none> for methods>
1879 // Indifferent to privacy flags
1880 pub fn field_ty(&self,
1882 field: ty::FieldDef<'tcx>,
1883 substs: &Substs<'tcx>)
1886 self.normalize_associated_types_in(span,
1887 &field.ty(self.tcx, substs))
1890 fn check_casts(&self) {
1891 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1892 for cast in deferred_cast_checks.drain(..) {
1897 /// Apply "fallbacks" to some types
1898 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1899 fn default_type_parameters(&self) {
1900 use rustc::ty::error::UnconstrainedNumeric::Neither;
1901 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1903 // Defaulting inference variables becomes very dubious if we have
1904 // encountered type-checking errors. Therefore, if we think we saw
1905 // some errors in this function, just resolve all uninstanted type
1906 // varibles to TyError.
1907 if self.is_tainted_by_errors() {
1908 for ty in &self.unsolved_variables() {
1909 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1910 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1911 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx().types.err);
1917 for ty in &self.unsolved_variables() {
1918 let resolved = self.resolve_type_vars_if_possible(ty);
1919 if self.type_var_diverges(resolved) {
1920 debug!("default_type_parameters: defaulting `{:?}` to `()` because it diverges",
1922 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.mk_nil());
1924 match self.type_is_unconstrained_numeric(resolved) {
1925 UnconstrainedInt => {
1926 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1928 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.i32)
1930 UnconstrainedFloat => {
1931 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1933 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.f64)
1941 fn select_all_obligations_and_apply_defaults(&self) {
1942 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
1943 self.new_select_all_obligations_and_apply_defaults();
1945 self.old_select_all_obligations_and_apply_defaults();
1949 // Implements old type inference fallback algorithm
1950 fn old_select_all_obligations_and_apply_defaults(&self) {
1951 self.select_obligations_where_possible();
1952 self.default_type_parameters();
1953 self.select_obligations_where_possible();
1956 fn new_select_all_obligations_and_apply_defaults(&self) {
1957 use rustc::ty::error::UnconstrainedNumeric::Neither;
1958 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1960 // For the time being this errs on the side of being memory wasteful but provides better
1962 // let type_variables = self.type_variables.clone();
1964 // There is a possibility that this algorithm will have to run an arbitrary number of times
1965 // to terminate so we bound it by the compiler's recursion limit.
1966 for _ in 0..self.tcx.sess.recursion_limit.get() {
1967 // First we try to solve all obligations, it is possible that the last iteration
1968 // has made it possible to make more progress.
1969 self.select_obligations_where_possible();
1971 let mut conflicts = Vec::new();
1973 // Collect all unsolved type, integral and floating point variables.
1974 let unsolved_variables = self.unsolved_variables();
1976 // We must collect the defaults *before* we do any unification. Because we have
1977 // directly attached defaults to the type variables any unification that occurs
1978 // will erase defaults causing conflicting defaults to be completely ignored.
1979 let default_map: FnvHashMap<_, _> =
1982 .filter_map(|t| self.default(t).map(|d| (t, d)))
1985 let mut unbound_tyvars = HashSet::new();
1987 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1989 // We loop over the unsolved variables, resolving them and if they are
1990 // and unconstrainted numeric type we add them to the set of unbound
1991 // variables. We do this so we only apply literal fallback to type
1992 // variables without defaults.
1993 for ty in &unsolved_variables {
1994 let resolved = self.resolve_type_vars_if_possible(ty);
1995 if self.type_var_diverges(resolved) {
1996 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.mk_nil());
1998 match self.type_is_unconstrained_numeric(resolved) {
1999 UnconstrainedInt | UnconstrainedFloat => {
2000 unbound_tyvars.insert(resolved);
2007 // We now remove any numeric types that also have defaults, and instead insert
2008 // the type variable with a defined fallback.
2009 for ty in &unsolved_variables {
2010 if let Some(_default) = default_map.get(ty) {
2011 let resolved = self.resolve_type_vars_if_possible(ty);
2013 debug!("select_all_obligations_and_apply_defaults: \
2014 ty: {:?} with default: {:?}",
2017 match resolved.sty {
2018 ty::TyInfer(ty::TyVar(_)) => {
2019 unbound_tyvars.insert(ty);
2022 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
2023 unbound_tyvars.insert(ty);
2024 if unbound_tyvars.contains(resolved) {
2025 unbound_tyvars.remove(resolved);
2034 // If there are no more fallbacks to apply at this point we have applied all possible
2035 // defaults and type inference will proceed as normal.
2036 if unbound_tyvars.is_empty() {
2040 // Finally we go through each of the unbound type variables and unify them with
2041 // the proper fallback, reporting a conflicting default error if any of the
2042 // unifications fail. We know it must be a conflicting default because the
2043 // variable would only be in `unbound_tyvars` and have a concrete value if
2044 // it had been solved by previously applying a default.
2046 // We wrap this in a transaction for error reporting, if we detect a conflict
2047 // we will rollback the inference context to its prior state so we can probe
2048 // for conflicts and correctly report them.
2051 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2052 for ty in &unbound_tyvars {
2053 if self.type_var_diverges(ty) {
2054 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.mk_nil());
2056 match self.type_is_unconstrained_numeric(ty) {
2057 UnconstrainedInt => {
2058 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.i32)
2060 UnconstrainedFloat => {
2061 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.f64)
2064 if let Some(default) = default_map.get(ty) {
2065 let default = default.clone();
2066 match self.eq_types(false,
2067 TypeOrigin::Misc(default.origin_span),
2069 Ok(InferOk { obligations, .. }) => {
2070 // FIXME(#32730) propagate obligations
2071 assert!(obligations.is_empty())
2074 conflicts.push((*ty, default));
2083 // If there are conflicts we rollback, otherwise commit
2084 if conflicts.len() > 0 {
2091 if conflicts.len() > 0 {
2092 // Loop through each conflicting default, figuring out the default that caused
2093 // a unification failure and then report an error for each.
2094 for (conflict, default) in conflicts {
2095 let conflicting_default =
2096 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
2097 .unwrap_or(type_variable::Default {
2098 ty: self.next_ty_var(),
2099 origin_span: codemap::DUMMY_SP,
2100 def_id: self.tcx.map.local_def_id(0) // what do I put here?
2103 // This is to ensure that we elimnate any non-determinism from the error
2104 // reporting by fixing an order, it doesn't matter what order we choose
2105 // just that it is consistent.
2106 let (first_default, second_default) =
2107 if default.def_id < conflicting_default.def_id {
2108 (default, conflicting_default)
2110 (conflicting_default, default)
2114 self.report_conflicting_default_types(
2115 first_default.origin_span,
2122 self.select_obligations_where_possible();
2125 // For use in error handling related to default type parameter fallback. We explicitly
2126 // apply the default that caused conflict first to a local version of the type variable
2127 // table then apply defaults until we find a conflict. That default must be the one
2128 // that caused conflict earlier.
2129 fn find_conflicting_default(&self,
2130 unbound_vars: &HashSet<Ty<'tcx>>,
2131 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
2133 -> Option<type_variable::Default<'tcx>> {
2134 use rustc::ty::error::UnconstrainedNumeric::Neither;
2135 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2137 // Ensure that we apply the conflicting default first
2138 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2139 unbound_tyvars.push(conflict);
2140 unbound_tyvars.extend(unbound_vars.iter());
2142 let mut result = None;
2143 // We run the same code as above applying defaults in order, this time when
2144 // we find the conflict we just return it for error reporting above.
2146 // We also run this inside snapshot that never commits so we can do error
2147 // reporting for more then one conflict.
2148 for ty in &unbound_tyvars {
2149 if self.type_var_diverges(ty) {
2150 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.mk_nil());
2152 match self.type_is_unconstrained_numeric(ty) {
2153 UnconstrainedInt => {
2154 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.i32)
2156 UnconstrainedFloat => {
2157 self.demand_eqtype(codemap::DUMMY_SP, *ty, self.tcx.types.f64)
2160 if let Some(default) = default_map.get(ty) {
2161 let default = default.clone();
2162 match self.eq_types(false,
2163 TypeOrigin::Misc(default.origin_span),
2165 // FIXME(#32730) propagate obligations
2166 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2168 result = Some(default);
2180 fn select_all_obligations_or_error(&self) {
2181 debug!("select_all_obligations_or_error");
2183 // upvar inference should have ensured that all deferred call
2184 // resolutions are handled by now.
2185 assert!(self.deferred_call_resolutions.borrow().is_empty());
2187 self.select_all_obligations_and_apply_defaults();
2189 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2190 match fulfillment_cx.select_all_or_error(self) {
2192 Err(errors) => { self.report_fulfillment_errors(&errors); }
2195 if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(self) {
2196 self.report_fulfillment_errors_as_warnings(errors, self.body_id);
2200 /// Select as many obligations as we can at present.
2201 fn select_obligations_where_possible(&self) {
2202 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2204 Err(errors) => { self.report_fulfillment_errors(&errors); }
2208 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2209 /// returns a type of `&T`, but the actual type we assign to the
2210 /// *expression* is `T`. So this function just peels off the return
2211 /// type by one layer to yield `T`.
2212 fn make_overloaded_lvalue_return_type(&self,
2213 method: MethodCallee<'tcx>)
2214 -> ty::TypeAndMut<'tcx>
2216 // extract method return type, which will be &T;
2217 // all LB regions should have been instantiated during method lookup
2218 let ret_ty = method.ty.fn_ret();
2219 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap().unwrap();
2221 // method returns &T, but the type as visible to user is T, so deref
2222 ret_ty.builtin_deref(true, NoPreference).unwrap()
2225 fn lookup_indexing(&self,
2227 base_expr: &'gcx hir::Expr,
2230 lvalue_pref: LvaluePreference)
2231 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2233 // FIXME(#18741) -- this is almost but not quite the same as the
2234 // autoderef that normal method probing does. They could likely be
2237 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2239 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2240 if let Some(final_mt) = self.try_index_step(
2241 MethodCall::expr(expr.id),
2242 expr, base_expr, adj_ty, autoderefs,
2243 false, lvalue_pref, idx_ty)
2245 autoderef.finalize(lvalue_pref, Some(base_expr));
2246 return Some(final_mt);
2249 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2250 autoderef.finalize(lvalue_pref, Some(base_expr));
2251 let adjusted_ty = self.tcx.mk_slice(element_ty);
2252 return self.try_index_step(
2253 MethodCall::expr(expr.id), expr, base_expr,
2254 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2257 autoderef.unambiguous_final_ty();
2261 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2262 /// (and otherwise adjust) `base_expr`, looking for a type which either
2263 /// supports builtin indexing or overloaded indexing.
2264 /// This loop implements one step in that search; the autoderef loop
2265 /// is implemented by `lookup_indexing`.
2266 fn try_index_step(&self,
2267 method_call: MethodCall,
2269 base_expr: &'gcx hir::Expr,
2270 adjusted_ty: Ty<'tcx>,
2273 lvalue_pref: LvaluePreference,
2275 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2278 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2279 autoderefs={}, unsize={}, index_ty={:?})",
2287 let input_ty = self.next_ty_var();
2289 // First, try built-in indexing.
2290 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2291 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2292 debug!("try_index_step: success, using built-in indexing");
2293 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2295 self.write_autoderef_adjustment(base_expr.id, autoderefs);
2296 return Some((tcx.types.usize, ty));
2301 // Try `IndexMut` first, if preferred.
2302 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2303 (PreferMutLvalue, Some(trait_did)) => {
2304 self.lookup_method_in_trait_adjusted(expr.span,
2306 token::intern("index_mut"),
2311 Some(vec![input_ty]))
2316 // Otherwise, fall back to `Index`.
2317 let method = match (method, tcx.lang_items.index_trait()) {
2318 (None, Some(trait_did)) => {
2319 self.lookup_method_in_trait_adjusted(expr.span,
2321 token::intern("index"),
2326 Some(vec![input_ty]))
2328 (method, _) => method,
2331 // If some lookup succeeds, write callee into table and extract index/element
2332 // type from the method signature.
2333 // If some lookup succeeded, install method in table
2334 method.map(|method| {
2335 debug!("try_index_step: success, using overloaded indexing");
2336 self.tables.borrow_mut().method_map.insert(method_call, method);
2337 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2341 fn check_method_argument_types(&self,
2343 method_fn_ty: Ty<'tcx>,
2344 callee_expr: &'gcx hir::Expr,
2345 args_no_rcvr: &'gcx [P<hir::Expr>],
2346 tuple_arguments: TupleArgumentsFlag,
2347 expected: Expectation<'tcx>)
2348 -> ty::FnOutput<'tcx> {
2349 if method_fn_ty.references_error() {
2350 let err_inputs = self.err_args(args_no_rcvr.len());
2352 let err_inputs = match tuple_arguments {
2353 DontTupleArguments => err_inputs,
2354 TupleArguments => vec![self.tcx.mk_tup(err_inputs)],
2357 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2358 false, tuple_arguments);
2359 ty::FnConverging(self.tcx.types.err)
2361 match method_fn_ty.sty {
2362 ty::TyFnDef(_, _, ref fty) => {
2363 // HACK(eddyb) ignore self in the definition (see above).
2364 let expected_arg_tys = self.expected_types_for_fn_args(sp, expected,
2366 &fty.sig.0.inputs[1..]);
2367 self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..],
2368 args_no_rcvr, fty.sig.0.variadic, tuple_arguments);
2372 span_bug!(callee_expr.span, "method without bare fn type");
2378 /// Generic function that factors out common logic from function calls,
2379 /// method calls and overloaded operators.
2380 fn check_argument_types(&self,
2382 fn_inputs: &[Ty<'tcx>],
2383 expected_arg_tys: &[Ty<'tcx>],
2384 args: &'gcx [P<hir::Expr>],
2386 tuple_arguments: TupleArgumentsFlag) {
2389 // Grab the argument types, supplying fresh type variables
2390 // if the wrong number of arguments were supplied
2391 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2397 // All the input types from the fn signature must outlive the call
2398 // so as to validate implied bounds.
2399 for &fn_input_ty in fn_inputs {
2400 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2403 let mut expected_arg_tys = expected_arg_tys;
2404 let expected_arg_count = fn_inputs.len();
2405 let formal_tys = if tuple_arguments == TupleArguments {
2406 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2407 match tuple_type.sty {
2408 ty::TyTuple(arg_types) => {
2409 if arg_types.len() != args.len() {
2410 span_err!(tcx.sess, sp, E0057,
2411 "this function takes {} parameter{} but {} parameter{} supplied",
2413 if arg_types.len() == 1 {""} else {"s"},
2415 if args.len() == 1 {" was"} else {"s were"});
2416 expected_arg_tys = &[];
2417 self.err_args(args.len())
2419 expected_arg_tys = match expected_arg_tys.get(0) {
2420 Some(&ty) => match ty.sty {
2421 ty::TyTuple(ref tys) => &tys,
2430 span_err!(tcx.sess, sp, E0059,
2431 "cannot use call notation; the first type parameter \
2432 for the function trait is neither a tuple nor unit");
2433 expected_arg_tys = &[];
2434 self.err_args(args.len())
2437 } else if expected_arg_count == supplied_arg_count {
2439 } else if variadic {
2440 if supplied_arg_count >= expected_arg_count {
2443 span_err!(tcx.sess, sp, E0060,
2444 "this function takes at least {} parameter{} \
2445 but {} parameter{} supplied",
2447 if expected_arg_count == 1 {""} else {"s"},
2449 if supplied_arg_count == 1 {" was"} else {"s were"});
2450 expected_arg_tys = &[];
2451 self.err_args(supplied_arg_count)
2454 span_err!(tcx.sess, sp, E0061,
2455 "this function takes {} parameter{} but {} parameter{} supplied",
2457 if expected_arg_count == 1 {""} else {"s"},
2459 if supplied_arg_count == 1 {" was"} else {"s were"});
2460 expected_arg_tys = &[];
2461 self.err_args(supplied_arg_count)
2464 debug!("check_argument_types: formal_tys={:?}",
2465 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2467 // Check the arguments.
2468 // We do this in a pretty awful way: first we typecheck any arguments
2469 // that are not anonymous functions, then we typecheck the anonymous
2470 // functions. This is so that we have more information about the types
2471 // of arguments when we typecheck the functions. This isn't really the
2472 // right way to do this.
2473 let xs = [false, true];
2474 let mut any_diverges = false; // has any of the arguments diverged?
2475 let mut warned = false; // have we already warned about unreachable code?
2476 for check_blocks in &xs {
2477 let check_blocks = *check_blocks;
2478 debug!("check_blocks={}", check_blocks);
2480 // More awful hacks: before we check argument types, try to do
2481 // an "opportunistic" vtable resolution of any trait bounds on
2482 // the call. This helps coercions.
2484 self.select_obligations_where_possible();
2487 // For variadic functions, we don't have a declared type for all of
2488 // the arguments hence we only do our usual type checking with
2489 // the arguments who's types we do know.
2490 let t = if variadic {
2492 } else if tuple_arguments == TupleArguments {
2497 for (i, arg) in args.iter().take(t).enumerate() {
2498 if any_diverges && !warned {
2501 .add_lint(lint::builtin::UNREACHABLE_CODE,
2504 "unreachable expression".to_string());
2507 let is_block = match arg.node {
2508 hir::ExprClosure(..) => true,
2512 if is_block == check_blocks {
2513 debug!("checking the argument");
2514 let formal_ty = formal_tys[i];
2516 // The special-cased logic below has three functions:
2517 // 1. Provide as good of an expected type as possible.
2518 let expected = expected_arg_tys.get(i).map(|&ty| {
2519 Expectation::rvalue_hint(self, ty)
2522 self.check_expr_with_expectation(&arg,
2523 expected.unwrap_or(ExpectHasType(formal_ty)));
2524 // 2. Coerce to the most detailed type that could be coerced
2525 // to, which is `expected_ty` if `rvalue_hint` returns an
2526 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2527 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2528 self.demand_coerce(&arg, coerce_ty.unwrap_or(formal_ty));
2530 // 3. Relate the expected type and the formal one,
2531 // if the expected type was used for the coercion.
2532 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2535 if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) {
2536 any_diverges = any_diverges || self.type_var_diverges(arg_ty);
2539 if any_diverges && !warned {
2540 let parent = self.tcx.map.get_parent_node(args[0].id);
2543 .add_lint(lint::builtin::UNREACHABLE_CODE,
2546 "unreachable call".to_string());
2552 // We also need to make sure we at least write the ty of the other
2553 // arguments which we skipped above.
2555 for arg in args.iter().skip(expected_arg_count) {
2556 self.check_expr(&arg);
2558 // There are a few types which get autopromoted when passed via varargs
2559 // in C but we just error out instead and require explicit casts.
2560 let arg_ty = self.structurally_resolved_type(arg.span,
2561 self.expr_ty(&arg));
2563 ty::TyFloat(ast::FloatTy::F32) => {
2564 self.type_error_message(arg.span, |t| {
2565 format!("can't pass an `{}` to variadic \
2566 function, cast to `c_double`", t)
2569 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2570 self.type_error_message(arg.span, |t| {
2571 format!("can't pass `{}` to variadic \
2572 function, cast to `c_int`",
2576 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2577 self.type_error_message(arg.span, |t| {
2578 format!("can't pass `{}` to variadic \
2579 function, cast to `c_uint`",
2583 ty::TyFnDef(_, _, f) => {
2584 let ptr_ty = self.tcx.mk_fn_ptr(f);
2585 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2586 self.type_error_message(arg.span,
2588 format!("can't pass `{}` to variadic \
2589 function, cast to `{}`", t, ptr_ty)
2598 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2599 (0..len).map(|_| self.tcx.types.err).collect()
2602 fn write_call(&self,
2603 call_expr: &hir::Expr,
2604 output: ty::FnOutput<'tcx>) {
2605 self.write_ty(call_expr.id, match output {
2606 ty::FnConverging(output_ty) => output_ty,
2607 ty::FnDiverging => self.next_diverging_ty_var()
2611 // AST fragment checking
2614 expected: Expectation<'tcx>)
2620 ast::LitKind::Str(..) => tcx.mk_static_str(),
2621 ast::LitKind::ByteStr(ref v) => {
2622 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2623 tcx.mk_array(tcx.types.u8, v.len()))
2625 ast::LitKind::Byte(_) => tcx.types.u8,
2626 ast::LitKind::Char(_) => tcx.types.char,
2627 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2628 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2629 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2630 let opt_ty = expected.to_option(self).and_then(|ty| {
2632 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2633 ty::TyChar => Some(tcx.types.u8),
2634 ty::TyRawPtr(..) => Some(tcx.types.usize),
2635 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2639 opt_ty.unwrap_or_else(
2640 || tcx.mk_int_var(self.next_int_var_id()))
2642 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2643 ast::LitKind::FloatUnsuffixed(_) => {
2644 let opt_ty = expected.to_option(self).and_then(|ty| {
2646 ty::TyFloat(_) => Some(ty),
2650 opt_ty.unwrap_or_else(
2651 || tcx.mk_float_var(self.next_float_var_id()))
2653 ast::LitKind::Bool(_) => tcx.types.bool
2657 fn check_expr_eq_type(&self,
2658 expr: &'gcx hir::Expr,
2659 expected: Ty<'tcx>) {
2660 self.check_expr_with_hint(expr, expected);
2661 self.demand_eqtype(expr.span, expected, self.expr_ty(expr));
2664 pub fn check_expr_has_type(&self,
2665 expr: &'gcx hir::Expr,
2666 expected: Ty<'tcx>) {
2667 self.check_expr_with_hint(expr, expected);
2668 self.demand_suptype(expr.span, expected, self.expr_ty(expr));
2671 fn check_expr_coercable_to_type(&self,
2672 expr: &'gcx hir::Expr,
2673 expected: Ty<'tcx>) {
2674 self.check_expr_with_hint(expr, expected);
2675 self.demand_coerce(expr, expected);
2678 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2679 expected: Ty<'tcx>) {
2680 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2683 fn check_expr_with_expectation(&self,
2684 expr: &'gcx hir::Expr,
2685 expected: Expectation<'tcx>) {
2686 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2689 fn check_expr(&self, expr: &'gcx hir::Expr) {
2690 self.check_expr_with_expectation(expr, NoExpectation)
2693 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2694 lvalue_pref: LvaluePreference) {
2695 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2698 // determine the `self` type, using fresh variables for all variables
2699 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2700 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2702 pub fn impl_self_ty(&self,
2703 span: Span, // (potential) receiver for this impl
2705 -> TypeAndSubsts<'tcx> {
2708 let ity = tcx.lookup_item_type(did);
2709 let (tps, rps, raw_ty) =
2710 (ity.generics.types.get_slice(subst::TypeSpace),
2711 ity.generics.regions.get_slice(subst::TypeSpace),
2714 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2716 let rps = self.region_vars_for_defs(span, rps);
2717 let mut substs = subst::Substs::new(
2718 VecPerParamSpace::empty(),
2719 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2720 self.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2721 let substd_ty = self.instantiate_type_scheme(span, &substs, &raw_ty);
2723 TypeAndSubsts { substs: substs, ty: substd_ty }
2726 /// Unifies the return type with the expected type early, for more coercions
2727 /// and forward type information on the argument expressions.
2728 fn expected_types_for_fn_args(&self,
2730 expected_ret: Expectation<'tcx>,
2731 formal_ret: ty::FnOutput<'tcx>,
2732 formal_args: &[Ty<'tcx>])
2734 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2735 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2736 self.commit_regions_if_ok(|| {
2737 // Attempt to apply a subtyping relationship between the formal
2738 // return type (likely containing type variables if the function
2739 // is polymorphic) and the expected return type.
2740 // No argument expectations are produced if unification fails.
2741 let origin = TypeOrigin::Misc(call_span);
2742 let ures = self.sub_types(false, origin, formal_ret_ty, ret_ty);
2743 // FIXME(#15760) can't use try! here, FromError doesn't default
2744 // to identity so the resulting type is not constrained.
2746 // FIXME(#32730) propagate obligations
2747 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2748 Err(e) => return Err(e),
2751 // Record all the argument types, with the substitutions
2752 // produced from the above subtyping unification.
2753 Ok(formal_args.iter().map(|ty| {
2754 self.resolve_type_vars_if_possible(ty)
2760 }).unwrap_or(vec![]);
2761 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2762 formal_args, formal_ret,
2763 expected_args, expected_ret);
2767 // Checks a method call.
2768 fn check_method_call(&self,
2769 expr: &'gcx hir::Expr,
2770 method_name: Spanned<ast::Name>,
2771 args: &'gcx [P<hir::Expr>],
2773 expected: Expectation<'tcx>,
2774 lvalue_pref: LvaluePreference) {
2775 let rcvr = &args[0];
2776 self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2778 // no need to check for bot/err -- callee does that
2779 let expr_t = self.structurally_resolved_type(expr.span, self.expr_ty(&rcvr));
2781 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2782 let fn_ty = match self.lookup_method(method_name.span,
2789 let method_ty = method.ty;
2790 let method_call = MethodCall::expr(expr.id);
2791 self.tables.borrow_mut().method_map.insert(method_call, method);
2795 if method_name.node != keywords::Invalid.name() {
2796 self.report_method_error(method_name.span, expr_t,
2797 method_name.node, Some(rcvr), error);
2799 self.write_error(expr.id);
2804 // Call the generic checker.
2805 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2810 self.write_call(expr, ret_ty);
2813 // A generic function for checking the then and else in an if
2815 fn check_then_else(&self,
2816 cond_expr: &'gcx hir::Expr,
2817 then_blk: &'gcx hir::Block,
2818 opt_else_expr: Option<&'gcx hir::Expr>,
2821 expected: Expectation<'tcx>) {
2822 self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2824 let expected = expected.adjust_for_branches(self);
2825 self.check_block_with_expected(then_blk, expected);
2826 let then_ty = self.node_ty(then_blk.id);
2828 let unit = self.tcx.mk_nil();
2829 let (origin, expected, found, result) =
2830 if let Some(else_expr) = opt_else_expr {
2831 self.check_expr_with_expectation(else_expr, expected);
2832 let else_ty = self.expr_ty(else_expr);
2833 let origin = TypeOrigin::IfExpression(sp);
2835 // Only try to coerce-unify if we have a then expression
2836 // to assign coercions to, otherwise it's () or diverging.
2837 let result = if let Some(ref then) = then_blk.expr {
2838 let res = self.try_find_coercion_lub(origin, || Some(&**then),
2839 then_ty, else_expr);
2841 // In case we did perform an adjustment, we have to update
2842 // the type of the block, because old trans still uses it.
2843 let adj = self.tables.borrow().adjustments.get(&then.id).cloned();
2844 if res.is_ok() && adj.is_some() {
2845 self.write_ty(then_blk.id, self.adjust_expr_ty(then, adj.as_ref()));
2850 self.commit_if_ok(|_| {
2851 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2852 self.lub(true, trace, &then_ty, &else_ty)
2853 .map(|InferOk { value, obligations }| {
2854 // FIXME(#32730) propagate obligations
2855 assert!(obligations.is_empty());
2860 (origin, then_ty, else_ty, result)
2862 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2863 (origin, unit, then_ty,
2864 self.eq_types(true, origin, unit, then_ty)
2865 .map(|InferOk { obligations, .. }| {
2866 // FIXME(#32730) propagate obligations
2867 assert!(obligations.is_empty());
2872 let if_ty = match result {
2874 if self.expr_ty(cond_expr).references_error() {
2881 self.report_mismatched_types(origin, expected, found, e);
2886 self.write_ty(id, if_ty);
2889 // Check field access expressions
2890 fn check_field(&self,
2891 expr: &'gcx hir::Expr,
2892 lvalue_pref: LvaluePreference,
2893 base: &'gcx hir::Expr,
2894 field: &Spanned<ast::Name>) {
2895 self.check_expr_with_lvalue_pref(base, lvalue_pref);
2896 let expr_t = self.structurally_resolved_type(expr.span,
2897 self.expr_ty(base));
2898 let mut private_candidate = None;
2899 let mut autoderef = self.autoderef(expr.span, expr_t);
2900 while let Some((base_t, autoderefs)) = autoderef.next() {
2901 if let ty::TyStruct(base_def, substs) = base_t.sty {
2902 debug!("struct named {:?}", base_t);
2903 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2904 let field_ty = self.field_ty(expr.span, field, substs);
2905 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
2906 autoderef.finalize(lvalue_pref, Some(base));
2907 self.write_ty(expr.id, field_ty);
2908 self.write_autoderef_adjustment(base.id, autoderefs);
2911 private_candidate = Some((base_def.did, field_ty));
2915 autoderef.unambiguous_final_ty();
2917 if let Some((did, field_ty)) = private_candidate {
2918 let struct_path = self.tcx().item_path_str(did);
2919 self.write_ty(expr.id, field_ty);
2920 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2921 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2922 // Also check if an accessible method exists, which is often what is meant.
2923 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2924 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2928 } else if field.node == keywords::Invalid.name() {
2929 self.write_error(expr.id);
2930 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2931 self.type_error_struct(field.span, |actual| {
2932 format!("attempted to take value of method `{}` on type \
2933 `{}`", field.node, actual)
2936 "maybe a `()` to call it is missing? \
2937 If not, try an anonymous function")
2939 self.write_error(expr.id);
2941 let mut err = self.type_error_struct(expr.span, |actual| {
2942 format!("attempted access of field `{}` on type `{}`, \
2943 but no field with that name was found",
2946 if let ty::TyStruct(def, _) = expr_t.sty {
2947 Self::suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2950 self.write_error(expr.id);
2954 // displays hints about the closest matches in field names
2955 fn suggest_field_names(err: &mut DiagnosticBuilder,
2956 variant: ty::VariantDef<'tcx>,
2957 field: &Spanned<ast::Name>,
2958 skip : Vec<InternedString>) {
2959 let name = field.node.as_str();
2960 let names = variant.fields.iter().filter_map(|field| {
2961 // ignore already set fields and private fields from non-local crates
2962 if skip.iter().any(|x| *x == field.name.as_str()) ||
2963 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2970 // only find fits with at least one matching letter
2971 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2972 err.span_help(field.span,
2973 &format!("did you mean `{}`?", name));
2977 // Check tuple index expressions
2978 fn check_tup_field(&self,
2979 expr: &'gcx hir::Expr,
2980 lvalue_pref: LvaluePreference,
2981 base: &'gcx hir::Expr,
2982 idx: codemap::Spanned<usize>) {
2983 self.check_expr_with_lvalue_pref(base, lvalue_pref);
2984 let expr_t = self.structurally_resolved_type(expr.span,
2985 self.expr_ty(base));
2986 let mut private_candidate = None;
2987 let mut tuple_like = false;
2988 let mut autoderef = self.autoderef(expr.span, expr_t);
2989 while let Some((base_t, autoderefs)) = autoderef.next() {
2990 let field = match base_t.sty {
2991 ty::TyStruct(base_def, substs) => {
2992 tuple_like = base_def.struct_variant().is_tuple_struct();
2993 if !tuple_like { continue }
2995 debug!("tuple struct named {:?}", base_t);
2996 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
2997 let field_ty = self.field_ty(expr.span, field, substs);
2998 private_candidate = Some((base_def.did, field_ty));
2999 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
3006 ty::TyTuple(ref v) => {
3008 v.get(idx.node).cloned()
3013 if let Some(field_ty) = field {
3014 autoderef.finalize(lvalue_pref, Some(base));
3015 self.write_ty(expr.id, field_ty);
3016 self.write_autoderef_adjustment(base.id, autoderefs);
3020 autoderef.unambiguous_final_ty();
3022 if let Some((did, field_ty)) = private_candidate {
3023 let struct_path = self.tcx().item_path_str(did);
3024 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3025 self.tcx().sess.span_err(expr.span, &msg);
3026 self.write_ty(expr.id, field_ty);
3030 self.type_error_message(
3034 format!("attempted out-of-bounds tuple index `{}` on \
3039 format!("attempted tuple index `{}` on type `{}`, but the \
3040 type was not a tuple or tuple struct",
3047 self.write_error(expr.id);
3050 fn report_unknown_field(&self,
3052 variant: ty::VariantDef<'tcx>,
3054 skip_fields: &[hir::Field]) {
3055 let mut err = self.type_error_struct(
3057 |actual| if let ty::TyEnum(..) = ty.sty {
3058 format!("struct variant `{}::{}` has no field named `{}`",
3059 actual, variant.name.as_str(), field.name.node)
3061 format!("structure `{}` has no field named `{}`",
3062 actual, field.name.node)
3066 // prevent all specified fields from being suggested
3067 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3068 Self::suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3072 fn check_expr_struct_fields(&self,
3075 variant: ty::VariantDef<'tcx>,
3076 ast_fields: &'gcx [hir::Field],
3077 check_completeness: bool) {
3079 let substs = match adt_ty.sty {
3080 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3081 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3084 let mut remaining_fields = FnvHashMap();
3085 for field in &variant.fields {
3086 remaining_fields.insert(field.name, field);
3089 let mut error_happened = false;
3091 // Typecheck each field.
3092 for field in ast_fields {
3093 let expected_field_type;
3095 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3096 expected_field_type = self.field_ty(field.span, v_field, substs);
3098 error_happened = true;
3099 expected_field_type = tcx.types.err;
3100 if let Some(_) = variant.find_field_named(field.name.node) {
3101 span_err!(self.tcx.sess, field.name.span, E0062,
3102 "field `{}` specified more than once",
3105 self.report_unknown_field(adt_ty, variant, field, ast_fields);
3109 // Make sure to give a type to the field even if there's
3110 // an error, so we can continue typechecking
3111 self.check_expr_coercable_to_type(&field.expr, expected_field_type);
3114 // Make sure the programmer specified all the fields.
3115 if check_completeness &&
3117 !remaining_fields.is_empty()
3119 span_err!(tcx.sess, span, E0063,
3120 "missing field{} {} in initializer of `{}`",
3121 if remaining_fields.len() == 1 {""} else {"s"},
3122 remaining_fields.keys()
3123 .map(|n| format!("`{}`", n))
3124 .collect::<Vec<_>>()
3131 fn check_struct_fields_on_error(&self,
3133 fields: &'gcx [hir::Field],
3134 base_expr: &'gcx Option<P<hir::Expr>>) {
3135 // Make sure to still write the types
3136 // otherwise we might ICE
3137 self.write_error(id);
3138 for field in fields {
3139 self.check_expr(&field.expr);
3142 Some(ref base) => self.check_expr(&base),
3147 fn check_expr_struct(&self,
3150 fields: &'gcx [hir::Field],
3151 base_expr: &'gcx Option<P<hir::Expr>>)
3155 // Find the relevant variant
3156 let def = tcx.expect_def(expr.id);
3157 if def == Def::Err {
3158 self.set_tainted_by_errors();
3159 self.check_struct_fields_on_error(expr.id, fields, base_expr);
3162 let variant = match self.def_struct_variant(def, path.span) {
3163 Some((_, variant)) => variant,
3165 span_err!(self.tcx.sess, path.span, E0071,
3166 "`{}` does not name a structure",
3167 pprust::path_to_string(path));
3168 self.check_struct_fields_on_error(expr.id, fields, base_expr);
3173 let expr_ty = self.instantiate_type(def.def_id(), path);
3174 self.write_ty(expr.id, expr_ty);
3176 self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
3177 base_expr.is_none());
3178 if let &Some(ref base_expr) = base_expr {
3179 self.check_expr_has_type(base_expr, expr_ty);
3181 ty::TyStruct(adt, substs) => {
3182 self.tables.borrow_mut().fru_field_types.insert(
3184 adt.struct_variant().fields.iter().map(|f| {
3185 self.normalize_associated_types_in(
3186 expr.span, &f.ty(tcx, substs)
3192 span_err!(tcx.sess, base_expr.span, E0436,
3193 "functional record update syntax requires a struct");
3201 /// If an expression has any sub-expressions that result in a type error,
3202 /// inspecting that expression's type with `ty.references_error()` will return
3203 /// true. Likewise, if an expression is known to diverge, inspecting its
3204 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3205 /// strict, _|_ can appear in the type of an expression that does not,
3206 /// itself, diverge: for example, fn() -> _|_.)
3207 /// Note that inspecting a type's structure *directly* may expose the fact
3208 /// that there are actually multiple representations for `TyError`, so avoid
3209 /// that when err needs to be handled differently.
3210 fn check_expr_with_expectation_and_lvalue_pref(&self,
3211 expr: &'gcx hir::Expr,
3212 expected: Expectation<'tcx>,
3213 lvalue_pref: LvaluePreference) {
3214 debug!(">> typechecking: expr={:?} expected={:?}",
3220 hir::ExprBox(ref subexpr) => {
3221 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3223 ty::TyBox(ty) => Expectation::rvalue_hint(self, ty),
3227 self.check_expr_with_expectation(subexpr, expected_inner);
3228 let referent_ty = self.expr_ty(&subexpr);
3229 self.write_ty(id, tcx.mk_box(referent_ty));
3232 hir::ExprLit(ref lit) => {
3233 let typ = self.check_lit(&lit, expected);
3234 self.write_ty(id, typ);
3236 hir::ExprBinary(op, ref lhs, ref rhs) => {
3237 self.check_binop(expr, op, lhs, rhs);
3239 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3240 self.check_binop_assign(expr, op, lhs, rhs);
3242 hir::ExprUnary(unop, ref oprnd) => {
3243 let expected_inner = match unop {
3244 hir::UnNot | hir::UnNeg => {
3251 let lvalue_pref = match unop {
3252 hir::UnDeref => lvalue_pref,
3255 self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3258 let mut oprnd_t = self.expr_ty(&oprnd);
3260 if !oprnd_t.references_error() {
3263 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3265 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3267 } else if let Some(method) = self.try_overloaded_deref(
3268 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3269 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3270 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3273 self.type_error_message(expr.span, |actual| {
3274 format!("type `{}` cannot be \
3275 dereferenced", actual)
3277 oprnd_t = tcx.types.err;
3281 oprnd_t = self.structurally_resolved_type(oprnd.span,
3283 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3284 oprnd_t = self.check_user_unop("!", "not",
3285 tcx.lang_items.not_trait(),
3286 expr, &oprnd, oprnd_t, unop);
3290 oprnd_t = self.structurally_resolved_type(oprnd.span,
3292 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3293 oprnd_t = self.check_user_unop("-", "neg",
3294 tcx.lang_items.neg_trait(),
3295 expr, &oprnd, oprnd_t, unop);
3300 self.write_ty(id, oprnd_t);
3302 hir::ExprAddrOf(mutbl, ref oprnd) => {
3303 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3305 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3306 if self.tcx.expr_is_lval(&oprnd) {
3307 // Lvalues may legitimately have unsized types.
3308 // For example, dereferences of a fat pointer and
3309 // the last field of a struct can be unsized.
3310 ExpectHasType(mt.ty)
3312 Expectation::rvalue_hint(self, mt.ty)
3318 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3319 self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3321 let tm = ty::TypeAndMut { ty: self.expr_ty(&oprnd), mutbl: mutbl };
3322 let oprnd_t = if tm.ty.references_error() {
3325 // Note: at this point, we cannot say what the best lifetime
3326 // is to use for resulting pointer. We want to use the
3327 // shortest lifetime possible so as to avoid spurious borrowck
3328 // errors. Moreover, the longest lifetime will depend on the
3329 // precise details of the value whose address is being taken
3330 // (and how long it is valid), which we don't know yet until type
3331 // inference is complete.
3333 // Therefore, here we simply generate a region variable. The
3334 // region inferencer will then select the ultimate value.
3335 // Finally, borrowck is charged with guaranteeing that the
3336 // value whose address was taken can actually be made to live
3337 // as long as it needs to live.
3338 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3339 tcx.mk_ref(tcx.mk_region(region), tm)
3341 self.write_ty(id, oprnd_t);
3343 hir::ExprPath(ref maybe_qself, ref path) => {
3344 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3345 self.to_ty(&qself.ty)
3348 let path_res = tcx.expect_resolution(id);
3349 if let Some((opt_ty, segments, def)) =
3350 self.resolve_ty_and_def_ufcs(path_res, opt_self_ty, path,
3351 expr.span, expr.id) {
3352 if def != Def::Err {
3353 let (scheme, predicates) = self.type_scheme_and_predicates_for_def(expr.span,
3355 self.instantiate_path(segments, scheme, &predicates,
3356 opt_ty, def, expr.span, id);
3358 self.set_tainted_by_errors();
3359 self.write_ty(id, self.tcx.types.err);
3363 // We always require that the type provided as the value for
3364 // a type parameter outlives the moment of instantiation.
3365 self.opt_node_ty_substs(expr.id, |item_substs| {
3366 self.add_wf_bounds(&item_substs.substs, expr);
3369 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3370 for output in outputs {
3371 self.check_expr(output);
3373 for input in inputs {
3374 self.check_expr(input);
3378 hir::ExprBreak(_) => { self.write_ty(id, self.next_diverging_ty_var()); }
3379 hir::ExprAgain(_) => { self.write_ty(id, self.next_diverging_ty_var()); }
3380 hir::ExprRet(ref expr_opt) => {
3382 ty::FnConverging(result_type) => {
3383 if let Some(ref e) = *expr_opt {
3384 self.check_expr_coercable_to_type(&e, result_type);
3386 let eq_result = self.eq_types(false,
3387 TypeOrigin::Misc(expr.span),
3390 // FIXME(#32730) propagate obligations
3391 .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
3392 if eq_result.is_err() {
3393 span_err!(tcx.sess, expr.span, E0069,
3394 "`return;` in a function whose return type is not `()`");
3398 ty::FnDiverging => {
3399 if let Some(ref e) = *expr_opt {
3400 self.check_expr(&e);
3402 span_err!(tcx.sess, expr.span, E0166,
3403 "`return` in a function declared as diverging");
3406 self.write_ty(id, self.next_diverging_ty_var());
3408 hir::ExprAssign(ref lhs, ref rhs) => {
3409 self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3412 if !tcx.expr_is_lval(&lhs) {
3413 span_err!(tcx.sess, expr.span, E0070,
3414 "invalid left-hand side expression");
3417 let lhs_ty = self.expr_ty(&lhs);
3418 self.check_expr_coercable_to_type(&rhs, lhs_ty);
3419 let rhs_ty = self.expr_ty(&rhs);
3421 self.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3423 if lhs_ty.references_error() || rhs_ty.references_error() {
3424 self.write_error(id);
3429 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3430 self.check_then_else(&cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3431 id, expr.span, expected);
3433 hir::ExprWhile(ref cond, ref body, _) => {
3434 self.check_expr_has_type(&cond, tcx.types.bool);
3435 self.check_block_no_value(&body);
3436 let cond_ty = self.expr_ty(&cond);
3437 let body_ty = self.node_ty(body.id);
3438 if cond_ty.references_error() || body_ty.references_error() {
3439 self.write_error(id);
3445 hir::ExprLoop(ref body, _) => {
3446 self.check_block_no_value(&body);
3447 if !may_break(tcx, expr.id, &body) {
3448 self.write_ty(id, self.next_diverging_ty_var());
3453 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3454 self.check_match(expr, &discrim, arms, expected, match_src);
3456 hir::ExprClosure(capture, ref decl, ref body, _) => {
3457 self.check_expr_closure(expr, capture, &decl, &body, expected);
3459 hir::ExprBlock(ref b) => {
3460 self.check_block_with_expected(&b, expected);
3461 self.write_ty(id, self.node_ty(b.id));
3463 hir::ExprCall(ref callee, ref args) => {
3464 self.check_call(expr, &callee, &args[..], expected);
3466 // we must check that return type of called functions is WF:
3467 let ret_ty = self.expr_ty(expr);
3468 self.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3470 hir::ExprMethodCall(name, ref tps, ref args) => {
3471 self.check_method_call(expr, name, &args[..], &tps[..], expected, lvalue_pref);
3472 let arg_tys = args.iter().map(|a| self.expr_ty(&a));
3473 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3475 self.write_error(id);
3478 hir::ExprCast(ref e, ref t) => {
3479 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3480 self.check_expr_with_hint(&count_expr, tcx.types.usize);
3483 // Find the type of `e`. Supply hints based on the type we are casting to,
3485 let t_cast = self.to_ty(t);
3486 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3487 self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3488 let t_expr = self.expr_ty(e);
3489 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3491 // Eagerly check for some obvious errors.
3492 if t_expr.references_error() || t_cast.references_error() {
3493 self.write_error(id);
3495 // Write a type for the whole expression, assuming everything is going
3497 self.write_ty(id, t_cast);
3499 // Defer other checks until we're done type checking.
3500 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3501 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3503 deferred_cast_checks.push(cast_check);
3505 Err(ErrorReported) => {
3506 self.write_error(id);
3511 hir::ExprType(ref e, ref t) => {
3512 let typ = self.to_ty(&t);
3513 self.check_expr_eq_type(&e, typ);
3514 self.write_ty(id, typ);
3516 hir::ExprVec(ref args) => {
3517 let uty = expected.to_option(self).and_then(|uty| {
3519 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3524 let mut unified = self.next_ty_var();
3525 let coerce_to = uty.unwrap_or(unified);
3527 for (i, e) in args.iter().enumerate() {
3528 self.check_expr_with_hint(e, coerce_to);
3529 let e_ty = self.expr_ty(e);
3530 let origin = TypeOrigin::Misc(e.span);
3532 // Special-case the first element, as it has no "previous expressions".
3533 let result = if i == 0 {
3534 self.try_coerce(e, coerce_to)
3536 let prev_elems = || args[..i].iter().map(|e| &**e);
3537 self.try_find_coercion_lub(origin, prev_elems, unified, e)
3541 Ok(ty) => unified = ty,
3543 self.report_mismatched_types(origin, unified, e_ty, e);
3547 self.write_ty(id, tcx.mk_array(unified, args.len()));
3549 hir::ExprRepeat(ref element, ref count_expr) => {
3550 self.check_expr_has_type(&count_expr, tcx.types.usize);
3551 let count = eval_repeat_count(self.tcx.global_tcx(), &count_expr);
3553 let uty = match expected {
3554 ExpectHasType(uty) => {
3556 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3563 let (element_ty, t) = match uty {
3565 self.check_expr_coercable_to_type(&element, uty);
3569 let t: Ty = self.next_ty_var();
3570 self.check_expr_has_type(&element, t);
3571 (self.expr_ty(&element), t)
3576 // For [foo, ..n] where n > 1, `foo` must have
3578 self.require_type_meets(t, expr.span, traits::RepeatVec, ty::BoundCopy);
3581 if element_ty.references_error() {
3582 self.write_error(id);
3584 let t = tcx.mk_array(t, count);
3585 self.write_ty(id, t);
3588 hir::ExprTup(ref elts) => {
3589 let flds = expected.only_has_type(self).and_then(|ty| {
3591 ty::TyTuple(ref flds) => Some(&flds[..]),
3595 let mut err_field = false;
3597 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3598 let t = match flds {
3599 Some(ref fs) if i < fs.len() => {
3601 self.check_expr_coercable_to_type(&e, ety);
3605 self.check_expr_with_expectation(&e, NoExpectation);
3609 err_field = err_field || t.references_error();
3613 self.write_error(id);
3615 let typ = tcx.mk_tup(elt_ts);
3616 self.write_ty(id, typ);
3619 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3620 self.check_expr_struct(expr, path, fields, base_expr);
3622 self.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3624 hir::ExprField(ref base, ref field) => {
3625 self.check_field(expr, lvalue_pref, &base, field);
3627 hir::ExprTupField(ref base, idx) => {
3628 self.check_tup_field(expr, lvalue_pref, &base, idx);
3630 hir::ExprIndex(ref base, ref idx) => {
3631 self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3632 self.check_expr(&idx);
3634 let base_t = self.expr_ty(&base);
3635 let idx_t = self.expr_ty(&idx);
3637 if base_t.references_error() {
3638 self.write_ty(id, base_t);
3639 } else if idx_t.references_error() {
3640 self.write_ty(id, idx_t);
3642 let base_t = self.structurally_resolved_type(expr.span, base_t);
3643 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3644 Some((index_ty, element_ty)) => {
3645 let idx_expr_ty = self.expr_ty(idx);
3646 self.demand_eqtype(expr.span, index_ty, idx_expr_ty);
3647 self.write_ty(id, element_ty);
3650 self.check_expr_has_type(&idx, self.tcx.types.err);
3651 let mut err = self.type_error_struct(
3654 format!("cannot index a value of type `{}`",
3659 // Try to give some advice about indexing tuples.
3660 if let ty::TyTuple(_) = base_t.sty {
3661 let mut needs_note = true;
3662 // If the index is an integer, we can show the actual
3663 // fixed expression:
3664 if let hir::ExprLit(ref lit) = idx.node {
3665 if let ast::LitKind::Int(i,
3666 ast::LitIntType::Unsuffixed) = lit.node {
3667 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3668 if let Ok(snip) = snip {
3669 err.span_suggestion(expr.span,
3670 "to access tuple elements, \
3671 use tuple indexing syntax \
3673 format!("{}.{}", snip, i));
3679 err.help("to access tuple elements, use tuple indexing \
3680 syntax (e.g. `tuple.0`)");
3684 self.write_ty(id, self.tcx().types.err);
3691 debug!("type of expr({}) {} is...", expr.id,
3692 pprust::expr_to_string(expr));
3693 debug!("... {:?}, expected is {:?}",
3698 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3699 path_res: def::PathResolution,
3700 opt_self_ty: Option<Ty<'tcx>>,
3701 path: &'b hir::Path,
3703 node_id: ast::NodeId)
3704 -> Option<(Option<Ty<'tcx>>, &'b [hir::PathSegment], Def)>
3707 // If fully resolved already, we don't have to do anything.
3708 if path_res.depth == 0 {
3709 Some((opt_self_ty, &path.segments, path_res.base_def))
3711 let def = path_res.base_def;
3712 let ty_segments = path.segments.split_last().unwrap().1;
3713 let base_ty_end = path.segments.len() - path_res.depth;
3714 let (ty, _def) = AstConv::finish_resolving_def_to_ty(self, self, span,
3715 PathParamMode::Optional,
3719 &ty_segments[..base_ty_end],
3720 &ty_segments[base_ty_end..]);
3721 let item_segment = path.segments.last().unwrap();
3722 let item_name = item_segment.name;
3723 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3724 Ok(def) => Some(def),
3726 let def = match error {
3727 method::MethodError::PrivateMatch(def) => Some(def),
3730 if item_name != keywords::Invalid.name() {
3731 self.report_method_error(span, ty, item_name, None, error);
3737 if let Some(def) = def {
3738 // Write back the new resolution.
3739 self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution::new(def));
3740 Some((Some(ty), slice::ref_slice(item_segment), def))
3742 self.write_error(node_id);
3748 pub fn check_decl_initializer(&self,
3749 local: &'gcx hir::Local,
3750 init: &'gcx hir::Expr)
3752 let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat);
3754 let local_ty = self.local_ty(init.span, local.id);
3755 if let Some(m) = ref_bindings {
3756 // Somewhat subtle: if we have a `ref` binding in the pattern,
3757 // we want to avoid introducing coercions for the RHS. This is
3758 // both because it helps preserve sanity and, in the case of
3759 // ref mut, for soundness (issue #23116). In particular, in
3760 // the latter case, we need to be clear that the type of the
3761 // referent for the reference that results is *equal to* the
3762 // type of the lvalue it is referencing, and not some
3763 // supertype thereof.
3764 self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3765 let init_ty = self.expr_ty(init);
3766 self.demand_eqtype(init.span, init_ty, local_ty);
3768 self.check_expr_coercable_to_type(init, local_ty)
3772 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3773 let t = self.local_ty(local.span, local.id);
3774 self.write_ty(local.id, t);
3776 if let Some(ref init) = local.init {
3777 self.check_decl_initializer(local, &init);
3778 let init_ty = self.expr_ty(&init);
3779 if init_ty.references_error() {
3780 self.write_ty(local.id, init_ty);
3784 self.check_pat(&local.pat, t);
3785 let pat_ty = self.node_ty(local.pat.id);
3786 if pat_ty.references_error() {
3787 self.write_ty(local.id, pat_ty);
3791 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3793 let mut saw_bot = false;
3794 let mut saw_err = false;
3796 hir::StmtDecl(ref decl, id) => {
3799 hir::DeclLocal(ref l) => {
3800 self.check_decl_local(&l);
3801 let l_t = self.node_ty(l.id);
3802 saw_bot = saw_bot || self.type_var_diverges(l_t);
3803 saw_err = saw_err || l_t.references_error();
3805 hir::DeclItem(_) => {/* ignore for now */ }
3808 hir::StmtExpr(ref expr, id) => {
3810 // Check with expected type of ()
3811 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3812 let expr_ty = self.expr_ty(&expr);
3813 saw_bot = saw_bot || self.type_var_diverges(expr_ty);
3814 saw_err = saw_err || expr_ty.references_error();
3816 hir::StmtSemi(ref expr, id) => {
3818 self.check_expr(&expr);
3819 let expr_ty = self.expr_ty(&expr);
3820 saw_bot |= self.type_var_diverges(expr_ty);
3821 saw_err |= expr_ty.references_error();
3825 self.write_ty(node_id, self.next_diverging_ty_var());
3828 self.write_error(node_id);
3831 self.write_nil(node_id)
3835 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
3836 self.check_block_with_expected(blk, ExpectHasType(self.tcx.mk_nil()));
3837 let blkty = self.node_ty(blk.id);
3838 if blkty.references_error() {
3839 self.write_error(blk.id);
3841 let nilty = self.tcx.mk_nil();
3842 self.demand_suptype(blk.span, nilty, blkty);
3846 fn check_block_with_expected(&self,
3847 blk: &'gcx hir::Block,
3848 expected: Expectation<'tcx>) {
3850 let mut fcx_ps = self.ps.borrow_mut();
3851 let unsafety_state = fcx_ps.recurse(blk);
3852 replace(&mut *fcx_ps, unsafety_state)
3855 let mut warned = false;
3856 let mut any_diverges = false;
3857 let mut any_err = false;
3858 for s in &blk.stmts {
3860 let s_id = s.node.id();
3861 let s_ty = self.node_ty(s_id);
3862 if any_diverges && !warned && match s.node {
3863 hir::StmtDecl(ref decl, _) => {
3865 hir::DeclLocal(_) => true,
3869 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3873 .add_lint(lint::builtin::UNREACHABLE_CODE,
3876 "unreachable statement".to_string());
3879 any_diverges = any_diverges || self.type_var_diverges(s_ty);
3880 any_err = any_err || s_ty.references_error();
3883 None => if any_err {
3884 self.write_error(blk.id);
3885 } else if any_diverges {
3886 self.write_ty(blk.id, self.next_diverging_ty_var());
3888 self.write_nil(blk.id);
3891 if any_diverges && !warned {
3894 .add_lint(lint::builtin::UNREACHABLE_CODE,
3897 "unreachable expression".to_string());
3899 let ety = match expected {
3900 ExpectHasType(ety) => {
3901 self.check_expr_coercable_to_type(&e, ety);
3905 self.check_expr_with_expectation(&e, expected);
3911 self.write_error(blk.id);
3912 } else if any_diverges {
3913 self.write_ty(blk.id, self.next_diverging_ty_var());
3915 self.write_ty(blk.id, ety);
3920 *self.ps.borrow_mut() = prev;
3924 fn check_const_with_ty(&self,
3928 // Gather locals in statics (because of block expressions).
3929 // This is technically unnecessary because locals in static items are forbidden,
3930 // but prevents type checking from blowing up before const checking can properly
3932 GatherLocalsVisitor { fcx: self }.visit_expr(e);
3934 self.check_expr_coercable_to_type(e, declty);
3936 self.select_all_obligations_and_apply_defaults();
3937 self.closure_analyze_const(e);
3938 self.select_obligations_where_possible();
3940 self.select_all_obligations_or_error();
3942 self.regionck_expr(e);
3943 self.resolve_type_vars_in_expr(e);
3946 // Returns the type parameter count and the type for the given definition.
3947 fn type_scheme_and_predicates_for_def(&self,
3950 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
3952 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
3953 let typ = self.local_ty(sp, nid);
3954 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
3955 ty::GenericPredicates::empty())
3957 Def::Fn(id) | Def::Method(id) |
3958 Def::Static(id, _) | Def::Variant(_, id) |
3959 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
3960 (self.tcx.lookup_item_type(id), self.tcx.lookup_predicates(id))
3965 Def::AssociatedTy(..) |
3969 Def::ForeignMod(..) |
3973 span_bug!(sp, "expected value, found {:?}", defn);
3978 // Instantiates the given path, which must refer to an item with the given
3979 // number of type parameters and type.
3980 pub fn instantiate_path(&self,
3981 segments: &[hir::PathSegment],
3982 type_scheme: TypeScheme<'tcx>,
3983 type_predicates: &ty::GenericPredicates<'tcx>,
3984 opt_self_ty: Option<Ty<'tcx>>,
3987 node_id: ast::NodeId) {
3988 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
3994 // We need to extract the type parameters supplied by the user in
3995 // the path `path`. Due to the current setup, this is a bit of a
3996 // tricky-process; the problem is that resolve only tells us the
3997 // end-point of the path resolution, and not the intermediate steps.
3998 // Luckily, we can (at least for now) deduce the intermediate steps
3999 // just from the end-point.
4001 // There are basically four cases to consider:
4003 // 1. Reference to a *type*, such as a struct or enum:
4005 // mod a { struct Foo<T> { ... } }
4007 // Because we don't allow types to be declared within one
4008 // another, a path that leads to a type will always look like
4009 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4010 // that only the final segment can have type parameters, and
4011 // they are located in the TypeSpace.
4013 // *Note:* Generally speaking, references to types don't
4014 // actually pass through this function, but rather the
4015 // `ast_ty_to_ty` function in `astconv`. However, in the case
4016 // of struct patterns (and maybe literals) we do invoke
4017 // `instantiate_path` to get the general type of an instance of
4018 // a struct. (In these cases, there are actually no type
4019 // parameters permitted at present, but perhaps we will allow
4020 // them in the future.)
4022 // 1b. Reference to an enum variant or tuple-like struct:
4024 // struct foo<T>(...)
4025 // enum E<T> { foo(...) }
4027 // In these cases, the parameters are declared in the type
4030 // 2. Reference to a *fn item*:
4034 // In this case, the path will again always have the form
4035 // `a::b::foo::<T>` where only the final segment should have
4036 // type parameters. However, in this case, those parameters are
4037 // declared on a value, and hence are in the `FnSpace`.
4039 // 3. Reference to a *method*:
4041 // impl<A> SomeStruct<A> {
4045 // Here we can have a path like
4046 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4047 // may appear in two places. The penultimate segment,
4048 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4049 // final segment, `foo::<B>` contains parameters in fn space.
4051 // 4. Reference to an *associated const*:
4053 // impl<A> AnotherStruct<A> {
4054 // const FOO: B = BAR;
4057 // The path in this case will look like
4058 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4059 // only will have parameters in TypeSpace.
4061 // The first step then is to categorize the segments appropriately.
4063 assert!(!segments.is_empty());
4065 let mut ufcs_associated = None;
4066 let mut segment_spaces: Vec<_>;
4068 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4074 Def::AssociatedTy(..) |
4077 Def::TyParam(..) => {
4078 // Everything but the final segment should have no
4079 // parameters at all.
4080 segment_spaces = vec![None; segments.len() - 1];
4081 segment_spaces.push(Some(subst::TypeSpace));
4084 // Case 2. Reference to a top-level value.
4087 Def::Static(..) => {
4088 segment_spaces = vec![None; segments.len() - 1];
4089 segment_spaces.push(Some(subst::FnSpace));
4092 // Case 3. Reference to a method.
4093 Def::Method(def_id) => {
4094 let container = self.tcx.impl_or_trait_item(def_id).container();
4096 ty::TraitContainer(trait_did) => {
4097 callee::check_legal_trait_for_method_call(self.ccx, span, trait_did)
4099 ty::ImplContainer(_) => {}
4102 if segments.len() >= 2 {
4103 segment_spaces = vec![None; segments.len() - 2];
4104 segment_spaces.push(Some(subst::TypeSpace));
4105 segment_spaces.push(Some(subst::FnSpace));
4107 // `<T>::method` will end up here, and so can `T::method`.
4108 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4109 segment_spaces = vec![Some(subst::FnSpace)];
4110 ufcs_associated = Some((container, self_ty));
4114 Def::AssociatedConst(def_id) => {
4115 let container = self.tcx.impl_or_trait_item(def_id).container();
4117 ty::TraitContainer(trait_did) => {
4118 callee::check_legal_trait_for_method_call(self.ccx, span, trait_did)
4120 ty::ImplContainer(_) => {}
4123 if segments.len() >= 2 {
4124 segment_spaces = vec![None; segments.len() - 2];
4125 segment_spaces.push(Some(subst::TypeSpace));
4126 segment_spaces.push(None);
4128 // `<T>::CONST` will end up here, and so can `T::CONST`.
4129 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4130 segment_spaces = vec![None];
4131 ufcs_associated = Some((container, self_ty));
4135 // Other cases. Various nonsense that really shouldn't show up
4136 // here. If they do, an error will have been reported
4137 // elsewhere. (I hope)
4139 Def::ForeignMod(..) |
4143 segment_spaces = vec![None; segments.len()];
4147 self.set_tainted_by_errors();
4148 segment_spaces = vec![None; segments.len()];
4151 assert_eq!(segment_spaces.len(), segments.len());
4153 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4154 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4155 // type parameters are not mandatory.
4156 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4158 debug!("segment_spaces={:?}", segment_spaces);
4160 // Next, examine the definition, and determine how many type
4161 // parameters we expect from each space.
4162 let type_defs = &type_scheme.generics.types;
4163 let region_defs = &type_scheme.generics.regions;
4165 // Now that we have categorized what space the parameters for each
4166 // segment belong to, let's sort out the parameters that the user
4167 // provided (if any) into their appropriate spaces. We'll also report
4168 // errors if type parameters are provided in an inappropriate place.
4169 let mut substs = Substs::empty();
4170 for (&opt_space, segment) in segment_spaces.iter().zip(segments) {
4171 if let Some(space) = opt_space {
4172 self.push_explicit_parameters_from_segment_to_substs(space,
4179 self.tcx.prohibit_type_params(slice::ref_slice(segment));
4182 if let Some(self_ty) = opt_self_ty {
4183 if type_defs.len(subst::SelfSpace) == 1 {
4184 substs.types.push(subst::SelfSpace, self_ty);
4188 // Now we have to compare the types that the user *actually*
4189 // provided against the types that were *expected*. If the user
4190 // did not provide any types, then we want to substitute inference
4191 // variables. If the user provided some types, we may still need
4192 // to add defaults. If the user provided *too many* types, that's
4194 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4195 self.adjust_type_parameters(span, space, type_defs,
4196 require_type_space, &mut substs);
4197 assert_eq!(substs.types.len(space), type_defs.len(space));
4199 self.adjust_region_parameters(span, space, region_defs, &mut substs);
4200 assert_eq!(substs.regions.len(space), region_defs.len(space));
4203 // The things we are substituting into the type should not contain
4204 // escaping late-bound regions, and nor should the base type scheme.
4205 let substs = self.tcx.mk_substs(substs);
4206 assert!(!substs.has_regions_escaping_depth(0));
4207 assert!(!type_scheme.has_escaping_regions());
4209 // Add all the obligations that are required, substituting and
4210 // normalized appropriately.
4211 let bounds = self.instantiate_bounds(span, &substs, &type_predicates);
4212 self.add_obligations_for_parameters(
4213 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4216 // Substitute the values for the type parameters into the type of
4217 // the referenced item.
4218 let ty_substituted = self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4221 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4222 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4223 // is inherent, there is no `Self` parameter, instead, the impl needs
4224 // type parameters, which we can infer by unifying the provided `Self`
4225 // with the substituted impl type.
4226 let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
4227 assert_eq!(substs.types.len(subst::TypeSpace),
4228 impl_scheme.generics.types.len(subst::TypeSpace));
4229 assert_eq!(substs.regions.len(subst::TypeSpace),
4230 impl_scheme.generics.regions.len(subst::TypeSpace));
4232 let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4233 match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
4234 Ok(InferOk { obligations, .. }) => {
4235 // FIXME(#32730) propagate obligations
4236 assert!(obligations.is_empty());
4240 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4247 debug!("instantiate_path: type of {:?} is {:?}",
4250 self.write_ty(node_id, ty_substituted);
4251 self.write_substs(node_id, ty::ItemSubsts {
4256 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4257 /// parameters are provided, then reports an error and clears the output vector.
4259 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4260 /// use inference variables. This seems less likely to lead to derived errors.
4262 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4263 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4264 /// here because we can easily use the precise span of the N+1'th parameter.
4265 fn push_explicit_parameters_from_segment_to_substs(&self,
4266 space: subst::ParamSpace,
4268 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4269 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4270 segment: &hir::PathSegment,
4271 substs: &mut Substs<'tcx>)
4273 match segment.parameters {
4274 hir::AngleBracketedParameters(ref data) => {
4275 self.push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4276 space, type_defs, region_defs, data, substs);
4279 hir::ParenthesizedParameters(ref data) => {
4280 span_err!(self.tcx.sess, span, E0238,
4281 "parenthesized parameters may only be used with a trait");
4282 self.push_explicit_parenthesized_parameters_from_segment_to_substs(
4283 space, span, type_defs, data, substs);
4288 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs(&self,
4289 space: subst::ParamSpace,
4290 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4291 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4292 data: &hir::AngleBracketedParameterData,
4293 substs: &mut Substs<'tcx>)
4296 let type_count = type_defs.len(space);
4297 assert_eq!(substs.types.len(space), 0);
4298 for (i, typ) in data.types.iter().enumerate() {
4299 let t = self.to_ty(&typ);
4301 substs.types.push(space, t);
4302 } else if i == type_count {
4303 span_err!(self.tcx.sess, typ.span, E0087,
4304 "too many type parameters provided: \
4305 expected at most {} parameter{}, \
4306 found {} parameter{}",
4308 if type_count == 1 {""} else {"s"},
4310 if data.types.len() == 1 {""} else {"s"});
4311 substs.types.truncate(space, 0);
4317 if !data.bindings.is_empty() {
4318 span_err!(self.tcx.sess, data.bindings[0].span, E0182,
4319 "unexpected binding of associated item in expression path \
4320 (only allowed in type paths)");
4324 let region_count = region_defs.len(space);
4325 assert_eq!(substs.regions.len(space), 0);
4326 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4327 let r = ast_region_to_region(self.tcx, lifetime);
4328 if i < region_count {
4329 substs.regions.push(space, r);
4330 } else if i == region_count {
4331 span_err!(self.tcx.sess, lifetime.span, E0088,
4332 "too many lifetime parameters provided: \
4333 expected {} parameter{}, found {} parameter{}",
4335 if region_count == 1 {""} else {"s"},
4336 data.lifetimes.len(),
4337 if data.lifetimes.len() == 1 {""} else {"s"});
4338 substs.regions.truncate(space, 0);
4346 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4347 /// but intended for `Foo(A,B) -> C` form. This expands to
4348 /// roughly the same thing as `Foo<(A,B),C>`. One important
4349 /// difference has to do with the treatment of anonymous
4350 /// regions, which are translated into bound regions (NYI).
4351 fn push_explicit_parenthesized_parameters_from_segment_to_substs(&self,
4352 space: subst::ParamSpace,
4354 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4355 data: &hir::ParenthesizedParameterData,
4356 substs: &mut Substs<'tcx>)
4358 let type_count = type_defs.len(space);
4360 span_err!(self.tcx.sess, span, E0167,
4361 "parenthesized form always supplies 2 type parameters, \
4362 but only {} parameter(s) were expected",
4366 let input_tys: Vec<Ty> =
4367 data.inputs.iter().map(|ty| self.to_ty(&ty)).collect();
4369 let tuple_ty = self.tcx.mk_tup(input_tys);
4371 if type_count >= 1 {
4372 substs.types.push(space, tuple_ty);
4375 let output_ty: Option<Ty> =
4376 data.output.as_ref().map(|ty| self.to_ty(&ty));
4379 output_ty.unwrap_or(self.tcx.mk_nil());
4381 if type_count >= 2 {
4382 substs.types.push(space, output_ty);
4386 fn adjust_type_parameters(&self,
4389 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4390 require_type_space: bool,
4391 substs: &mut Substs<'tcx>)
4393 let provided_len = substs.types.len(space);
4394 let desired = defs.get_slice(space);
4395 let required_len = desired.iter()
4396 .take_while(|d| d.default.is_none())
4399 debug!("adjust_type_parameters(space={:?}, \
4408 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4409 assert!(provided_len <= desired.len());
4411 // Nothing specified at all: supply inference variables for
4413 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4414 substs.types.replace(space, Vec::new());
4415 self.type_vars_for_defs(span, space, substs, &desired[..]);
4419 // Too few parameters specified: report an error and use Err
4421 if provided_len < required_len {
4423 if desired.len() != required_len { "at least " } else { "" };
4424 span_err!(self.tcx.sess, span, E0089,
4425 "too few type parameters provided: expected {}{} parameter{}, \
4426 found {} parameter{}",
4427 qualifier, required_len,
4428 if required_len == 1 {""} else {"s"},
4430 if provided_len == 1 {""} else {"s"});
4431 substs.types.replace(space, vec![self.tcx.types.err; desired.len()]);
4435 // Otherwise, add in any optional parameters that the user
4436 // omitted. The case of *too many* parameters is handled
4438 // push_explicit_parameters_from_segment_to_substs(). Note
4439 // that the *default* type are expressed in terms of all prior
4440 // parameters, so we have to substitute as we go with the
4441 // partial substitution that we have built up.
4442 for i in provided_len..desired.len() {
4443 let default = desired[i].default.unwrap();
4444 let default = default.subst_spanned(self.tcx, substs, Some(span));
4445 substs.types.push(space, default);
4447 assert_eq!(substs.types.len(space), desired.len());
4449 debug!("Final substs: {:?}", substs);
4452 fn adjust_region_parameters(&self,
4455 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4456 substs: &mut Substs)
4458 let provided_len = substs.regions.len(space);
4459 let desired = defs.get_slice(space);
4461 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4462 assert!(provided_len <= desired.len());
4464 // If nothing was provided, just use inference variables.
4465 if provided_len == 0 {
4466 substs.regions.replace(
4468 self.region_vars_for_defs(span, desired));
4472 // If just the right number were provided, everybody is happy.
4473 if provided_len == desired.len() {
4477 // Otherwise, too few were provided. Report an error and then
4478 // use inference variables.
4479 span_err!(self.tcx.sess, span, E0090,
4480 "too few lifetime parameters provided: expected {} parameter{}, \
4481 found {} parameter{}",
4483 if desired.len() == 1 {""} else {"s"},
4485 if provided_len == 1 {""} else {"s"});
4487 substs.regions.replace(
4489 self.region_vars_for_defs(span, desired));
4492 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4494 where F: Fn() -> Ty<'tcx>
4496 let mut ty = self.resolve_type_vars_with_obligations(ty);
4499 let alternative = f();
4502 if alternative.is_ty_var() || alternative.references_error() {
4503 if !self.is_tainted_by_errors() {
4504 self.type_error_message(sp, |_actual| {
4505 "the type of this value must be known in this context".to_string()
4508 self.demand_suptype(sp, self.tcx.types.err, ty);
4509 ty = self.tcx.types.err;
4511 self.demand_suptype(sp, alternative, ty);
4519 // Resolves `typ` by a single level if `typ` is a type variable. If no
4520 // resolution is possible, then an error is reported.
4521 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4522 self.structurally_resolve_type_or_else(sp, ty, || {
4528 // Returns true if b contains a break that can exit from b
4529 pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4530 // First: is there an unlabeled break immediately
4532 (loop_query(&b, |e| {
4534 hir::ExprBreak(None) => true,
4538 // Second: is there a labeled break with label
4539 // <id> nested anywhere inside the loop?
4540 (block_query(b, |e| {
4541 if let hir::ExprBreak(Some(_)) = e.node {
4542 tcx.expect_def(e.id) == Def::Label(id)
4549 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4550 tps: &[hir::TyParam],
4552 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4555 // make a vector of booleans initially false, set to true when used
4556 if tps.is_empty() { return; }
4557 let mut tps_used = vec![false; tps.len()];
4559 for leaf_ty in ty.walk() {
4560 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4561 debug!("Found use of ty param num {}", idx);
4562 tps_used[idx as usize] = true;
4566 for (i, b) in tps_used.iter().enumerate() {
4568 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4569 "type parameter `{}` is unused",