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::{Def, PathResolution};
88 use hir::def_id::DefId;
90 use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
91 use rustc::ty::subst::{Subst, Substs};
92 use rustc::traits::{self, Reveal};
93 use rustc::ty::{ParamTy, ParameterEnvironment};
94 use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
95 use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
96 use rustc::ty::{MethodCall, MethodCallee};
97 use rustc::ty::adjustment;
98 use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
99 use rustc::ty::util::{Representability, IntTypeExt};
100 use require_c_abi_if_variadic;
101 use rscope::{ElisionFailureInfo, RegionScope};
102 use session::{Session, CompileResult};
106 use util::common::{block_query, ErrorReported, indenter, loop_query};
107 use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet, NodeMap};
109 use std::cell::{Cell, Ref, RefCell};
110 use std::mem::replace;
112 use syntax::abi::Abi;
115 use syntax::codemap::{self, Spanned};
116 use syntax::feature_gate::{GateIssue, emit_feature_err};
117 use syntax::parse::token::{self, InternedString, keywords};
119 use syntax::util::lev_distance::find_best_match_for_name;
120 use syntax_pos::{self, Span};
121 use errors::DiagnosticBuilder;
123 use rustc::hir::intravisit::{self, Visitor};
124 use rustc::hir::{self, PatKind};
125 use rustc::hir::print as pprust;
126 use rustc_back::slice;
127 use rustc_const_eval::eval_length;
147 /// closures defined within the function. For example:
150 /// bar(move|| { ... })
153 /// Here, the function `foo()` and the closure passed to
154 /// `bar()` will each have their own `FnCtxt`, but they will
155 /// share the inherited fields.
156 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
157 ccx: &'a CrateCtxt<'a, 'gcx>,
158 infcx: InferCtxt<'a, 'gcx, 'tcx>,
159 locals: RefCell<NodeMap<Ty<'tcx>>>,
161 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
163 // When we process a call like `c()` where `c` is a closure type,
164 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
165 // `FnOnce` closure. In that case, we defer full resolution of the
166 // call until upvar inference can kick in and make the
167 // decision. We keep these deferred resolutions grouped by the
168 // def-id of the closure, so that once we decide, we can easily go
169 // back and process them.
170 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
172 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
174 // Anonymized types found in explicit return types and their
175 // associated fresh inference variable. Writeback resolves these
176 // variables to get the concrete type, which can be used to
177 // deanonymize TyAnon, after typeck is done with all functions.
178 anon_types: RefCell<DefIdMap<Ty<'tcx>>>,
180 // Obligations which will have to be checked at the end of
181 // type-checking, after all functions have been inferred.
182 deferred_obligations: RefCell<Vec<traits::DeferredObligation<'tcx>>>,
185 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
186 type Target = InferCtxt<'a, 'gcx, 'tcx>;
187 fn deref(&self) -> &Self::Target {
192 trait DeferredCallResolution<'gcx, 'tcx> {
193 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
196 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
198 /// When type-checking an expression, we propagate downward
199 /// whatever type hint we are able in the form of an `Expectation`.
200 #[derive(Copy, Clone, Debug)]
201 pub enum Expectation<'tcx> {
202 /// We know nothing about what type this expression should have.
205 /// This expression should have the type given (or some subtype)
206 ExpectHasType(Ty<'tcx>),
208 /// This expression will be cast to the `Ty`
209 ExpectCastableToType(Ty<'tcx>),
211 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
212 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
213 ExpectRvalueLikeUnsized(Ty<'tcx>),
216 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
217 // Disregard "castable to" expectations because they
218 // can lead us astray. Consider for example `if cond
219 // {22} else {c} as u8` -- if we propagate the
220 // "castable to u8" constraint to 22, it will pick the
221 // type 22u8, which is overly constrained (c might not
222 // be a u8). In effect, the problem is that the
223 // "castable to" expectation is not the tightest thing
224 // we can say, so we want to drop it in this case.
225 // The tightest thing we can say is "must unify with
226 // else branch". Note that in the case of a "has type"
227 // constraint, this limitation does not hold.
229 // If the expected type is just a type variable, then don't use
230 // an expected type. Otherwise, we might write parts of the type
231 // when checking the 'then' block which are incompatible with the
233 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
235 ExpectHasType(ety) => {
236 let ety = fcx.shallow_resolve(ety);
237 if !ety.is_ty_var() {
243 ExpectRvalueLikeUnsized(ety) => {
244 ExpectRvalueLikeUnsized(ety)
250 /// Provide an expectation for an rvalue expression given an *optional*
251 /// hint, which is not required for type safety (the resulting type might
252 /// be checked higher up, as is the case with `&expr` and `box expr`), but
253 /// is useful in determining the concrete type.
255 /// The primary use case is where the expected type is a fat pointer,
256 /// like `&[isize]`. For example, consider the following statement:
258 /// let x: &[isize] = &[1, 2, 3];
260 /// In this case, the expected type for the `&[1, 2, 3]` expression is
261 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
262 /// expectation `ExpectHasType([isize])`, that would be too strong --
263 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
264 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
265 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
266 /// which still is useful, because it informs integer literals and the like.
267 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
268 /// for examples of where this comes up,.
269 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
270 match fcx.tcx.struct_tail(ty).sty {
271 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
272 ExpectRvalueLikeUnsized(ty)
274 _ => ExpectHasType(ty)
278 // Resolves `expected` by a single level if it is a variable. If
279 // there is no expected type or resolution is not possible (e.g.,
280 // no constraints yet present), just returns `None`.
281 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
286 ExpectCastableToType(t) => {
287 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
289 ExpectHasType(t) => {
290 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
292 ExpectRvalueLikeUnsized(t) => {
293 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
298 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
299 match self.resolve(fcx) {
300 NoExpectation => None,
301 ExpectCastableToType(ty) |
303 ExpectRvalueLikeUnsized(ty) => Some(ty),
307 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
308 match self.resolve(fcx) {
309 ExpectHasType(ty) => Some(ty),
315 #[derive(Copy, Clone)]
316 pub struct UnsafetyState {
317 pub def: ast::NodeId,
318 pub unsafety: hir::Unsafety,
319 pub unsafe_push_count: u32,
324 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
325 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
328 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
329 match self.unsafety {
330 // If this unsafe, then if the outer function was already marked as
331 // unsafe we shouldn't attribute the unsafe'ness to the block. This
332 // way the block can be warned about instead of ignoring this
333 // extraneous block (functions are never warned about).
334 hir::Unsafety::Unsafe if self.from_fn => *self,
337 let (unsafety, def, count) = match blk.rules {
338 hir::PushUnsafeBlock(..) =>
339 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
340 hir::PopUnsafeBlock(..) =>
341 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
342 hir::UnsafeBlock(..) =>
343 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
344 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
345 (unsafety, self.def, self.unsafe_push_count),
347 UnsafetyState{ def: def,
349 unsafe_push_count: count,
357 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
358 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
360 body_id: ast::NodeId,
362 // This flag is set to true if, during the writeback phase, we encounter
363 // a type error in this function.
364 writeback_errors: Cell<bool>,
366 // Number of errors that had been reported when we started
367 // checking this function. On exit, if we find that *more* errors
368 // have been reported, we will skip regionck and other work that
369 // expects the types within the function to be consistent.
370 err_count_on_creation: usize,
374 ps: RefCell<UnsafetyState>,
376 inh: &'a Inherited<'a, 'gcx, 'tcx>,
379 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
380 type Target = Inherited<'a, 'gcx, 'tcx>;
381 fn deref(&self) -> &Self::Target {
386 /// Helper type of a temporary returned by ccx.inherited(...).
387 /// Necessary because we can't write the following bound:
388 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
389 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
390 ccx: &'a CrateCtxt<'a, 'gcx>,
391 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
394 impl<'a, 'gcx, 'tcx> CrateCtxt<'a, 'gcx> {
395 pub fn inherited(&'a self, id: ast::NodeId)
396 -> InheritedBuilder<'a, 'gcx, 'tcx> {
397 let param_env = ParameterEnvironment::for_item(self.tcx, id);
400 infcx: self.tcx.infer_ctxt(Some(ty::Tables::empty()),
402 Reveal::NotSpecializable)
407 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
408 fn enter<F, R>(&'tcx mut self, f: F) -> R
409 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
412 self.infcx.enter(|infcx| {
416 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
417 locals: RefCell::new(NodeMap()),
418 deferred_call_resolutions: RefCell::new(DefIdMap()),
419 deferred_cast_checks: RefCell::new(Vec::new()),
420 anon_types: RefCell::new(DefIdMap()),
421 deferred_obligations: RefCell::new(Vec::new()),
427 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
428 fn normalize_associated_types_in<T>(&self,
430 body_id: ast::NodeId,
433 where T : TypeFoldable<'tcx>
435 assoc::normalize_associated_types_in(self,
436 &mut self.fulfillment_cx.borrow_mut(),
444 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
445 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
447 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
448 fn visit_item(&mut self, i: &'tcx hir::Item) {
449 check_item_type(self.ccx, i);
450 intravisit::walk_item(self, i);
453 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
455 hir::TyFixedLengthVec(_, ref expr) => {
456 check_const_with_type(self.ccx, &expr, self.ccx.tcx.types.usize, expr.id);
461 intravisit::walk_ty(self, t);
465 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
466 fn visit_item(&mut self, i: &'tcx hir::Item) {
467 check_item_body(self.ccx, i);
471 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
472 ccx.tcx.sess.track_errors(|| {
473 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
474 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
478 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
479 ccx.tcx.sess.track_errors(|| {
480 let mut visit = CheckItemTypesVisitor { ccx: ccx };
481 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
485 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
486 ccx.tcx.sess.track_errors(|| {
487 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
488 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
490 // Process deferred obligations, now that all functions
491 // bodies have been fully inferred.
492 for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() {
493 // Use the same DepNode as for the body of the original function/item.
494 let def_id = ccx.tcx.map.local_def_id(item_id);
495 let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckItemBody(def_id));
497 let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id);
498 ccx.tcx.infer_ctxt(None, Some(param_env),
499 Reveal::NotSpecializable).enter(|infcx| {
500 let mut fulfillment_cx = traits::FulfillmentContext::new();
501 for obligation in obligations.iter().map(|o| o.to_obligation()) {
502 fulfillment_cx.register_predicate_obligation(&infcx, obligation);
505 if let Err(errors) = fulfillment_cx.select_all_or_error(&infcx) {
506 infcx.report_fulfillment_errors(&errors);
509 if let Err(errors) = fulfillment_cx.select_rfc1592_obligations(&infcx) {
510 infcx.report_fulfillment_errors_as_warnings(&errors, item_id);
517 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
518 ccx.tcx.sess.track_errors(|| {
519 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
520 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
521 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
523 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
524 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
525 if drop_impl_did.is_local() {
526 match dropck::check_drop_impl(ccx, drop_impl_did) {
529 assert!(ccx.tcx.sess.has_errors());
537 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
538 decl: &'tcx hir::FnDecl,
539 body: &'tcx hir::Block,
540 fn_id: ast::NodeId) {
541 let raw_fty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(fn_id)).ty;
542 let fn_ty = match raw_fty.sty {
543 ty::TyFnDef(_, _, f) => f,
544 _ => span_bug!(body.span, "check_bare_fn: function type expected")
547 ccx.inherited(fn_id).enter(|inh| {
548 // Compute the fty from point of view of inside fn.
549 let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body.id);
551 fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
553 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
555 inh.normalize_associated_types_in(body.span, body.id, &fn_sig);
557 let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
559 fcx.select_all_obligations_and_apply_defaults();
560 fcx.closure_analyze_fn(body);
561 fcx.select_obligations_where_possible();
563 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
565 fcx.regionck_fn(fn_id, decl, body);
566 fcx.resolve_type_vars_in_fn(decl, body, fn_id);
570 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
571 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
574 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
575 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
578 // infer the variable's type
579 let var_ty = self.fcx.next_ty_var();
580 self.fcx.locals.borrow_mut().insert(nid, var_ty);
584 // take type that the user specified
585 self.fcx.locals.borrow_mut().insert(nid, typ);
592 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
593 // Add explicitly-declared locals.
594 fn visit_local(&mut self, local: &'gcx hir::Local) {
595 let o_ty = match local.ty {
596 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
599 self.assign(local.span, local.id, o_ty);
600 debug!("Local variable {:?} is assigned type {}",
602 self.fcx.ty_to_string(
603 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
604 intravisit::walk_local(self, local);
607 // Add pattern bindings.
608 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
609 if let PatKind::Binding(_, ref path1, _) = p.node {
610 let var_ty = self.assign(p.span, p.id, None);
612 self.fcx.require_type_is_sized(var_ty, p.span,
613 traits::VariableType(p.id));
615 debug!("Pattern binding {} is assigned to {} with type {:?}",
617 self.fcx.ty_to_string(
618 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
621 intravisit::walk_pat(self, p);
624 fn visit_block(&mut self, b: &'gcx hir::Block) {
625 // non-obvious: the `blk` variable maps to region lb, so
626 // we have to keep this up-to-date. This
627 // is... unfortunate. It'd be nice to not need this.
628 intravisit::walk_block(self, b);
631 // Since an expr occurs as part of the type fixed size arrays we
632 // need to record the type for that node
633 fn visit_ty(&mut self, t: &'gcx hir::Ty) {
635 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
637 self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize);
639 hir::TyBareFn(ref function_declaration) => {
640 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
641 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
643 _ => intravisit::walk_ty(self, t)
647 // Don't descend into the bodies of nested closures
648 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
649 _: &'gcx hir::Block, _: Span, _: ast::NodeId) { }
652 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
653 /// body and returns the function context used for that purpose, since in the case of a fn item
654 /// there is still a bit more to do.
657 /// * inherited: other fields inherited from the enclosing fn (if any)
658 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
659 unsafety: hir::Unsafety,
660 unsafety_id: ast::NodeId,
661 fn_sig: &ty::FnSig<'tcx>,
662 decl: &'gcx hir::FnDecl,
664 body: &'gcx hir::Block)
665 -> FnCtxt<'a, 'gcx, 'tcx>
667 let mut fn_sig = fn_sig.clone();
669 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
671 // Create the function context. This is either derived from scratch or,
672 // in the case of function expressions, based on the outer context.
673 let mut fcx = FnCtxt::new(inherited, fn_sig.output, body.id);
674 *fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id);
676 fcx.require_type_is_sized(fcx.ret_ty, decl.output.span(), traits::ReturnType);
677 fcx.ret_ty = fcx.instantiate_anon_types(&fcx.ret_ty);
678 fn_sig.output = fcx.ret_ty;
681 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
683 // Add formal parameters.
684 for (arg_ty, input) in fn_sig.inputs.iter().zip(&decl.inputs) {
685 // The type of the argument must be well-formed.
687 // NB -- this is now checked in wfcheck, but that
688 // currently only results in warnings, so we issue an
689 // old-style WF obligation here so that we still get the
690 // errors that we used to get.
691 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
693 // Create type variables for each argument.
694 pat_util::pat_bindings(&input.pat, |_bm, pat_id, sp, _path| {
695 let var_ty = visit.assign(sp, pat_id, None);
696 fcx.require_type_is_sized(var_ty, sp, traits::VariableType(pat_id));
699 // Check the pattern.
700 fcx.check_pat(&input.pat, arg_ty);
701 fcx.write_ty(input.id, arg_ty);
704 visit.visit_block(body);
707 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
709 // FIXME(aburka) do we need this special case? and should it be is_uninhabited?
710 let expected = if fcx.ret_ty.is_never() {
713 ExpectHasType(fcx.ret_ty)
715 fcx.check_block_with_expected(body, expected);
720 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
723 check_representable(tcx, span, id, "struct");
725 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
726 check_simd(tcx, span, id);
730 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
731 debug!("check_item_type(it.id={}, it.name={})",
733 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
734 let _indenter = indenter();
736 // Consts can play a role in type-checking, so they are included here.
737 hir::ItemStatic(_, _, ref e) |
738 hir::ItemConst(_, ref e) => check_const(ccx, &e, it.id),
739 hir::ItemEnum(ref enum_definition, _) => {
740 check_enum_variants(ccx,
742 &enum_definition.variants,
745 hir::ItemFn(..) => {} // entirely within check_item_body
746 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
747 debug!("ItemImpl {} with id {}", it.name, it.id);
748 let impl_def_id = ccx.tcx.map.local_def_id(it.id);
749 match ccx.tcx.impl_trait_ref(impl_def_id) {
750 Some(impl_trait_ref) => {
751 check_impl_items_against_trait(ccx,
756 let trait_def_id = impl_trait_ref.def_id;
757 check_on_unimplemented(ccx, trait_def_id, it);
762 hir::ItemTrait(..) => {
763 let def_id = ccx.tcx.map.local_def_id(it.id);
764 check_on_unimplemented(ccx, def_id, it);
766 hir::ItemStruct(..) => {
767 check_struct(ccx, it.id, it.span);
769 hir::ItemTy(_, ref generics) => {
770 let pty_ty = ccx.tcx.node_id_to_type(it.id);
771 check_bounds_are_used(ccx, generics, pty_ty);
773 hir::ItemForeignMod(ref m) => {
774 if m.abi == Abi::RustIntrinsic {
775 for item in &m.items {
776 intrinsic::check_intrinsic_type(ccx, item);
778 } else if m.abi == Abi::PlatformIntrinsic {
779 for item in &m.items {
780 intrinsic::check_platform_intrinsic_type(ccx, item);
783 for item in &m.items {
784 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
785 if !pty.generics.types.is_empty() {
786 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
787 "foreign items may not have type parameters");
788 span_help!(&mut err, item.span,
789 "consider using specialization instead of \
794 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
795 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
800 _ => {/* nothing to do */ }
804 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
805 debug!("check_item_body(it.id={}, it.name={})",
807 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
808 let _indenter = indenter();
810 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
811 check_bare_fn(ccx, &decl, &body, it.id);
813 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
814 debug!("ItemImpl {} with id {}", it.name, it.id);
816 for impl_item in impl_items {
817 match impl_item.node {
818 hir::ImplItemKind::Const(_, ref expr) => {
819 check_const(ccx, &expr, impl_item.id)
821 hir::ImplItemKind::Method(ref sig, ref body) => {
822 check_bare_fn(ccx, &sig.decl, body, impl_item.id);
824 hir::ImplItemKind::Type(_) => {
825 // Nothing to do here.
830 hir::ItemTrait(_, _, _, ref trait_items) => {
831 for trait_item in trait_items {
832 match trait_item.node {
833 hir::ConstTraitItem(_, Some(ref expr)) => {
834 check_const(ccx, &expr, trait_item.id)
836 hir::MethodTraitItem(ref sig, Some(ref body)) => {
837 check_bare_fn(ccx, &sig.decl, body, trait_item.id);
839 hir::MethodTraitItem(_, None) |
840 hir::ConstTraitItem(_, None) |
841 hir::TypeTraitItem(..) => {
847 _ => {/* nothing to do */ }
851 fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
854 let generics = ccx.tcx.lookup_generics(def_id);
855 if let Some(ref attr) = item.attrs.iter().find(|a| {
856 a.check_name("rustc_on_unimplemented")
858 if let Some(ref istring) = attr.value_str() {
859 let parser = Parser::new(&istring);
860 let types = &generics.types;
861 for token in parser {
863 Piece::String(_) => (), // Normal string, no need to check it
864 Piece::NextArgument(a) => match a.position {
865 // `{Self}` is allowed
866 Position::ArgumentNamed(s) if s == "Self" => (),
867 // So is `{A}` if A is a type parameter
868 Position::ArgumentNamed(s) => match types.iter().find(|t| {
873 let name = ccx.tcx.item_name(def_id);
874 span_err!(ccx.tcx.sess, attr.span, E0230,
875 "there is no type parameter \
880 // `{:1}` and `{}` are not to be used
881 Position::ArgumentIs(_) => {
882 span_err!(ccx.tcx.sess, attr.span, E0231,
883 "only named substitution \
884 parameters are allowed");
891 ccx.tcx.sess, attr.span, E0232,
892 "this attribute must have a value")
893 .span_label(attr.span, &format!("attribute requires a value"))
894 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
900 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
901 impl_item: &hir::ImplItem,
904 let mut err = struct_span_err!(
905 tcx.sess, impl_item.span, E0520,
906 "`{}` specializes an item from a parent `impl`, but \
907 neither that item nor the `impl` are marked `default`",
909 err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
912 match tcx.span_of_impl(parent_impl) {
914 err.span_label(span, &"parent `impl` is here");
915 err.note(&format!("to specialize, either the parent `impl` or `{}` \
916 in the parent `impl` must be marked `default`",
920 err.note(&format!("parent implementation is in crate `{}`", cname));
927 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
928 trait_def: &ty::TraitDef<'tcx>,
930 impl_item: &hir::ImplItem)
932 let ancestors = trait_def.ancestors(impl_id);
934 let parent = match impl_item.node {
935 hir::ImplItemKind::Const(..) => {
936 ancestors.const_defs(tcx, impl_item.name).skip(1).next()
937 .map(|node_item| node_item.map(|parent| parent.defaultness))
939 hir::ImplItemKind::Method(..) => {
940 ancestors.fn_defs(tcx, impl_item.name).skip(1).next()
941 .map(|node_item| node_item.map(|parent| parent.defaultness))
944 hir::ImplItemKind::Type(_) => {
945 ancestors.type_defs(tcx, impl_item.name).skip(1).next()
946 .map(|node_item| node_item.map(|parent| parent.defaultness))
950 if let Some(parent) = parent {
951 if parent.item.is_final() {
952 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
958 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
961 impl_trait_ref: &ty::TraitRef<'tcx>,
962 impl_items: &[hir::ImplItem]) {
963 // If the trait reference itself is erroneous (so the compilation is going
964 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
965 // isn't populated for such impls.
966 if impl_trait_ref.references_error() { return; }
968 // Locate trait definition and items
970 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
971 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
972 let mut overridden_associated_type = None;
974 // Check existing impl methods to see if they are both present in trait
975 // and compatible with trait signature
976 for impl_item in impl_items {
977 let ty_impl_item = tcx.impl_or_trait_item(tcx.map.local_def_id(impl_item.id));
978 let ty_trait_item = trait_items.iter()
979 .find(|ac| ac.name() == ty_impl_item.name());
981 // Check that impl definition matches trait definition
982 if let Some(ty_trait_item) = ty_trait_item {
983 match impl_item.node {
984 hir::ImplItemKind::Const(..) => {
985 let impl_const = match ty_impl_item {
986 ty::ConstTraitItem(ref cti) => cti,
987 _ => span_bug!(impl_item.span, "non-const impl-item for const")
990 // Find associated const definition.
991 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
992 compare_const_impl(ccx,
998 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
999 "item `{}` is an associated const, \
1000 which doesn't match its trait `{:?}`",
1003 err.span_label(impl_item.span, &format!("does not match trait"));
1004 // We can only get the spans from local trait definition
1005 // Same for E0324 and E0325
1006 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1007 err.span_label(trait_span, &format!("item in trait"));
1012 hir::ImplItemKind::Method(_, ref body) => {
1013 let impl_method = match ty_impl_item {
1014 ty::MethodTraitItem(ref mti) => mti,
1015 _ => span_bug!(impl_item.span, "non-method impl-item for method")
1018 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
1019 compare_impl_method(ccx,
1026 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1027 "item `{}` is an associated method, \
1028 which doesn't match its trait `{:?}`",
1031 err.span_label(impl_item.span, &format!("does not match trait"));
1032 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1033 err.span_label(trait_span, &format!("item in trait"));
1038 hir::ImplItemKind::Type(_) => {
1039 let impl_type = match ty_impl_item {
1040 ty::TypeTraitItem(ref tti) => tti,
1041 _ => span_bug!(impl_item.span, "non-type impl-item for type")
1044 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
1045 if let Some(_) = at.ty {
1046 overridden_associated_type = Some(impl_item);
1049 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1050 "item `{}` is an associated type, \
1051 which doesn't match its trait `{:?}`",
1054 err.span_label(impl_item.span, &format!("does not match trait"));
1055 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1056 err.span_label(trait_span, &format!("item in trait"));
1064 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1067 // Check for missing items from trait
1068 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
1069 let mut missing_items = Vec::new();
1070 let mut invalidated_items = Vec::new();
1071 let associated_type_overridden = overridden_associated_type.is_some();
1072 for trait_item in trait_items.iter() {
1077 ty::ConstTraitItem(ref associated_const) => {
1078 is_provided = associated_const.has_value;
1079 is_implemented = impl_items.iter().any(|ii| {
1081 hir::ImplItemKind::Const(..) => {
1082 ii.name == associated_const.name
1088 ty::MethodTraitItem(ref trait_method) => {
1089 is_provided = provided_methods.iter().any(|m| m.name == trait_method.name);
1090 is_implemented = trait_def.ancestors(impl_id)
1091 .fn_defs(tcx, trait_method.name)
1093 .map(|node_item| !node_item.node.is_from_trait())
1096 ty::TypeTraitItem(ref trait_assoc_ty) => {
1097 is_provided = trait_assoc_ty.ty.is_some();
1098 is_implemented = trait_def.ancestors(impl_id)
1099 .type_defs(tcx, trait_assoc_ty.name)
1101 .map(|node_item| !node_item.node.is_from_trait())
1106 if !is_implemented {
1108 missing_items.push(trait_item.name());
1109 } else if associated_type_overridden {
1110 invalidated_items.push(trait_item.name());
1115 if !missing_items.is_empty() {
1116 struct_span_err!(tcx.sess, impl_span, E0046,
1117 "not all trait items implemented, missing: `{}`",
1118 missing_items.iter()
1119 .map(|name| name.to_string())
1120 .collect::<Vec<_>>().join("`, `"))
1121 .span_label(impl_span, &format!("missing `{}` in implementation",
1122 missing_items.iter()
1123 .map(|name| name.to_string())
1124 .collect::<Vec<_>>().join("`, `"))
1128 if !invalidated_items.is_empty() {
1129 let invalidator = overridden_associated_type.unwrap();
1130 span_err!(tcx.sess, invalidator.span, E0399,
1131 "the following trait items need to be reimplemented \
1132 as `{}` was overridden: `{}`",
1134 invalidated_items.iter()
1135 .map(|name| name.to_string())
1136 .collect::<Vec<_>>().join("`, `"))
1140 /// Checks a constant with a given type.
1141 fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
1142 expr: &'tcx hir::Expr,
1143 expected_type: Ty<'tcx>,
1145 ccx.inherited(id).enter(|inh| {
1146 let fcx = FnCtxt::new(&inh, expected_type, expr.id);
1147 fcx.require_type_is_sized(expected_type, expr.span, traits::ConstSized);
1149 // Gather locals in statics (because of block expressions).
1150 // This is technically unnecessary because locals in static items are forbidden,
1151 // but prevents type checking from blowing up before const checking can properly
1153 GatherLocalsVisitor { fcx: &fcx }.visit_expr(expr);
1155 fcx.check_expr_coercable_to_type(expr, expected_type);
1157 fcx.select_all_obligations_and_apply_defaults();
1158 fcx.closure_analyze_const(expr);
1159 fcx.select_obligations_where_possible();
1161 fcx.select_all_obligations_or_error();
1163 fcx.regionck_expr(expr);
1164 fcx.resolve_type_vars_in_expr(expr, id);
1168 fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1169 expr: &'tcx hir::Expr,
1171 let decl_ty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
1172 check_const_with_type(ccx, expr, decl_ty, id);
1175 /// Checks whether a type can be represented in memory. In particular, it
1176 /// identifies types that contain themselves without indirection through a
1177 /// pointer, which would mean their size is unbounded.
1178 pub fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1180 item_id: ast::NodeId,
1181 _designation: &str) -> bool {
1182 let rty = tcx.node_id_to_type(item_id);
1184 // Check that it is possible to represent this type. This call identifies
1185 // (1) types that contain themselves and (2) types that contain a different
1186 // recursive type. It is only necessary to throw an error on those that
1187 // contain themselves. For case 2, there must be an inner type that will be
1188 // caught by case 1.
1189 match rty.is_representable(tcx, sp) {
1190 Representability::SelfRecursive => {
1191 let item_def_id = tcx.map.local_def_id(item_id);
1192 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1195 Representability::Representable | Representability::ContainsRecursive => (),
1200 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) {
1201 let t = tcx.node_id_to_type(id);
1203 ty::TyStruct(def, substs) => {
1204 let fields = &def.struct_variant().fields;
1205 if fields.is_empty() {
1206 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1209 let e = fields[0].ty(tcx, substs);
1210 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1211 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
1215 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1216 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1218 span_err!(tcx.sess, sp, E0077,
1219 "SIMD vector element type should be machine type");
1228 #[allow(trivial_numeric_casts)]
1229 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1231 vs: &'tcx [hir::Variant],
1233 let def_id = ccx.tcx.map.local_def_id(id);
1234 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
1236 if hint != attr::ReprAny && vs.is_empty() {
1238 ccx.tcx.sess, sp, E0084,
1239 "unsupported representation for zero-variant enum")
1240 .span_label(sp, &format!("unsupported enum representation"))
1244 let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx);
1246 if let Some(ref e) = v.node.disr_expr {
1247 check_const_with_type(ccx, e, repr_type_ty, e.id);
1251 let def_id = ccx.tcx.map.local_def_id(id);
1253 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
1254 let mut disr_vals: Vec<ty::Disr> = Vec::new();
1255 for (v, variant) in vs.iter().zip(variants.iter()) {
1256 let current_disr_val = variant.disr_val;
1258 // Check for duplicate discriminant values
1259 if let Some(i) = disr_vals.iter().position(|&x| x == current_disr_val) {
1260 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
1261 let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id);
1262 let i_span = match variant_i.node.disr_expr {
1263 Some(ref expr) => expr.span,
1264 None => ccx.tcx.map.span(variant_i_node_id)
1266 let span = match v.node.disr_expr {
1267 Some(ref expr) => expr.span,
1270 struct_span_err!(ccx.tcx.sess, span, E0081,
1271 "discriminant value `{}` already exists", disr_vals[i])
1272 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1273 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1276 disr_vals.push(current_disr_val);
1279 check_representable(ccx.tcx, sp, id, "enum");
1282 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1283 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1285 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1286 &self.ast_ty_to_ty_cache
1289 fn get_generics(&self, _: Span, id: DefId)
1290 -> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
1292 Ok(self.tcx().lookup_generics(id))
1295 fn get_item_type_scheme(&self, _: Span, id: DefId)
1296 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1298 Ok(self.tcx().lookup_item_type(id))
1301 fn get_trait_def(&self, _: Span, id: DefId)
1302 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1304 Ok(self.tcx().lookup_trait_def(id))
1307 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1308 // all super predicates are ensured during collect pass
1312 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1313 Some(&self.parameter_environment.free_substs)
1316 fn get_type_parameter_bounds(&self,
1318 node_id: ast::NodeId)
1319 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1321 let def = self.tcx.type_parameter_def(node_id);
1322 let r = self.parameter_environment
1325 .filter_map(|predicate| {
1327 ty::Predicate::Trait(ref data) => {
1328 if data.0.self_ty().is_param(def.index) {
1329 Some(data.to_poly_trait_ref())
1343 fn trait_defines_associated_type_named(&self,
1344 trait_def_id: DefId,
1345 assoc_name: ast::Name)
1348 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
1349 trait_def.associated_type_names.contains(&assoc_name)
1352 fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
1356 fn ty_infer_for_def(&self,
1357 ty_param_def: &ty::TypeParameterDef<'tcx>,
1358 substs: &Substs<'tcx>,
1359 span: Span) -> Ty<'tcx> {
1360 self.type_var_for_def(span, ty_param_def, substs)
1363 fn projected_ty_from_poly_trait_ref(&self,
1365 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1366 item_name: ast::Name)
1369 let (trait_ref, _) =
1370 self.replace_late_bound_regions_with_fresh_var(
1372 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1375 self.normalize_associated_type(span, trait_ref, item_name)
1378 fn projected_ty(&self,
1380 trait_ref: ty::TraitRef<'tcx>,
1381 item_name: ast::Name)
1384 self.normalize_associated_type(span, trait_ref, item_name)
1387 fn set_tainted_by_errors(&self) {
1388 self.infcx.set_tainted_by_errors()
1392 impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> {
1393 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1394 Some(self.base_object_lifetime_default(span))
1397 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1398 // RFC #599 specifies that object lifetime defaults take
1399 // precedence over other defaults. But within a fn body we
1400 // don't have a *default* region, rather we use inference to
1401 // find the *correct* region, which is strictly more general
1402 // (and anyway, within a fn body the right region may not even
1403 // be something the user can write explicitly, since it might
1404 // be some expression).
1405 *self.next_region_var(infer::MiscVariable(span))
1408 fn anon_regions(&self, span: Span, count: usize)
1409 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1410 Ok((0..count).map(|_| {
1411 *self.next_region_var(infer::MiscVariable(span))
1416 /// Controls whether the arguments are tupled. This is used for the call
1419 /// Tupling means that all call-side arguments are packed into a tuple and
1420 /// passed as a single parameter. For example, if tupling is enabled, this
1423 /// fn f(x: (isize, isize))
1425 /// Can be called as:
1432 #[derive(Clone, Eq, PartialEq)]
1433 enum TupleArgumentsFlag {
1438 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1439 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1441 body_id: ast::NodeId)
1442 -> FnCtxt<'a, 'gcx, 'tcx> {
1444 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1446 writeback_errors: Cell::new(false),
1447 err_count_on_creation: inh.tcx.sess.err_count(),
1449 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
1454 pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> {
1455 &self.parameter_environment
1458 pub fn sess(&self) -> &Session {
1462 pub fn err_count_since_creation(&self) -> usize {
1463 self.tcx.sess.err_count() - self.err_count_on_creation
1466 /// Resolves type variables in `ty` if possible. Unlike the infcx
1467 /// version (resolve_type_vars_if_possible), this version will
1468 /// also select obligations if it seems useful, in an effort
1469 /// to get more type information.
1470 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1471 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1473 // No TyInfer()? Nothing needs doing.
1474 if !ty.has_infer_types() {
1475 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1479 // If `ty` is a type variable, see whether we already know what it is.
1480 ty = self.resolve_type_vars_if_possible(&ty);
1481 if !ty.has_infer_types() {
1482 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1486 // If not, try resolving pending obligations as much as
1487 // possible. This can help substantially when there are
1488 // indirect dependencies that don't seem worth tracking
1490 self.select_obligations_where_possible();
1491 ty = self.resolve_type_vars_if_possible(&ty);
1493 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1497 fn record_deferred_call_resolution(&self,
1498 closure_def_id: DefId,
1499 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1500 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1501 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1504 fn remove_deferred_call_resolutions(&self,
1505 closure_def_id: DefId)
1506 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1508 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1509 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1512 pub fn tag(&self) -> String {
1513 let self_ptr: *const FnCtxt = self;
1514 format!("{:?}", self_ptr)
1517 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1518 match self.locals.borrow().get(&nid) {
1521 span_err!(self.tcx.sess, span, E0513,
1522 "no type for local variable {}",
1530 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1531 debug!("write_ty({}, {:?}) in fcx {}",
1532 node_id, ty, self.tag());
1533 self.tables.borrow_mut().node_types.insert(node_id, ty);
1535 // Add adjustments to !-expressions
1537 if let Some(hir::map::NodeExpr(_)) = self.tcx.map.find(node_id) {
1538 let adj = adjustment::AdjustNeverToAny(self.next_diverging_ty_var());
1539 self.write_adjustment(node_id, adj);
1544 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1545 if !substs.substs.is_noop() {
1546 debug!("write_substs({}, {:?}) in fcx {}",
1551 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1555 pub fn write_autoderef_adjustment(&self,
1556 node_id: ast::NodeId,
1558 self.write_adjustment(
1560 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1568 pub fn write_adjustment(&self,
1569 node_id: ast::NodeId,
1570 adj: adjustment::AutoAdjustment<'tcx>) {
1571 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1573 if adj.is_identity() {
1577 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1580 /// Basically whenever we are converting from a type scheme into
1581 /// the fn body space, we always want to normalize associated
1582 /// types as well. This function combines the two.
1583 fn instantiate_type_scheme<T>(&self,
1585 substs: &Substs<'tcx>,
1588 where T : TypeFoldable<'tcx>
1590 let value = value.subst(self.tcx, substs);
1591 let result = self.normalize_associated_types_in(span, &value);
1592 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1599 /// As `instantiate_type_scheme`, but for the bounds found in a
1600 /// generic type scheme.
1601 fn instantiate_bounds(&self,
1603 substs: &Substs<'tcx>,
1604 bounds: &ty::GenericPredicates<'tcx>)
1605 -> ty::InstantiatedPredicates<'tcx>
1607 let result = bounds.instantiate(self.tcx, substs);
1608 let result = self.normalize_associated_types_in(span, &result.predicates);
1609 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1613 ty::InstantiatedPredicates {
1618 /// Replace all anonymized types with fresh inference variables
1619 /// and record them for writeback.
1620 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1621 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1622 if let ty::TyAnon(def_id, substs) = ty.sty {
1623 // Use the same type variable if the exact same TyAnon appears more
1624 // than once in the return type (e.g. if it's pased to a type alias).
1625 if let Some(ty_var) = self.anon_types.borrow().get(&def_id) {
1628 let ty_var = self.next_ty_var();
1629 self.anon_types.borrow_mut().insert(def_id, ty_var);
1631 let item_predicates = self.tcx.lookup_predicates(def_id);
1632 let bounds = item_predicates.instantiate(self.tcx, substs);
1634 let span = self.tcx.map.def_id_span(def_id, codemap::DUMMY_SP);
1635 for predicate in bounds.predicates {
1636 // Change the predicate to refer to the type variable,
1637 // which will be the concrete type, instead of the TyAnon.
1638 // This also instantiates nested `impl Trait`.
1639 let predicate = self.instantiate_anon_types(&predicate);
1641 // Require that the predicate holds for the concrete type.
1642 let cause = traits::ObligationCause::new(span, self.body_id,
1643 traits::ReturnType);
1644 self.register_predicate(traits::Obligation::new(cause, predicate));
1654 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1655 where T : TypeFoldable<'tcx>
1657 self.inh.normalize_associated_types_in(span, self.body_id, value)
1660 fn normalize_associated_type(&self,
1662 trait_ref: ty::TraitRef<'tcx>,
1663 item_name: ast::Name)
1666 let cause = traits::ObligationCause::new(span,
1668 traits::ObligationCauseCode::MiscObligation);
1671 .normalize_projection_type(self,
1673 trait_ref: trait_ref,
1674 item_name: item_name,
1679 /// Instantiates the type in `did` with the generics in `path` and returns
1680 /// it (registering the necessary trait obligations along the way).
1682 /// Note that this function is only intended to be used with type-paths,
1683 /// not with value-paths.
1684 pub fn instantiate_type_path(&self,
1687 node_id: ast::NodeId)
1689 debug!("instantiate_type_path(did={:?}, path={:?})", did, path);
1690 let mut ty = self.tcx.lookup_item_type(did).ty;
1692 // Tuple variants have fn type even in type namespace, extract true variant type from it
1693 ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap();
1695 let type_predicates = self.tcx.lookup_predicates(did);
1696 let substs = AstConv::ast_path_substs_for_ty(self, self,
1698 PathParamMode::Optional,
1700 path.segments.last().unwrap());
1701 debug!("instantiate_type_path: ty={:?} substs={:?}", ty, substs);
1702 let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);
1703 let cause = traits::ObligationCause::new(path.span, self.body_id,
1704 traits::ItemObligation(did));
1705 self.add_obligations_for_parameters(cause, &bounds);
1707 let ty_substituted = self.instantiate_type_scheme(path.span, substs, &ty);
1708 self.write_ty(node_id, ty_substituted);
1709 self.write_substs(node_id, ty::ItemSubsts {
1715 pub fn write_nil(&self, node_id: ast::NodeId) {
1716 self.write_ty(node_id, self.tcx.mk_nil());
1719 pub fn write_never(&self, node_id: ast::NodeId) {
1720 self.write_ty(node_id, self.tcx.types.never);
1723 pub fn write_error(&self, node_id: ast::NodeId) {
1724 self.write_ty(node_id, self.tcx.types.err);
1727 pub fn require_type_meets(&self,
1730 code: traits::ObligationCauseCode<'tcx>,
1731 bound: ty::BuiltinBound)
1733 self.register_builtin_bound(
1736 traits::ObligationCause::new(span, self.body_id, code));
1739 pub fn require_type_is_sized(&self,
1742 code: traits::ObligationCauseCode<'tcx>)
1744 self.require_type_meets(ty, span, code, ty::BoundSized);
1747 pub fn require_expr_have_sized_type(&self,
1749 code: traits::ObligationCauseCode<'tcx>)
1751 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1754 pub fn register_builtin_bound(&self,
1756 builtin_bound: ty::BuiltinBound,
1757 cause: traits::ObligationCause<'tcx>)
1759 self.fulfillment_cx.borrow_mut()
1760 .register_builtin_bound(self, ty, builtin_bound, cause);
1763 pub fn register_predicate(&self,
1764 obligation: traits::PredicateObligation<'tcx>)
1766 debug!("register_predicate({:?})",
1770 .register_predicate_obligation(self, obligation);
1773 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1774 let t = AstConv::ast_ty_to_ty(self, self, ast_t);
1775 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1779 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1780 if let Some(&adjustment::AdjustNeverToAny(ref t))
1781 = self.tables.borrow().adjustments.get(&ex.id) {
1784 match self.tables.borrow().node_types.get(&ex.id) {
1787 bug!("no type for expr in fcx {}", self.tag());
1792 /// Apply `adjustment` to the type of `expr`
1793 pub fn adjust_expr_ty(&self,
1795 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1798 let raw_ty = self.expr_ty(expr);
1799 let raw_ty = self.shallow_resolve(raw_ty);
1800 let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1801 raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| {
1802 self.tables.borrow().method_map.get(&method_call)
1803 .map(|method| resolve_ty(method.ty))
1807 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1808 match self.tables.borrow().node_types.get(&id) {
1810 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1812 bug!("no type for node {}: {} in fcx {}",
1813 id, self.tcx.map.node_to_string(id),
1819 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1820 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1821 // it changes when we upgrade the snapshot compiler
1822 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1823 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1827 Ref::map(self.tables.borrow(), project_item_susbts)
1830 pub fn opt_node_ty_substs<F>(&self,
1833 F: FnOnce(&ty::ItemSubsts<'tcx>),
1835 match self.tables.borrow().item_substs.get(&id) {
1841 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1842 /// outlive the region `r`.
1843 pub fn register_region_obligation(&self,
1845 region: &'tcx ty::Region,
1846 cause: traits::ObligationCause<'tcx>)
1848 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1849 fulfillment_cx.register_region_obligation(ty, region, cause);
1852 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1853 /// outlive the region `r`.
1854 pub fn register_wf_obligation(&self,
1857 code: traits::ObligationCauseCode<'tcx>)
1859 // WF obligations never themselves fail, so no real need to give a detailed cause:
1860 let cause = traits::ObligationCause::new(span, self.body_id, code);
1861 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1864 pub fn register_old_wf_obligation(&self,
1867 code: traits::ObligationCauseCode<'tcx>)
1869 // Registers an "old-style" WF obligation that uses the
1870 // implicator code. This is basically a buggy version of
1871 // `register_wf_obligation` that is being kept around
1872 // temporarily just to help with phasing in the newer rules.
1874 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1875 let cause = traits::ObligationCause::new(span, self.body_id, code);
1876 self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
1879 /// Registers obligations that all types appearing in `substs` are well-formed.
1880 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1882 for ty in substs.types() {
1883 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1887 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1888 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1889 /// trait/region obligations.
1891 /// For example, if there is a function:
1894 /// fn foo<'a,T:'a>(...)
1897 /// and a reference:
1903 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1904 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1905 pub fn add_obligations_for_parameters(&self,
1906 cause: traits::ObligationCause<'tcx>,
1907 predicates: &ty::InstantiatedPredicates<'tcx>)
1909 assert!(!predicates.has_escaping_regions());
1911 debug!("add_obligations_for_parameters(predicates={:?})",
1914 for obligation in traits::predicates_for_generics(cause, predicates) {
1915 self.register_predicate(obligation);
1919 // FIXME(arielb1): use this instead of field.ty everywhere
1920 // Only for fields! Returns <none> for methods>
1921 // Indifferent to privacy flags
1922 pub fn field_ty(&self,
1924 field: ty::FieldDef<'tcx>,
1925 substs: &Substs<'tcx>)
1928 self.normalize_associated_types_in(span,
1929 &field.ty(self.tcx, substs))
1932 fn check_casts(&self) {
1933 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1934 for cast in deferred_cast_checks.drain(..) {
1939 /// Apply "fallbacks" to some types
1940 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1941 fn default_type_parameters(&self) {
1942 use rustc::ty::error::UnconstrainedNumeric::Neither;
1943 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1945 // Defaulting inference variables becomes very dubious if we have
1946 // encountered type-checking errors. Therefore, if we think we saw
1947 // some errors in this function, just resolve all uninstanted type
1948 // varibles to TyError.
1949 if self.is_tainted_by_errors() {
1950 for ty in &self.unsolved_variables() {
1951 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1952 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1953 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
1959 for ty in &self.unsolved_variables() {
1960 let resolved = self.resolve_type_vars_if_possible(ty);
1961 if self.type_var_diverges(resolved) {
1962 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
1964 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1965 self.tcx.mk_diverging_default());
1967 match self.type_is_unconstrained_numeric(resolved) {
1968 UnconstrainedInt => {
1969 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1971 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
1973 UnconstrainedFloat => {
1974 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1976 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
1984 fn select_all_obligations_and_apply_defaults(&self) {
1985 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
1986 self.new_select_all_obligations_and_apply_defaults();
1988 self.old_select_all_obligations_and_apply_defaults();
1992 // Implements old type inference fallback algorithm
1993 fn old_select_all_obligations_and_apply_defaults(&self) {
1994 self.select_obligations_where_possible();
1995 self.default_type_parameters();
1996 self.select_obligations_where_possible();
1999 fn new_select_all_obligations_and_apply_defaults(&self) {
2000 use rustc::ty::error::UnconstrainedNumeric::Neither;
2001 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2003 // For the time being this errs on the side of being memory wasteful but provides better
2005 // let type_variables = self.type_variables.clone();
2007 // There is a possibility that this algorithm will have to run an arbitrary number of times
2008 // to terminate so we bound it by the compiler's recursion limit.
2009 for _ in 0..self.tcx.sess.recursion_limit.get() {
2010 // First we try to solve all obligations, it is possible that the last iteration
2011 // has made it possible to make more progress.
2012 self.select_obligations_where_possible();
2014 let mut conflicts = Vec::new();
2016 // Collect all unsolved type, integral and floating point variables.
2017 let unsolved_variables = self.unsolved_variables();
2019 // We must collect the defaults *before* we do any unification. Because we have
2020 // directly attached defaults to the type variables any unification that occurs
2021 // will erase defaults causing conflicting defaults to be completely ignored.
2022 let default_map: FnvHashMap<_, _> =
2025 .filter_map(|t| self.default(t).map(|d| (t, d)))
2028 let mut unbound_tyvars = FnvHashSet();
2030 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
2032 // We loop over the unsolved variables, resolving them and if they are
2033 // and unconstrainted numeric type we add them to the set of unbound
2034 // variables. We do this so we only apply literal fallback to type
2035 // variables without defaults.
2036 for ty in &unsolved_variables {
2037 let resolved = self.resolve_type_vars_if_possible(ty);
2038 if self.type_var_diverges(resolved) {
2039 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2040 self.tcx.mk_diverging_default());
2042 match self.type_is_unconstrained_numeric(resolved) {
2043 UnconstrainedInt | UnconstrainedFloat => {
2044 unbound_tyvars.insert(resolved);
2051 // We now remove any numeric types that also have defaults, and instead insert
2052 // the type variable with a defined fallback.
2053 for ty in &unsolved_variables {
2054 if let Some(_default) = default_map.get(ty) {
2055 let resolved = self.resolve_type_vars_if_possible(ty);
2057 debug!("select_all_obligations_and_apply_defaults: \
2058 ty: {:?} with default: {:?}",
2061 match resolved.sty {
2062 ty::TyInfer(ty::TyVar(_)) => {
2063 unbound_tyvars.insert(ty);
2066 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
2067 unbound_tyvars.insert(ty);
2068 if unbound_tyvars.contains(resolved) {
2069 unbound_tyvars.remove(resolved);
2078 // If there are no more fallbacks to apply at this point we have applied all possible
2079 // defaults and type inference will proceed as normal.
2080 if unbound_tyvars.is_empty() {
2084 // Finally we go through each of the unbound type variables and unify them with
2085 // the proper fallback, reporting a conflicting default error if any of the
2086 // unifications fail. We know it must be a conflicting default because the
2087 // variable would only be in `unbound_tyvars` and have a concrete value if
2088 // it had been solved by previously applying a default.
2090 // We wrap this in a transaction for error reporting, if we detect a conflict
2091 // we will rollback the inference context to its prior state so we can probe
2092 // for conflicts and correctly report them.
2095 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2096 for ty in &unbound_tyvars {
2097 if self.type_var_diverges(ty) {
2098 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2099 self.tcx.mk_diverging_default());
2101 match self.type_is_unconstrained_numeric(ty) {
2102 UnconstrainedInt => {
2103 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2105 UnconstrainedFloat => {
2106 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2109 if let Some(default) = default_map.get(ty) {
2110 let default = default.clone();
2111 match self.eq_types(false,
2112 TypeOrigin::Misc(default.origin_span),
2114 Ok(InferOk { obligations, .. }) => {
2115 // FIXME(#32730) propagate obligations
2116 assert!(obligations.is_empty())
2119 conflicts.push((*ty, default));
2128 // If there are conflicts we rollback, otherwise commit
2129 if conflicts.len() > 0 {
2136 if conflicts.len() > 0 {
2137 // Loop through each conflicting default, figuring out the default that caused
2138 // a unification failure and then report an error for each.
2139 for (conflict, default) in conflicts {
2140 let conflicting_default =
2141 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
2142 .unwrap_or(type_variable::Default {
2143 ty: self.next_ty_var(),
2144 origin_span: syntax_pos::DUMMY_SP,
2145 def_id: self.tcx.map.local_def_id(0) // what do I put here?
2148 // This is to ensure that we elimnate any non-determinism from the error
2149 // reporting by fixing an order, it doesn't matter what order we choose
2150 // just that it is consistent.
2151 let (first_default, second_default) =
2152 if default.def_id < conflicting_default.def_id {
2153 (default, conflicting_default)
2155 (conflicting_default, default)
2159 self.report_conflicting_default_types(
2160 first_default.origin_span,
2167 self.select_obligations_where_possible();
2170 // For use in error handling related to default type parameter fallback. We explicitly
2171 // apply the default that caused conflict first to a local version of the type variable
2172 // table then apply defaults until we find a conflict. That default must be the one
2173 // that caused conflict earlier.
2174 fn find_conflicting_default(&self,
2175 unbound_vars: &FnvHashSet<Ty<'tcx>>,
2176 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
2178 -> Option<type_variable::Default<'tcx>> {
2179 use rustc::ty::error::UnconstrainedNumeric::Neither;
2180 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2182 // Ensure that we apply the conflicting default first
2183 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2184 unbound_tyvars.push(conflict);
2185 unbound_tyvars.extend(unbound_vars.iter());
2187 let mut result = None;
2188 // We run the same code as above applying defaults in order, this time when
2189 // we find the conflict we just return it for error reporting above.
2191 // We also run this inside snapshot that never commits so we can do error
2192 // reporting for more then one conflict.
2193 for ty in &unbound_tyvars {
2194 if self.type_var_diverges(ty) {
2195 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2196 self.tcx.mk_diverging_default());
2198 match self.type_is_unconstrained_numeric(ty) {
2199 UnconstrainedInt => {
2200 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2202 UnconstrainedFloat => {
2203 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2206 if let Some(default) = default_map.get(ty) {
2207 let default = default.clone();
2208 match self.eq_types(false,
2209 TypeOrigin::Misc(default.origin_span),
2211 // FIXME(#32730) propagate obligations
2212 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2214 result = Some(default);
2226 fn select_all_obligations_or_error(&self) {
2227 debug!("select_all_obligations_or_error");
2229 // upvar inference should have ensured that all deferred call
2230 // resolutions are handled by now.
2231 assert!(self.deferred_call_resolutions.borrow().is_empty());
2233 self.select_all_obligations_and_apply_defaults();
2235 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2237 // Steal the deferred obligations before the fulfillment
2238 // context can turn all of them into errors.
2239 let obligations = fulfillment_cx.take_deferred_obligations();
2240 self.deferred_obligations.borrow_mut().extend(obligations);
2242 match fulfillment_cx.select_all_or_error(self) {
2244 Err(errors) => { self.report_fulfillment_errors(&errors); }
2247 if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(self) {
2248 self.report_fulfillment_errors_as_warnings(errors, self.body_id);
2252 /// Select as many obligations as we can at present.
2253 fn select_obligations_where_possible(&self) {
2254 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2256 Err(errors) => { self.report_fulfillment_errors(&errors); }
2260 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2261 /// returns a type of `&T`, but the actual type we assign to the
2262 /// *expression* is `T`. So this function just peels off the return
2263 /// type by one layer to yield `T`.
2264 fn make_overloaded_lvalue_return_type(&self,
2265 method: MethodCallee<'tcx>)
2266 -> ty::TypeAndMut<'tcx>
2268 // extract method return type, which will be &T;
2269 // all LB regions should have been instantiated during method lookup
2270 let ret_ty = method.ty.fn_ret();
2271 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2273 // method returns &T, but the type as visible to user is T, so deref
2274 ret_ty.builtin_deref(true, NoPreference).unwrap()
2277 fn lookup_indexing(&self,
2279 base_expr: &'gcx hir::Expr,
2282 lvalue_pref: LvaluePreference)
2283 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2285 // FIXME(#18741) -- this is almost but not quite the same as the
2286 // autoderef that normal method probing does. They could likely be
2289 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2291 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2292 if let Some(final_mt) = self.try_index_step(
2293 MethodCall::expr(expr.id),
2294 expr, base_expr, adj_ty, autoderefs,
2295 false, lvalue_pref, idx_ty)
2297 autoderef.finalize(lvalue_pref, Some(base_expr));
2298 return Some(final_mt);
2301 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2302 autoderef.finalize(lvalue_pref, Some(base_expr));
2303 let adjusted_ty = self.tcx.mk_slice(element_ty);
2304 return self.try_index_step(
2305 MethodCall::expr(expr.id), expr, base_expr,
2306 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2309 autoderef.unambiguous_final_ty();
2313 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2314 /// (and otherwise adjust) `base_expr`, looking for a type which either
2315 /// supports builtin indexing or overloaded indexing.
2316 /// This loop implements one step in that search; the autoderef loop
2317 /// is implemented by `lookup_indexing`.
2318 fn try_index_step(&self,
2319 method_call: MethodCall,
2321 base_expr: &'gcx hir::Expr,
2322 adjusted_ty: Ty<'tcx>,
2325 lvalue_pref: LvaluePreference,
2327 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2330 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2331 autoderefs={}, unsize={}, index_ty={:?})",
2339 let input_ty = self.next_ty_var();
2341 // First, try built-in indexing.
2342 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2343 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2344 debug!("try_index_step: success, using built-in indexing");
2345 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2347 self.write_autoderef_adjustment(base_expr.id, autoderefs);
2348 return Some((tcx.types.usize, ty));
2353 // Try `IndexMut` first, if preferred.
2354 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2355 (PreferMutLvalue, Some(trait_did)) => {
2356 self.lookup_method_in_trait_adjusted(expr.span,
2358 token::intern("index_mut"),
2363 Some(vec![input_ty]))
2368 // Otherwise, fall back to `Index`.
2369 let method = match (method, tcx.lang_items.index_trait()) {
2370 (None, Some(trait_did)) => {
2371 self.lookup_method_in_trait_adjusted(expr.span,
2373 token::intern("index"),
2378 Some(vec![input_ty]))
2380 (method, _) => method,
2383 // If some lookup succeeds, write callee into table and extract index/element
2384 // type from the method signature.
2385 // If some lookup succeeded, install method in table
2386 method.map(|method| {
2387 debug!("try_index_step: success, using overloaded indexing");
2388 self.tables.borrow_mut().method_map.insert(method_call, method);
2389 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2393 fn check_method_argument_types(&self,
2395 method_fn_ty: Ty<'tcx>,
2396 callee_expr: &'gcx hir::Expr,
2397 args_no_rcvr: &'gcx [P<hir::Expr>],
2398 tuple_arguments: TupleArgumentsFlag,
2399 expected: Expectation<'tcx>)
2401 if method_fn_ty.references_error() {
2402 let err_inputs = self.err_args(args_no_rcvr.len());
2404 let err_inputs = match tuple_arguments {
2405 DontTupleArguments => err_inputs,
2406 TupleArguments => vec![self.tcx.mk_tup(err_inputs)],
2409 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2410 false, tuple_arguments);
2413 match method_fn_ty.sty {
2414 ty::TyFnDef(_, _, ref fty) => {
2415 // HACK(eddyb) ignore self in the definition (see above).
2416 let expected_arg_tys = self.expected_types_for_fn_args(sp, expected,
2418 &fty.sig.0.inputs[1..]);
2419 self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..],
2420 args_no_rcvr, fty.sig.0.variadic, tuple_arguments);
2424 span_bug!(callee_expr.span, "method without bare fn type");
2430 /// Generic function that factors out common logic from function calls,
2431 /// method calls and overloaded operators.
2432 fn check_argument_types(&self,
2434 fn_inputs: &[Ty<'tcx>],
2435 expected_arg_tys: &[Ty<'tcx>],
2436 args: &'gcx [P<hir::Expr>],
2438 tuple_arguments: TupleArgumentsFlag) {
2441 // Grab the argument types, supplying fresh type variables
2442 // if the wrong number of arguments were supplied
2443 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2449 // All the input types from the fn signature must outlive the call
2450 // so as to validate implied bounds.
2451 for &fn_input_ty in fn_inputs {
2452 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2455 let mut expected_arg_tys = expected_arg_tys;
2456 let expected_arg_count = fn_inputs.len();
2458 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
2459 expected_count: usize, arg_count: usize, error_code: &str,
2461 let mut err = sess.struct_span_err_with_code(sp,
2462 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2463 if variadic {"at least "} else {""},
2465 if expected_count == 1 {""} else {"s"},
2467 if arg_count == 1 {" was"} else {"s were"}),
2470 err.span_label(sp, &format!("expected {}{} parameter{}",
2471 if variadic {"at least "} else {""},
2473 if expected_count == 1 {""} else {"s"}));
2475 let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
2476 if input_types.len() > 0 {
2477 err.note(&format!("the following parameter type{} expected: {}",
2478 if expected_count == 1 {" was"} else {"s were"},
2479 input_types.join(", ")));
2484 let formal_tys = if tuple_arguments == TupleArguments {
2485 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2486 match tuple_type.sty {
2487 ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
2488 parameter_count_error(tcx.sess, sp, fn_inputs, arg_types.len(), args.len(),
2490 expected_arg_tys = &[];
2491 self.err_args(args.len())
2493 ty::TyTuple(arg_types) => {
2494 expected_arg_tys = match expected_arg_tys.get(0) {
2495 Some(&ty) => match ty.sty {
2496 ty::TyTuple(ref tys) => &tys,
2504 span_err!(tcx.sess, sp, E0059,
2505 "cannot use call notation; the first type parameter \
2506 for the function trait is neither a tuple nor unit");
2507 expected_arg_tys = &[];
2508 self.err_args(args.len())
2511 } else if expected_arg_count == supplied_arg_count {
2513 } else if variadic {
2514 if supplied_arg_count >= expected_arg_count {
2517 parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count,
2518 supplied_arg_count, "E0060", true);
2519 expected_arg_tys = &[];
2520 self.err_args(supplied_arg_count)
2523 parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count,
2525 expected_arg_tys = &[];
2526 self.err_args(supplied_arg_count)
2529 debug!("check_argument_types: formal_tys={:?}",
2530 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2532 // Check the arguments.
2533 // We do this in a pretty awful way: first we typecheck any arguments
2534 // that are not anonymous functions, then we typecheck the anonymous
2535 // functions. This is so that we have more information about the types
2536 // of arguments when we typecheck the functions. This isn't really the
2537 // right way to do this.
2538 let xs = [false, true];
2539 let mut any_diverges = false; // has any of the arguments diverged?
2540 let mut warned = false; // have we already warned about unreachable code?
2541 for check_blocks in &xs {
2542 let check_blocks = *check_blocks;
2543 debug!("check_blocks={}", check_blocks);
2545 // More awful hacks: before we check argument types, try to do
2546 // an "opportunistic" vtable resolution of any trait bounds on
2547 // the call. This helps coercions.
2549 self.select_obligations_where_possible();
2552 // For variadic functions, we don't have a declared type for all of
2553 // the arguments hence we only do our usual type checking with
2554 // the arguments who's types we do know.
2555 let t = if variadic {
2557 } else if tuple_arguments == TupleArguments {
2562 for (i, arg) in args.iter().take(t).enumerate() {
2563 if any_diverges && !warned {
2566 .add_lint(lint::builtin::UNREACHABLE_CODE,
2569 "unreachable expression".to_string());
2572 let is_block = match arg.node {
2573 hir::ExprClosure(..) => true,
2577 if is_block == check_blocks {
2578 debug!("checking the argument");
2579 let formal_ty = formal_tys[i];
2581 // The special-cased logic below has three functions:
2582 // 1. Provide as good of an expected type as possible.
2583 let expected = expected_arg_tys.get(i).map(|&ty| {
2584 Expectation::rvalue_hint(self, ty)
2587 self.check_expr_with_expectation(&arg,
2588 expected.unwrap_or(ExpectHasType(formal_ty)));
2589 // 2. Coerce to the most detailed type that could be coerced
2590 // to, which is `expected_ty` if `rvalue_hint` returns an
2591 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2592 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2593 self.demand_coerce(&arg, coerce_ty.unwrap_or(formal_ty));
2595 // 3. Relate the expected type and the formal one,
2596 // if the expected type was used for the coercion.
2597 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2600 if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) {
2601 // FIXME(canndrew): This is_never should probably be an is_uninhabited
2602 any_diverges = any_diverges ||
2603 self.type_var_diverges(arg_ty) ||
2607 if any_diverges && !warned {
2608 let parent = self.tcx.map.get_parent_node(args[0].id);
2611 .add_lint(lint::builtin::UNREACHABLE_CODE,
2614 "unreachable call".to_string());
2620 // We also need to make sure we at least write the ty of the other
2621 // arguments which we skipped above.
2623 for arg in args.iter().skip(expected_arg_count) {
2624 self.check_expr(&arg);
2626 // There are a few types which get autopromoted when passed via varargs
2627 // in C but we just error out instead and require explicit casts.
2628 let arg_ty = self.structurally_resolved_type(arg.span,
2629 self.expr_ty(&arg));
2631 ty::TyFloat(ast::FloatTy::F32) => {
2632 self.type_error_message(arg.span, |t| {
2633 format!("can't pass an `{}` to variadic \
2634 function, cast to `c_double`", t)
2637 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2638 self.type_error_message(arg.span, |t| {
2639 format!("can't pass `{}` to variadic \
2640 function, cast to `c_int`",
2644 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2645 self.type_error_message(arg.span, |t| {
2646 format!("can't pass `{}` to variadic \
2647 function, cast to `c_uint`",
2651 ty::TyFnDef(_, _, f) => {
2652 let ptr_ty = self.tcx.mk_fn_ptr(f);
2653 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2654 self.type_error_message(arg.span,
2656 format!("can't pass `{}` to variadic \
2657 function, cast to `{}`", t, ptr_ty)
2666 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2667 (0..len).map(|_| self.tcx.types.err).collect()
2670 fn write_call(&self,
2671 call_expr: &hir::Expr,
2673 self.write_ty(call_expr.id, output);
2676 // AST fragment checking
2679 expected: Expectation<'tcx>)
2685 ast::LitKind::Str(..) => tcx.mk_static_str(),
2686 ast::LitKind::ByteStr(ref v) => {
2687 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2688 tcx.mk_array(tcx.types.u8, v.len()))
2690 ast::LitKind::Byte(_) => tcx.types.u8,
2691 ast::LitKind::Char(_) => tcx.types.char,
2692 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2693 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2694 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2695 let opt_ty = expected.to_option(self).and_then(|ty| {
2697 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2698 ty::TyChar => Some(tcx.types.u8),
2699 ty::TyRawPtr(..) => Some(tcx.types.usize),
2700 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2704 opt_ty.unwrap_or_else(
2705 || tcx.mk_int_var(self.next_int_var_id()))
2707 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2708 ast::LitKind::FloatUnsuffixed(_) => {
2709 let opt_ty = expected.to_option(self).and_then(|ty| {
2711 ty::TyFloat(_) => Some(ty),
2715 opt_ty.unwrap_or_else(
2716 || tcx.mk_float_var(self.next_float_var_id()))
2718 ast::LitKind::Bool(_) => tcx.types.bool
2722 fn check_expr_eq_type(&self,
2723 expr: &'gcx hir::Expr,
2724 expected: Ty<'tcx>) {
2725 self.check_expr_with_hint(expr, expected);
2726 self.demand_eqtype(expr.span, expected, self.expr_ty(expr));
2729 pub fn check_expr_has_type(&self,
2730 expr: &'gcx hir::Expr,
2731 expected: Ty<'tcx>) {
2732 self.check_expr_with_hint(expr, expected);
2733 self.demand_suptype(expr.span, expected, self.expr_ty(expr));
2736 fn check_expr_coercable_to_type(&self,
2737 expr: &'gcx hir::Expr,
2738 expected: Ty<'tcx>) {
2739 self.check_expr_with_hint(expr, expected);
2740 self.demand_coerce(expr, expected);
2743 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2744 expected: Ty<'tcx>) {
2745 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2748 fn check_expr_with_expectation(&self,
2749 expr: &'gcx hir::Expr,
2750 expected: Expectation<'tcx>) {
2751 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2754 fn check_expr(&self, expr: &'gcx hir::Expr) {
2755 self.check_expr_with_expectation(expr, NoExpectation)
2758 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2759 lvalue_pref: LvaluePreference) {
2760 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2763 // determine the `self` type, using fresh variables for all variables
2764 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2765 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2767 pub fn impl_self_ty(&self,
2768 span: Span, // (potential) receiver for this impl
2770 -> TypeAndSubsts<'tcx> {
2771 let ity = self.tcx.lookup_item_type(did);
2772 debug!("impl_self_ty: ity={:?}", ity);
2774 let substs = self.fresh_substs_for_item(span, did);
2775 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity.ty);
2777 TypeAndSubsts { substs: substs, ty: substd_ty }
2780 /// Unifies the return type with the expected type early, for more coercions
2781 /// and forward type information on the argument expressions.
2782 fn expected_types_for_fn_args(&self,
2784 expected_ret: Expectation<'tcx>,
2785 formal_ret: Ty<'tcx>,
2786 formal_args: &[Ty<'tcx>])
2788 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2789 self.commit_regions_if_ok(|| {
2790 // Attempt to apply a subtyping relationship between the formal
2791 // return type (likely containing type variables if the function
2792 // is polymorphic) and the expected return type.
2793 // No argument expectations are produced if unification fails.
2794 let origin = TypeOrigin::Misc(call_span);
2795 let ures = self.sub_types(false, origin, formal_ret, ret_ty);
2796 // FIXME(#15760) can't use try! here, FromError doesn't default
2797 // to identity so the resulting type is not constrained.
2799 // FIXME(#32730) propagate obligations
2800 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2801 Err(e) => return Err(e),
2804 // Record all the argument types, with the substitutions
2805 // produced from the above subtyping unification.
2806 Ok(formal_args.iter().map(|ty| {
2807 self.resolve_type_vars_if_possible(ty)
2810 }).unwrap_or(vec![]);
2811 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2812 formal_args, formal_ret,
2813 expected_args, expected_ret);
2817 // Checks a method call.
2818 fn check_method_call(&self,
2819 expr: &'gcx hir::Expr,
2820 method_name: Spanned<ast::Name>,
2821 args: &'gcx [P<hir::Expr>],
2823 expected: Expectation<'tcx>,
2824 lvalue_pref: LvaluePreference) {
2825 let rcvr = &args[0];
2826 self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2828 // no need to check for bot/err -- callee does that
2829 let expr_t = self.structurally_resolved_type(expr.span, self.expr_ty(&rcvr));
2831 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2832 let fn_ty = match self.lookup_method(method_name.span,
2839 let method_ty = method.ty;
2840 let method_call = MethodCall::expr(expr.id);
2841 self.tables.borrow_mut().method_map.insert(method_call, method);
2845 if method_name.node != keywords::Invalid.name() {
2846 self.report_method_error(method_name.span, expr_t,
2847 method_name.node, Some(rcvr), error);
2849 self.write_error(expr.id);
2854 // Call the generic checker.
2855 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2860 self.write_call(expr, ret_ty);
2863 // A generic function for checking the then and else in an if
2865 fn check_then_else(&self,
2866 cond_expr: &'gcx hir::Expr,
2867 then_blk: &'gcx hir::Block,
2868 opt_else_expr: Option<&'gcx hir::Expr>,
2871 expected: Expectation<'tcx>) {
2872 self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2874 let expected = expected.adjust_for_branches(self);
2875 self.check_block_with_expected(then_blk, expected);
2876 let then_ty = self.node_ty(then_blk.id);
2878 let unit = self.tcx.mk_nil();
2879 let (origin, expected, found, result) =
2880 if let Some(else_expr) = opt_else_expr {
2881 self.check_expr_with_expectation(else_expr, expected);
2882 let else_ty = self.expr_ty(else_expr);
2883 let origin = TypeOrigin::IfExpression(sp);
2885 // Only try to coerce-unify if we have a then expression
2886 // to assign coercions to, otherwise it's () or diverging.
2887 let result = if let Some(ref then) = then_blk.expr {
2888 let res = self.try_find_coercion_lub(origin, || Some(&**then),
2889 then_ty, else_expr);
2891 // In case we did perform an adjustment, we have to update
2892 // the type of the block, because old trans still uses it.
2893 let adj = self.tables.borrow().adjustments.get(&then.id).cloned();
2894 if res.is_ok() && adj.is_some() {
2895 self.write_ty(then_blk.id, self.adjust_expr_ty(then, adj.as_ref()));
2900 self.commit_if_ok(|_| {
2901 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2902 self.lub(true, trace, &then_ty, &else_ty)
2903 .map(|InferOk { value, obligations }| {
2904 // FIXME(#32730) propagate obligations
2905 assert!(obligations.is_empty());
2910 (origin, then_ty, else_ty, result)
2912 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2913 (origin, unit, then_ty,
2914 self.eq_types(true, origin, unit, then_ty)
2915 .map(|InferOk { obligations, .. }| {
2916 // FIXME(#32730) propagate obligations
2917 assert!(obligations.is_empty());
2922 let if_ty = match result {
2924 if self.expr_ty(cond_expr).references_error() {
2931 self.report_mismatched_types(origin, expected, found, e);
2936 self.write_ty(id, if_ty);
2939 // Check field access expressions
2940 fn check_field(&self,
2941 expr: &'gcx hir::Expr,
2942 lvalue_pref: LvaluePreference,
2943 base: &'gcx hir::Expr,
2944 field: &Spanned<ast::Name>) {
2945 self.check_expr_with_lvalue_pref(base, lvalue_pref);
2946 let expr_t = self.structurally_resolved_type(expr.span,
2947 self.expr_ty(base));
2948 let mut private_candidate = None;
2949 let mut autoderef = self.autoderef(expr.span, expr_t);
2950 while let Some((base_t, autoderefs)) = autoderef.next() {
2951 if let ty::TyStruct(base_def, substs) = base_t.sty {
2952 debug!("struct named {:?}", base_t);
2953 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2954 let field_ty = self.field_ty(expr.span, field, substs);
2955 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
2956 autoderef.finalize(lvalue_pref, Some(base));
2957 self.write_ty(expr.id, field_ty);
2958 self.write_autoderef_adjustment(base.id, autoderefs);
2961 private_candidate = Some((base_def.did, field_ty));
2965 autoderef.unambiguous_final_ty();
2967 if let Some((did, field_ty)) = private_candidate {
2968 let struct_path = self.tcx().item_path_str(did);
2969 self.write_ty(expr.id, field_ty);
2970 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2971 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2972 // Also check if an accessible method exists, which is often what is meant.
2973 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2974 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2978 } else if field.node == keywords::Invalid.name() {
2979 self.write_error(expr.id);
2980 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2981 self.type_error_struct(field.span, |actual| {
2982 format!("attempted to take value of method `{}` on type \
2983 `{}`", field.node, actual)
2985 .help("maybe a `()` to call it is missing? \
2986 If not, try an anonymous function")
2988 self.write_error(expr.id);
2990 let mut err = self.type_error_struct(expr.span, |actual| {
2991 format!("attempted access of field `{}` on type `{}`, \
2992 but no field with that name was found",
2995 if let ty::TyRawPtr(..) = expr_t.sty {
2996 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
2997 `(*{0}).{1}`", pprust::expr_to_string(base), field.node));
2999 if let ty::TyStruct(def, _) = expr_t.sty {
3000 Self::suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
3003 self.write_error(expr.id);
3007 // displays hints about the closest matches in field names
3008 fn suggest_field_names(err: &mut DiagnosticBuilder,
3009 variant: ty::VariantDef<'tcx>,
3010 field: &Spanned<ast::Name>,
3011 skip : Vec<InternedString>) {
3012 let name = field.node.as_str();
3013 let names = variant.fields.iter().filter_map(|field| {
3014 // ignore already set fields and private fields from non-local crates
3015 if skip.iter().any(|x| *x == field.name.as_str()) ||
3016 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3023 // only find fits with at least one matching letter
3024 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3025 err.span_help(field.span,
3026 &format!("did you mean `{}`?", name));
3030 // Check tuple index expressions
3031 fn check_tup_field(&self,
3032 expr: &'gcx hir::Expr,
3033 lvalue_pref: LvaluePreference,
3034 base: &'gcx hir::Expr,
3035 idx: codemap::Spanned<usize>) {
3036 self.check_expr_with_lvalue_pref(base, lvalue_pref);
3037 let expr_t = self.structurally_resolved_type(expr.span,
3038 self.expr_ty(base));
3039 let mut private_candidate = None;
3040 let mut tuple_like = false;
3041 let mut autoderef = self.autoderef(expr.span, expr_t);
3042 while let Some((base_t, autoderefs)) = autoderef.next() {
3043 let field = match base_t.sty {
3044 ty::TyStruct(base_def, substs) => {
3045 tuple_like = base_def.struct_variant().kind == ty::VariantKind::Tuple;
3046 if !tuple_like { continue }
3048 debug!("tuple struct named {:?}", base_t);
3049 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
3050 let field_ty = self.field_ty(expr.span, field, substs);
3051 private_candidate = Some((base_def.did, field_ty));
3052 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
3059 ty::TyTuple(ref v) => {
3061 v.get(idx.node).cloned()
3066 if let Some(field_ty) = field {
3067 autoderef.finalize(lvalue_pref, Some(base));
3068 self.write_ty(expr.id, field_ty);
3069 self.write_autoderef_adjustment(base.id, autoderefs);
3073 autoderef.unambiguous_final_ty();
3075 if let Some((did, field_ty)) = private_candidate {
3076 let struct_path = self.tcx().item_path_str(did);
3077 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3078 self.tcx().sess.span_err(expr.span, &msg);
3079 self.write_ty(expr.id, field_ty);
3083 self.type_error_message(
3087 format!("attempted out-of-bounds tuple index `{}` on \
3092 format!("attempted tuple index `{}` on type `{}`, but the \
3093 type was not a tuple or tuple struct",
3100 self.write_error(expr.id);
3103 fn report_unknown_field(&self,
3105 variant: ty::VariantDef<'tcx>,
3107 skip_fields: &[hir::Field]) {
3108 let mut err = self.type_error_struct_with_diag(
3110 |actual| if let ty::TyEnum(..) = ty.sty {
3111 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3112 "struct variant `{}::{}` has no field named `{}`",
3113 actual, variant.name.as_str(), field.name.node)
3115 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3116 "structure `{}` has no field named `{}`",
3117 actual, field.name.node)
3120 // prevent all specified fields from being suggested
3121 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3122 Self::suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3126 fn check_expr_struct_fields(&self,
3129 variant: ty::VariantDef<'tcx>,
3130 ast_fields: &'gcx [hir::Field],
3131 check_completeness: bool) {
3133 let substs = match adt_ty.sty {
3134 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3135 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3138 let mut remaining_fields = FnvHashMap();
3139 for field in &variant.fields {
3140 remaining_fields.insert(field.name, field);
3143 let mut seen_fields = FnvHashMap();
3145 let mut error_happened = false;
3147 // Typecheck each field.
3148 for field in ast_fields {
3149 let expected_field_type;
3151 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3152 expected_field_type = self.field_ty(field.span, v_field, substs);
3154 seen_fields.insert(field.name.node, field.span);
3156 error_happened = true;
3157 expected_field_type = tcx.types.err;
3158 if let Some(_) = variant.find_field_named(field.name.node) {
3159 let mut err = struct_span_err!(self.tcx.sess,
3162 "field `{}` specified more than once",
3165 err.span_label(field.name.span, &format!("used more than once"));
3167 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3168 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3173 self.report_unknown_field(adt_ty, variant, field, ast_fields);
3177 // Make sure to give a type to the field even if there's
3178 // an error, so we can continue typechecking
3179 self.check_expr_coercable_to_type(&field.expr, expected_field_type);
3182 // Make sure the programmer specified all the fields.
3183 if check_completeness &&
3185 !remaining_fields.is_empty()
3187 span_err!(tcx.sess, span, E0063,
3188 "missing field{} {} in initializer of `{}`",
3189 if remaining_fields.len() == 1 {""} else {"s"},
3190 remaining_fields.keys()
3191 .map(|n| format!("`{}`", n))
3192 .collect::<Vec<_>>()
3199 fn check_struct_fields_on_error(&self,
3201 fields: &'gcx [hir::Field],
3202 base_expr: &'gcx Option<P<hir::Expr>>) {
3203 // Make sure to still write the types
3204 // otherwise we might ICE
3205 self.write_error(id);
3206 for field in fields {
3207 self.check_expr(&field.expr);
3210 Some(ref base) => self.check_expr(&base),
3215 pub fn check_struct_path(&self,
3217 node_id: ast::NodeId,
3219 -> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> {
3220 let def = self.finish_resolving_struct_path(path, node_id, span);
3221 let variant = match def {
3223 self.set_tainted_by_errors();
3226 Def::Variant(type_did, _) | Def::Struct(type_did) => {
3227 Some((type_did, self.tcx.expect_variant_def(def)))
3229 Def::TyAlias(did) => {
3230 if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did)
3231 .map(|scheme| &scheme.ty.sty) {
3232 Some((did, adt.struct_variant()))
3240 if let Some((def_id, variant)) = variant {
3241 if variant.kind == ty::VariantKind::Tuple &&
3242 !self.tcx.sess.features.borrow().relaxed_adts {
3243 emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
3244 "relaxed_adts", span, GateIssue::Language,
3245 "tuple structs and variants in struct patterns are unstable");
3247 let ty = self.instantiate_type_path(def_id, path, node_id);
3250 struct_span_err!(self.tcx.sess, path.span, E0071,
3251 "`{}` does not name a struct or a struct variant",
3252 pprust::path_to_string(path))
3253 .span_label(path.span, &format!("not a struct"))
3259 fn check_expr_struct(&self,
3262 fields: &'gcx [hir::Field],
3263 base_expr: &'gcx Option<P<hir::Expr>>)
3265 // Find the relevant variant
3266 let (variant, expr_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id,
3270 self.check_struct_fields_on_error(expr.id, fields, base_expr);
3274 self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
3275 base_expr.is_none());
3276 if let &Some(ref base_expr) = base_expr {
3277 self.check_expr_has_type(base_expr, expr_ty);
3279 ty::TyStruct(adt, substs) => {
3280 self.tables.borrow_mut().fru_field_types.insert(
3282 adt.struct_variant().fields.iter().map(|f| {
3283 self.normalize_associated_types_in(
3284 expr.span, &f.ty(self.tcx, substs)
3290 span_err!(self.tcx.sess, base_expr.span, E0436,
3291 "functional record update syntax requires a struct");
3299 /// If an expression has any sub-expressions that result in a type error,
3300 /// inspecting that expression's type with `ty.references_error()` will return
3301 /// true. Likewise, if an expression is known to diverge, inspecting its
3302 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3303 /// strict, _|_ can appear in the type of an expression that does not,
3304 /// itself, diverge: for example, fn() -> _|_.)
3305 /// Note that inspecting a type's structure *directly* may expose the fact
3306 /// that there are actually multiple representations for `TyError`, so avoid
3307 /// that when err needs to be handled differently.
3308 fn check_expr_with_expectation_and_lvalue_pref(&self,
3309 expr: &'gcx hir::Expr,
3310 expected: Expectation<'tcx>,
3311 lvalue_pref: LvaluePreference) {
3312 debug!(">> typechecking: expr={:?} expected={:?}",
3318 hir::ExprBox(ref subexpr) => {
3319 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3321 ty::TyBox(ty) => Expectation::rvalue_hint(self, ty),
3325 self.check_expr_with_expectation(subexpr, expected_inner);
3326 let referent_ty = self.expr_ty(&subexpr);
3327 self.write_ty(id, tcx.mk_box(referent_ty));
3330 hir::ExprLit(ref lit) => {
3331 let typ = self.check_lit(&lit, expected);
3332 self.write_ty(id, typ);
3334 hir::ExprBinary(op, ref lhs, ref rhs) => {
3335 self.check_binop(expr, op, lhs, rhs);
3337 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3338 self.check_binop_assign(expr, op, lhs, rhs);
3340 hir::ExprUnary(unop, ref oprnd) => {
3341 let expected_inner = match unop {
3342 hir::UnNot | hir::UnNeg => {
3349 let lvalue_pref = match unop {
3350 hir::UnDeref => lvalue_pref,
3353 self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3356 let mut oprnd_t = self.expr_ty(&oprnd);
3358 if !oprnd_t.references_error() {
3361 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3363 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3365 } else if let Some(method) = self.try_overloaded_deref(
3366 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3367 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3368 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3371 self.type_error_message(expr.span, |actual| {
3372 format!("type `{}` cannot be \
3373 dereferenced", actual)
3375 oprnd_t = tcx.types.err;
3379 oprnd_t = self.structurally_resolved_type(oprnd.span,
3381 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3382 oprnd_t = self.check_user_unop("!", "not",
3383 tcx.lang_items.not_trait(),
3384 expr, &oprnd, oprnd_t, unop);
3388 oprnd_t = self.structurally_resolved_type(oprnd.span,
3390 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3391 oprnd_t = self.check_user_unop("-", "neg",
3392 tcx.lang_items.neg_trait(),
3393 expr, &oprnd, oprnd_t, unop);
3398 self.write_ty(id, oprnd_t);
3400 hir::ExprAddrOf(mutbl, ref oprnd) => {
3401 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3403 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3404 if self.tcx.expr_is_lval(&oprnd) {
3405 // Lvalues may legitimately have unsized types.
3406 // For example, dereferences of a fat pointer and
3407 // the last field of a struct can be unsized.
3408 ExpectHasType(mt.ty)
3410 Expectation::rvalue_hint(self, mt.ty)
3416 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3417 self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3419 let tm = ty::TypeAndMut { ty: self.expr_ty(&oprnd), mutbl: mutbl };
3420 let oprnd_t = if tm.ty.references_error() {
3423 // Note: at this point, we cannot say what the best lifetime
3424 // is to use for resulting pointer. We want to use the
3425 // shortest lifetime possible so as to avoid spurious borrowck
3426 // errors. Moreover, the longest lifetime will depend on the
3427 // precise details of the value whose address is being taken
3428 // (and how long it is valid), which we don't know yet until type
3429 // inference is complete.
3431 // Therefore, here we simply generate a region variable. The
3432 // region inferencer will then select the ultimate value.
3433 // Finally, borrowck is charged with guaranteeing that the
3434 // value whose address was taken can actually be made to live
3435 // as long as it needs to live.
3436 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3437 tcx.mk_ref(region, tm)
3439 self.write_ty(id, oprnd_t);
3441 hir::ExprPath(ref opt_qself, ref path) => {
3442 let opt_self_ty = opt_qself.as_ref().map(|qself| self.to_ty(&qself.ty));
3443 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path,
3444 expr.id, expr.span);
3445 if def != Def::Err {
3446 self.instantiate_value_path(segments, opt_ty, def, expr.span, id);
3448 self.set_tainted_by_errors();
3449 self.write_error(id);
3452 // We always require that the type provided as the value for
3453 // a type parameter outlives the moment of instantiation.
3454 self.opt_node_ty_substs(expr.id, |item_substs| {
3455 self.add_wf_bounds(&item_substs.substs, expr);
3458 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3459 for output in outputs {
3460 self.check_expr(output);
3462 for input in inputs {
3463 self.check_expr(input);
3467 hir::ExprBreak(_) => { self.write_never(id); }
3468 hir::ExprAgain(_) => { self.write_never(id); }
3469 hir::ExprRet(ref expr_opt) => {
3470 if let Some(ref e) = *expr_opt {
3471 self.check_expr_coercable_to_type(&e, self.ret_ty);
3473 let eq_result = self.eq_types(false,
3474 TypeOrigin::Misc(expr.span),
3477 // FIXME(#32730) propagate obligations
3478 .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
3479 if eq_result.is_err() {
3480 struct_span_err!(tcx.sess, expr.span, E0069,
3481 "`return;` in a function whose return type is not `()`")
3482 .span_label(expr.span, &format!("return type is not ()"))
3486 self.write_never(id);
3488 hir::ExprAssign(ref lhs, ref rhs) => {
3489 self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3492 if !tcx.expr_is_lval(&lhs) {
3494 tcx.sess, expr.span, E0070,
3495 "invalid left-hand side expression")
3498 &format!("left-hand of expression not valid"))
3502 let lhs_ty = self.expr_ty(&lhs);
3503 self.check_expr_coercable_to_type(&rhs, lhs_ty);
3504 let rhs_ty = self.expr_ty(&rhs);
3506 self.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3508 if lhs_ty.references_error() || rhs_ty.references_error() {
3509 self.write_error(id);
3514 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3515 self.check_then_else(&cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3516 id, expr.span, expected);
3518 hir::ExprWhile(ref cond, ref body, _) => {
3519 self.check_expr_has_type(&cond, tcx.types.bool);
3520 self.check_block_no_value(&body);
3521 let cond_ty = self.expr_ty(&cond);
3522 let body_ty = self.node_ty(body.id);
3523 if cond_ty.references_error() || body_ty.references_error() {
3524 self.write_error(id);
3530 hir::ExprLoop(ref body, _) => {
3531 self.check_block_no_value(&body);
3532 if !may_break(tcx, expr.id, &body) {
3533 self.write_never(id);
3538 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3539 self.check_match(expr, &discrim, arms, expected, match_src);
3541 hir::ExprClosure(capture, ref decl, ref body, _) => {
3542 self.check_expr_closure(expr, capture, &decl, &body, expected);
3544 hir::ExprBlock(ref b) => {
3545 self.check_block_with_expected(&b, expected);
3546 self.write_ty(id, self.node_ty(b.id));
3548 hir::ExprCall(ref callee, ref args) => {
3549 self.check_call(expr, &callee, &args[..], expected);
3551 // we must check that return type of called functions is WF:
3552 let ret_ty = self.expr_ty(expr);
3553 self.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3555 hir::ExprMethodCall(name, ref tps, ref args) => {
3556 self.check_method_call(expr, name, &args[..], &tps[..], expected, lvalue_pref);
3557 let arg_tys = args.iter().map(|a| self.expr_ty(&a));
3558 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3560 self.write_error(id);
3563 hir::ExprCast(ref e, ref t) => {
3564 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3565 self.check_expr_with_hint(&count_expr, tcx.types.usize);
3568 // Find the type of `e`. Supply hints based on the type we are casting to,
3570 let t_cast = self.to_ty(t);
3571 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3572 self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3573 let t_expr = self.expr_ty(e);
3574 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3576 // Eagerly check for some obvious errors.
3577 if t_expr.references_error() || t_cast.references_error() {
3578 self.write_error(id);
3580 // Write a type for the whole expression, assuming everything is going
3582 self.write_ty(id, t_cast);
3584 // Defer other checks until we're done type checking.
3585 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3586 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3588 deferred_cast_checks.push(cast_check);
3590 Err(ErrorReported) => {
3591 self.write_error(id);
3596 hir::ExprType(ref e, ref t) => {
3597 let typ = self.to_ty(&t);
3598 self.check_expr_eq_type(&e, typ);
3599 self.write_ty(id, typ);
3601 hir::ExprVec(ref args) => {
3602 let uty = expected.to_option(self).and_then(|uty| {
3604 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3609 let mut unified = self.next_ty_var();
3610 let coerce_to = uty.unwrap_or(unified);
3612 for (i, e) in args.iter().enumerate() {
3613 self.check_expr_with_hint(e, coerce_to);
3614 let e_ty = self.expr_ty(e);
3615 let origin = TypeOrigin::Misc(e.span);
3617 // Special-case the first element, as it has no "previous expressions".
3618 let result = if i == 0 {
3619 self.try_coerce(e, coerce_to)
3621 let prev_elems = || args[..i].iter().map(|e| &**e);
3622 self.try_find_coercion_lub(origin, prev_elems, unified, e)
3626 Ok(ty) => unified = ty,
3628 self.report_mismatched_types(origin, unified, e_ty, e);
3632 self.write_ty(id, tcx.mk_array(unified, args.len()));
3634 hir::ExprRepeat(ref element, ref count_expr) => {
3635 self.check_expr_has_type(&count_expr, tcx.types.usize);
3636 let count = eval_length(self.tcx.global_tcx(), &count_expr, "repeat count")
3639 let uty = match expected {
3640 ExpectHasType(uty) => {
3642 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3649 let (element_ty, t) = match uty {
3651 self.check_expr_coercable_to_type(&element, uty);
3655 let t: Ty = self.next_ty_var();
3656 self.check_expr_has_type(&element, t);
3657 (self.expr_ty(&element), t)
3662 // For [foo, ..n] where n > 1, `foo` must have
3664 self.require_type_meets(t, expr.span, traits::RepeatVec, ty::BoundCopy);
3667 if element_ty.references_error() {
3668 self.write_error(id);
3670 let t = tcx.mk_array(t, count);
3671 self.write_ty(id, t);
3674 hir::ExprTup(ref elts) => {
3675 let flds = expected.only_has_type(self).and_then(|ty| {
3677 ty::TyTuple(ref flds) => Some(&flds[..]),
3681 let mut err_field = false;
3683 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3684 let t = match flds {
3685 Some(ref fs) if i < fs.len() => {
3687 self.check_expr_coercable_to_type(&e, ety);
3691 self.check_expr_with_expectation(&e, NoExpectation);
3695 err_field = err_field || t.references_error();
3699 self.write_error(id);
3701 let typ = tcx.mk_tup(elt_ts);
3702 self.write_ty(id, typ);
3705 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3706 self.check_expr_struct(expr, path, fields, base_expr);
3708 self.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3710 hir::ExprField(ref base, ref field) => {
3711 self.check_field(expr, lvalue_pref, &base, field);
3713 hir::ExprTupField(ref base, idx) => {
3714 self.check_tup_field(expr, lvalue_pref, &base, idx);
3716 hir::ExprIndex(ref base, ref idx) => {
3717 self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3718 self.check_expr(&idx);
3720 let base_t = self.expr_ty(&base);
3721 let idx_t = self.expr_ty(&idx);
3723 if base_t.references_error() {
3724 self.write_ty(id, base_t);
3725 } else if idx_t.references_error() {
3726 self.write_ty(id, idx_t);
3728 let base_t = self.structurally_resolved_type(expr.span, base_t);
3729 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3730 Some((index_ty, element_ty)) => {
3731 let idx_expr_ty = self.expr_ty(idx);
3732 self.demand_eqtype(expr.span, index_ty, idx_expr_ty);
3733 self.write_ty(id, element_ty);
3736 self.check_expr_has_type(&idx, self.tcx.types.err);
3737 let mut err = self.type_error_struct(
3740 format!("cannot index a value of type `{}`",
3744 // Try to give some advice about indexing tuples.
3745 if let ty::TyTuple(_) = base_t.sty {
3746 let mut needs_note = true;
3747 // If the index is an integer, we can show the actual
3748 // fixed expression:
3749 if let hir::ExprLit(ref lit) = idx.node {
3750 if let ast::LitKind::Int(i,
3751 ast::LitIntType::Unsuffixed) = lit.node {
3752 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3753 if let Ok(snip) = snip {
3754 err.span_suggestion(expr.span,
3755 "to access tuple elements, \
3756 use tuple indexing syntax \
3758 format!("{}.{}", snip, i));
3764 err.help("to access tuple elements, use tuple indexing \
3765 syntax (e.g. `tuple.0`)");
3769 self.write_ty(id, self.tcx().types.err);
3776 debug!("type of expr({}) {} is...", expr.id,
3777 pprust::expr_to_string(expr));
3778 debug!("... {:?}, expected is {:?}",
3783 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3784 // The newly resolved definition is written into `def_map`.
3785 pub fn finish_resolving_struct_path(&self,
3787 node_id: ast::NodeId,
3791 let path_res = self.tcx().expect_resolution(node_id);
3792 if path_res.depth == 0 {
3793 // If fully resolved already, we don't have to do anything.
3796 let base_ty_end = path.segments.len() - path_res.depth;
3797 let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span,
3798 PathParamMode::Optional,
3802 &path.segments[..base_ty_end],
3803 &path.segments[base_ty_end..]);
3804 // Write back the new resolution.
3805 self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
3810 // Resolve associated value path into a base type and associated constant or method definition.
3811 // The newly resolved definition is written into `def_map`.
3812 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3813 opt_self_ty: Option<Ty<'tcx>>,
3814 path: &'b hir::Path,
3815 node_id: ast::NodeId,
3817 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3819 let path_res = self.tcx().expect_resolution(node_id);
3820 if path_res.depth == 0 {
3821 // If fully resolved already, we don't have to do anything.
3822 (path_res.base_def, opt_self_ty, &path.segments)
3824 // Try to resolve everything except for the last segment as a type.
3825 let ty_segments = path.segments.split_last().unwrap().1;
3826 let base_ty_end = path.segments.len() - path_res.depth;
3827 let (ty, _def) = AstConv::finish_resolving_def_to_ty(self, self, span,
3828 PathParamMode::Optional,
3832 &ty_segments[..base_ty_end],
3833 &ty_segments[base_ty_end..]);
3835 // Resolve an associated constant or method on the previously resolved type.
3836 let item_segment = path.segments.last().unwrap();
3837 let item_name = item_segment.name;
3838 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3841 let def = match error {
3842 method::MethodError::PrivateMatch(def) => def,
3845 if item_name != keywords::Invalid.name() {
3846 self.report_method_error(span, ty, item_name, None, error);
3852 // Write back the new resolution.
3853 self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
3854 (def, Some(ty), slice::ref_slice(item_segment))
3858 pub fn check_decl_initializer(&self,
3859 local: &'gcx hir::Local,
3860 init: &'gcx hir::Expr)
3862 let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat);
3864 let local_ty = self.local_ty(init.span, local.id);
3865 if let Some(m) = ref_bindings {
3866 // Somewhat subtle: if we have a `ref` binding in the pattern,
3867 // we want to avoid introducing coercions for the RHS. This is
3868 // both because it helps preserve sanity and, in the case of
3869 // ref mut, for soundness (issue #23116). In particular, in
3870 // the latter case, we need to be clear that the type of the
3871 // referent for the reference that results is *equal to* the
3872 // type of the lvalue it is referencing, and not some
3873 // supertype thereof.
3874 self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3875 let init_ty = self.expr_ty(init);
3876 self.demand_eqtype(init.span, init_ty, local_ty);
3878 self.check_expr_coercable_to_type(init, local_ty)
3882 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3883 let t = self.local_ty(local.span, local.id);
3884 self.write_ty(local.id, t);
3886 if let Some(ref init) = local.init {
3887 self.check_decl_initializer(local, &init);
3888 let init_ty = self.expr_ty(&init);
3889 if init_ty.references_error() {
3890 self.write_ty(local.id, init_ty);
3894 self.check_pat(&local.pat, t);
3895 let pat_ty = self.node_ty(local.pat.id);
3896 if pat_ty.references_error() {
3897 self.write_ty(local.id, pat_ty);
3901 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3903 let mut saw_bot = false;
3904 let mut saw_err = false;
3906 hir::StmtDecl(ref decl, id) => {
3909 hir::DeclLocal(ref l) => {
3910 self.check_decl_local(&l);
3911 let l_t = self.node_ty(l.id);
3912 saw_bot = saw_bot || self.type_var_diverges(l_t);
3913 saw_err = saw_err || l_t.references_error();
3915 hir::DeclItem(_) => {/* ignore for now */ }
3918 hir::StmtExpr(ref expr, id) => {
3920 // Check with expected type of ()
3921 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3922 let expr_ty = self.expr_ty(&expr);
3923 saw_bot = saw_bot || self.type_var_diverges(expr_ty);
3924 saw_err = saw_err || expr_ty.references_error();
3926 hir::StmtSemi(ref expr, id) => {
3928 self.check_expr(&expr);
3929 let expr_ty = self.expr_ty(&expr);
3930 saw_bot |= self.type_var_diverges(expr_ty);
3931 saw_err |= expr_ty.references_error();
3935 self.write_ty(node_id, self.next_diverging_ty_var());
3938 self.write_error(node_id);
3941 self.write_nil(node_id)
3945 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
3946 self.check_block_with_expected(blk, ExpectHasType(self.tcx.mk_nil()));
3947 let blkty = self.node_ty(blk.id);
3948 if blkty.references_error() {
3949 self.write_error(blk.id);
3951 let nilty = self.tcx.mk_nil();
3952 self.demand_suptype(blk.span, nilty, blkty);
3956 fn check_block_with_expected(&self,
3957 blk: &'gcx hir::Block,
3958 expected: Expectation<'tcx>) {
3960 let mut fcx_ps = self.ps.borrow_mut();
3961 let unsafety_state = fcx_ps.recurse(blk);
3962 replace(&mut *fcx_ps, unsafety_state)
3965 let mut warned = false;
3966 let mut any_diverges = false;
3967 let mut any_err = false;
3968 for s in &blk.stmts {
3970 let s_id = s.node.id();
3971 let s_ty = self.node_ty(s_id);
3972 if any_diverges && !warned && match s.node {
3973 hir::StmtDecl(ref decl, _) => {
3975 hir::DeclLocal(_) => true,
3979 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3983 .add_lint(lint::builtin::UNREACHABLE_CODE,
3986 "unreachable statement".to_string());
3989 // FIXME(canndrew): This is_never should probably be an is_uninhabited
3990 any_diverges = any_diverges ||
3991 self.type_var_diverges(s_ty) ||
3993 any_err = any_err || s_ty.references_error();
3996 None => if any_err {
3997 self.write_error(blk.id);
3998 } else if any_diverges {
3999 self.write_ty(blk.id, self.next_diverging_ty_var());
4001 self.write_nil(blk.id);
4004 if any_diverges && !warned {
4007 .add_lint(lint::builtin::UNREACHABLE_CODE,
4010 "unreachable expression".to_string());
4012 let ety = match expected {
4013 ExpectHasType(ety) => {
4014 self.check_expr_coercable_to_type(&e, ety);
4018 self.check_expr_with_expectation(&e, expected);
4024 self.write_error(blk.id);
4025 } else if any_diverges {
4026 self.write_ty(blk.id, self.next_diverging_ty_var());
4028 self.write_ty(blk.id, ety);
4033 *self.ps.borrow_mut() = prev;
4036 // Instantiates the given path, which must refer to an item with the given
4037 // number of type parameters and type.
4038 pub fn instantiate_value_path(&self,
4039 segments: &[hir::PathSegment],
4040 opt_self_ty: Option<Ty<'tcx>>,
4043 node_id: ast::NodeId)
4045 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4050 // We need to extract the type parameters supplied by the user in
4051 // the path `path`. Due to the current setup, this is a bit of a
4052 // tricky-process; the problem is that resolve only tells us the
4053 // end-point of the path resolution, and not the intermediate steps.
4054 // Luckily, we can (at least for now) deduce the intermediate steps
4055 // just from the end-point.
4057 // There are basically four cases to consider:
4059 // 1. Reference to a *type*, such as a struct or enum:
4061 // mod a { struct Foo<T> { ... } }
4063 // Because we don't allow types to be declared within one
4064 // another, a path that leads to a type will always look like
4065 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4066 // that only the final segment can have type parameters, and
4067 // they are located in the TypeSpace.
4069 // *Note:* Generally speaking, references to types don't
4070 // actually pass through this function, but rather the
4071 // `ast_ty_to_ty` function in `astconv`. However, in the case
4072 // of struct patterns (and maybe literals) we do invoke
4073 // `instantiate_value_path` to get the general type of an instance of
4074 // a struct. (In these cases, there are actually no type
4075 // parameters permitted at present, but perhaps we will allow
4076 // them in the future.)
4078 // 1b. Reference to an enum variant or tuple-like struct:
4080 // struct foo<T>(...)
4081 // enum E<T> { foo(...) }
4083 // In these cases, the parameters are declared in the type
4086 // 2. Reference to a *fn item*:
4090 // In this case, the path will again always have the form
4091 // `a::b::foo::<T>` where only the final segment should have
4092 // type parameters. However, in this case, those parameters are
4093 // declared on a value, and hence are in the `FnSpace`.
4095 // 3. Reference to a *method*:
4097 // impl<A> SomeStruct<A> {
4101 // Here we can have a path like
4102 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4103 // may appear in two places. The penultimate segment,
4104 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4105 // final segment, `foo::<B>` contains parameters in fn space.
4107 // 4. Reference to an *associated const*:
4109 // impl<A> AnotherStruct<A> {
4110 // const FOO: B = BAR;
4113 // The path in this case will look like
4114 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4115 // only will have parameters in TypeSpace.
4117 // The first step then is to categorize the segments appropriately.
4119 assert!(!segments.is_empty());
4121 let mut ufcs_associated = None;
4122 let mut type_segment = None;
4123 let mut fn_segment = None;
4125 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4126 Def::Struct(def_id) |
4127 Def::Variant(_, def_id) |
4129 Def::TyAlias(def_id) |
4130 Def::AssociatedTy(_, def_id) |
4131 Def::Trait(def_id) => {
4132 // Everything but the final segment should have no
4133 // parameters at all.
4134 let mut generics = self.tcx.lookup_generics(def_id);
4135 if let Some(def_id) = generics.parent {
4136 // Variant and struct constructors use the
4137 // generics of their parent type definition.
4138 generics = self.tcx.lookup_generics(def_id);
4140 type_segment = Some((segments.last().unwrap(), generics));
4143 // Case 2. Reference to a top-level value.
4145 Def::Const(def_id) |
4146 Def::Static(def_id, _) => {
4147 fn_segment = Some((segments.last().unwrap(),
4148 self.tcx.lookup_generics(def_id)));
4151 // Case 3. Reference to a method or associated const.
4152 Def::Method(def_id) |
4153 Def::AssociatedConst(def_id) => {
4154 let container = self.tcx.impl_or_trait_item(def_id).container();
4156 ty::TraitContainer(trait_did) => {
4157 callee::check_legal_trait_for_method_call(self.ccx, span, trait_did)
4159 ty::ImplContainer(_) => {}
4162 let generics = self.tcx.lookup_generics(def_id);
4163 if segments.len() >= 2 {
4164 let parent_generics = self.tcx.lookup_generics(generics.parent.unwrap());
4165 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4167 // `<T>::assoc` will end up here, and so can `T::assoc`.
4168 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4169 ufcs_associated = Some((container, self_ty));
4171 fn_segment = Some((segments.last().unwrap(), generics));
4174 // Other cases. Various nonsense that really shouldn't show up
4175 // here. If they do, an error will have been reported
4176 // elsewhere. (I hope)
4178 Def::ForeignMod(..) |
4188 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4189 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4190 // type parameters are not mandatory.
4191 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4193 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4195 // Now that we have categorized what space the parameters for each
4196 // segment belong to, let's sort out the parameters that the user
4197 // provided (if any) into their appropriate spaces. We'll also report
4198 // errors if type parameters are provided in an inappropriate place.
4199 let poly_segments = type_segment.is_some() as usize +
4200 fn_segment.is_some() as usize;
4201 self.tcx.prohibit_type_params(&segments[..segments.len() - poly_segments]);
4204 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4205 let ty = self.local_ty(span, nid);
4206 let ty = self.normalize_associated_types_in(span, &ty);
4207 self.write_ty(node_id, ty);
4208 self.write_substs(node_id, ty::ItemSubsts {
4209 substs: Substs::empty(self.tcx)
4216 // Now we have to compare the types that the user *actually*
4217 // provided against the types that were *expected*. If the user
4218 // did not provide any types, then we want to substitute inference
4219 // variables. If the user provided some types, we may still need
4220 // to add defaults. If the user provided *too many* types, that's
4222 self.check_path_parameter_count(span, !require_type_space, &mut type_segment);
4223 self.check_path_parameter_count(span, true, &mut fn_segment);
4225 let (fn_start, has_self) = match (type_segment, fn_segment) {
4226 (_, Some((_, generics))) => {
4227 (generics.parent_count(), generics.has_self)
4229 (Some((_, generics)), None) => {
4230 (generics.own_count(), generics.has_self)
4232 (None, None) => (0, false)
4234 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4235 let mut i = def.index as usize;
4237 let segment = if i < fn_start {
4238 i -= has_self as usize;
4244 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4245 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4246 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4250 if let Some(ast_lifetime) = lifetimes.get(i) {
4251 ast_region_to_region(self.tcx, ast_lifetime)
4253 self.region_var_for_def(span, def)
4256 let mut i = def.index as usize;
4258 let can_omit = i >= fn_start || !require_type_space;
4259 let segment = if i < fn_start {
4260 // Handle Self first, so we can adjust the index to match the AST.
4261 if has_self && i == 0 {
4262 return opt_self_ty.unwrap_or_else(|| {
4263 self.type_var_for_def(span, def, substs)
4266 i -= has_self as usize;
4272 let types = match segment.map(|(s, _)| &s.parameters) {
4273 Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
4274 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4278 // Skip over the lifetimes in the same segment.
4279 if let Some((_, generics)) = segment {
4280 i -= generics.regions.len();
4283 let omitted = can_omit && types.is_empty();
4284 if let Some(ast_ty) = types.get(i) {
4285 // A provided type parameter.
4287 } else if let (false, Some(default)) = (omitted, def.default) {
4288 // No type parameter provided, but a default exists.
4289 default.subst_spanned(self.tcx, substs, Some(span))
4291 // No type parameters were provided, we can infer all.
4292 // This can also be reached in some error cases:
4293 // We prefer to use inference variables instead of
4294 // TyError to let type inference recover somewhat.
4295 self.type_var_for_def(span, def, substs)
4299 // The things we are substituting into the type should not contain
4300 // escaping late-bound regions, and nor should the base type scheme.
4301 let scheme = self.tcx.lookup_item_type(def.def_id());
4302 let type_predicates = self.tcx.lookup_predicates(def.def_id());
4303 assert!(!substs.has_escaping_regions());
4304 assert!(!scheme.ty.has_escaping_regions());
4306 // Add all the obligations that are required, substituting and
4307 // normalized appropriately.
4308 let bounds = self.instantiate_bounds(span, &substs, &type_predicates);
4309 self.add_obligations_for_parameters(
4310 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4313 // Substitute the values for the type parameters into the type of
4314 // the referenced item.
4315 let ty_substituted = self.instantiate_type_scheme(span, &substs, &scheme.ty);
4318 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4319 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4320 // is inherent, there is no `Self` parameter, instead, the impl needs
4321 // type parameters, which we can infer by unifying the provided `Self`
4322 // with the substituted impl type.
4323 let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
4325 let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4326 match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
4327 Ok(InferOk { obligations, .. }) => {
4328 // FIXME(#32730) propagate obligations
4329 assert!(obligations.is_empty());
4333 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4340 debug!("instantiate_value_path: type of {:?} is {:?}",
4343 self.write_ty(node_id, ty_substituted);
4344 self.write_substs(node_id, ty::ItemSubsts {
4350 /// Report errors if the provided parameters are too few or too many.
4351 fn check_path_parameter_count(&self,
4354 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4355 let (lifetimes, types, bindings) = match segment.map(|(s, _)| &s.parameters) {
4356 Some(&hir::AngleBracketedParameters(ref data)) => {
4357 (&data.lifetimes[..], &data.types[..], &data.bindings[..])
4359 Some(&hir::ParenthesizedParameters(_)) => {
4360 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4362 None => (&[][..], &[][..], &[][..])
4366 format!("{} parameter{}", n, if n == 1 { "" } else { "s" })
4369 // Check provided lifetime parameters.
4370 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4371 if lifetimes.len() > lifetime_defs.len() {
4372 let span = lifetimes[lifetime_defs.len()].span;
4373 span_err!(self.tcx.sess, span, E0088,
4374 "too many lifetime parameters provided: \
4375 expected {}, found {}",
4376 count(lifetime_defs.len()),
4377 count(lifetimes.len()));
4378 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4379 span_err!(self.tcx.sess, span, E0090,
4380 "too few lifetime parameters provided: \
4381 expected {}, found {}",
4382 count(lifetime_defs.len()),
4383 count(lifetimes.len()));
4386 // Check provided type parameters.
4387 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4388 if generics.parent.is_none() {
4389 &generics.types[generics.has_self as usize..]
4394 let required_len = type_defs.iter()
4395 .take_while(|d| d.default.is_none())
4397 if types.len() > type_defs.len() {
4398 let span = types[type_defs.len()].span;
4399 struct_span_err!(self.tcx.sess, span, E0087,
4400 "too many type parameters provided: \
4401 expected at most {}, found {}",
4402 count(type_defs.len()),
4404 .span_label(span, &format!("too many type parameters")).emit();
4406 // To prevent derived errors to accumulate due to extra
4407 // type parameters, we force instantiate_value_path to
4408 // use inference variables instead of the provided types.
4410 } else if !(can_omit && types.len() == 0) && types.len() < required_len {
4412 if type_defs.len() != required_len { "at least " } else { "" };
4413 span_err!(self.tcx.sess, span, E0089,
4414 "too few type parameters provided: \
4415 expected {}{}, found {}",
4417 count(required_len),
4418 count(types.len()));
4421 if !bindings.is_empty() {
4422 span_err!(self.tcx.sess, bindings[0].span, E0182,
4423 "unexpected binding of associated item in expression path \
4424 (only allowed in type paths)");
4428 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4430 where F: Fn() -> Ty<'tcx>
4432 let mut ty = self.resolve_type_vars_with_obligations(ty);
4435 let alternative = f();
4438 if alternative.is_ty_var() || alternative.references_error() {
4439 if !self.is_tainted_by_errors() {
4440 self.type_error_message(sp, |_actual| {
4441 "the type of this value must be known in this context".to_string()
4444 self.demand_suptype(sp, self.tcx.types.err, ty);
4445 ty = self.tcx.types.err;
4447 self.demand_suptype(sp, alternative, ty);
4455 // Resolves `typ` by a single level if `typ` is a type variable. If no
4456 // resolution is possible, then an error is reported.
4457 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4458 self.structurally_resolve_type_or_else(sp, ty, || {
4464 // Returns true if b contains a break that can exit from b
4465 pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4466 // First: is there an unlabeled break immediately
4468 (loop_query(&b, |e| {
4470 hir::ExprBreak(None) => true,
4474 // Second: is there a labeled break with label
4475 // <id> nested anywhere inside the loop?
4476 (block_query(b, |e| {
4477 if let hir::ExprBreak(Some(_)) = e.node {
4478 tcx.expect_def(e.id) == Def::Label(id)
4485 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4486 generics: &hir::Generics,
4488 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4489 generics.ty_params.len(), ty);
4491 // make a vector of booleans initially false, set to true when used
4492 if generics.ty_params.is_empty() { return; }
4493 let mut tps_used = vec![false; generics.ty_params.len()];
4495 for leaf_ty in ty.walk() {
4496 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4497 debug!("Found use of ty param num {}", idx);
4498 tps_used[idx as usize - generics.lifetimes.len()] = true;
4502 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4504 struct_span_err!(ccx.tcx.sess, param.span, E0091,
4505 "type parameter `{}` is unused",
4507 .span_label(param.span, &format!("unused type parameter"))