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::attr::AttrMetaMethods;
116 use syntax::codemap::{self, Spanned};
117 use syntax::feature_gate::{GateIssue, emit_feature_err};
118 use syntax::parse::token::{self, InternedString, keywords};
120 use syntax::util::lev_distance::find_best_match_for_name;
121 use syntax_pos::{self, Span};
122 use errors::DiagnosticBuilder;
124 use rustc::hir::intravisit::{self, Visitor};
125 use rustc::hir::{self, PatKind};
126 use rustc::hir::print as pprust;
127 use rustc_back::slice;
128 use rustc_const_eval::eval_length;
148 /// closures defined within the function. For example:
151 /// bar(move|| { ... })
154 /// Here, the function `foo()` and the closure passed to
155 /// `bar()` will each have their own `FnCtxt`, but they will
156 /// share the inherited fields.
157 pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
158 ccx: &'a CrateCtxt<'a, 'gcx>,
159 infcx: InferCtxt<'a, 'gcx, 'tcx>,
160 locals: RefCell<NodeMap<Ty<'tcx>>>,
162 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
164 // When we process a call like `c()` where `c` is a closure type,
165 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
166 // `FnOnce` closure. In that case, we defer full resolution of the
167 // call until upvar inference can kick in and make the
168 // decision. We keep these deferred resolutions grouped by the
169 // def-id of the closure, so that once we decide, we can easily go
170 // back and process them.
171 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>>>,
173 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
175 // Anonymized types found in explicit return types and their
176 // associated fresh inference variable. Writeback resolves these
177 // variables to get the concrete type, which can be used to
178 // deanonymize TyAnon, after typeck is done with all functions.
179 anon_types: RefCell<DefIdMap<Ty<'tcx>>>,
181 // Obligations which will have to be checked at the end of
182 // type-checking, after all functions have been inferred.
183 deferred_obligations: RefCell<Vec<traits::DeferredObligation<'tcx>>>,
186 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
187 type Target = InferCtxt<'a, 'gcx, 'tcx>;
188 fn deref(&self) -> &Self::Target {
193 trait DeferredCallResolution<'gcx, 'tcx> {
194 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>);
197 type DeferredCallResolutionHandler<'gcx, 'tcx> = Box<DeferredCallResolution<'gcx, 'tcx>+'tcx>;
199 /// When type-checking an expression, we propagate downward
200 /// whatever type hint we are able in the form of an `Expectation`.
201 #[derive(Copy, Clone, Debug)]
202 pub enum Expectation<'tcx> {
203 /// We know nothing about what type this expression should have.
206 /// This expression should have the type given (or some subtype)
207 ExpectHasType(Ty<'tcx>),
209 /// This expression will be cast to the `Ty`
210 ExpectCastableToType(Ty<'tcx>),
212 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
213 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
214 ExpectRvalueLikeUnsized(Ty<'tcx>),
217 impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
218 // Disregard "castable to" expectations because they
219 // can lead us astray. Consider for example `if cond
220 // {22} else {c} as u8` -- if we propagate the
221 // "castable to u8" constraint to 22, it will pick the
222 // type 22u8, which is overly constrained (c might not
223 // be a u8). In effect, the problem is that the
224 // "castable to" expectation is not the tightest thing
225 // we can say, so we want to drop it in this case.
226 // The tightest thing we can say is "must unify with
227 // else branch". Note that in the case of a "has type"
228 // constraint, this limitation does not hold.
230 // If the expected type is just a type variable, then don't use
231 // an expected type. Otherwise, we might write parts of the type
232 // when checking the 'then' block which are incompatible with the
234 fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
236 ExpectHasType(ety) => {
237 let ety = fcx.shallow_resolve(ety);
238 if !ety.is_ty_var() {
244 ExpectRvalueLikeUnsized(ety) => {
245 ExpectRvalueLikeUnsized(ety)
251 /// Provide an expectation for an rvalue expression given an *optional*
252 /// hint, which is not required for type safety (the resulting type might
253 /// be checked higher up, as is the case with `&expr` and `box expr`), but
254 /// is useful in determining the concrete type.
256 /// The primary use case is where the expected type is a fat pointer,
257 /// like `&[isize]`. For example, consider the following statement:
259 /// let x: &[isize] = &[1, 2, 3];
261 /// In this case, the expected type for the `&[1, 2, 3]` expression is
262 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
263 /// expectation `ExpectHasType([isize])`, that would be too strong --
264 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
265 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
266 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
267 /// which still is useful, because it informs integer literals and the like.
268 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
269 /// for examples of where this comes up,.
270 fn rvalue_hint(fcx: &FnCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
271 match fcx.tcx.struct_tail(ty).sty {
272 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
273 ExpectRvalueLikeUnsized(ty)
275 _ => ExpectHasType(ty)
279 // Resolves `expected` by a single level if it is a variable. If
280 // there is no expected type or resolution is not possible (e.g.,
281 // no constraints yet present), just returns `None`.
282 fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Expectation<'tcx> {
287 ExpectCastableToType(t) => {
288 ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
290 ExpectHasType(t) => {
291 ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
293 ExpectRvalueLikeUnsized(t) => {
294 ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
299 fn to_option(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
300 match self.resolve(fcx) {
301 NoExpectation => None,
302 ExpectCastableToType(ty) |
304 ExpectRvalueLikeUnsized(ty) => Some(ty),
308 fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
309 match self.resolve(fcx) {
310 ExpectHasType(ty) => Some(ty),
316 #[derive(Copy, Clone)]
317 pub struct UnsafetyState {
318 pub def: ast::NodeId,
319 pub unsafety: hir::Unsafety,
320 pub unsafe_push_count: u32,
325 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
326 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
329 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
330 match self.unsafety {
331 // If this unsafe, then if the outer function was already marked as
332 // unsafe we shouldn't attribute the unsafe'ness to the block. This
333 // way the block can be warned about instead of ignoring this
334 // extraneous block (functions are never warned about).
335 hir::Unsafety::Unsafe if self.from_fn => *self,
338 let (unsafety, def, count) = match blk.rules {
339 hir::PushUnsafeBlock(..) =>
340 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
341 hir::PopUnsafeBlock(..) =>
342 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
343 hir::UnsafeBlock(..) =>
344 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
345 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
346 (unsafety, self.def, self.unsafe_push_count),
348 UnsafetyState{ def: def,
350 unsafe_push_count: count,
358 pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
359 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
361 body_id: ast::NodeId,
363 // This flag is set to true if, during the writeback phase, we encounter
364 // a type error in this function.
365 writeback_errors: Cell<bool>,
367 // Number of errors that had been reported when we started
368 // checking this function. On exit, if we find that *more* errors
369 // have been reported, we will skip regionck and other work that
370 // expects the types within the function to be consistent.
371 err_count_on_creation: usize,
375 ps: RefCell<UnsafetyState>,
377 inh: &'a Inherited<'a, 'gcx, 'tcx>,
380 impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
381 type Target = Inherited<'a, 'gcx, 'tcx>;
382 fn deref(&self) -> &Self::Target {
387 /// Helper type of a temporary returned by ccx.inherited(...).
388 /// Necessary because we can't write the following bound:
389 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
390 pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
391 ccx: &'a CrateCtxt<'a, 'gcx>,
392 infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
395 impl<'a, 'gcx, 'tcx> CrateCtxt<'a, 'gcx> {
396 pub fn inherited(&'a self, id: ast::NodeId)
397 -> InheritedBuilder<'a, 'gcx, 'tcx> {
398 let param_env = ParameterEnvironment::for_item(self.tcx, id);
401 infcx: self.tcx.infer_ctxt(Some(ty::Tables::empty()),
403 Reveal::NotSpecializable)
408 impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
409 fn enter<F, R>(&'tcx mut self, f: F) -> R
410 where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
413 self.infcx.enter(|infcx| {
417 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
418 locals: RefCell::new(NodeMap()),
419 deferred_call_resolutions: RefCell::new(DefIdMap()),
420 deferred_cast_checks: RefCell::new(Vec::new()),
421 anon_types: RefCell::new(DefIdMap()),
422 deferred_obligations: RefCell::new(Vec::new()),
428 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
429 fn normalize_associated_types_in<T>(&self,
431 body_id: ast::NodeId,
434 where T : TypeFoldable<'tcx>
436 assoc::normalize_associated_types_in(self,
437 &mut self.fulfillment_cx.borrow_mut(),
445 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
446 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
448 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
449 fn visit_item(&mut self, i: &'tcx hir::Item) {
450 check_item_type(self.ccx, i);
451 intravisit::walk_item(self, i);
454 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
456 hir::TyFixedLengthVec(_, ref expr) => {
457 check_const_with_type(self.ccx, &expr, self.ccx.tcx.types.usize, expr.id);
462 intravisit::walk_ty(self, t);
466 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
467 fn visit_item(&mut self, i: &'tcx hir::Item) {
468 check_item_body(self.ccx, i);
472 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
473 ccx.tcx.sess.track_errors(|| {
474 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
475 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
479 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
480 ccx.tcx.sess.track_errors(|| {
481 let mut visit = CheckItemTypesVisitor { ccx: ccx };
482 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
486 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
487 ccx.tcx.sess.track_errors(|| {
488 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
489 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
491 // Process deferred obligations, now that all functions
492 // bodies have been fully inferred.
493 for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() {
494 // Use the same DepNode as for the body of the original function/item.
495 let def_id = ccx.tcx.map.local_def_id(item_id);
496 let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckItemBody(def_id));
498 let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id);
499 ccx.tcx.infer_ctxt(None, Some(param_env),
500 Reveal::NotSpecializable).enter(|infcx| {
501 let mut fulfillment_cx = traits::FulfillmentContext::new();
502 for obligation in obligations.iter().map(|o| o.to_obligation()) {
503 fulfillment_cx.register_predicate_obligation(&infcx, obligation);
506 if let Err(errors) = fulfillment_cx.select_all_or_error(&infcx) {
507 infcx.report_fulfillment_errors(&errors);
510 if let Err(errors) = fulfillment_cx.select_rfc1592_obligations(&infcx) {
511 infcx.report_fulfillment_errors_as_warnings(&errors, item_id);
518 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
519 ccx.tcx.sess.track_errors(|| {
520 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
521 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
522 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
524 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
525 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
526 if drop_impl_did.is_local() {
527 match dropck::check_drop_impl(ccx, drop_impl_did) {
530 assert!(ccx.tcx.sess.has_errors());
538 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
539 decl: &'tcx hir::FnDecl,
540 body: &'tcx hir::Block,
541 fn_id: ast::NodeId) {
542 let raw_fty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(fn_id)).ty;
543 let fn_ty = match raw_fty.sty {
544 ty::TyFnDef(_, _, f) => f,
545 _ => span_bug!(body.span, "check_bare_fn: function type expected")
548 ccx.inherited(fn_id).enter(|inh| {
549 // Compute the fty from point of view of inside fn.
550 let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body.id);
552 fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
554 inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
556 inh.normalize_associated_types_in(body.span, body.id, &fn_sig);
558 let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
560 fcx.select_all_obligations_and_apply_defaults();
561 fcx.closure_analyze_fn(body);
562 fcx.select_obligations_where_possible();
564 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
566 fcx.regionck_fn(fn_id, decl, body);
567 fcx.resolve_type_vars_in_fn(decl, body, fn_id);
571 struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
572 fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
575 impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> {
576 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
579 // infer the variable's type
580 let var_ty = self.fcx.next_ty_var();
581 self.fcx.locals.borrow_mut().insert(nid, var_ty);
585 // take type that the user specified
586 self.fcx.locals.borrow_mut().insert(nid, typ);
593 impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
594 // Add explicitly-declared locals.
595 fn visit_local(&mut self, local: &'gcx hir::Local) {
596 let o_ty = match local.ty {
597 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
600 self.assign(local.span, local.id, o_ty);
601 debug!("Local variable {:?} is assigned type {}",
603 self.fcx.ty_to_string(
604 self.fcx.locals.borrow().get(&local.id).unwrap().clone()));
605 intravisit::walk_local(self, local);
608 // Add pattern bindings.
609 fn visit_pat(&mut self, p: &'gcx hir::Pat) {
610 if let PatKind::Binding(_, ref path1, _) = p.node {
611 let var_ty = self.assign(p.span, p.id, None);
613 self.fcx.require_type_is_sized(var_ty, p.span,
614 traits::VariableType(p.id));
616 debug!("Pattern binding {} is assigned to {} with type {:?}",
618 self.fcx.ty_to_string(
619 self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
622 intravisit::walk_pat(self, p);
625 fn visit_block(&mut self, b: &'gcx hir::Block) {
626 // non-obvious: the `blk` variable maps to region lb, so
627 // we have to keep this up-to-date. This
628 // is... unfortunate. It'd be nice to not need this.
629 intravisit::walk_block(self, b);
632 // Since an expr occurs as part of the type fixed size arrays we
633 // need to record the type for that node
634 fn visit_ty(&mut self, t: &'gcx hir::Ty) {
636 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
638 self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize);
640 hir::TyBareFn(ref function_declaration) => {
641 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
642 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
644 _ => intravisit::walk_ty(self, t)
648 // Don't descend into the bodies of nested closures
649 fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
650 _: &'gcx hir::Block, _: Span, _: ast::NodeId) { }
653 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
654 /// body and returns the function context used for that purpose, since in the case of a fn item
655 /// there is still a bit more to do.
658 /// * inherited: other fields inherited from the enclosing fn (if any)
659 fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
660 unsafety: hir::Unsafety,
661 unsafety_id: ast::NodeId,
662 fn_sig: &ty::FnSig<'tcx>,
663 decl: &'gcx hir::FnDecl,
665 body: &'gcx hir::Block)
666 -> FnCtxt<'a, 'gcx, 'tcx>
668 let mut fn_sig = fn_sig.clone();
670 debug!("check_fn(sig={:?}, fn_id={})", fn_sig, fn_id);
672 // Create the function context. This is either derived from scratch or,
673 // in the case of function expressions, based on the outer context.
674 let mut fcx = FnCtxt::new(inherited, fn_sig.output, body.id);
675 *fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id);
677 fcx.require_type_is_sized(fcx.ret_ty, decl.output.span(), traits::ReturnType);
678 fcx.ret_ty = fcx.instantiate_anon_types(&fcx.ret_ty);
679 fn_sig.output = fcx.ret_ty;
682 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
684 // Add formal parameters.
685 for (arg_ty, input) in fn_sig.inputs.iter().zip(&decl.inputs) {
686 // The type of the argument must be well-formed.
688 // NB -- this is now checked in wfcheck, but that
689 // currently only results in warnings, so we issue an
690 // old-style WF obligation here so that we still get the
691 // errors that we used to get.
692 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
694 // Create type variables for each argument.
695 pat_util::pat_bindings(&input.pat, |_bm, pat_id, sp, _path| {
696 let var_ty = visit.assign(sp, pat_id, None);
697 fcx.require_type_is_sized(var_ty, sp, traits::VariableType(pat_id));
700 // Check the pattern.
701 fcx.check_pat(&input.pat, arg_ty);
702 fcx.write_ty(input.id, arg_ty);
705 visit.visit_block(body);
708 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
710 // FIXME(aburka) do we need this special case? and should it be is_uninhabited?
711 let expected = if fcx.ret_ty.is_never() {
714 ExpectHasType(fcx.ret_ty)
716 fcx.check_block_with_expected(body, expected);
721 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
724 check_representable(tcx, span, id, "struct");
726 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
727 check_simd(tcx, span, id);
731 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
732 debug!("check_item_type(it.id={}, it.name={})",
734 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
735 let _indenter = indenter();
737 // Consts can play a role in type-checking, so they are included here.
738 hir::ItemStatic(_, _, ref e) |
739 hir::ItemConst(_, ref e) => check_const(ccx, &e, it.id),
740 hir::ItemEnum(ref enum_definition, _) => {
741 check_enum_variants(ccx,
743 &enum_definition.variants,
746 hir::ItemFn(..) => {} // entirely within check_item_body
747 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
748 debug!("ItemImpl {} with id {}", it.name, it.id);
749 let impl_def_id = ccx.tcx.map.local_def_id(it.id);
750 match ccx.tcx.impl_trait_ref(impl_def_id) {
751 Some(impl_trait_ref) => {
752 check_impl_items_against_trait(ccx,
757 let trait_def_id = impl_trait_ref.def_id;
758 check_on_unimplemented(ccx, trait_def_id, it);
763 hir::ItemTrait(..) => {
764 let def_id = ccx.tcx.map.local_def_id(it.id);
765 check_on_unimplemented(ccx, def_id, it);
767 hir::ItemStruct(..) => {
768 check_struct(ccx, it.id, it.span);
770 hir::ItemTy(_, ref generics) => {
771 let pty_ty = ccx.tcx.node_id_to_type(it.id);
772 check_bounds_are_used(ccx, generics, pty_ty);
774 hir::ItemForeignMod(ref m) => {
775 if m.abi == Abi::RustIntrinsic {
776 for item in &m.items {
777 intrinsic::check_intrinsic_type(ccx, item);
779 } else if m.abi == Abi::PlatformIntrinsic {
780 for item in &m.items {
781 intrinsic::check_platform_intrinsic_type(ccx, item);
784 for item in &m.items {
785 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
786 if !pty.generics.types.is_empty() {
787 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
788 "foreign items may not have type parameters");
789 span_help!(&mut err, item.span,
790 "consider using specialization instead of \
795 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
796 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
801 _ => {/* nothing to do */ }
805 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
806 debug!("check_item_body(it.id={}, it.name={})",
808 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
809 let _indenter = indenter();
811 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
812 check_bare_fn(ccx, &decl, &body, it.id);
814 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
815 debug!("ItemImpl {} with id {}", it.name, it.id);
817 for impl_item in impl_items {
818 match impl_item.node {
819 hir::ImplItemKind::Const(_, ref expr) => {
820 check_const(ccx, &expr, impl_item.id)
822 hir::ImplItemKind::Method(ref sig, ref body) => {
823 check_bare_fn(ccx, &sig.decl, body, impl_item.id);
825 hir::ImplItemKind::Type(_) => {
826 // Nothing to do here.
831 hir::ItemTrait(_, _, _, ref trait_items) => {
832 for trait_item in trait_items {
833 match trait_item.node {
834 hir::ConstTraitItem(_, Some(ref expr)) => {
835 check_const(ccx, &expr, trait_item.id)
837 hir::MethodTraitItem(ref sig, Some(ref body)) => {
838 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
840 check_bare_fn(ccx, &sig.decl, body, trait_item.id);
842 hir::MethodTraitItem(ref sig, None) => {
843 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
845 hir::ConstTraitItem(_, None) |
846 hir::TypeTraitItem(..) => {
852 _ => {/* nothing to do */ }
856 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
858 constness: hir::Constness)
861 hir::Constness::NotConst => {
864 hir::Constness::Const => {
865 struct_span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const")
866 .span_label(span, &format!("trait fns cannot be const"))
872 fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
875 let generics = ccx.tcx.lookup_generics(def_id);
876 if let Some(ref attr) = item.attrs.iter().find(|a| {
877 a.check_name("rustc_on_unimplemented")
879 if let Some(ref istring) = attr.value_str() {
880 let parser = Parser::new(&istring);
881 let types = &generics.types;
882 for token in parser {
884 Piece::String(_) => (), // Normal string, no need to check it
885 Piece::NextArgument(a) => match a.position {
886 // `{Self}` is allowed
887 Position::ArgumentNamed(s) if s == "Self" => (),
888 // So is `{A}` if A is a type parameter
889 Position::ArgumentNamed(s) => match types.iter().find(|t| {
894 let name = ccx.tcx.item_name(def_id);
895 span_err!(ccx.tcx.sess, attr.span, E0230,
896 "there is no type parameter \
901 // `{:1}` and `{}` are not to be used
902 Position::ArgumentIs(_) => {
903 span_err!(ccx.tcx.sess, attr.span, E0231,
904 "only named substitution \
905 parameters are allowed");
912 ccx.tcx.sess, attr.span, E0232,
913 "this attribute must have a value")
914 .span_label(attr.span, &format!("attribute requires a value"))
915 .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
921 fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
922 impl_item: &hir::ImplItem,
925 let mut err = struct_span_err!(
926 tcx.sess, impl_item.span, E0520,
927 "item `{}` is provided by an `impl` that specializes \
928 another, but the item in the parent `impl` is not \
929 marked `default` and so it cannot be specialized.",
932 match tcx.span_of_impl(parent_impl) {
934 err.span_note(span, "parent implementation is here:");
937 err.note(&format!("parent implementation is in crate `{}`", cname));
944 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
945 trait_def: &ty::TraitDef<'tcx>,
947 impl_item: &hir::ImplItem)
949 let ancestors = trait_def.ancestors(impl_id);
951 let parent = match impl_item.node {
952 hir::ImplItemKind::Const(..) => {
953 ancestors.const_defs(tcx, impl_item.name).skip(1).next()
954 .map(|node_item| node_item.map(|parent| parent.defaultness))
956 hir::ImplItemKind::Method(..) => {
957 ancestors.fn_defs(tcx, impl_item.name).skip(1).next()
958 .map(|node_item| node_item.map(|parent| parent.defaultness))
961 hir::ImplItemKind::Type(_) => {
962 ancestors.type_defs(tcx, impl_item.name).skip(1).next()
963 .map(|node_item| node_item.map(|parent| parent.defaultness))
967 if let Some(parent) = parent {
968 if parent.item.is_final() {
969 report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
975 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
978 impl_trait_ref: &ty::TraitRef<'tcx>,
979 impl_items: &[hir::ImplItem]) {
980 // If the trait reference itself is erroneous (so the compilation is going
981 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
982 // isn't populated for such impls.
983 if impl_trait_ref.references_error() { return; }
985 // Locate trait definition and items
987 let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id);
988 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
989 let mut overridden_associated_type = None;
991 // Check existing impl methods to see if they are both present in trait
992 // and compatible with trait signature
993 for impl_item in impl_items {
994 let ty_impl_item = tcx.impl_or_trait_item(tcx.map.local_def_id(impl_item.id));
995 let ty_trait_item = trait_items.iter()
996 .find(|ac| ac.name() == ty_impl_item.name());
998 // Check that impl definition matches trait definition
999 if let Some(ty_trait_item) = ty_trait_item {
1000 match impl_item.node {
1001 hir::ImplItemKind::Const(..) => {
1002 let impl_const = match ty_impl_item {
1003 ty::ConstTraitItem(ref cti) => cti,
1004 _ => span_bug!(impl_item.span, "non-const impl-item for const")
1007 // Find associated const definition.
1008 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
1009 compare_const_impl(ccx,
1015 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
1016 "item `{}` is an associated const, \
1017 which doesn't match its trait `{:?}`",
1020 err.span_label(impl_item.span, &format!("does not match trait"));
1021 // We can only get the spans from local trait definition
1022 // Same for E0324 and E0325
1023 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1024 err.span_label(trait_span, &format!("item in trait"));
1029 hir::ImplItemKind::Method(ref sig, ref body) => {
1030 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
1032 let impl_method = match ty_impl_item {
1033 ty::MethodTraitItem(ref mti) => mti,
1034 _ => span_bug!(impl_item.span, "non-method impl-item for method")
1037 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
1038 compare_impl_method(ccx,
1045 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
1046 "item `{}` is an associated method, \
1047 which doesn't match its trait `{:?}`",
1050 err.span_label(impl_item.span, &format!("does not match trait"));
1051 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1052 err.span_label(trait_span, &format!("item in trait"));
1057 hir::ImplItemKind::Type(_) => {
1058 let impl_type = match ty_impl_item {
1059 ty::TypeTraitItem(ref tti) => tti,
1060 _ => span_bug!(impl_item.span, "non-type impl-item for type")
1063 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
1064 if let Some(_) = at.ty {
1065 overridden_associated_type = Some(impl_item);
1068 let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
1069 "item `{}` is an associated type, \
1070 which doesn't match its trait `{:?}`",
1073 err.span_label(impl_item.span, &format!("does not match trait"));
1074 if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
1075 err.span_label(trait_span, &format!("item in trait"));
1083 check_specialization_validity(tcx, trait_def, impl_id, impl_item);
1086 // Check for missing items from trait
1087 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
1088 let mut missing_items = Vec::new();
1089 let mut invalidated_items = Vec::new();
1090 let associated_type_overridden = overridden_associated_type.is_some();
1091 for trait_item in trait_items.iter() {
1096 ty::ConstTraitItem(ref associated_const) => {
1097 is_provided = associated_const.has_value;
1098 is_implemented = impl_items.iter().any(|ii| {
1100 hir::ImplItemKind::Const(..) => {
1101 ii.name == associated_const.name
1107 ty::MethodTraitItem(ref trait_method) => {
1108 is_provided = provided_methods.iter().any(|m| m.name == trait_method.name);
1109 is_implemented = trait_def.ancestors(impl_id)
1110 .fn_defs(tcx, trait_method.name)
1112 .map(|node_item| !node_item.node.is_from_trait())
1115 ty::TypeTraitItem(ref trait_assoc_ty) => {
1116 is_provided = trait_assoc_ty.ty.is_some();
1117 is_implemented = trait_def.ancestors(impl_id)
1118 .type_defs(tcx, trait_assoc_ty.name)
1120 .map(|node_item| !node_item.node.is_from_trait())
1125 if !is_implemented {
1127 missing_items.push(trait_item.name());
1128 } else if associated_type_overridden {
1129 invalidated_items.push(trait_item.name());
1134 if !missing_items.is_empty() {
1135 struct_span_err!(tcx.sess, impl_span, E0046,
1136 "not all trait items implemented, missing: `{}`",
1137 missing_items.iter()
1138 .map(|name| name.to_string())
1139 .collect::<Vec<_>>().join("`, `"))
1140 .span_label(impl_span, &format!("missing `{}` in implementation",
1141 missing_items.iter()
1142 .map(|name| name.to_string())
1143 .collect::<Vec<_>>().join("`, `"))
1147 if !invalidated_items.is_empty() {
1148 let invalidator = overridden_associated_type.unwrap();
1149 span_err!(tcx.sess, invalidator.span, E0399,
1150 "the following trait items need to be reimplemented \
1151 as `{}` was overridden: `{}`",
1153 invalidated_items.iter()
1154 .map(|name| name.to_string())
1155 .collect::<Vec<_>>().join("`, `"))
1159 /// Checks a constant with a given type.
1160 fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
1161 expr: &'tcx hir::Expr,
1162 expected_type: Ty<'tcx>,
1164 ccx.inherited(id).enter(|inh| {
1165 let fcx = FnCtxt::new(&inh, expected_type, expr.id);
1166 fcx.require_type_is_sized(expected_type, expr.span, traits::ConstSized);
1168 // Gather locals in statics (because of block expressions).
1169 // This is technically unnecessary because locals in static items are forbidden,
1170 // but prevents type checking from blowing up before const checking can properly
1172 GatherLocalsVisitor { fcx: &fcx }.visit_expr(expr);
1174 fcx.check_expr_coercable_to_type(expr, expected_type);
1176 fcx.select_all_obligations_and_apply_defaults();
1177 fcx.closure_analyze_const(expr);
1178 fcx.select_obligations_where_possible();
1180 fcx.select_all_obligations_or_error();
1182 fcx.regionck_expr(expr);
1183 fcx.resolve_type_vars_in_expr(expr, id);
1187 fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1188 expr: &'tcx hir::Expr,
1190 let decl_ty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
1191 check_const_with_type(ccx, expr, decl_ty, id);
1194 /// Checks whether a type can be represented in memory. In particular, it
1195 /// identifies types that contain themselves without indirection through a
1196 /// pointer, which would mean their size is unbounded.
1197 pub fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1199 item_id: ast::NodeId,
1200 _designation: &str) -> bool {
1201 let rty = tcx.node_id_to_type(item_id);
1203 // Check that it is possible to represent this type. This call identifies
1204 // (1) types that contain themselves and (2) types that contain a different
1205 // recursive type. It is only necessary to throw an error on those that
1206 // contain themselves. For case 2, there must be an inner type that will be
1207 // caught by case 1.
1208 match rty.is_representable(tcx, sp) {
1209 Representability::SelfRecursive => {
1210 let item_def_id = tcx.map.local_def_id(item_id);
1211 tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
1214 Representability::Representable | Representability::ContainsRecursive => (),
1219 pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) {
1220 let t = tcx.node_id_to_type(id);
1222 ty::TyStruct(def, substs) => {
1223 let fields = &def.struct_variant().fields;
1224 if fields.is_empty() {
1225 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
1228 let e = fields[0].ty(tcx, substs);
1229 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1230 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
1234 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
1235 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
1237 span_err!(tcx.sess, sp, E0077,
1238 "SIMD vector element type should be machine type");
1247 #[allow(trivial_numeric_casts)]
1248 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
1250 vs: &'tcx [hir::Variant],
1252 let def_id = ccx.tcx.map.local_def_id(id);
1253 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
1255 if hint != attr::ReprAny && vs.is_empty() {
1257 ccx.tcx.sess, sp, E0084,
1258 "unsupported representation for zero-variant enum")
1259 .span_label(sp, &format!("unsupported enum representation"))
1263 let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx);
1265 if let Some(ref e) = v.node.disr_expr {
1266 check_const_with_type(ccx, e, repr_type_ty, e.id);
1270 let def_id = ccx.tcx.map.local_def_id(id);
1272 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
1273 let mut disr_vals: Vec<ty::Disr> = Vec::new();
1274 for (v, variant) in vs.iter().zip(variants.iter()) {
1275 let current_disr_val = variant.disr_val;
1277 // Check for duplicate discriminant values
1278 if let Some(i) = disr_vals.iter().position(|&x| x == current_disr_val) {
1279 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
1280 let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id);
1281 let i_span = match variant_i.node.disr_expr {
1282 Some(ref expr) => expr.span,
1283 None => ccx.tcx.map.span(variant_i_node_id)
1285 let span = match v.node.disr_expr {
1286 Some(ref expr) => expr.span,
1289 struct_span_err!(ccx.tcx.sess, span, E0081,
1290 "discriminant value `{}` already exists", disr_vals[i])
1291 .span_label(i_span, &format!("first use of `{}`", disr_vals[i]))
1292 .span_label(span , &format!("enum already has `{}`", disr_vals[i]))
1295 disr_vals.push(current_disr_val);
1298 check_representable(ccx.tcx, sp, id, "enum");
1301 impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
1302 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
1304 fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>> {
1305 &self.ast_ty_to_ty_cache
1308 fn get_generics(&self, _: Span, id: DefId)
1309 -> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
1311 Ok(self.tcx().lookup_generics(id))
1314 fn get_item_type_scheme(&self, _: Span, id: DefId)
1315 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1317 Ok(self.tcx().lookup_item_type(id))
1320 fn get_trait_def(&self, _: Span, id: DefId)
1321 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1323 Ok(self.tcx().lookup_trait_def(id))
1326 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1327 // all super predicates are ensured during collect pass
1331 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1332 Some(&self.parameter_environment.free_substs)
1335 fn get_type_parameter_bounds(&self,
1337 node_id: ast::NodeId)
1338 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1340 let def = self.tcx.type_parameter_def(node_id);
1341 let r = self.parameter_environment
1344 .filter_map(|predicate| {
1346 ty::Predicate::Trait(ref data) => {
1347 if data.0.self_ty().is_param(def.index) {
1348 Some(data.to_poly_trait_ref())
1362 fn trait_defines_associated_type_named(&self,
1363 trait_def_id: DefId,
1364 assoc_name: ast::Name)
1367 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
1368 trait_def.associated_type_names.contains(&assoc_name)
1371 fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
1375 fn ty_infer_for_def(&self,
1376 ty_param_def: &ty::TypeParameterDef<'tcx>,
1377 substs: &Substs<'tcx>,
1378 span: Span) -> Ty<'tcx> {
1379 self.type_var_for_def(span, ty_param_def, substs)
1382 fn projected_ty_from_poly_trait_ref(&self,
1384 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1385 item_name: ast::Name)
1388 let (trait_ref, _) =
1389 self.replace_late_bound_regions_with_fresh_var(
1391 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1394 self.normalize_associated_type(span, trait_ref, item_name)
1397 fn projected_ty(&self,
1399 trait_ref: ty::TraitRef<'tcx>,
1400 item_name: ast::Name)
1403 self.normalize_associated_type(span, trait_ref, item_name)
1406 fn set_tainted_by_errors(&self) {
1407 self.infcx.set_tainted_by_errors()
1411 impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> {
1412 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1413 Some(self.base_object_lifetime_default(span))
1416 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
1417 // RFC #599 specifies that object lifetime defaults take
1418 // precedence over other defaults. But within a fn body we
1419 // don't have a *default* region, rather we use inference to
1420 // find the *correct* region, which is strictly more general
1421 // (and anyway, within a fn body the right region may not even
1422 // be something the user can write explicitly, since it might
1423 // be some expression).
1424 *self.next_region_var(infer::MiscVariable(span))
1427 fn anon_regions(&self, span: Span, count: usize)
1428 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
1429 Ok((0..count).map(|_| {
1430 *self.next_region_var(infer::MiscVariable(span))
1435 /// Controls whether the arguments are tupled. This is used for the call
1438 /// Tupling means that all call-side arguments are packed into a tuple and
1439 /// passed as a single parameter. For example, if tupling is enabled, this
1442 /// fn f(x: (isize, isize))
1444 /// Can be called as:
1451 #[derive(Clone, Eq, PartialEq)]
1452 enum TupleArgumentsFlag {
1457 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1458 pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
1460 body_id: ast::NodeId)
1461 -> FnCtxt<'a, 'gcx, 'tcx> {
1463 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
1465 writeback_errors: Cell::new(false),
1466 err_count_on_creation: inh.tcx.sess.err_count(),
1468 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
1473 pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> {
1474 &self.parameter_environment
1477 pub fn sess(&self) -> &Session {
1481 pub fn err_count_since_creation(&self) -> usize {
1482 self.tcx.sess.err_count() - self.err_count_on_creation
1485 /// Resolves type variables in `ty` if possible. Unlike the infcx
1486 /// version (resolve_type_vars_if_possible), this version will
1487 /// also select obligations if it seems useful, in an effort
1488 /// to get more type information.
1489 fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1490 debug!("resolve_type_vars_with_obligations(ty={:?})", ty);
1492 // No TyInfer()? Nothing needs doing.
1493 if !ty.has_infer_types() {
1494 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1498 // If `ty` is a type variable, see whether we already know what it is.
1499 ty = self.resolve_type_vars_if_possible(&ty);
1500 if !ty.has_infer_types() {
1501 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1505 // If not, try resolving pending obligations as much as
1506 // possible. This can help substantially when there are
1507 // indirect dependencies that don't seem worth tracking
1509 self.select_obligations_where_possible();
1510 ty = self.resolve_type_vars_if_possible(&ty);
1512 debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
1516 fn record_deferred_call_resolution(&self,
1517 closure_def_id: DefId,
1518 r: DeferredCallResolutionHandler<'gcx, 'tcx>) {
1519 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1520 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1523 fn remove_deferred_call_resolutions(&self,
1524 closure_def_id: DefId)
1525 -> Vec<DeferredCallResolutionHandler<'gcx, 'tcx>>
1527 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
1528 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1531 pub fn tag(&self) -> String {
1532 let self_ptr: *const FnCtxt = self;
1533 format!("{:?}", self_ptr)
1536 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1537 match self.locals.borrow().get(&nid) {
1540 span_err!(self.tcx.sess, span, E0513,
1541 "no type for local variable {}",
1549 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1550 debug!("write_ty({}, {:?}) in fcx {}",
1551 node_id, ty, self.tag());
1552 self.tables.borrow_mut().node_types.insert(node_id, ty);
1554 // Add adjustments to !-expressions
1556 if let Some(hir::map::NodeExpr(_)) = self.tcx.map.find(node_id) {
1557 let adj = adjustment::AdjustNeverToAny(self.next_diverging_ty_var());
1558 self.write_adjustment(node_id, adj);
1563 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1564 if !substs.substs.is_noop() {
1565 debug!("write_substs({}, {:?}) in fcx {}",
1570 self.tables.borrow_mut().item_substs.insert(node_id, substs);
1574 pub fn write_autoderef_adjustment(&self,
1575 node_id: ast::NodeId,
1577 self.write_adjustment(
1579 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1587 pub fn write_adjustment(&self,
1588 node_id: ast::NodeId,
1589 adj: adjustment::AutoAdjustment<'tcx>) {
1590 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1592 if adj.is_identity() {
1596 self.tables.borrow_mut().adjustments.insert(node_id, adj);
1599 /// Basically whenever we are converting from a type scheme into
1600 /// the fn body space, we always want to normalize associated
1601 /// types as well. This function combines the two.
1602 fn instantiate_type_scheme<T>(&self,
1604 substs: &Substs<'tcx>,
1607 where T : TypeFoldable<'tcx>
1609 let value = value.subst(self.tcx, substs);
1610 let result = self.normalize_associated_types_in(span, &value);
1611 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1618 /// As `instantiate_type_scheme`, but for the bounds found in a
1619 /// generic type scheme.
1620 fn instantiate_bounds(&self,
1622 substs: &Substs<'tcx>,
1623 bounds: &ty::GenericPredicates<'tcx>)
1624 -> ty::InstantiatedPredicates<'tcx>
1626 let result = bounds.instantiate(self.tcx, substs);
1627 let result = self.normalize_associated_types_in(span, &result.predicates);
1628 debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
1632 ty::InstantiatedPredicates {
1637 /// Replace all anonymized types with fresh inference variables
1638 /// and record them for writeback.
1639 fn instantiate_anon_types<T: TypeFoldable<'tcx>>(&self, value: &T) -> T {
1640 value.fold_with(&mut BottomUpFolder { tcx: self.tcx, fldop: |ty| {
1641 if let ty::TyAnon(def_id, substs) = ty.sty {
1642 // Use the same type variable if the exact same TyAnon appears more
1643 // than once in the return type (e.g. if it's pased to a type alias).
1644 if let Some(ty_var) = self.anon_types.borrow().get(&def_id) {
1647 let ty_var = self.next_ty_var();
1648 self.anon_types.borrow_mut().insert(def_id, ty_var);
1650 let item_predicates = self.tcx.lookup_predicates(def_id);
1651 let bounds = item_predicates.instantiate(self.tcx, substs);
1653 let span = self.tcx.map.def_id_span(def_id, codemap::DUMMY_SP);
1654 for predicate in bounds.predicates {
1655 // Change the predicate to refer to the type variable,
1656 // which will be the concrete type, instead of the TyAnon.
1657 // This also instantiates nested `impl Trait`.
1658 let predicate = self.instantiate_anon_types(&predicate);
1660 // Require that the predicate holds for the concrete type.
1661 let cause = traits::ObligationCause::new(span, self.body_id,
1662 traits::ReturnType);
1663 self.register_predicate(traits::Obligation::new(cause, predicate));
1673 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1674 where T : TypeFoldable<'tcx>
1676 self.inh.normalize_associated_types_in(span, self.body_id, value)
1679 fn normalize_associated_type(&self,
1681 trait_ref: ty::TraitRef<'tcx>,
1682 item_name: ast::Name)
1685 let cause = traits::ObligationCause::new(span,
1687 traits::ObligationCauseCode::MiscObligation);
1690 .normalize_projection_type(self,
1692 trait_ref: trait_ref,
1693 item_name: item_name,
1698 /// Instantiates the type in `did` with the generics in `path` and returns
1699 /// it (registering the necessary trait obligations along the way).
1701 /// Note that this function is only intended to be used with type-paths,
1702 /// not with value-paths.
1703 pub fn instantiate_type_path(&self,
1706 node_id: ast::NodeId)
1708 debug!("instantiate_type_path(did={:?}, path={:?})", did, path);
1709 let mut ty = self.tcx.lookup_item_type(did).ty;
1711 // Tuple variants have fn type even in type namespace, extract true variant type from it
1712 ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap();
1714 let type_predicates = self.tcx.lookup_predicates(did);
1715 let substs = AstConv::ast_path_substs_for_ty(self, self,
1717 PathParamMode::Optional,
1719 path.segments.last().unwrap());
1720 debug!("instantiate_type_path: ty={:?} substs={:?}", ty, substs);
1721 let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);
1722 let cause = traits::ObligationCause::new(path.span, self.body_id,
1723 traits::ItemObligation(did));
1724 self.add_obligations_for_parameters(cause, &bounds);
1726 let ty_substituted = self.instantiate_type_scheme(path.span, substs, &ty);
1727 self.write_ty(node_id, ty_substituted);
1728 self.write_substs(node_id, ty::ItemSubsts {
1734 pub fn write_nil(&self, node_id: ast::NodeId) {
1735 self.write_ty(node_id, self.tcx.mk_nil());
1738 pub fn write_never(&self, node_id: ast::NodeId) {
1739 self.write_ty(node_id, self.tcx.types.never);
1742 pub fn write_error(&self, node_id: ast::NodeId) {
1743 self.write_ty(node_id, self.tcx.types.err);
1746 pub fn require_type_meets(&self,
1749 code: traits::ObligationCauseCode<'tcx>,
1750 bound: ty::BuiltinBound)
1752 self.register_builtin_bound(
1755 traits::ObligationCause::new(span, self.body_id, code));
1758 pub fn require_type_is_sized(&self,
1761 code: traits::ObligationCauseCode<'tcx>)
1763 self.require_type_meets(ty, span, code, ty::BoundSized);
1766 pub fn require_expr_have_sized_type(&self,
1768 code: traits::ObligationCauseCode<'tcx>)
1770 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1773 pub fn register_builtin_bound(&self,
1775 builtin_bound: ty::BuiltinBound,
1776 cause: traits::ObligationCause<'tcx>)
1778 self.fulfillment_cx.borrow_mut()
1779 .register_builtin_bound(self, ty, builtin_bound, cause);
1782 pub fn register_predicate(&self,
1783 obligation: traits::PredicateObligation<'tcx>)
1785 debug!("register_predicate({:?})",
1789 .register_predicate_obligation(self, obligation);
1792 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1793 let t = AstConv::ast_ty_to_ty(self, self, ast_t);
1794 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1798 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1799 if let Some(&adjustment::AdjustNeverToAny(ref t))
1800 = self.tables.borrow().adjustments.get(&ex.id) {
1803 match self.tables.borrow().node_types.get(&ex.id) {
1806 bug!("no type for expr in fcx {}", self.tag());
1811 /// Apply `adjustment` to the type of `expr`
1812 pub fn adjust_expr_ty(&self,
1814 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1817 let raw_ty = self.expr_ty(expr);
1818 let raw_ty = self.shallow_resolve(raw_ty);
1819 let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1820 raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| {
1821 self.tables.borrow().method_map.get(&method_call)
1822 .map(|method| resolve_ty(method.ty))
1826 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1827 match self.tables.borrow().node_types.get(&id) {
1829 None if self.err_count_since_creation() != 0 => self.tcx.types.err,
1831 bug!("no type for node {}: {} in fcx {}",
1832 id, self.tcx.map.node_to_string(id),
1838 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1839 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1840 // it changes when we upgrade the snapshot compiler
1841 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1842 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1846 Ref::map(self.tables.borrow(), project_item_susbts)
1849 pub fn opt_node_ty_substs<F>(&self,
1852 F: FnOnce(&ty::ItemSubsts<'tcx>),
1854 match self.tables.borrow().item_substs.get(&id) {
1860 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1861 /// outlive the region `r`.
1862 pub fn register_region_obligation(&self,
1864 region: &'tcx ty::Region,
1865 cause: traits::ObligationCause<'tcx>)
1867 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
1868 fulfillment_cx.register_region_obligation(ty, region, cause);
1871 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1872 /// outlive the region `r`.
1873 pub fn register_wf_obligation(&self,
1876 code: traits::ObligationCauseCode<'tcx>)
1878 // WF obligations never themselves fail, so no real need to give a detailed cause:
1879 let cause = traits::ObligationCause::new(span, self.body_id, code);
1880 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1883 pub fn register_old_wf_obligation(&self,
1886 code: traits::ObligationCauseCode<'tcx>)
1888 // Registers an "old-style" WF obligation that uses the
1889 // implicator code. This is basically a buggy version of
1890 // `register_wf_obligation` that is being kept around
1891 // temporarily just to help with phasing in the newer rules.
1893 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1894 let cause = traits::ObligationCause::new(span, self.body_id, code);
1895 self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause);
1898 /// Registers obligations that all types appearing in `substs` are well-formed.
1899 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1901 for ty in substs.types() {
1902 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1906 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1907 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1908 /// trait/region obligations.
1910 /// For example, if there is a function:
1913 /// fn foo<'a,T:'a>(...)
1916 /// and a reference:
1922 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1923 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1924 pub fn add_obligations_for_parameters(&self,
1925 cause: traits::ObligationCause<'tcx>,
1926 predicates: &ty::InstantiatedPredicates<'tcx>)
1928 assert!(!predicates.has_escaping_regions());
1930 debug!("add_obligations_for_parameters(predicates={:?})",
1933 for obligation in traits::predicates_for_generics(cause, predicates) {
1934 self.register_predicate(obligation);
1938 // FIXME(arielb1): use this instead of field.ty everywhere
1939 // Only for fields! Returns <none> for methods>
1940 // Indifferent to privacy flags
1941 pub fn field_ty(&self,
1943 field: ty::FieldDef<'tcx>,
1944 substs: &Substs<'tcx>)
1947 self.normalize_associated_types_in(span,
1948 &field.ty(self.tcx, substs))
1951 fn check_casts(&self) {
1952 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
1953 for cast in deferred_cast_checks.drain(..) {
1958 /// Apply "fallbacks" to some types
1959 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1960 fn default_type_parameters(&self) {
1961 use rustc::ty::error::UnconstrainedNumeric::Neither;
1962 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1964 // Defaulting inference variables becomes very dubious if we have
1965 // encountered type-checking errors. Therefore, if we think we saw
1966 // some errors in this function, just resolve all uninstanted type
1967 // varibles to TyError.
1968 if self.is_tainted_by_errors() {
1969 for ty in &self.unsolved_variables() {
1970 if let ty::TyInfer(_) = self.shallow_resolve(ty).sty {
1971 debug!("default_type_parameters: defaulting `{:?}` to error", ty);
1972 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
1978 for ty in &self.unsolved_variables() {
1979 let resolved = self.resolve_type_vars_if_possible(ty);
1980 if self.type_var_diverges(resolved) {
1981 debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
1983 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
1984 self.tcx.mk_diverging_default());
1986 match self.type_is_unconstrained_numeric(resolved) {
1987 UnconstrainedInt => {
1988 debug!("default_type_parameters: defaulting `{:?}` to `i32`",
1990 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
1992 UnconstrainedFloat => {
1993 debug!("default_type_parameters: defaulting `{:?}` to `f32`",
1995 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2003 fn select_all_obligations_and_apply_defaults(&self) {
2004 if self.tcx.sess.features.borrow().default_type_parameter_fallback {
2005 self.new_select_all_obligations_and_apply_defaults();
2007 self.old_select_all_obligations_and_apply_defaults();
2011 // Implements old type inference fallback algorithm
2012 fn old_select_all_obligations_and_apply_defaults(&self) {
2013 self.select_obligations_where_possible();
2014 self.default_type_parameters();
2015 self.select_obligations_where_possible();
2018 fn new_select_all_obligations_and_apply_defaults(&self) {
2019 use rustc::ty::error::UnconstrainedNumeric::Neither;
2020 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2022 // For the time being this errs on the side of being memory wasteful but provides better
2024 // let type_variables = self.type_variables.clone();
2026 // There is a possibility that this algorithm will have to run an arbitrary number of times
2027 // to terminate so we bound it by the compiler's recursion limit.
2028 for _ in 0..self.tcx.sess.recursion_limit.get() {
2029 // First we try to solve all obligations, it is possible that the last iteration
2030 // has made it possible to make more progress.
2031 self.select_obligations_where_possible();
2033 let mut conflicts = Vec::new();
2035 // Collect all unsolved type, integral and floating point variables.
2036 let unsolved_variables = self.unsolved_variables();
2038 // We must collect the defaults *before* we do any unification. Because we have
2039 // directly attached defaults to the type variables any unification that occurs
2040 // will erase defaults causing conflicting defaults to be completely ignored.
2041 let default_map: FnvHashMap<_, _> =
2044 .filter_map(|t| self.default(t).map(|d| (t, d)))
2047 let mut unbound_tyvars = FnvHashSet();
2049 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
2051 // We loop over the unsolved variables, resolving them and if they are
2052 // and unconstrainted numeric type we add them to the set of unbound
2053 // variables. We do this so we only apply literal fallback to type
2054 // variables without defaults.
2055 for ty in &unsolved_variables {
2056 let resolved = self.resolve_type_vars_if_possible(ty);
2057 if self.type_var_diverges(resolved) {
2058 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2059 self.tcx.mk_diverging_default());
2061 match self.type_is_unconstrained_numeric(resolved) {
2062 UnconstrainedInt | UnconstrainedFloat => {
2063 unbound_tyvars.insert(resolved);
2070 // We now remove any numeric types that also have defaults, and instead insert
2071 // the type variable with a defined fallback.
2072 for ty in &unsolved_variables {
2073 if let Some(_default) = default_map.get(ty) {
2074 let resolved = self.resolve_type_vars_if_possible(ty);
2076 debug!("select_all_obligations_and_apply_defaults: \
2077 ty: {:?} with default: {:?}",
2080 match resolved.sty {
2081 ty::TyInfer(ty::TyVar(_)) => {
2082 unbound_tyvars.insert(ty);
2085 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
2086 unbound_tyvars.insert(ty);
2087 if unbound_tyvars.contains(resolved) {
2088 unbound_tyvars.remove(resolved);
2097 // If there are no more fallbacks to apply at this point we have applied all possible
2098 // defaults and type inference will proceed as normal.
2099 if unbound_tyvars.is_empty() {
2103 // Finally we go through each of the unbound type variables and unify them with
2104 // the proper fallback, reporting a conflicting default error if any of the
2105 // unifications fail. We know it must be a conflicting default because the
2106 // variable would only be in `unbound_tyvars` and have a concrete value if
2107 // it had been solved by previously applying a default.
2109 // We wrap this in a transaction for error reporting, if we detect a conflict
2110 // we will rollback the inference context to its prior state so we can probe
2111 // for conflicts and correctly report them.
2114 let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2115 for ty in &unbound_tyvars {
2116 if self.type_var_diverges(ty) {
2117 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2118 self.tcx.mk_diverging_default());
2120 match self.type_is_unconstrained_numeric(ty) {
2121 UnconstrainedInt => {
2122 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2124 UnconstrainedFloat => {
2125 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2128 if let Some(default) = default_map.get(ty) {
2129 let default = default.clone();
2130 match self.eq_types(false,
2131 TypeOrigin::Misc(default.origin_span),
2133 Ok(InferOk { obligations, .. }) => {
2134 // FIXME(#32730) propagate obligations
2135 assert!(obligations.is_empty())
2138 conflicts.push((*ty, default));
2147 // If there are conflicts we rollback, otherwise commit
2148 if conflicts.len() > 0 {
2155 if conflicts.len() > 0 {
2156 // Loop through each conflicting default, figuring out the default that caused
2157 // a unification failure and then report an error for each.
2158 for (conflict, default) in conflicts {
2159 let conflicting_default =
2160 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
2161 .unwrap_or(type_variable::Default {
2162 ty: self.next_ty_var(),
2163 origin_span: syntax_pos::DUMMY_SP,
2164 def_id: self.tcx.map.local_def_id(0) // what do I put here?
2167 // This is to ensure that we elimnate any non-determinism from the error
2168 // reporting by fixing an order, it doesn't matter what order we choose
2169 // just that it is consistent.
2170 let (first_default, second_default) =
2171 if default.def_id < conflicting_default.def_id {
2172 (default, conflicting_default)
2174 (conflicting_default, default)
2178 self.report_conflicting_default_types(
2179 first_default.origin_span,
2186 self.select_obligations_where_possible();
2189 // For use in error handling related to default type parameter fallback. We explicitly
2190 // apply the default that caused conflict first to a local version of the type variable
2191 // table then apply defaults until we find a conflict. That default must be the one
2192 // that caused conflict earlier.
2193 fn find_conflicting_default(&self,
2194 unbound_vars: &FnvHashSet<Ty<'tcx>>,
2195 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
2197 -> Option<type_variable::Default<'tcx>> {
2198 use rustc::ty::error::UnconstrainedNumeric::Neither;
2199 use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2201 // Ensure that we apply the conflicting default first
2202 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2203 unbound_tyvars.push(conflict);
2204 unbound_tyvars.extend(unbound_vars.iter());
2206 let mut result = None;
2207 // We run the same code as above applying defaults in order, this time when
2208 // we find the conflict we just return it for error reporting above.
2210 // We also run this inside snapshot that never commits so we can do error
2211 // reporting for more then one conflict.
2212 for ty in &unbound_tyvars {
2213 if self.type_var_diverges(ty) {
2214 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2215 self.tcx.mk_diverging_default());
2217 match self.type_is_unconstrained_numeric(ty) {
2218 UnconstrainedInt => {
2219 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2221 UnconstrainedFloat => {
2222 self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2225 if let Some(default) = default_map.get(ty) {
2226 let default = default.clone();
2227 match self.eq_types(false,
2228 TypeOrigin::Misc(default.origin_span),
2230 // FIXME(#32730) propagate obligations
2231 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2233 result = Some(default);
2245 fn select_all_obligations_or_error(&self) {
2246 debug!("select_all_obligations_or_error");
2248 // upvar inference should have ensured that all deferred call
2249 // resolutions are handled by now.
2250 assert!(self.deferred_call_resolutions.borrow().is_empty());
2252 self.select_all_obligations_and_apply_defaults();
2254 let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
2256 // Steal the deferred obligations before the fulfillment
2257 // context can turn all of them into errors.
2258 let obligations = fulfillment_cx.take_deferred_obligations();
2259 self.deferred_obligations.borrow_mut().extend(obligations);
2261 match fulfillment_cx.select_all_or_error(self) {
2263 Err(errors) => { self.report_fulfillment_errors(&errors); }
2266 if let Err(ref errors) = fulfillment_cx.select_rfc1592_obligations(self) {
2267 self.report_fulfillment_errors_as_warnings(errors, self.body_id);
2271 /// Select as many obligations as we can at present.
2272 fn select_obligations_where_possible(&self) {
2273 match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2275 Err(errors) => { self.report_fulfillment_errors(&errors); }
2279 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait
2280 /// returns a type of `&T`, but the actual type we assign to the
2281 /// *expression* is `T`. So this function just peels off the return
2282 /// type by one layer to yield `T`.
2283 fn make_overloaded_lvalue_return_type(&self,
2284 method: MethodCallee<'tcx>)
2285 -> ty::TypeAndMut<'tcx>
2287 // extract method return type, which will be &T;
2288 // all LB regions should have been instantiated during method lookup
2289 let ret_ty = method.ty.fn_ret();
2290 let ret_ty = self.tcx.no_late_bound_regions(&ret_ty).unwrap();
2292 // method returns &T, but the type as visible to user is T, so deref
2293 ret_ty.builtin_deref(true, NoPreference).unwrap()
2296 fn lookup_indexing(&self,
2298 base_expr: &'gcx hir::Expr,
2301 lvalue_pref: LvaluePreference)
2302 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2304 // FIXME(#18741) -- this is almost but not quite the same as the
2305 // autoderef that normal method probing does. They could likely be
2308 let mut autoderef = self.autoderef(base_expr.span, base_ty);
2310 while let Some((adj_ty, autoderefs)) = autoderef.next() {
2311 if let Some(final_mt) = self.try_index_step(
2312 MethodCall::expr(expr.id),
2313 expr, base_expr, adj_ty, autoderefs,
2314 false, lvalue_pref, idx_ty)
2316 autoderef.finalize(lvalue_pref, Some(base_expr));
2317 return Some(final_mt);
2320 if let ty::TyArray(element_ty, _) = adj_ty.sty {
2321 autoderef.finalize(lvalue_pref, Some(base_expr));
2322 let adjusted_ty = self.tcx.mk_slice(element_ty);
2323 return self.try_index_step(
2324 MethodCall::expr(expr.id), expr, base_expr,
2325 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty);
2328 autoderef.unambiguous_final_ty();
2332 /// To type-check `base_expr[index_expr]`, we progressively autoderef
2333 /// (and otherwise adjust) `base_expr`, looking for a type which either
2334 /// supports builtin indexing or overloaded indexing.
2335 /// This loop implements one step in that search; the autoderef loop
2336 /// is implemented by `lookup_indexing`.
2337 fn try_index_step(&self,
2338 method_call: MethodCall,
2340 base_expr: &'gcx hir::Expr,
2341 adjusted_ty: Ty<'tcx>,
2344 lvalue_pref: LvaluePreference,
2346 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2349 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2350 autoderefs={}, unsize={}, index_ty={:?})",
2358 let input_ty = self.next_ty_var();
2360 // First, try built-in indexing.
2361 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2362 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2363 debug!("try_index_step: success, using built-in indexing");
2364 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2366 self.write_autoderef_adjustment(base_expr.id, autoderefs);
2367 return Some((tcx.types.usize, ty));
2372 // Try `IndexMut` first, if preferred.
2373 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2374 (PreferMutLvalue, Some(trait_did)) => {
2375 self.lookup_method_in_trait_adjusted(expr.span,
2377 token::intern("index_mut"),
2382 Some(vec![input_ty]))
2387 // Otherwise, fall back to `Index`.
2388 let method = match (method, tcx.lang_items.index_trait()) {
2389 (None, Some(trait_did)) => {
2390 self.lookup_method_in_trait_adjusted(expr.span,
2392 token::intern("index"),
2397 Some(vec![input_ty]))
2399 (method, _) => method,
2402 // If some lookup succeeds, write callee into table and extract index/element
2403 // type from the method signature.
2404 // If some lookup succeeded, install method in table
2405 method.map(|method| {
2406 debug!("try_index_step: success, using overloaded indexing");
2407 self.tables.borrow_mut().method_map.insert(method_call, method);
2408 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
2412 fn check_method_argument_types(&self,
2414 method_fn_ty: Ty<'tcx>,
2415 callee_expr: &'gcx hir::Expr,
2416 args_no_rcvr: &'gcx [P<hir::Expr>],
2417 tuple_arguments: TupleArgumentsFlag,
2418 expected: Expectation<'tcx>)
2420 if method_fn_ty.references_error() {
2421 let err_inputs = self.err_args(args_no_rcvr.len());
2423 let err_inputs = match tuple_arguments {
2424 DontTupleArguments => err_inputs,
2425 TupleArguments => vec![self.tcx.mk_tup(err_inputs)],
2428 self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2429 false, tuple_arguments);
2432 match method_fn_ty.sty {
2433 ty::TyFnDef(_, _, ref fty) => {
2434 // HACK(eddyb) ignore self in the definition (see above).
2435 let expected_arg_tys = self.expected_types_for_fn_args(sp, expected,
2437 &fty.sig.0.inputs[1..]);
2438 self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..],
2439 args_no_rcvr, fty.sig.0.variadic, tuple_arguments);
2443 span_bug!(callee_expr.span, "method without bare fn type");
2449 /// Generic function that factors out common logic from function calls,
2450 /// method calls and overloaded operators.
2451 fn check_argument_types(&self,
2453 fn_inputs: &[Ty<'tcx>],
2454 expected_arg_tys: &[Ty<'tcx>],
2455 args: &'gcx [P<hir::Expr>],
2457 tuple_arguments: TupleArgumentsFlag) {
2460 // Grab the argument types, supplying fresh type variables
2461 // if the wrong number of arguments were supplied
2462 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2468 // All the input types from the fn signature must outlive the call
2469 // so as to validate implied bounds.
2470 for &fn_input_ty in fn_inputs {
2471 self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2474 let mut expected_arg_tys = expected_arg_tys;
2475 let expected_arg_count = fn_inputs.len();
2477 fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
2478 expected_count: usize, arg_count: usize, error_code: &str,
2480 let mut err = sess.struct_span_err_with_code(sp,
2481 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
2482 if variadic {"at least "} else {""},
2484 if expected_count == 1 {""} else {"s"},
2486 if arg_count == 1 {" was"} else {"s were"}),
2489 err.span_label(sp, &format!("expected {}{} parameter{}",
2490 if variadic {"at least "} else {""},
2492 if expected_count == 1 {""} else {"s"}));
2494 let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
2495 if input_types.len() > 0 {
2496 err.note(&format!("the following parameter type{} expected: {}",
2497 if expected_count == 1 {" was"} else {"s were"},
2498 input_types.join(", ")));
2503 let formal_tys = if tuple_arguments == TupleArguments {
2504 let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
2505 match tuple_type.sty {
2506 ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
2507 parameter_count_error(tcx.sess, sp, fn_inputs, arg_types.len(), args.len(),
2509 expected_arg_tys = &[];
2510 self.err_args(args.len())
2512 ty::TyTuple(arg_types) => {
2513 expected_arg_tys = match expected_arg_tys.get(0) {
2514 Some(&ty) => match ty.sty {
2515 ty::TyTuple(ref tys) => &tys,
2523 span_err!(tcx.sess, sp, E0059,
2524 "cannot use call notation; the first type parameter \
2525 for the function trait is neither a tuple nor unit");
2526 expected_arg_tys = &[];
2527 self.err_args(args.len())
2530 } else if expected_arg_count == supplied_arg_count {
2532 } else if variadic {
2533 if supplied_arg_count >= expected_arg_count {
2536 parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count,
2537 supplied_arg_count, "E0060", true);
2538 expected_arg_tys = &[];
2539 self.err_args(supplied_arg_count)
2542 parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count,
2544 expected_arg_tys = &[];
2545 self.err_args(supplied_arg_count)
2548 debug!("check_argument_types: formal_tys={:?}",
2549 formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
2551 // Check the arguments.
2552 // We do this in a pretty awful way: first we typecheck any arguments
2553 // that are not anonymous functions, then we typecheck the anonymous
2554 // functions. This is so that we have more information about the types
2555 // of arguments when we typecheck the functions. This isn't really the
2556 // right way to do this.
2557 let xs = [false, true];
2558 let mut any_diverges = false; // has any of the arguments diverged?
2559 let mut warned = false; // have we already warned about unreachable code?
2560 for check_blocks in &xs {
2561 let check_blocks = *check_blocks;
2562 debug!("check_blocks={}", check_blocks);
2564 // More awful hacks: before we check argument types, try to do
2565 // an "opportunistic" vtable resolution of any trait bounds on
2566 // the call. This helps coercions.
2568 self.select_obligations_where_possible();
2571 // For variadic functions, we don't have a declared type for all of
2572 // the arguments hence we only do our usual type checking with
2573 // the arguments who's types we do know.
2574 let t = if variadic {
2576 } else if tuple_arguments == TupleArguments {
2581 for (i, arg) in args.iter().take(t).enumerate() {
2582 if any_diverges && !warned {
2585 .add_lint(lint::builtin::UNREACHABLE_CODE,
2588 "unreachable expression".to_string());
2591 let is_block = match arg.node {
2592 hir::ExprClosure(..) => true,
2596 if is_block == check_blocks {
2597 debug!("checking the argument");
2598 let formal_ty = formal_tys[i];
2600 // The special-cased logic below has three functions:
2601 // 1. Provide as good of an expected type as possible.
2602 let expected = expected_arg_tys.get(i).map(|&ty| {
2603 Expectation::rvalue_hint(self, ty)
2606 self.check_expr_with_expectation(&arg,
2607 expected.unwrap_or(ExpectHasType(formal_ty)));
2608 // 2. Coerce to the most detailed type that could be coerced
2609 // to, which is `expected_ty` if `rvalue_hint` returns an
2610 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2611 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2612 self.demand_coerce(&arg, coerce_ty.unwrap_or(formal_ty));
2614 // 3. Relate the expected type and the formal one,
2615 // if the expected type was used for the coercion.
2616 coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2619 if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) {
2620 // FIXME(canndrew): This is_never should probably be an is_uninhabited
2621 any_diverges = any_diverges ||
2622 self.type_var_diverges(arg_ty) ||
2626 if any_diverges && !warned {
2627 let parent = self.tcx.map.get_parent_node(args[0].id);
2630 .add_lint(lint::builtin::UNREACHABLE_CODE,
2633 "unreachable call".to_string());
2639 // We also need to make sure we at least write the ty of the other
2640 // arguments which we skipped above.
2642 for arg in args.iter().skip(expected_arg_count) {
2643 self.check_expr(&arg);
2645 // There are a few types which get autopromoted when passed via varargs
2646 // in C but we just error out instead and require explicit casts.
2647 let arg_ty = self.structurally_resolved_type(arg.span,
2648 self.expr_ty(&arg));
2650 ty::TyFloat(ast::FloatTy::F32) => {
2651 self.type_error_message(arg.span, |t| {
2652 format!("can't pass an `{}` to variadic \
2653 function, cast to `c_double`", t)
2656 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2657 self.type_error_message(arg.span, |t| {
2658 format!("can't pass `{}` to variadic \
2659 function, cast to `c_int`",
2663 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2664 self.type_error_message(arg.span, |t| {
2665 format!("can't pass `{}` to variadic \
2666 function, cast to `c_uint`",
2670 ty::TyFnDef(_, _, f) => {
2671 let ptr_ty = self.tcx.mk_fn_ptr(f);
2672 let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
2673 self.type_error_message(arg.span,
2675 format!("can't pass `{}` to variadic \
2676 function, cast to `{}`", t, ptr_ty)
2685 fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
2686 (0..len).map(|_| self.tcx.types.err).collect()
2689 fn write_call(&self,
2690 call_expr: &hir::Expr,
2692 self.write_ty(call_expr.id, output);
2695 // AST fragment checking
2698 expected: Expectation<'tcx>)
2704 ast::LitKind::Str(..) => tcx.mk_static_str(),
2705 ast::LitKind::ByteStr(ref v) => {
2706 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2707 tcx.mk_array(tcx.types.u8, v.len()))
2709 ast::LitKind::Byte(_) => tcx.types.u8,
2710 ast::LitKind::Char(_) => tcx.types.char,
2711 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2712 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2713 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2714 let opt_ty = expected.to_option(self).and_then(|ty| {
2716 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2717 ty::TyChar => Some(tcx.types.u8),
2718 ty::TyRawPtr(..) => Some(tcx.types.usize),
2719 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2723 opt_ty.unwrap_or_else(
2724 || tcx.mk_int_var(self.next_int_var_id()))
2726 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2727 ast::LitKind::FloatUnsuffixed(_) => {
2728 let opt_ty = expected.to_option(self).and_then(|ty| {
2730 ty::TyFloat(_) => Some(ty),
2734 opt_ty.unwrap_or_else(
2735 || tcx.mk_float_var(self.next_float_var_id()))
2737 ast::LitKind::Bool(_) => tcx.types.bool
2741 fn check_expr_eq_type(&self,
2742 expr: &'gcx hir::Expr,
2743 expected: Ty<'tcx>) {
2744 self.check_expr_with_hint(expr, expected);
2745 self.demand_eqtype(expr.span, expected, self.expr_ty(expr));
2748 pub fn check_expr_has_type(&self,
2749 expr: &'gcx hir::Expr,
2750 expected: Ty<'tcx>) {
2751 self.check_expr_with_hint(expr, expected);
2752 self.demand_suptype(expr.span, expected, self.expr_ty(expr));
2755 fn check_expr_coercable_to_type(&self,
2756 expr: &'gcx hir::Expr,
2757 expected: Ty<'tcx>) {
2758 self.check_expr_with_hint(expr, expected);
2759 self.demand_coerce(expr, expected);
2762 fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
2763 expected: Ty<'tcx>) {
2764 self.check_expr_with_expectation(expr, ExpectHasType(expected))
2767 fn check_expr_with_expectation(&self,
2768 expr: &'gcx hir::Expr,
2769 expected: Expectation<'tcx>) {
2770 self.check_expr_with_expectation_and_lvalue_pref(expr, expected, NoPreference)
2773 fn check_expr(&self, expr: &'gcx hir::Expr) {
2774 self.check_expr_with_expectation(expr, NoExpectation)
2777 fn check_expr_with_lvalue_pref(&self, expr: &'gcx hir::Expr,
2778 lvalue_pref: LvaluePreference) {
2779 self.check_expr_with_expectation_and_lvalue_pref(expr, NoExpectation, lvalue_pref)
2782 // determine the `self` type, using fresh variables for all variables
2783 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2784 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2786 pub fn impl_self_ty(&self,
2787 span: Span, // (potential) receiver for this impl
2789 -> TypeAndSubsts<'tcx> {
2790 let ity = self.tcx.lookup_item_type(did);
2791 debug!("impl_self_ty: ity={:?}", ity);
2793 let substs = self.fresh_substs_for_item(span, did);
2794 let substd_ty = self.instantiate_type_scheme(span, &substs, &ity.ty);
2796 TypeAndSubsts { substs: substs, ty: substd_ty }
2799 /// Unifies the return type with the expected type early, for more coercions
2800 /// and forward type information on the argument expressions.
2801 fn expected_types_for_fn_args(&self,
2803 expected_ret: Expectation<'tcx>,
2804 formal_ret: Ty<'tcx>,
2805 formal_args: &[Ty<'tcx>])
2807 let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2808 self.commit_regions_if_ok(|| {
2809 // Attempt to apply a subtyping relationship between the formal
2810 // return type (likely containing type variables if the function
2811 // is polymorphic) and the expected return type.
2812 // No argument expectations are produced if unification fails.
2813 let origin = TypeOrigin::Misc(call_span);
2814 let ures = self.sub_types(false, origin, formal_ret, ret_ty);
2815 // FIXME(#15760) can't use try! here, FromError doesn't default
2816 // to identity so the resulting type is not constrained.
2818 // FIXME(#32730) propagate obligations
2819 Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
2820 Err(e) => return Err(e),
2823 // Record all the argument types, with the substitutions
2824 // produced from the above subtyping unification.
2825 Ok(formal_args.iter().map(|ty| {
2826 self.resolve_type_vars_if_possible(ty)
2829 }).unwrap_or(vec![]);
2830 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2831 formal_args, formal_ret,
2832 expected_args, expected_ret);
2836 // Checks a method call.
2837 fn check_method_call(&self,
2838 expr: &'gcx hir::Expr,
2839 method_name: Spanned<ast::Name>,
2840 args: &'gcx [P<hir::Expr>],
2842 expected: Expectation<'tcx>,
2843 lvalue_pref: LvaluePreference) {
2844 let rcvr = &args[0];
2845 self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2847 // no need to check for bot/err -- callee does that
2848 let expr_t = self.structurally_resolved_type(expr.span, self.expr_ty(&rcvr));
2850 let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2851 let fn_ty = match self.lookup_method(method_name.span,
2858 let method_ty = method.ty;
2859 let method_call = MethodCall::expr(expr.id);
2860 self.tables.borrow_mut().method_map.insert(method_call, method);
2864 if method_name.node != keywords::Invalid.name() {
2865 self.report_method_error(method_name.span, expr_t,
2866 method_name.node, Some(rcvr), error);
2868 self.write_error(expr.id);
2873 // Call the generic checker.
2874 let ret_ty = self.check_method_argument_types(method_name.span, fn_ty,
2879 self.write_call(expr, ret_ty);
2882 // A generic function for checking the then and else in an if
2884 fn check_then_else(&self,
2885 cond_expr: &'gcx hir::Expr,
2886 then_blk: &'gcx hir::Block,
2887 opt_else_expr: Option<&'gcx hir::Expr>,
2890 expected: Expectation<'tcx>) {
2891 self.check_expr_has_type(cond_expr, self.tcx.types.bool);
2893 let expected = expected.adjust_for_branches(self);
2894 self.check_block_with_expected(then_blk, expected);
2895 let then_ty = self.node_ty(then_blk.id);
2897 let unit = self.tcx.mk_nil();
2898 let (origin, expected, found, result) =
2899 if let Some(else_expr) = opt_else_expr {
2900 self.check_expr_with_expectation(else_expr, expected);
2901 let else_ty = self.expr_ty(else_expr);
2902 let origin = TypeOrigin::IfExpression(sp);
2904 // Only try to coerce-unify if we have a then expression
2905 // to assign coercions to, otherwise it's () or diverging.
2906 let result = if let Some(ref then) = then_blk.expr {
2907 let res = self.try_find_coercion_lub(origin, || Some(&**then),
2908 then_ty, else_expr);
2910 // In case we did perform an adjustment, we have to update
2911 // the type of the block, because old trans still uses it.
2912 let adj = self.tables.borrow().adjustments.get(&then.id).cloned();
2913 if res.is_ok() && adj.is_some() {
2914 self.write_ty(then_blk.id, self.adjust_expr_ty(then, adj.as_ref()));
2919 self.commit_if_ok(|_| {
2920 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2921 self.lub(true, trace, &then_ty, &else_ty)
2922 .map(|InferOk { value, obligations }| {
2923 // FIXME(#32730) propagate obligations
2924 assert!(obligations.is_empty());
2929 (origin, then_ty, else_ty, result)
2931 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2932 (origin, unit, then_ty,
2933 self.eq_types(true, origin, unit, then_ty)
2934 .map(|InferOk { obligations, .. }| {
2935 // FIXME(#32730) propagate obligations
2936 assert!(obligations.is_empty());
2941 let if_ty = match result {
2943 if self.expr_ty(cond_expr).references_error() {
2950 self.report_mismatched_types(origin, expected, found, e);
2955 self.write_ty(id, if_ty);
2958 // Check field access expressions
2959 fn check_field(&self,
2960 expr: &'gcx hir::Expr,
2961 lvalue_pref: LvaluePreference,
2962 base: &'gcx hir::Expr,
2963 field: &Spanned<ast::Name>) {
2964 self.check_expr_with_lvalue_pref(base, lvalue_pref);
2965 let expr_t = self.structurally_resolved_type(expr.span,
2966 self.expr_ty(base));
2967 let mut private_candidate = None;
2968 let mut autoderef = self.autoderef(expr.span, expr_t);
2969 while let Some((base_t, autoderefs)) = autoderef.next() {
2970 if let ty::TyStruct(base_def, substs) = base_t.sty {
2971 debug!("struct named {:?}", base_t);
2972 if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
2973 let field_ty = self.field_ty(expr.span, field, substs);
2974 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
2975 autoderef.finalize(lvalue_pref, Some(base));
2976 self.write_ty(expr.id, field_ty);
2977 self.write_autoderef_adjustment(base.id, autoderefs);
2980 private_candidate = Some((base_def.did, field_ty));
2984 autoderef.unambiguous_final_ty();
2986 if let Some((did, field_ty)) = private_candidate {
2987 let struct_path = self.tcx().item_path_str(did);
2988 self.write_ty(expr.id, field_ty);
2989 let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2990 let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2991 // Also check if an accessible method exists, which is often what is meant.
2992 if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
2993 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
2997 } else if field.node == keywords::Invalid.name() {
2998 self.write_error(expr.id);
2999 } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
3000 self.type_error_struct(field.span, |actual| {
3001 format!("attempted to take value of method `{}` on type \
3002 `{}`", field.node, actual)
3004 .help("maybe a `()` to call it is missing? \
3005 If not, try an anonymous function")
3007 self.write_error(expr.id);
3009 let mut err = self.type_error_struct(expr.span, |actual| {
3010 format!("attempted access of field `{}` on type `{}`, \
3011 but no field with that name was found",
3014 if let ty::TyRawPtr(..) = expr_t.sty {
3015 err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
3016 `(*{0}).{1}`", pprust::expr_to_string(base), field.node));
3018 if let ty::TyStruct(def, _) = expr_t.sty {
3019 Self::suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
3022 self.write_error(expr.id);
3026 // displays hints about the closest matches in field names
3027 fn suggest_field_names(err: &mut DiagnosticBuilder,
3028 variant: ty::VariantDef<'tcx>,
3029 field: &Spanned<ast::Name>,
3030 skip : Vec<InternedString>) {
3031 let name = field.node.as_str();
3032 let names = variant.fields.iter().filter_map(|field| {
3033 // ignore already set fields and private fields from non-local crates
3034 if skip.iter().any(|x| *x == field.name.as_str()) ||
3035 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3042 // only find fits with at least one matching letter
3043 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3044 err.span_help(field.span,
3045 &format!("did you mean `{}`?", name));
3049 // Check tuple index expressions
3050 fn check_tup_field(&self,
3051 expr: &'gcx hir::Expr,
3052 lvalue_pref: LvaluePreference,
3053 base: &'gcx hir::Expr,
3054 idx: codemap::Spanned<usize>) {
3055 self.check_expr_with_lvalue_pref(base, lvalue_pref);
3056 let expr_t = self.structurally_resolved_type(expr.span,
3057 self.expr_ty(base));
3058 let mut private_candidate = None;
3059 let mut tuple_like = false;
3060 let mut autoderef = self.autoderef(expr.span, expr_t);
3061 while let Some((base_t, autoderefs)) = autoderef.next() {
3062 let field = match base_t.sty {
3063 ty::TyStruct(base_def, substs) => {
3064 tuple_like = base_def.struct_variant().kind == ty::VariantKind::Tuple;
3065 if !tuple_like { continue }
3067 debug!("tuple struct named {:?}", base_t);
3068 base_def.struct_variant().fields.get(idx.node).and_then(|field| {
3069 let field_ty = self.field_ty(expr.span, field, substs);
3070 private_candidate = Some((base_def.did, field_ty));
3071 if field.vis.is_accessible_from(self.body_id, &self.tcx().map) {
3078 ty::TyTuple(ref v) => {
3080 v.get(idx.node).cloned()
3085 if let Some(field_ty) = field {
3086 autoderef.finalize(lvalue_pref, Some(base));
3087 self.write_ty(expr.id, field_ty);
3088 self.write_autoderef_adjustment(base.id, autoderefs);
3092 autoderef.unambiguous_final_ty();
3094 if let Some((did, field_ty)) = private_candidate {
3095 let struct_path = self.tcx().item_path_str(did);
3096 let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
3097 self.tcx().sess.span_err(expr.span, &msg);
3098 self.write_ty(expr.id, field_ty);
3102 self.type_error_message(
3106 format!("attempted out-of-bounds tuple index `{}` on \
3111 format!("attempted tuple index `{}` on type `{}`, but the \
3112 type was not a tuple or tuple struct",
3119 self.write_error(expr.id);
3122 fn report_unknown_field(&self,
3124 variant: ty::VariantDef<'tcx>,
3126 skip_fields: &[hir::Field]) {
3127 let mut err = self.type_error_struct_with_diag(
3129 |actual| if let ty::TyEnum(..) = ty.sty {
3130 struct_span_err!(self.tcx.sess, field.name.span, E0559,
3131 "struct variant `{}::{}` has no field named `{}`",
3132 actual, variant.name.as_str(), field.name.node)
3134 struct_span_err!(self.tcx.sess, field.name.span, E0560,
3135 "structure `{}` has no field named `{}`",
3136 actual, field.name.node)
3139 // prevent all specified fields from being suggested
3140 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3141 Self::suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3145 fn check_expr_struct_fields(&self,
3148 variant: ty::VariantDef<'tcx>,
3149 ast_fields: &'gcx [hir::Field],
3150 check_completeness: bool) {
3152 let substs = match adt_ty.sty {
3153 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3154 _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields")
3157 let mut remaining_fields = FnvHashMap();
3158 for field in &variant.fields {
3159 remaining_fields.insert(field.name, field);
3162 let mut seen_fields = FnvHashMap();
3164 let mut error_happened = false;
3166 // Typecheck each field.
3167 for field in ast_fields {
3168 let expected_field_type;
3170 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3171 expected_field_type = self.field_ty(field.span, v_field, substs);
3173 seen_fields.insert(field.name.node, field.span);
3175 error_happened = true;
3176 expected_field_type = tcx.types.err;
3177 if let Some(_) = variant.find_field_named(field.name.node) {
3178 let mut err = struct_span_err!(self.tcx.sess,
3181 "field `{}` specified more than once",
3184 err.span_label(field.name.span, &format!("used more than once"));
3186 if let Some(prev_span) = seen_fields.get(&field.name.node) {
3187 err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
3192 self.report_unknown_field(adt_ty, variant, field, ast_fields);
3196 // Make sure to give a type to the field even if there's
3197 // an error, so we can continue typechecking
3198 self.check_expr_coercable_to_type(&field.expr, expected_field_type);
3201 // Make sure the programmer specified all the fields.
3202 if check_completeness &&
3204 !remaining_fields.is_empty()
3206 span_err!(tcx.sess, span, E0063,
3207 "missing field{} {} in initializer of `{}`",
3208 if remaining_fields.len() == 1 {""} else {"s"},
3209 remaining_fields.keys()
3210 .map(|n| format!("`{}`", n))
3211 .collect::<Vec<_>>()
3218 fn check_struct_fields_on_error(&self,
3220 fields: &'gcx [hir::Field],
3221 base_expr: &'gcx Option<P<hir::Expr>>) {
3222 // Make sure to still write the types
3223 // otherwise we might ICE
3224 self.write_error(id);
3225 for field in fields {
3226 self.check_expr(&field.expr);
3229 Some(ref base) => self.check_expr(&base),
3234 pub fn check_struct_path(&self,
3236 node_id: ast::NodeId,
3238 -> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> {
3239 let def = self.finish_resolving_struct_path(path, node_id, span);
3240 let variant = match def {
3242 self.set_tainted_by_errors();
3245 Def::Variant(type_did, _) | Def::Struct(type_did) => {
3246 Some((type_did, self.tcx.expect_variant_def(def)))
3248 Def::TyAlias(did) => {
3249 if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did)
3250 .map(|scheme| &scheme.ty.sty) {
3251 Some((did, adt.struct_variant()))
3259 if let Some((def_id, variant)) = variant {
3260 if variant.kind == ty::VariantKind::Tuple &&
3261 !self.tcx.sess.features.borrow().relaxed_adts {
3262 emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
3263 "relaxed_adts", span, GateIssue::Language,
3264 "tuple structs and variants in struct patterns are unstable");
3266 let ty = self.instantiate_type_path(def_id, path, node_id);
3269 struct_span_err!(self.tcx.sess, path.span, E0071,
3270 "`{}` does not name a struct or a struct variant",
3271 pprust::path_to_string(path))
3272 .span_label(path.span, &format!("not a struct"))
3278 fn check_expr_struct(&self,
3281 fields: &'gcx [hir::Field],
3282 base_expr: &'gcx Option<P<hir::Expr>>)
3284 // Find the relevant variant
3285 let (variant, expr_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id,
3289 self.check_struct_fields_on_error(expr.id, fields, base_expr);
3293 self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
3294 base_expr.is_none());
3295 if let &Some(ref base_expr) = base_expr {
3296 self.check_expr_has_type(base_expr, expr_ty);
3298 ty::TyStruct(adt, substs) => {
3299 self.tables.borrow_mut().fru_field_types.insert(
3301 adt.struct_variant().fields.iter().map(|f| {
3302 self.normalize_associated_types_in(
3303 expr.span, &f.ty(self.tcx, substs)
3309 span_err!(self.tcx.sess, base_expr.span, E0436,
3310 "functional record update syntax requires a struct");
3318 /// If an expression has any sub-expressions that result in a type error,
3319 /// inspecting that expression's type with `ty.references_error()` will return
3320 /// true. Likewise, if an expression is known to diverge, inspecting its
3321 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3322 /// strict, _|_ can appear in the type of an expression that does not,
3323 /// itself, diverge: for example, fn() -> _|_.)
3324 /// Note that inspecting a type's structure *directly* may expose the fact
3325 /// that there are actually multiple representations for `TyError`, so avoid
3326 /// that when err needs to be handled differently.
3327 fn check_expr_with_expectation_and_lvalue_pref(&self,
3328 expr: &'gcx hir::Expr,
3329 expected: Expectation<'tcx>,
3330 lvalue_pref: LvaluePreference) {
3331 debug!(">> typechecking: expr={:?} expected={:?}",
3337 hir::ExprBox(ref subexpr) => {
3338 let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| {
3340 ty::TyBox(ty) => Expectation::rvalue_hint(self, ty),
3344 self.check_expr_with_expectation(subexpr, expected_inner);
3345 let referent_ty = self.expr_ty(&subexpr);
3346 self.write_ty(id, tcx.mk_box(referent_ty));
3349 hir::ExprLit(ref lit) => {
3350 let typ = self.check_lit(&lit, expected);
3351 self.write_ty(id, typ);
3353 hir::ExprBinary(op, ref lhs, ref rhs) => {
3354 self.check_binop(expr, op, lhs, rhs);
3356 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3357 self.check_binop_assign(expr, op, lhs, rhs);
3359 hir::ExprUnary(unop, ref oprnd) => {
3360 let expected_inner = match unop {
3361 hir::UnNot | hir::UnNeg => {
3368 let lvalue_pref = match unop {
3369 hir::UnDeref => lvalue_pref,
3372 self.check_expr_with_expectation_and_lvalue_pref(&oprnd,
3375 let mut oprnd_t = self.expr_ty(&oprnd);
3377 if !oprnd_t.references_error() {
3380 oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
3382 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3384 } else if let Some(method) = self.try_overloaded_deref(
3385 expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3386 oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
3387 self.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3390 self.type_error_message(expr.span, |actual| {
3391 format!("type `{}` cannot be \
3392 dereferenced", actual)
3394 oprnd_t = tcx.types.err;
3398 oprnd_t = self.structurally_resolved_type(oprnd.span,
3400 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3401 oprnd_t = self.check_user_unop("!", "not",
3402 tcx.lang_items.not_trait(),
3403 expr, &oprnd, oprnd_t, unop);
3407 oprnd_t = self.structurally_resolved_type(oprnd.span,
3409 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3410 oprnd_t = self.check_user_unop("-", "neg",
3411 tcx.lang_items.neg_trait(),
3412 expr, &oprnd, oprnd_t, unop);
3417 self.write_ty(id, oprnd_t);
3419 hir::ExprAddrOf(mutbl, ref oprnd) => {
3420 let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
3422 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3423 if self.tcx.expr_is_lval(&oprnd) {
3424 // Lvalues may legitimately have unsized types.
3425 // For example, dereferences of a fat pointer and
3426 // the last field of a struct can be unsized.
3427 ExpectHasType(mt.ty)
3429 Expectation::rvalue_hint(self, mt.ty)
3435 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3436 self.check_expr_with_expectation_and_lvalue_pref(&oprnd, hint, lvalue_pref);
3438 let tm = ty::TypeAndMut { ty: self.expr_ty(&oprnd), mutbl: mutbl };
3439 let oprnd_t = if tm.ty.references_error() {
3442 // Note: at this point, we cannot say what the best lifetime
3443 // is to use for resulting pointer. We want to use the
3444 // shortest lifetime possible so as to avoid spurious borrowck
3445 // errors. Moreover, the longest lifetime will depend on the
3446 // precise details of the value whose address is being taken
3447 // (and how long it is valid), which we don't know yet until type
3448 // inference is complete.
3450 // Therefore, here we simply generate a region variable. The
3451 // region inferencer will then select the ultimate value.
3452 // Finally, borrowck is charged with guaranteeing that the
3453 // value whose address was taken can actually be made to live
3454 // as long as it needs to live.
3455 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
3456 tcx.mk_ref(region, tm)
3458 self.write_ty(id, oprnd_t);
3460 hir::ExprPath(ref opt_qself, ref path) => {
3461 let opt_self_ty = opt_qself.as_ref().map(|qself| self.to_ty(&qself.ty));
3462 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path,
3463 expr.id, expr.span);
3464 if def != Def::Err {
3465 self.instantiate_value_path(segments, opt_ty, def, expr.span, id);
3467 self.set_tainted_by_errors();
3468 self.write_error(id);
3471 // We always require that the type provided as the value for
3472 // a type parameter outlives the moment of instantiation.
3473 self.opt_node_ty_substs(expr.id, |item_substs| {
3474 self.add_wf_bounds(&item_substs.substs, expr);
3477 hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
3478 for output in outputs {
3479 self.check_expr(output);
3481 for input in inputs {
3482 self.check_expr(input);
3486 hir::ExprBreak(_) => { self.write_never(id); }
3487 hir::ExprAgain(_) => { self.write_never(id); }
3488 hir::ExprRet(ref expr_opt) => {
3489 if let Some(ref e) = *expr_opt {
3490 self.check_expr_coercable_to_type(&e, self.ret_ty);
3492 let eq_result = self.eq_types(false,
3493 TypeOrigin::Misc(expr.span),
3496 // FIXME(#32730) propagate obligations
3497 .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
3498 if eq_result.is_err() {
3499 struct_span_err!(tcx.sess, expr.span, E0069,
3500 "`return;` in a function whose return type is not `()`")
3501 .span_label(expr.span, &format!("return type is not ()"))
3505 self.write_never(id);
3507 hir::ExprAssign(ref lhs, ref rhs) => {
3508 self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
3511 if !tcx.expr_is_lval(&lhs) {
3513 tcx.sess, expr.span, E0070,
3514 "invalid left-hand side expression")
3517 &format!("left-hand of expression not valid"))
3521 let lhs_ty = self.expr_ty(&lhs);
3522 self.check_expr_coercable_to_type(&rhs, lhs_ty);
3523 let rhs_ty = self.expr_ty(&rhs);
3525 self.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3527 if lhs_ty.references_error() || rhs_ty.references_error() {
3528 self.write_error(id);
3533 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3534 self.check_then_else(&cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3535 id, expr.span, expected);
3537 hir::ExprWhile(ref cond, ref body, _) => {
3538 self.check_expr_has_type(&cond, tcx.types.bool);
3539 self.check_block_no_value(&body);
3540 let cond_ty = self.expr_ty(&cond);
3541 let body_ty = self.node_ty(body.id);
3542 if cond_ty.references_error() || body_ty.references_error() {
3543 self.write_error(id);
3549 hir::ExprLoop(ref body, _) => {
3550 self.check_block_no_value(&body);
3551 if !may_break(tcx, expr.id, &body) {
3552 self.write_never(id);
3557 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3558 self.check_match(expr, &discrim, arms, expected, match_src);
3560 hir::ExprClosure(capture, ref decl, ref body, _) => {
3561 self.check_expr_closure(expr, capture, &decl, &body, expected);
3563 hir::ExprBlock(ref b) => {
3564 self.check_block_with_expected(&b, expected);
3565 self.write_ty(id, self.node_ty(b.id));
3567 hir::ExprCall(ref callee, ref args) => {
3568 self.check_call(expr, &callee, &args[..], expected);
3570 // we must check that return type of called functions is WF:
3571 let ret_ty = self.expr_ty(expr);
3572 self.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3574 hir::ExprMethodCall(name, ref tps, ref args) => {
3575 self.check_method_call(expr, name, &args[..], &tps[..], expected, lvalue_pref);
3576 let arg_tys = args.iter().map(|a| self.expr_ty(&a));
3577 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3579 self.write_error(id);
3582 hir::ExprCast(ref e, ref t) => {
3583 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3584 self.check_expr_with_hint(&count_expr, tcx.types.usize);
3587 // Find the type of `e`. Supply hints based on the type we are casting to,
3589 let t_cast = self.to_ty(t);
3590 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3591 self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
3592 let t_expr = self.expr_ty(e);
3593 let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3595 // Eagerly check for some obvious errors.
3596 if t_expr.references_error() || t_cast.references_error() {
3597 self.write_error(id);
3599 // Write a type for the whole expression, assuming everything is going
3601 self.write_ty(id, t_cast);
3603 // Defer other checks until we're done type checking.
3604 let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3605 match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3607 deferred_cast_checks.push(cast_check);
3609 Err(ErrorReported) => {
3610 self.write_error(id);
3615 hir::ExprType(ref e, ref t) => {
3616 let typ = self.to_ty(&t);
3617 self.check_expr_eq_type(&e, typ);
3618 self.write_ty(id, typ);
3620 hir::ExprVec(ref args) => {
3621 let uty = expected.to_option(self).and_then(|uty| {
3623 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3628 let mut unified = self.next_ty_var();
3629 let coerce_to = uty.unwrap_or(unified);
3631 for (i, e) in args.iter().enumerate() {
3632 self.check_expr_with_hint(e, coerce_to);
3633 let e_ty = self.expr_ty(e);
3634 let origin = TypeOrigin::Misc(e.span);
3636 // Special-case the first element, as it has no "previous expressions".
3637 let result = if i == 0 {
3638 self.try_coerce(e, coerce_to)
3640 let prev_elems = || args[..i].iter().map(|e| &**e);
3641 self.try_find_coercion_lub(origin, prev_elems, unified, e)
3645 Ok(ty) => unified = ty,
3647 self.report_mismatched_types(origin, unified, e_ty, e);
3651 self.write_ty(id, tcx.mk_array(unified, args.len()));
3653 hir::ExprRepeat(ref element, ref count_expr) => {
3654 self.check_expr_has_type(&count_expr, tcx.types.usize);
3655 let count = eval_length(self.tcx.global_tcx(), &count_expr, "repeat count")
3658 let uty = match expected {
3659 ExpectHasType(uty) => {
3661 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3668 let (element_ty, t) = match uty {
3670 self.check_expr_coercable_to_type(&element, uty);
3674 let t: Ty = self.next_ty_var();
3675 self.check_expr_has_type(&element, t);
3676 (self.expr_ty(&element), t)
3681 // For [foo, ..n] where n > 1, `foo` must have
3683 self.require_type_meets(t, expr.span, traits::RepeatVec, ty::BoundCopy);
3686 if element_ty.references_error() {
3687 self.write_error(id);
3689 let t = tcx.mk_array(t, count);
3690 self.write_ty(id, t);
3693 hir::ExprTup(ref elts) => {
3694 let flds = expected.only_has_type(self).and_then(|ty| {
3696 ty::TyTuple(ref flds) => Some(&flds[..]),
3700 let mut err_field = false;
3702 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3703 let t = match flds {
3704 Some(ref fs) if i < fs.len() => {
3706 self.check_expr_coercable_to_type(&e, ety);
3710 self.check_expr_with_expectation(&e, NoExpectation);
3714 err_field = err_field || t.references_error();
3718 self.write_error(id);
3720 let typ = tcx.mk_tup(elt_ts);
3721 self.write_ty(id, typ);
3724 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3725 self.check_expr_struct(expr, path, fields, base_expr);
3727 self.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3729 hir::ExprField(ref base, ref field) => {
3730 self.check_field(expr, lvalue_pref, &base, field);
3732 hir::ExprTupField(ref base, idx) => {
3733 self.check_tup_field(expr, lvalue_pref, &base, idx);
3735 hir::ExprIndex(ref base, ref idx) => {
3736 self.check_expr_with_lvalue_pref(&base, lvalue_pref);
3737 self.check_expr(&idx);
3739 let base_t = self.expr_ty(&base);
3740 let idx_t = self.expr_ty(&idx);
3742 if base_t.references_error() {
3743 self.write_ty(id, base_t);
3744 } else if idx_t.references_error() {
3745 self.write_ty(id, idx_t);
3747 let base_t = self.structurally_resolved_type(expr.span, base_t);
3748 match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) {
3749 Some((index_ty, element_ty)) => {
3750 let idx_expr_ty = self.expr_ty(idx);
3751 self.demand_eqtype(expr.span, index_ty, idx_expr_ty);
3752 self.write_ty(id, element_ty);
3755 self.check_expr_has_type(&idx, self.tcx.types.err);
3756 let mut err = self.type_error_struct(
3759 format!("cannot index a value of type `{}`",
3763 // Try to give some advice about indexing tuples.
3764 if let ty::TyTuple(_) = base_t.sty {
3765 let mut needs_note = true;
3766 // If the index is an integer, we can show the actual
3767 // fixed expression:
3768 if let hir::ExprLit(ref lit) = idx.node {
3769 if let ast::LitKind::Int(i,
3770 ast::LitIntType::Unsuffixed) = lit.node {
3771 let snip = tcx.sess.codemap().span_to_snippet(base.span);
3772 if let Ok(snip) = snip {
3773 err.span_suggestion(expr.span,
3774 "to access tuple elements, \
3775 use tuple indexing syntax \
3777 format!("{}.{}", snip, i));
3783 err.help("to access tuple elements, use tuple indexing \
3784 syntax (e.g. `tuple.0`)");
3788 self.write_ty(id, self.tcx().types.err);
3795 debug!("type of expr({}) {} is...", expr.id,
3796 pprust::expr_to_string(expr));
3797 debug!("... {:?}, expected is {:?}",
3802 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
3803 // The newly resolved definition is written into `def_map`.
3804 pub fn finish_resolving_struct_path(&self,
3806 node_id: ast::NodeId,
3810 let path_res = self.tcx().expect_resolution(node_id);
3811 if path_res.depth == 0 {
3812 // If fully resolved already, we don't have to do anything.
3815 let base_ty_end = path.segments.len() - path_res.depth;
3816 let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span,
3817 PathParamMode::Optional,
3821 &path.segments[..base_ty_end],
3822 &path.segments[base_ty_end..]);
3823 // Write back the new resolution.
3824 self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
3829 // Resolve associated value path into a base type and associated constant or method definition.
3830 // The newly resolved definition is written into `def_map`.
3831 pub fn resolve_ty_and_def_ufcs<'b>(&self,
3832 opt_self_ty: Option<Ty<'tcx>>,
3833 path: &'b hir::Path,
3834 node_id: ast::NodeId,
3836 -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
3838 let path_res = self.tcx().expect_resolution(node_id);
3839 if path_res.depth == 0 {
3840 // If fully resolved already, we don't have to do anything.
3841 (path_res.base_def, opt_self_ty, &path.segments)
3843 // Try to resolve everything except for the last segment as a type.
3844 let ty_segments = path.segments.split_last().unwrap().1;
3845 let base_ty_end = path.segments.len() - path_res.depth;
3846 let (ty, _def) = AstConv::finish_resolving_def_to_ty(self, self, span,
3847 PathParamMode::Optional,
3851 &ty_segments[..base_ty_end],
3852 &ty_segments[base_ty_end..]);
3854 // Resolve an associated constant or method on the previously resolved type.
3855 let item_segment = path.segments.last().unwrap();
3856 let item_name = item_segment.name;
3857 let def = match self.resolve_ufcs(span, item_name, ty, node_id) {
3860 let def = match error {
3861 method::MethodError::PrivateMatch(def) => def,
3864 if item_name != keywords::Invalid.name() {
3865 self.report_method_error(span, ty, item_name, None, error);
3871 // Write back the new resolution.
3872 self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
3873 (def, Some(ty), slice::ref_slice(item_segment))
3877 pub fn check_decl_initializer(&self,
3878 local: &'gcx hir::Local,
3879 init: &'gcx hir::Expr)
3881 let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat);
3883 let local_ty = self.local_ty(init.span, local.id);
3884 if let Some(m) = ref_bindings {
3885 // Somewhat subtle: if we have a `ref` binding in the pattern,
3886 // we want to avoid introducing coercions for the RHS. This is
3887 // both because it helps preserve sanity and, in the case of
3888 // ref mut, for soundness (issue #23116). In particular, in
3889 // the latter case, we need to be clear that the type of the
3890 // referent for the reference that results is *equal to* the
3891 // type of the lvalue it is referencing, and not some
3892 // supertype thereof.
3893 self.check_expr_with_lvalue_pref(init, LvaluePreference::from_mutbl(m));
3894 let init_ty = self.expr_ty(init);
3895 self.demand_eqtype(init.span, init_ty, local_ty);
3897 self.check_expr_coercable_to_type(init, local_ty)
3901 pub fn check_decl_local(&self, local: &'gcx hir::Local) {
3902 let t = self.local_ty(local.span, local.id);
3903 self.write_ty(local.id, t);
3905 if let Some(ref init) = local.init {
3906 self.check_decl_initializer(local, &init);
3907 let init_ty = self.expr_ty(&init);
3908 if init_ty.references_error() {
3909 self.write_ty(local.id, init_ty);
3913 self.check_pat(&local.pat, t);
3914 let pat_ty = self.node_ty(local.pat.id);
3915 if pat_ty.references_error() {
3916 self.write_ty(local.id, pat_ty);
3920 pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
3922 let mut saw_bot = false;
3923 let mut saw_err = false;
3925 hir::StmtDecl(ref decl, id) => {
3928 hir::DeclLocal(ref l) => {
3929 self.check_decl_local(&l);
3930 let l_t = self.node_ty(l.id);
3931 saw_bot = saw_bot || self.type_var_diverges(l_t);
3932 saw_err = saw_err || l_t.references_error();
3934 hir::DeclItem(_) => {/* ignore for now */ }
3937 hir::StmtExpr(ref expr, id) => {
3939 // Check with expected type of ()
3940 self.check_expr_has_type(&expr, self.tcx.mk_nil());
3941 let expr_ty = self.expr_ty(&expr);
3942 saw_bot = saw_bot || self.type_var_diverges(expr_ty);
3943 saw_err = saw_err || expr_ty.references_error();
3945 hir::StmtSemi(ref expr, id) => {
3947 self.check_expr(&expr);
3948 let expr_ty = self.expr_ty(&expr);
3949 saw_bot |= self.type_var_diverges(expr_ty);
3950 saw_err |= expr_ty.references_error();
3954 self.write_ty(node_id, self.next_diverging_ty_var());
3957 self.write_error(node_id);
3960 self.write_nil(node_id)
3964 pub fn check_block_no_value(&self, blk: &'gcx hir::Block) {
3965 self.check_block_with_expected(blk, ExpectHasType(self.tcx.mk_nil()));
3966 let blkty = self.node_ty(blk.id);
3967 if blkty.references_error() {
3968 self.write_error(blk.id);
3970 let nilty = self.tcx.mk_nil();
3971 self.demand_suptype(blk.span, nilty, blkty);
3975 fn check_block_with_expected(&self,
3976 blk: &'gcx hir::Block,
3977 expected: Expectation<'tcx>) {
3979 let mut fcx_ps = self.ps.borrow_mut();
3980 let unsafety_state = fcx_ps.recurse(blk);
3981 replace(&mut *fcx_ps, unsafety_state)
3984 let mut warned = false;
3985 let mut any_diverges = false;
3986 let mut any_err = false;
3987 for s in &blk.stmts {
3989 let s_id = s.node.id();
3990 let s_ty = self.node_ty(s_id);
3991 if any_diverges && !warned && match s.node {
3992 hir::StmtDecl(ref decl, _) => {
3994 hir::DeclLocal(_) => true,
3998 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4002 .add_lint(lint::builtin::UNREACHABLE_CODE,
4005 "unreachable statement".to_string());
4008 // FIXME(canndrew): This is_never should probably be an is_uninhabited
4009 any_diverges = any_diverges ||
4010 self.type_var_diverges(s_ty) ||
4012 any_err = any_err || s_ty.references_error();
4015 None => if any_err {
4016 self.write_error(blk.id);
4017 } else if any_diverges {
4018 self.write_ty(blk.id, self.next_diverging_ty_var());
4020 self.write_nil(blk.id);
4023 if any_diverges && !warned {
4026 .add_lint(lint::builtin::UNREACHABLE_CODE,
4029 "unreachable expression".to_string());
4031 let ety = match expected {
4032 ExpectHasType(ety) => {
4033 self.check_expr_coercable_to_type(&e, ety);
4037 self.check_expr_with_expectation(&e, expected);
4043 self.write_error(blk.id);
4044 } else if any_diverges {
4045 self.write_ty(blk.id, self.next_diverging_ty_var());
4047 self.write_ty(blk.id, ety);
4052 *self.ps.borrow_mut() = prev;
4055 // Instantiates the given path, which must refer to an item with the given
4056 // number of type parameters and type.
4057 pub fn instantiate_value_path(&self,
4058 segments: &[hir::PathSegment],
4059 opt_self_ty: Option<Ty<'tcx>>,
4062 node_id: ast::NodeId)
4064 debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
4069 // We need to extract the type parameters supplied by the user in
4070 // the path `path`. Due to the current setup, this is a bit of a
4071 // tricky-process; the problem is that resolve only tells us the
4072 // end-point of the path resolution, and not the intermediate steps.
4073 // Luckily, we can (at least for now) deduce the intermediate steps
4074 // just from the end-point.
4076 // There are basically four cases to consider:
4078 // 1. Reference to a *type*, such as a struct or enum:
4080 // mod a { struct Foo<T> { ... } }
4082 // Because we don't allow types to be declared within one
4083 // another, a path that leads to a type will always look like
4084 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4085 // that only the final segment can have type parameters, and
4086 // they are located in the TypeSpace.
4088 // *Note:* Generally speaking, references to types don't
4089 // actually pass through this function, but rather the
4090 // `ast_ty_to_ty` function in `astconv`. However, in the case
4091 // of struct patterns (and maybe literals) we do invoke
4092 // `instantiate_value_path` to get the general type of an instance of
4093 // a struct. (In these cases, there are actually no type
4094 // parameters permitted at present, but perhaps we will allow
4095 // them in the future.)
4097 // 1b. Reference to an enum variant or tuple-like struct:
4099 // struct foo<T>(...)
4100 // enum E<T> { foo(...) }
4102 // In these cases, the parameters are declared in the type
4105 // 2. Reference to a *fn item*:
4109 // In this case, the path will again always have the form
4110 // `a::b::foo::<T>` where only the final segment should have
4111 // type parameters. However, in this case, those parameters are
4112 // declared on a value, and hence are in the `FnSpace`.
4114 // 3. Reference to a *method*:
4116 // impl<A> SomeStruct<A> {
4120 // Here we can have a path like
4121 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4122 // may appear in two places. The penultimate segment,
4123 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4124 // final segment, `foo::<B>` contains parameters in fn space.
4126 // 4. Reference to an *associated const*:
4128 // impl<A> AnotherStruct<A> {
4129 // const FOO: B = BAR;
4132 // The path in this case will look like
4133 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4134 // only will have parameters in TypeSpace.
4136 // The first step then is to categorize the segments appropriately.
4138 assert!(!segments.is_empty());
4140 let mut ufcs_associated = None;
4141 let mut type_segment = None;
4142 let mut fn_segment = None;
4144 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4145 Def::Struct(def_id) |
4146 Def::Variant(_, def_id) |
4148 Def::TyAlias(def_id) |
4149 Def::AssociatedTy(_, def_id) |
4150 Def::Trait(def_id) => {
4151 // Everything but the final segment should have no
4152 // parameters at all.
4153 let mut generics = self.tcx.lookup_generics(def_id);
4154 if let Some(def_id) = generics.parent {
4155 // Variant and struct constructors use the
4156 // generics of their parent type definition.
4157 generics = self.tcx.lookup_generics(def_id);
4159 type_segment = Some((segments.last().unwrap(), generics));
4162 // Case 2. Reference to a top-level value.
4164 Def::Const(def_id) |
4165 Def::Static(def_id, _) => {
4166 fn_segment = Some((segments.last().unwrap(),
4167 self.tcx.lookup_generics(def_id)));
4170 // Case 3. Reference to a method or associated const.
4171 Def::Method(def_id) |
4172 Def::AssociatedConst(def_id) => {
4173 let container = self.tcx.impl_or_trait_item(def_id).container();
4175 ty::TraitContainer(trait_did) => {
4176 callee::check_legal_trait_for_method_call(self.ccx, span, trait_did)
4178 ty::ImplContainer(_) => {}
4181 let generics = self.tcx.lookup_generics(def_id);
4182 if segments.len() >= 2 {
4183 let parent_generics = self.tcx.lookup_generics(generics.parent.unwrap());
4184 type_segment = Some((&segments[segments.len() - 2], parent_generics));
4186 // `<T>::assoc` will end up here, and so can `T::assoc`.
4187 let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
4188 ufcs_associated = Some((container, self_ty));
4190 fn_segment = Some((segments.last().unwrap(), generics));
4193 // Other cases. Various nonsense that really shouldn't show up
4194 // here. If they do, an error will have been reported
4195 // elsewhere. (I hope)
4197 Def::ForeignMod(..) |
4207 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4208 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4209 // type parameters are not mandatory.
4210 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4212 debug!("type_segment={:?} fn_segment={:?}", type_segment, fn_segment);
4214 // Now that we have categorized what space the parameters for each
4215 // segment belong to, let's sort out the parameters that the user
4216 // provided (if any) into their appropriate spaces. We'll also report
4217 // errors if type parameters are provided in an inappropriate place.
4218 let poly_segments = type_segment.is_some() as usize +
4219 fn_segment.is_some() as usize;
4220 self.tcx.prohibit_type_params(&segments[..segments.len() - poly_segments]);
4223 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4224 let ty = self.local_ty(span, nid);
4225 let ty = self.normalize_associated_types_in(span, &ty);
4226 self.write_ty(node_id, ty);
4227 self.write_substs(node_id, ty::ItemSubsts {
4228 substs: Substs::empty(self.tcx)
4235 // Now we have to compare the types that the user *actually*
4236 // provided against the types that were *expected*. If the user
4237 // did not provide any types, then we want to substitute inference
4238 // variables. If the user provided some types, we may still need
4239 // to add defaults. If the user provided *too many* types, that's
4241 self.check_path_parameter_count(span, !require_type_space, &mut type_segment);
4242 self.check_path_parameter_count(span, true, &mut fn_segment);
4244 let (fn_start, has_self) = match (type_segment, fn_segment) {
4245 (_, Some((_, generics))) => {
4246 (generics.parent_count(), generics.has_self)
4248 (Some((_, generics)), None) => {
4249 (generics.own_count(), generics.has_self)
4251 (None, None) => (0, false)
4253 let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
4254 let mut i = def.index as usize;
4256 let segment = if i < fn_start {
4257 i -= has_self as usize;
4263 let lifetimes = match segment.map(|(s, _)| &s.parameters) {
4264 Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
4265 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4269 if let Some(ast_lifetime) = lifetimes.get(i) {
4270 ast_region_to_region(self.tcx, ast_lifetime)
4272 self.region_var_for_def(span, def)
4275 let mut i = def.index as usize;
4277 let can_omit = i >= fn_start || !require_type_space;
4278 let segment = if i < fn_start {
4279 // Handle Self first, so we can adjust the index to match the AST.
4280 if has_self && i == 0 {
4281 return opt_self_ty.unwrap_or_else(|| {
4282 self.type_var_for_def(span, def, substs)
4285 i -= has_self as usize;
4291 let types = match segment.map(|(s, _)| &s.parameters) {
4292 Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
4293 Some(&hir::ParenthesizedParameters(_)) => bug!(),
4297 // Skip over the lifetimes in the same segment.
4298 if let Some((_, generics)) = segment {
4299 i -= generics.regions.len();
4302 let omitted = can_omit && types.is_empty();
4303 if let Some(ast_ty) = types.get(i) {
4304 // A provided type parameter.
4306 } else if let (false, Some(default)) = (omitted, def.default) {
4307 // No type parameter provided, but a default exists.
4308 default.subst_spanned(self.tcx, substs, Some(span))
4310 // No type parameters were provided, we can infer all.
4311 // This can also be reached in some error cases:
4312 // We prefer to use inference variables instead of
4313 // TyError to let type inference recover somewhat.
4314 self.type_var_for_def(span, def, substs)
4318 // The things we are substituting into the type should not contain
4319 // escaping late-bound regions, and nor should the base type scheme.
4320 let scheme = self.tcx.lookup_item_type(def.def_id());
4321 let type_predicates = self.tcx.lookup_predicates(def.def_id());
4322 assert!(!substs.has_escaping_regions());
4323 assert!(!scheme.ty.has_escaping_regions());
4325 // Add all the obligations that are required, substituting and
4326 // normalized appropriately.
4327 let bounds = self.instantiate_bounds(span, &substs, &type_predicates);
4328 self.add_obligations_for_parameters(
4329 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def.def_id())),
4332 // Substitute the values for the type parameters into the type of
4333 // the referenced item.
4334 let ty_substituted = self.instantiate_type_scheme(span, &substs, &scheme.ty);
4337 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4338 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4339 // is inherent, there is no `Self` parameter, instead, the impl needs
4340 // type parameters, which we can infer by unifying the provided `Self`
4341 // with the substituted impl type.
4342 let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
4344 let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4345 match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
4346 Ok(InferOk { obligations, .. }) => {
4347 // FIXME(#32730) propagate obligations
4348 assert!(obligations.is_empty());
4352 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4359 debug!("instantiate_value_path: type of {:?} is {:?}",
4362 self.write_ty(node_id, ty_substituted);
4363 self.write_substs(node_id, ty::ItemSubsts {
4369 /// Report errors if the provided parameters are too few or too many.
4370 fn check_path_parameter_count(&self,
4373 segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4374 let (lifetimes, types, bindings) = match segment.map(|(s, _)| &s.parameters) {
4375 Some(&hir::AngleBracketedParameters(ref data)) => {
4376 (&data.lifetimes[..], &data.types[..], &data.bindings[..])
4378 Some(&hir::ParenthesizedParameters(_)) => {
4379 span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
4381 None => (&[][..], &[][..], &[][..])
4385 format!("{} parameter{}", n, if n == 1 { "" } else { "s" })
4388 // Check provided lifetime parameters.
4389 let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
4390 if lifetimes.len() > lifetime_defs.len() {
4391 let span = lifetimes[lifetime_defs.len()].span;
4392 span_err!(self.tcx.sess, span, E0088,
4393 "too many lifetime parameters provided: \
4394 expected {}, found {}",
4395 count(lifetime_defs.len()),
4396 count(lifetimes.len()));
4397 } else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
4398 span_err!(self.tcx.sess, span, E0090,
4399 "too few lifetime parameters provided: \
4400 expected {}, found {}",
4401 count(lifetime_defs.len()),
4402 count(lifetimes.len()));
4405 // Check provided type parameters.
4406 let type_defs = segment.map_or(&[][..], |(_, generics)| {
4407 if generics.parent.is_none() {
4408 &generics.types[generics.has_self as usize..]
4413 let required_len = type_defs.iter()
4414 .take_while(|d| d.default.is_none())
4416 if types.len() > type_defs.len() {
4417 let span = types[type_defs.len()].span;
4418 struct_span_err!(self.tcx.sess, span, E0087,
4419 "too many type parameters provided: \
4420 expected at most {}, found {}",
4421 count(type_defs.len()),
4423 .span_label(span, &format!("too many type parameters")).emit();
4425 // To prevent derived errors to accumulate due to extra
4426 // type parameters, we force instantiate_value_path to
4427 // use inference variables instead of the provided types.
4429 } else if !(can_omit && types.len() == 0) && types.len() < required_len {
4430 let adjust = |len| if len > 1 { "parameters" } else { "parameter" };
4431 let required_param_str = adjust(required_len);
4432 let actual_param_str = adjust(types.len());
4433 struct_span_err!(self.tcx.sess, span, E0089,
4434 "too few type parameters provided: \
4435 expected {} {}, found {} {}",
4436 count(required_len),
4440 .span_label(span, &format!("expected {} type {}", required_len, required_param_str))
4444 if !bindings.is_empty() {
4445 span_err!(self.tcx.sess, bindings[0].span, E0182,
4446 "unexpected binding of associated item in expression path \
4447 (only allowed in type paths)");
4451 fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
4453 where F: Fn() -> Ty<'tcx>
4455 let mut ty = self.resolve_type_vars_with_obligations(ty);
4458 let alternative = f();
4461 if alternative.is_ty_var() || alternative.references_error() {
4462 if !self.is_tainted_by_errors() {
4463 self.type_error_message(sp, |_actual| {
4464 "the type of this value must be known in this context".to_string()
4467 self.demand_suptype(sp, self.tcx.types.err, ty);
4468 ty = self.tcx.types.err;
4470 self.demand_suptype(sp, alternative, ty);
4478 // Resolves `typ` by a single level if `typ` is a type variable. If no
4479 // resolution is possible, then an error is reported.
4480 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4481 self.structurally_resolve_type_or_else(sp, ty, || {
4487 // Returns true if b contains a break that can exit from b
4488 pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4489 // First: is there an unlabeled break immediately
4491 (loop_query(&b, |e| {
4493 hir::ExprBreak(None) => true,
4497 // Second: is there a labeled break with label
4498 // <id> nested anywhere inside the loop?
4499 (block_query(b, |e| {
4500 if let hir::ExprBreak(Some(_)) = e.node {
4501 tcx.expect_def(e.id) == Def::Label(id)
4508 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4509 generics: &hir::Generics,
4511 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4512 generics.ty_params.len(), ty);
4514 // make a vector of booleans initially false, set to true when used
4515 if generics.ty_params.is_empty() { return; }
4516 let mut tps_used = vec![false; generics.ty_params.len()];
4518 for leaf_ty in ty.walk() {
4519 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4520 debug!("Found use of ty param num {}", idx);
4521 tps_used[idx as usize - generics.lifetimes.len()] = true;
4525 for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
4527 struct_span_err!(ccx.tcx.sess, param.span, E0091,
4528 "type parameter `{}` is unused",
4530 .span_label(param.span, &format!("unused type parameter"))