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::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
84 use check::_match::pat_ctxt;
85 use fmt_macros::{Parser, Piece, Position};
86 use metadata::cstore::LOCAL_CRATE;
87 use middle::astconv_util::prohibit_type_params;
89 use middle::def_id::DefId;
91 use middle::infer::type_variable;
92 use middle::pat_util::{self, pat_id_map};
93 use middle::privacy::{AllPublic, LastMod};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
97 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
100 use middle::ty::{MethodCall, MethodCallee};
101 use middle::ty::adjustment;
102 use middle::ty::error::TypeError;
103 use middle::ty::fold::{TypeFolder, TypeFoldable};
104 use middle::ty::util::Representability;
105 use require_c_abi_if_variadic;
106 use rscope::{ElisionFailureInfo, RegionScope};
107 use session::Session;
108 use {CrateCtxt, lookup_full_def};
111 use util::common::{block_query, ErrorReported, indenter, loop_query};
112 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
113 use util::lev_distance::lev_distance;
115 use std::cell::{Cell, Ref, RefCell};
116 use std::collections::{HashSet};
117 use std::mem::replace;
121 use syntax::attr::AttrMetaMethods;
122 use syntax::codemap::{self, Span, Spanned};
123 use syntax::owned_slice::OwnedSlice;
124 use syntax::parse::token::{self, InternedString};
127 use rustc_front::visit::{self, Visitor};
128 use rustc_front::hir;
129 use rustc_front::hir::Visibility;
130 use rustc_front::hir::{Item, ItemImpl};
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
152 /// closures defined within the function. For example:
155 /// bar(move|| { ... })
158 /// Here, the function `foo()` and the closure passed to
159 /// `bar()` will each have their own `FnCtxt`, but they will
160 /// share the inherited fields.
161 pub struct Inherited<'a, 'tcx: 'a> {
162 infcx: infer::InferCtxt<'a, 'tcx>,
163 locals: RefCell<NodeMap<Ty<'tcx>>>,
165 tables: &'a RefCell<ty::Tables<'tcx>>,
167 // When we process a call like `c()` where `c` is a closure type,
168 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
169 // `FnOnce` closure. In that case, we defer full resolution of the
170 // call until upvar inference can kick in and make the
171 // decision. We keep these deferred resolutions grouped by the
172 // def-id of the closure, so that once we decide, we can easily go
173 // back and process them.
174 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
176 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
179 trait DeferredCallResolution<'tcx> {
180 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
183 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
185 /// When type-checking an expression, we propagate downward
186 /// whatever type hint we are able in the form of an `Expectation`.
187 #[derive(Copy, Clone, Debug)]
188 pub enum Expectation<'tcx> {
189 /// We know nothing about what type this expression should have.
192 /// This expression should have the type given (or some subtype)
193 ExpectHasType(Ty<'tcx>),
195 /// This expression will be cast to the `Ty`
196 ExpectCastableToType(Ty<'tcx>),
198 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
199 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
200 ExpectRvalueLikeUnsized(Ty<'tcx>),
203 impl<'tcx> Expectation<'tcx> {
204 // Disregard "castable to" expectations because they
205 // can lead us astray. Consider for example `if cond
206 // {22} else {c} as u8` -- if we propagate the
207 // "castable to u8" constraint to 22, it will pick the
208 // type 22u8, which is overly constrained (c might not
209 // be a u8). In effect, the problem is that the
210 // "castable to" expectation is not the tightest thing
211 // we can say, so we want to drop it in this case.
212 // The tightest thing we can say is "must unify with
213 // else branch". Note that in the case of a "has type"
214 // constraint, this limitation does not hold.
216 // If the expected type is just a type variable, then don't use
217 // an expected type. Otherwise, we might write parts of the type
218 // when checking the 'then' block which are incompatible with the
220 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
222 ExpectHasType(ety) => {
223 let ety = fcx.infcx().shallow_resolve(ety);
224 if !ety.is_ty_var() {
230 ExpectRvalueLikeUnsized(ety) => {
231 ExpectRvalueLikeUnsized(ety)
238 #[derive(Copy, Clone)]
239 pub struct UnsafetyState {
240 pub def: ast::NodeId,
241 pub unsafety: hir::Unsafety,
242 pub unsafe_push_count: u32,
247 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
248 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
251 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
252 match self.unsafety {
253 // If this unsafe, then if the outer function was already marked as
254 // unsafe we shouldn't attribute the unsafe'ness to the block. This
255 // way the block can be warned about instead of ignoring this
256 // extraneous block (functions are never warned about).
257 hir::Unsafety::Unsafe if self.from_fn => *self,
260 let (unsafety, def, count) = match blk.rules {
261 hir::PushUnsafeBlock(..) =>
262 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
263 hir::PopUnsafeBlock(..) =>
264 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
265 hir::UnsafeBlock(..) =>
266 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
267 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
268 (unsafety, self.def, self.unsafe_push_count),
270 UnsafetyState{ def: def,
272 unsafe_push_count: count,
280 pub struct FnCtxt<'a, 'tcx: 'a> {
281 body_id: ast::NodeId,
283 // This flag is set to true if, during the writeback phase, we encounter
284 // a type error in this function.
285 writeback_errors: Cell<bool>,
287 // Number of errors that had been reported when we started
288 // checking this function. On exit, if we find that *more* errors
289 // have been reported, we will skip regionck and other work that
290 // expects the types within the function to be consistent.
291 err_count_on_creation: usize,
293 ret_ty: ty::FnOutput<'tcx>,
295 ps: RefCell<UnsafetyState>,
297 inh: &'a Inherited<'a, 'tcx>,
299 ccx: &'a CrateCtxt<'a, 'tcx>,
302 impl<'a, 'tcx> Inherited<'a, 'tcx> {
303 fn new(tcx: &'a ty::ctxt<'tcx>,
304 tables: &'a RefCell<ty::Tables<'tcx>>,
305 param_env: ty::ParameterEnvironment<'a, 'tcx>)
306 -> Inherited<'a, 'tcx> {
309 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
310 locals: RefCell::new(NodeMap()),
312 deferred_call_resolutions: RefCell::new(DefIdMap()),
313 deferred_cast_checks: RefCell::new(Vec::new()),
317 fn normalize_associated_types_in<T>(&self,
319 body_id: ast::NodeId,
322 where T : TypeFoldable<'tcx> + HasTypeFlags
324 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
325 assoc::normalize_associated_types_in(&self.infcx,
334 // Used by check_const and check_enum_variants
335 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
336 inh: &'a Inherited<'a, 'tcx>,
337 rty: ty::FnOutput<'tcx>,
338 body_id: ast::NodeId)
339 -> FnCtxt<'a, 'tcx> {
342 writeback_errors: Cell::new(false),
343 err_count_on_creation: ccx.tcx.sess.err_count(),
345 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
351 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
352 tables: &'a RefCell<ty::Tables<'tcx>>)
353 -> Inherited<'a, 'tcx> {
354 // It's kind of a kludge to manufacture a fake function context
355 // and statement context, but we might as well do write the code only once
356 let param_env = ccx.tcx.empty_parameter_environment();
357 Inherited::new(ccx.tcx, &tables, param_env)
360 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
361 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
363 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
364 fn visit_item(&mut self, i: &'tcx hir::Item) {
365 check_item_type(self.ccx, i);
366 visit::walk_item(self, i);
369 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
371 hir::TyFixedLengthVec(_, ref expr) => {
372 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
374 hir::TyBareFn(ref function_declaration) => {
375 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
376 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
382 visit::walk_ty(self, t);
386 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
387 fn visit_item(&mut self, i: &'tcx hir::Item) {
388 check_item_body(self.ccx, i);
389 visit::walk_item(self, i);
393 pub fn check_wf_old(ccx: &CrateCtxt) {
394 // FIXME(#25759). The new code below is much more reliable but (for now)
395 // only generates warnings. So as to ensure that we continue
396 // getting errors where we used to get errors, we run the old wf
397 // code first and abort if it encounters any errors. If no abort
398 // comes, we run the new code and issue warnings.
399 let krate = ccx.tcx.map.krate();
400 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
401 visit::walk_crate(&mut visit, krate);
403 // If types are not well-formed, it leads to all manner of errors
404 // downstream, so stop reporting errors at this point.
405 ccx.tcx.sess.abort_if_errors();
408 pub fn check_wf_new(ccx: &CrateCtxt) {
409 let krate = ccx.tcx.map.krate();
410 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
411 visit::walk_crate(&mut visit, krate);
413 // If types are not well-formed, it leads to all manner of errors
414 // downstream, so stop reporting errors at this point.
415 ccx.tcx.sess.abort_if_errors();
418 pub fn check_item_types(ccx: &CrateCtxt) {
419 let krate = ccx.tcx.map.krate();
420 let mut visit = CheckItemTypesVisitor { ccx: ccx };
421 visit::walk_crate(&mut visit, krate);
422 ccx.tcx.sess.abort_if_errors();
425 pub fn check_item_bodies(ccx: &CrateCtxt) {
426 let krate = ccx.tcx.map.krate();
427 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
428 visit::walk_crate(&mut visit, krate);
430 ccx.tcx.sess.abort_if_errors();
433 pub fn check_drop_impls(ccx: &CrateCtxt) {
434 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
435 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
437 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
438 if drop_impl_did.is_local() {
439 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
442 assert!(ccx.tcx.sess.has_errors());
448 ccx.tcx.sess.abort_if_errors();
451 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
452 decl: &'tcx hir::FnDecl,
453 body: &'tcx hir::Block,
457 param_env: ty::ParameterEnvironment<'a, 'tcx>)
460 ty::TyBareFn(_, ref fn_ty) => {
461 let tables = RefCell::new(ty::Tables::empty());
462 let inh = Inherited::new(ccx.tcx, &tables, param_env);
464 // Compute the fty from point of view of inside fn.
465 let fn_scope = ccx.tcx.region_maps.item_extent(body.id);
467 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
469 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
471 inh.normalize_associated_types_in(body.span,
475 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
476 decl, fn_id, body, &inh);
478 fcx.select_all_obligations_and_apply_defaults();
479 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
480 fcx.select_obligations_where_possible();
482 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
484 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
485 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
487 _ => ccx.tcx.sess.impossible_case(body.span,
488 "check_bare_fn: function type expected")
492 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
493 fcx: &'a FnCtxt<'a, 'tcx>
496 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
497 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
500 // infer the variable's type
501 let var_ty = self.fcx.infcx().next_ty_var();
502 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
506 // take type that the user specified
507 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
514 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
515 // Add explicitly-declared locals.
516 fn visit_local(&mut self, local: &'tcx hir::Local) {
517 let o_ty = match local.ty {
518 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
521 self.assign(local.span, local.id, o_ty);
522 debug!("Local variable {:?} is assigned type {}",
524 self.fcx.infcx().ty_to_string(
525 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
526 visit::walk_local(self, local);
529 // Add pattern bindings.
530 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
531 if let hir::PatIdent(_, ref path1, _) = p.node {
532 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
533 let var_ty = self.assign(p.span, p.id, None);
535 self.fcx.require_type_is_sized(var_ty, p.span,
536 traits::VariableType(p.id));
538 debug!("Pattern binding {} is assigned to {} with type {:?}",
540 self.fcx.infcx().ty_to_string(
541 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
545 visit::walk_pat(self, p);
548 fn visit_block(&mut self, b: &'tcx hir::Block) {
549 // non-obvious: the `blk` variable maps to region lb, so
550 // we have to keep this up-to-date. This
551 // is... unfortunate. It'd be nice to not need this.
552 visit::walk_block(self, b);
555 // Since an expr occurs as part of the type fixed size arrays we
556 // need to record the type for that node
557 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
559 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
560 self.visit_ty(&**ty);
561 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
563 hir::TyBareFn(ref function_declaration) => {
564 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
565 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
567 _ => visit::walk_ty(self, t)
571 // Don't descend into fns and items
572 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
573 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
574 fn visit_item(&mut self, _: &hir::Item) { }
578 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
579 /// body and returns the function context used for that purpose, since in the case of a fn item
580 /// there is still a bit more to do.
583 /// * inherited: other fields inherited from the enclosing fn (if any)
584 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
585 unsafety: hir::Unsafety,
586 unsafety_id: ast::NodeId,
587 fn_sig: &ty::FnSig<'tcx>,
588 decl: &'tcx hir::FnDecl,
590 body: &'tcx hir::Block,
591 inherited: &'a Inherited<'a, 'tcx>)
595 let err_count_on_creation = tcx.sess.err_count();
597 let arg_tys = &fn_sig.inputs;
598 let ret_ty = fn_sig.output;
600 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
605 // Create the function context. This is either derived from scratch or,
606 // in the case of function expressions, based on the outer context.
609 writeback_errors: Cell::new(false),
610 err_count_on_creation: err_count_on_creation,
612 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
617 if let ty::FnConverging(ret_ty) = ret_ty {
618 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
621 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
623 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
626 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
628 // Add formal parameters.
629 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
630 // The type of the argument must be well-formed.
632 // NB -- this is now checked in wfcheck, but that
633 // currently only results in warnings, so we issue an
634 // old-style WF obligation here so that we still get the
635 // errors that we used to get.
636 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
638 // Create type variables for each argument.
639 pat_util::pat_bindings(
642 |_bm, pat_id, sp, _path| {
643 let var_ty = visit.assign(sp, pat_id, None);
644 fcx.require_type_is_sized(var_ty, sp,
645 traits::VariableType(pat_id));
648 // Check the pattern.
651 map: pat_id_map(&tcx.def_map, &*input.pat),
653 _match::check_pat(&pcx, &*input.pat, *arg_ty);
656 visit.visit_block(body);
659 check_block_with_expected(&fcx, body, match ret_ty {
660 ty::FnConverging(result_type) => ExpectHasType(result_type),
661 ty::FnDiverging => NoExpectation
664 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
665 fcx.write_ty(input.id, arg);
671 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
674 check_representable(tcx, span, id, "struct");
676 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
677 check_simd(tcx, span, id);
681 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
682 debug!("check_item_type(it.id={}, it.name={})",
684 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
685 let _indenter = indenter();
687 // Consts can play a role in type-checking, so they are included here.
688 hir::ItemStatic(_, _, ref e) |
689 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
690 hir::ItemEnum(ref enum_definition, _) => {
691 check_enum_variants(ccx,
693 &enum_definition.variants,
696 hir::ItemFn(..) => {} // entirely within check_item_body
697 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
698 debug!("ItemImpl {} with id {}", it.name, it.id);
699 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
700 Some(impl_trait_ref) => {
701 check_impl_items_against_trait(ccx,
709 hir::ItemTrait(_, ref generics, _, _) => {
710 check_trait_on_unimplemented(ccx, generics, it);
712 hir::ItemStruct(..) => {
713 check_struct(ccx, it.id, it.span);
715 hir::ItemTy(ref t, ref generics) => {
716 let pty_ty = ccx.tcx.node_id_to_type(it.id);
717 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
719 hir::ItemForeignMod(ref m) => {
720 if m.abi == abi::RustIntrinsic {
721 for item in &m.items {
722 intrinsic::check_intrinsic_type(ccx, &**item);
724 } else if m.abi == abi::PlatformIntrinsic {
725 for item in &m.items {
726 intrinsic::check_platform_intrinsic_type(ccx, &**item);
729 for item in &m.items {
730 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
731 if !pty.generics.types.is_empty() {
732 span_err!(ccx.tcx.sess, item.span, E0044,
733 "foreign items may not have type parameters");
734 span_help!(ccx.tcx.sess, item.span,
735 "consider using specialization instead of \
739 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
740 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
745 _ => {/* nothing to do */ }
749 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
750 debug!("check_item_body(it.id={}, it.name={})",
752 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
753 let _indenter = indenter();
755 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
756 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
757 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
758 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
760 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
761 debug!("ItemImpl {} with id {}", it.name, it.id);
763 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
765 for impl_item in impl_items {
766 match impl_item.node {
767 hir::ConstImplItem(_, ref expr) => {
768 check_const(ccx, impl_item.span, &*expr, impl_item.id)
770 hir::MethodImplItem(ref sig, ref body) => {
771 check_method_body(ccx, &impl_pty.generics, sig, body,
772 impl_item.id, impl_item.span);
774 hir::TypeImplItem(_) => {
775 // Nothing to do here.
780 hir::ItemTrait(_, _, _, ref trait_items) => {
781 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
782 for trait_item in trait_items {
783 match trait_item.node {
784 hir::ConstTraitItem(_, Some(ref expr)) => {
785 check_const(ccx, trait_item.span, &*expr, trait_item.id)
787 hir::MethodTraitItem(ref sig, Some(ref body)) => {
788 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
790 check_method_body(ccx, &trait_def.generics, sig, body,
791 trait_item.id, trait_item.span);
793 hir::MethodTraitItem(ref sig, None) => {
794 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
796 hir::ConstTraitItem(_, None) |
797 hir::TypeTraitItem(..) => {
803 _ => {/* nothing to do */ }
807 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
809 constness: hir::Constness)
812 hir::Constness::NotConst => {
815 hir::Constness::Const => {
816 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
821 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
822 generics: &hir::Generics,
824 if let Some(ref attr) = item.attrs.iter().find(|a| {
825 a.check_name("rustc_on_unimplemented")
827 if let Some(ref istring) = attr.value_str() {
828 let parser = Parser::new(&istring);
829 let types = &*generics.ty_params;
830 for token in parser {
832 Piece::String(_) => (), // Normal string, no need to check it
833 Piece::NextArgument(a) => match a.position {
834 // `{Self}` is allowed
835 Position::ArgumentNamed(s) if s == "Self" => (),
836 // So is `{A}` if A is a type parameter
837 Position::ArgumentNamed(s) => match types.iter().find(|t| {
842 span_err!(ccx.tcx.sess, attr.span, E0230,
843 "there is no type parameter \
848 // `{:1}` and `{}` are not to be used
849 Position::ArgumentIs(_) | Position::ArgumentNext => {
850 span_err!(ccx.tcx.sess, attr.span, E0231,
851 "only named substitution \
852 parameters are allowed");
858 span_err!(ccx.tcx.sess, attr.span, E0232,
859 "this attribute must have a value, \
860 eg `#[rustc_on_unimplemented = \"foo\"]`")
865 /// Type checks a method body.
869 /// * `item_generics`: generics defined on the impl/trait that contains
871 /// * `self_bound`: bound for the `Self` type parameter, if any
872 /// * `method`: the method definition
873 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
874 item_generics: &ty::Generics<'tcx>,
875 sig: &'tcx hir::MethodSig,
876 body: &'tcx hir::Block,
877 id: ast::NodeId, span: Span) {
878 debug!("check_method_body(item_generics={:?}, id={})",
880 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
882 let fty = ccx.tcx.node_id_to_type(id);
883 debug!("check_method_body: fty={:?}", fty);
885 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
888 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
890 impl_trait_ref: &ty::TraitRef<'tcx>,
891 impl_items: &[P<hir::ImplItem>]) {
892 // Locate trait methods
894 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
895 let mut overridden_associated_type = None;
897 // Check existing impl methods to see if they are both present in trait
898 // and compatible with trait signature
899 for impl_item in impl_items {
900 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
901 let ty_trait_item = trait_items.iter()
902 .find(|ac| ac.name() == ty_impl_item.name())
904 // This is checked by resolve
905 tcx.sess.span_bug(impl_item.span,
906 &format!("impl-item `{}` is not a member of `{:?}`",
910 match impl_item.node {
911 hir::ConstImplItem(..) => {
912 let impl_const = match ty_impl_item {
913 ty::ConstTraitItem(ref cti) => cti,
914 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
917 // Find associated const definition.
918 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
919 compare_const_impl(ccx.tcx,
925 span_err!(tcx.sess, impl_item.span, E0323,
926 "item `{}` is an associated const, \
927 which doesn't match its trait `{:?}`",
932 hir::MethodImplItem(ref sig, ref body) => {
933 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
935 let impl_method = match ty_impl_item {
936 ty::MethodTraitItem(ref mti) => mti,
937 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
940 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
941 compare_impl_method(ccx.tcx,
948 span_err!(tcx.sess, impl_item.span, E0324,
949 "item `{}` is an associated method, \
950 which doesn't match its trait `{:?}`",
955 hir::TypeImplItem(_) => {
956 let impl_type = match ty_impl_item {
957 ty::TypeTraitItem(ref tti) => tti,
958 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
961 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
962 if let Some(_) = at.ty {
963 overridden_associated_type = Some(impl_item);
966 span_err!(tcx.sess, impl_item.span, E0325,
967 "item `{}` is an associated type, \
968 which doesn't match its trait `{:?}`",
976 // Check for missing items from trait
977 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
978 let mut missing_items = Vec::new();
979 let mut invalidated_items = Vec::new();
980 let associated_type_overridden = overridden_associated_type.is_some();
981 for trait_item in trait_items.iter() {
983 ty::ConstTraitItem(ref associated_const) => {
984 let is_implemented = impl_items.iter().any(|ii| {
986 hir::ConstImplItem(..) => {
987 ii.name == associated_const.name
992 let is_provided = associated_const.has_value;
996 missing_items.push(associated_const.name);
997 } else if associated_type_overridden {
998 invalidated_items.push(associated_const.name);
1002 ty::MethodTraitItem(ref trait_method) => {
1003 let is_implemented =
1004 impl_items.iter().any(|ii| {
1006 hir::MethodImplItem(..) => {
1007 ii.name == trait_method.name
1013 provided_methods.iter().any(|m| m.name == trait_method.name);
1014 if !is_implemented {
1016 missing_items.push(trait_method.name);
1017 } else if associated_type_overridden {
1018 invalidated_items.push(trait_method.name);
1022 ty::TypeTraitItem(ref associated_type) => {
1023 let is_implemented = impl_items.iter().any(|ii| {
1025 hir::TypeImplItem(_) => {
1026 ii.name == associated_type.name
1031 let is_provided = associated_type.ty.is_some();
1032 if !is_implemented {
1034 missing_items.push(associated_type.name);
1035 } else if associated_type_overridden {
1036 invalidated_items.push(associated_type.name);
1043 if !missing_items.is_empty() {
1044 span_err!(tcx.sess, impl_span, E0046,
1045 "not all trait items implemented, missing: `{}`",
1046 missing_items.iter()
1047 .map(|name| name.to_string())
1048 .collect::<Vec<_>>().join("`, `"))
1051 if !invalidated_items.is_empty() {
1052 let invalidator = overridden_associated_type.unwrap();
1053 span_err!(tcx.sess, invalidator.span, E0399,
1054 "the following trait items need to be reimplemented \
1055 as `{}` was overridden: `{}`",
1057 invalidated_items.iter()
1058 .map(|name| name.to_string())
1059 .collect::<Vec<_>>().join("`, `"))
1063 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1070 let tstr = fcx.infcx().ty_to_string(t_cast);
1071 fcx.type_error_message(span, |actual| {
1072 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1075 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1076 let mtstr = match mt {
1077 hir::MutMutable => "mut ",
1078 hir::MutImmutable => ""
1080 if t_cast.is_trait() {
1081 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1083 fcx.tcx().sess.span_suggestion(t_span,
1084 "try casting to a reference instead:",
1085 format!("&{}{}", mtstr, s));
1088 span_help!(fcx.tcx().sess, t_span,
1089 "did you mean `&{}{}`?", mtstr, tstr),
1092 span_help!(fcx.tcx().sess, span,
1093 "consider using an implicit coercion to `&{}{}` instead",
1098 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1100 fcx.tcx().sess.span_suggestion(t_span,
1101 "try casting to a `Box` instead:",
1102 format!("Box<{}>", s));
1105 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1109 span_help!(fcx.tcx().sess, e_span,
1110 "consider using a box or reference as appropriate");
1113 fcx.write_error(id);
1117 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1118 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1120 fn get_item_type_scheme(&self, _: Span, id: DefId)
1121 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1123 Ok(self.tcx().lookup_item_type(id))
1126 fn get_trait_def(&self, _: Span, id: DefId)
1127 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1129 Ok(self.tcx().lookup_trait_def(id))
1132 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1133 // all super predicates are ensured during collect pass
1137 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1138 Some(&self.inh.infcx.parameter_environment.free_substs)
1141 fn get_type_parameter_bounds(&self,
1143 node_id: ast::NodeId)
1144 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1146 let def = self.tcx().type_parameter_def(node_id);
1147 let r = self.inh.infcx.parameter_environment
1150 .filter_map(|predicate| {
1152 ty::Predicate::Trait(ref data) => {
1153 if data.0.self_ty().is_param(def.space, def.index) {
1154 Some(data.to_poly_trait_ref())
1168 fn trait_defines_associated_type_named(&self,
1169 trait_def_id: DefId,
1170 assoc_name: ast::Name)
1173 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1174 trait_def.associated_type_names.contains(&assoc_name)
1178 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1179 substs: Option<&mut subst::Substs<'tcx>>,
1180 space: Option<subst::ParamSpace>,
1181 span: Span) -> Ty<'tcx> {
1182 // Grab the default doing subsitution
1183 let default = ty_param_def.and_then(|def| {
1184 def.default.map(|ty| type_variable::Default {
1185 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1187 def_id: def.default_def_id
1191 let ty_var = self.infcx().next_ty_var_with_default(default);
1193 // Finally we add the type variable to the substs
1196 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1200 fn projected_ty_from_poly_trait_ref(&self,
1202 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1203 item_name: ast::Name)
1206 let (trait_ref, _) =
1207 self.infcx().replace_late_bound_regions_with_fresh_var(
1209 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1212 self.normalize_associated_type(span, trait_ref, item_name)
1215 fn projected_ty(&self,
1217 trait_ref: ty::TraitRef<'tcx>,
1218 item_name: ast::Name)
1221 self.normalize_associated_type(span, trait_ref, item_name)
1225 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1226 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1228 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1232 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1233 &self.inh.infcx.parameter_environment
1236 pub fn sess(&self) -> &Session {
1240 pub fn err_count_since_creation(&self) -> usize {
1241 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1244 /// Resolves type variables in `ty` if possible. Unlike the infcx
1245 /// version, this version will also select obligations if it seems
1246 /// useful, in an effort to get more type information.
1247 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1248 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1250 // No TyInfer()? Nothing needs doing.
1251 if !ty.has_infer_types() {
1252 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1256 // If `ty` is a type variable, see whether we already know what it is.
1257 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1258 if !ty.has_infer_types() {
1259 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1263 // If not, try resolving any new fcx obligations that have cropped up.
1264 self.select_new_obligations();
1265 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1266 if !ty.has_infer_types() {
1267 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1271 // If not, try resolving *all* pending obligations as much as
1272 // possible. This can help substantially when there are
1273 // indirect dependencies that don't seem worth tracking
1275 self.select_obligations_where_possible();
1276 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1278 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1282 fn record_deferred_call_resolution(&self,
1283 closure_def_id: DefId,
1284 r: DeferredCallResolutionHandler<'tcx>) {
1285 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1286 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1289 fn remove_deferred_call_resolutions(&self,
1290 closure_def_id: DefId)
1291 -> Vec<DeferredCallResolutionHandler<'tcx>>
1293 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1294 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1297 pub fn tag(&self) -> String {
1298 let self_ptr: *const FnCtxt = self;
1299 format!("{:?}", self_ptr)
1302 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1303 match self.inh.locals.borrow().get(&nid) {
1306 span_err!(self.tcx().sess, span, E0513,
1307 "no type for local variable {}",
1309 self.tcx().types.err
1315 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1316 debug!("write_ty({}, {:?}) in fcx {}",
1317 node_id, ty, self.tag());
1318 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1321 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1322 if !substs.substs.is_noop() {
1323 debug!("write_substs({}, {:?}) in fcx {}",
1328 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1332 pub fn write_autoderef_adjustment(&self,
1333 node_id: ast::NodeId,
1335 self.write_adjustment(
1337 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1345 pub fn write_adjustment(&self,
1346 node_id: ast::NodeId,
1347 adj: adjustment::AutoAdjustment<'tcx>) {
1348 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1350 if adj.is_identity() {
1354 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1357 /// Basically whenever we are converting from a type scheme into
1358 /// the fn body space, we always want to normalize associated
1359 /// types as well. This function combines the two.
1360 fn instantiate_type_scheme<T>(&self,
1362 substs: &Substs<'tcx>,
1365 where T : TypeFoldable<'tcx> + HasTypeFlags
1367 let value = value.subst(self.tcx(), substs);
1368 let result = self.normalize_associated_types_in(span, &value);
1369 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1376 /// As `instantiate_type_scheme`, but for the bounds found in a
1377 /// generic type scheme.
1378 fn instantiate_bounds(&self,
1380 substs: &Substs<'tcx>,
1381 bounds: &ty::GenericPredicates<'tcx>)
1382 -> ty::InstantiatedPredicates<'tcx>
1384 ty::InstantiatedPredicates {
1385 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1390 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1391 where T : TypeFoldable<'tcx> + HasTypeFlags
1393 self.inh.normalize_associated_types_in(span, self.body_id, value)
1396 fn normalize_associated_type(&self,
1398 trait_ref: ty::TraitRef<'tcx>,
1399 item_name: ast::Name)
1402 let cause = traits::ObligationCause::new(span,
1404 traits::ObligationCauseCode::MiscObligation);
1409 .normalize_projection_type(self.infcx(),
1411 trait_ref: trait_ref,
1412 item_name: item_name,
1417 /// Instantiates the type in `did` with the generics in `path` and returns
1418 /// it (registering the necessary trait obligations along the way).
1420 /// Note that this function is only intended to be used with type-paths,
1421 /// not with value-paths.
1422 pub fn instantiate_type(&self,
1427 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1429 self.tcx().lookup_item_type(did);
1430 let type_predicates =
1431 self.tcx().lookup_predicates(did);
1432 let substs = astconv::ast_path_substs_for_ty(self, self,
1434 PathParamMode::Optional,
1435 &type_scheme.generics,
1436 path.segments.last().unwrap());
1437 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1439 self.instantiate_bounds(path.span, &substs, &type_predicates);
1440 self.add_obligations_for_parameters(
1441 traits::ObligationCause::new(
1444 traits::ItemObligation(did)),
1447 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1450 /// Return the dict-like variant corresponding to a given `Def`.
1451 pub fn def_struct_variant(&self,
1454 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1456 let (adt, variant) = match def {
1457 def::DefVariant(enum_id, variant_id, true) => {
1458 let adt = self.tcx().lookup_adt_def(enum_id);
1459 (adt, adt.variant_with_id(variant_id))
1461 def::DefTy(did, _) | def::DefStruct(did) => {
1462 let typ = self.tcx().lookup_item_type(did);
1463 if let ty::TyStruct(adt, _) = typ.ty.sty {
1464 (adt, adt.struct_variant())
1472 let var_kind = variant.kind();
1473 if var_kind == ty::VariantKind::Struct {
1474 Some((adt, variant))
1475 } else if var_kind == ty::VariantKind::Unit {
1476 if !self.tcx().sess.features.borrow().braced_empty_structs {
1477 self.tcx().sess.span_err(span, "empty structs and enum variants \
1478 with braces are unstable");
1479 fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
1480 the crate features to enable");
1483 Some((adt, variant))
1489 pub fn write_nil(&self, node_id: ast::NodeId) {
1490 self.write_ty(node_id, self.tcx().mk_nil());
1492 pub fn write_error(&self, node_id: ast::NodeId) {
1493 self.write_ty(node_id, self.tcx().types.err);
1496 pub fn require_type_meets(&self,
1499 code: traits::ObligationCauseCode<'tcx>,
1500 bound: ty::BuiltinBound)
1502 self.register_builtin_bound(
1505 traits::ObligationCause::new(span, self.body_id, code));
1508 pub fn require_type_is_sized(&self,
1511 code: traits::ObligationCauseCode<'tcx>)
1513 self.require_type_meets(ty, span, code, ty::BoundSized);
1516 pub fn require_expr_have_sized_type(&self,
1518 code: traits::ObligationCauseCode<'tcx>)
1520 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1523 pub fn type_is_known_to_be_sized(&self,
1528 traits::type_known_to_meet_builtin_bound(self.infcx(),
1534 pub fn register_builtin_bound(&self,
1536 builtin_bound: ty::BuiltinBound,
1537 cause: traits::ObligationCause<'tcx>)
1539 self.inh.infcx.fulfillment_cx.borrow_mut()
1540 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1543 pub fn register_predicate(&self,
1544 obligation: traits::PredicateObligation<'tcx>)
1546 debug!("register_predicate({:?})",
1548 self.inh.infcx.fulfillment_cx
1550 .register_predicate_obligation(self.infcx(), obligation);
1553 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1554 let t = ast_ty_to_ty(self, self, ast_t);
1555 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1559 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1560 match self.inh.tables.borrow().node_types.get(&ex.id) {
1563 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1569 /// Apply `adjustment` to the type of `expr`
1570 pub fn adjust_expr_ty(&self,
1572 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1575 let raw_ty = self.expr_ty(expr);
1576 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1577 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1578 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1579 self.inh.tables.borrow().method_map.get(&method_call)
1580 .map(|method| resolve_ty(method.ty))
1584 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1585 match self.inh.tables.borrow().node_types.get(&id) {
1587 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1589 self.tcx().sess.bug(
1590 &format!("no type for node {}: {} in fcx {}",
1591 id, self.tcx().map.node_to_string(id),
1597 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1598 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1599 // it changes when we upgrade the snapshot compiler
1600 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1601 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1605 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1608 pub fn opt_node_ty_substs<F>(&self,
1611 F: FnOnce(&ty::ItemSubsts<'tcx>),
1613 match self.inh.tables.borrow().item_substs.get(&id) {
1619 pub fn mk_subty(&self,
1620 a_is_expected: bool,
1621 origin: infer::TypeOrigin,
1624 -> Result<(), TypeError<'tcx>> {
1625 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1628 pub fn mk_eqty(&self,
1629 a_is_expected: bool,
1630 origin: infer::TypeOrigin,
1633 -> Result<(), TypeError<'tcx>> {
1634 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1637 pub fn mk_subr(&self,
1638 origin: infer::SubregionOrigin<'tcx>,
1641 infer::mk_subr(self.infcx(), origin, sub, sup)
1644 pub fn type_error_message<M>(&self,
1647 actual_ty: Ty<'tcx>,
1648 err: Option<&TypeError<'tcx>>) where
1649 M: FnOnce(String) -> String,
1651 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1654 pub fn report_mismatched_types(&self,
1658 err: &TypeError<'tcx>) {
1659 self.infcx().report_mismatched_types(sp, e, a, err)
1662 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1663 /// outlive the region `r`.
1664 pub fn register_region_obligation(&self,
1667 cause: traits::ObligationCause<'tcx>)
1669 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
1670 fulfillment_cx.register_region_obligation(ty, region, cause);
1673 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1674 /// outlive the region `r`.
1675 pub fn register_wf_obligation(&self,
1678 code: traits::ObligationCauseCode<'tcx>)
1680 // WF obligations never themselves fail, so no real need to give a detailed cause:
1681 let cause = traits::ObligationCause::new(span, self.body_id, code);
1682 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1685 pub fn register_old_wf_obligation(&self,
1688 code: traits::ObligationCauseCode<'tcx>)
1690 // Registers an "old-style" WF obligation that uses the
1691 // implicator code. This is basically a buggy version of
1692 // `register_wf_obligation` that is being kept around
1693 // temporarily just to help with phasing in the newer rules.
1695 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1696 let cause = traits::ObligationCause::new(span, self.body_id, code);
1697 self.register_region_obligation(ty, ty::ReEmpty, cause);
1700 /// Registers obligations that all types appearing in `substs` are well-formed.
1701 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1703 for &ty in &substs.types {
1704 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1708 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1709 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1710 /// trait/region obligations.
1712 /// For example, if there is a function:
1715 /// fn foo<'a,T:'a>(...)
1718 /// and a reference:
1724 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1725 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1726 pub fn add_obligations_for_parameters(&self,
1727 cause: traits::ObligationCause<'tcx>,
1728 predicates: &ty::InstantiatedPredicates<'tcx>)
1730 assert!(!predicates.has_escaping_regions());
1732 debug!("add_obligations_for_parameters(predicates={:?})",
1735 for obligation in traits::predicates_for_generics(cause, predicates) {
1736 self.register_predicate(obligation);
1740 // FIXME(arielb1): use this instead of field.ty everywhere
1741 pub fn field_ty(&self,
1743 field: ty::FieldDef<'tcx>,
1744 substs: &Substs<'tcx>)
1747 self.normalize_associated_types_in(span,
1748 &field.ty(self.tcx(), substs))
1751 // Only for fields! Returns <none> for methods>
1752 // Indifferent to privacy flags
1753 fn check_casts(&self) {
1754 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1755 for cast in deferred_cast_checks.drain(..) {
1760 /// Apply "fallbacks" to some types
1761 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1762 fn default_type_parameters(&self) {
1763 use middle::ty::error::UnconstrainedNumeric::Neither;
1764 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1765 for ty in &self.infcx().unsolved_variables() {
1766 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1767 if self.infcx().type_var_diverges(resolved) {
1768 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1770 match self.infcx().type_is_unconstrained_numeric(resolved) {
1771 UnconstrainedInt => {
1772 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1774 UnconstrainedFloat => {
1775 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1783 fn select_all_obligations_and_apply_defaults(&self) {
1784 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1785 self.new_select_all_obligations_and_apply_defaults();
1787 self.old_select_all_obligations_and_apply_defaults();
1791 // Implements old type inference fallback algorithm
1792 fn old_select_all_obligations_and_apply_defaults(&self) {
1793 self.select_obligations_where_possible();
1794 self.default_type_parameters();
1795 self.select_obligations_where_possible();
1798 fn new_select_all_obligations_and_apply_defaults(&self) {
1799 use middle::ty::error::UnconstrainedNumeric::Neither;
1800 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1802 // For the time being this errs on the side of being memory wasteful but provides better
1804 // let type_variables = self.infcx().type_variables.clone();
1806 // There is a possibility that this algorithm will have to run an arbitrary number of times
1807 // to terminate so we bound it by the compiler's recursion limit.
1808 for _ in 0..self.tcx().sess.recursion_limit.get() {
1809 // First we try to solve all obligations, it is possible that the last iteration
1810 // has made it possible to make more progress.
1811 self.select_obligations_where_possible();
1813 let mut conflicts = Vec::new();
1815 // Collect all unsolved type, integral and floating point variables.
1816 let unsolved_variables = self.inh.infcx.unsolved_variables();
1818 // We must collect the defaults *before* we do any unification. Because we have
1819 // directly attached defaults to the type variables any unification that occurs
1820 // will erase defaults causing conflicting defaults to be completely ignored.
1821 let default_map: FnvHashMap<_, _> =
1824 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1827 let mut unbound_tyvars = HashSet::new();
1829 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1831 // We loop over the unsolved variables, resolving them and if they are
1832 // and unconstrainted numberic type we add them to the set of unbound
1833 // variables. We do this so we only apply literal fallback to type
1834 // variables without defaults.
1835 for ty in &unsolved_variables {
1836 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1837 if self.infcx().type_var_diverges(resolved) {
1838 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1840 match self.infcx().type_is_unconstrained_numeric(resolved) {
1841 UnconstrainedInt | UnconstrainedFloat => {
1842 unbound_tyvars.insert(resolved);
1849 // We now remove any numeric types that also have defaults, and instead insert
1850 // the type variable with a defined fallback.
1851 for ty in &unsolved_variables {
1852 if let Some(_default) = default_map.get(ty) {
1853 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1855 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1858 match resolved.sty {
1859 ty::TyInfer(ty::TyVar(_)) => {
1860 unbound_tyvars.insert(ty);
1863 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1864 unbound_tyvars.insert(ty);
1865 if unbound_tyvars.contains(resolved) {
1866 unbound_tyvars.remove(resolved);
1875 // If there are no more fallbacks to apply at this point we have applied all possible
1876 // defaults and type inference will proceed as normal.
1877 if unbound_tyvars.is_empty() {
1881 // Finally we go through each of the unbound type variables and unify them with
1882 // the proper fallback, reporting a conflicting default error if any of the
1883 // unifications fail. We know it must be a conflicting default because the
1884 // variable would only be in `unbound_tyvars` and have a concrete value if
1885 // it had been solved by previously applying a default.
1887 // We wrap this in a transaction for error reporting, if we detect a conflict
1888 // we will rollback the inference context to its prior state so we can probe
1889 // for conflicts and correctly report them.
1892 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1893 for ty in &unbound_tyvars {
1894 if self.infcx().type_var_diverges(ty) {
1895 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1897 match self.infcx().type_is_unconstrained_numeric(ty) {
1898 UnconstrainedInt => {
1899 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1901 UnconstrainedFloat => {
1902 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1905 if let Some(default) = default_map.get(ty) {
1906 let default = default.clone();
1907 match infer::mk_eqty(self.infcx(), false,
1908 infer::Misc(default.origin_span),
1912 conflicts.push((*ty, default));
1921 // If there are conflicts we rollback, otherwise commit
1922 if conflicts.len() > 0 {
1929 if conflicts.len() > 0 {
1930 // Loop through each conflicting default, figuring out the default that caused
1931 // a unification failure and then report an error for each.
1932 for (conflict, default) in conflicts {
1933 let conflicting_default =
1934 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1935 .unwrap_or(type_variable::Default {
1936 ty: self.infcx().next_ty_var(),
1937 origin_span: codemap::DUMMY_SP,
1938 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1941 // This is to ensure that we elimnate any non-determinism from the error
1942 // reporting by fixing an order, it doesn't matter what order we choose
1943 // just that it is consistent.
1944 let (first_default, second_default) =
1945 if default.def_id < conflicting_default.def_id {
1946 (default, conflicting_default)
1948 (conflicting_default, default)
1952 self.infcx().report_conflicting_default_types(
1953 first_default.origin_span,
1960 self.select_obligations_where_possible();
1963 // For use in error handling related to default type parameter fallback. We explicitly
1964 // apply the default that caused conflict first to a local version of the type variable
1965 // table then apply defaults until we find a conflict. That default must be the one
1966 // that caused conflict earlier.
1967 fn find_conflicting_default(&self,
1968 unbound_vars: &HashSet<Ty<'tcx>>,
1969 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1971 -> Option<type_variable::Default<'tcx>> {
1972 use middle::ty::error::UnconstrainedNumeric::Neither;
1973 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1975 // Ensure that we apply the conflicting default first
1976 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1977 unbound_tyvars.push(conflict);
1978 unbound_tyvars.extend(unbound_vars.iter());
1980 let mut result = None;
1981 // We run the same code as above applying defaults in order, this time when
1982 // we find the conflict we just return it for error reporting above.
1984 // We also run this inside snapshot that never commits so we can do error
1985 // reporting for more then one conflict.
1986 for ty in &unbound_tyvars {
1987 if self.infcx().type_var_diverges(ty) {
1988 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1990 match self.infcx().type_is_unconstrained_numeric(ty) {
1991 UnconstrainedInt => {
1992 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1994 UnconstrainedFloat => {
1995 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1998 if let Some(default) = default_map.get(ty) {
1999 let default = default.clone();
2000 match infer::mk_eqty(self.infcx(), false,
2001 infer::Misc(default.origin_span),
2005 result = Some(default);
2017 fn select_all_obligations_or_error(&self) {
2018 debug!("select_all_obligations_or_error");
2020 // upvar inference should have ensured that all deferred call
2021 // resolutions are handled by now.
2022 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2024 self.select_all_obligations_and_apply_defaults();
2026 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2027 match fulfillment_cx.select_all_or_error(self.infcx()) {
2029 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2033 /// Select as many obligations as we can at present.
2034 fn select_obligations_where_possible(&self) {
2036 self.inh.infcx.fulfillment_cx
2038 .select_where_possible(self.infcx())
2041 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2045 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2046 /// to improve inference. You could just call
2047 /// `select_obligations_where_possible` except that it leads to repeated
2049 fn select_new_obligations(&self) {
2051 self.inh.infcx.fulfillment_cx
2053 .select_new_obligations(self.infcx())
2056 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2062 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2063 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2064 Some(self.base_object_lifetime_default(span))
2067 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2068 // RFC #599 specifies that object lifetime defaults take
2069 // precedence over other defaults. But within a fn body we
2070 // don't have a *default* region, rather we use inference to
2071 // find the *correct* region, which is strictly more general
2072 // (and anyway, within a fn body the right region may not even
2073 // be something the user can write explicitly, since it might
2074 // be some expression).
2075 self.infcx().next_region_var(infer::MiscVariable(span))
2078 fn anon_regions(&self, span: Span, count: usize)
2079 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2080 Ok((0..count).map(|_| {
2081 self.infcx().next_region_var(infer::MiscVariable(span))
2086 /// Whether `autoderef` requires types to resolve.
2087 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2088 pub enum UnresolvedTypeAction {
2089 /// Produce an error and return `TyError` whenever a type cannot
2090 /// be resolved (i.e. it is `TyInfer`).
2092 /// Go on without emitting any errors, and return the unresolved
2093 /// type. Useful for probing, e.g. in coercions.
2097 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2098 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2100 /// Note: this method does not modify the adjustments table. The caller is responsible for
2101 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2102 pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2105 opt_expr: Option<&hir::Expr>,
2106 unresolved_type_action: UnresolvedTypeAction,
2107 mut lvalue_pref: LvaluePreference,
2109 -> (Ty<'tcx>, usize, Option<T>)
2110 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2112 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2117 let mut t = base_ty;
2118 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2119 let resolved_t = match unresolved_type_action {
2120 UnresolvedTypeAction::Error => {
2121 structurally_resolved_type(fcx, sp, t)
2123 UnresolvedTypeAction::Ignore => {
2124 // We can continue even when the type cannot be resolved
2125 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2126 // and `try_overloaded_deref` both simply return `None`
2127 // in such a case without producing spurious errors.
2128 fcx.resolve_type_vars_if_possible(t)
2131 if resolved_t.references_error() {
2132 return (resolved_t, autoderefs, None);
2135 match should_stop(resolved_t, autoderefs) {
2136 Some(x) => return (resolved_t, autoderefs, Some(x)),
2140 // Otherwise, deref if type is derefable:
2141 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
2142 Some(mt) => Some(mt),
2145 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
2147 // Super subtle: it might seem as though we should
2148 // pass `opt_expr` to `try_overloaded_deref`, so that
2149 // the (implicit) autoref of using an overloaded deref
2150 // would get added to the adjustment table. However we
2151 // do not do that, because it's kind of a
2152 // "meta-adjustment" -- instead, we just leave it
2153 // unrecorded and know that there "will be" an
2154 // autoref. regionck and other bits of the code base,
2155 // when they encounter an overloaded autoderef, have
2156 // to do some reconstructive surgery. This is a pretty
2157 // complex mess that is begging for a proper MIR.
2158 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2164 if mt.mutbl == hir::MutImmutable {
2165 lvalue_pref = NoPreference;
2168 None => return (resolved_t, autoderefs, None)
2172 // We've reached the recursion limit, error gracefully.
2173 span_err!(fcx.tcx().sess, sp, E0055,
2174 "reached the recursion limit while auto-dereferencing {:?}",
2176 (fcx.tcx().types.err, 0, None)
2179 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2181 method_call: Option<MethodCall>,
2182 base_expr: Option<&hir::Expr>,
2184 lvalue_pref: LvaluePreference)
2185 -> Option<ty::TypeAndMut<'tcx>>
2187 // Try DerefMut first, if preferred.
2188 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2189 (PreferMutLvalue, Some(trait_did)) => {
2190 method::lookup_in_trait(fcx, span, base_expr,
2191 token::intern("deref_mut"), trait_did,
2197 // Otherwise, fall back to Deref.
2198 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2199 (None, Some(trait_did)) => {
2200 method::lookup_in_trait(fcx, span, base_expr,
2201 token::intern("deref"), trait_did,
2204 (method, _) => method
2207 make_overloaded_lvalue_return_type(fcx, method_call, method)
2210 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2211 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2212 /// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2213 fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2214 method_call: Option<MethodCall>,
2215 method: Option<MethodCallee<'tcx>>)
2216 -> Option<ty::TypeAndMut<'tcx>>
2220 // extract method return type, which will be &T;
2221 // all LB regions should have been instantiated during method lookup
2222 let ret_ty = method.ty.fn_ret();
2223 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
2225 if let Some(method_call) = method_call {
2226 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2229 // method returns &T, but the type as visible to user is T, so deref
2230 ret_ty.builtin_deref(true, NoPreference)
2236 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2238 base_expr: &'tcx hir::Expr,
2241 lvalue_pref: LvaluePreference)
2242 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2244 // FIXME(#18741) -- this is almost but not quite the same as the
2245 // autoderef that normal method probing does. They could likely be
2248 let (ty, autoderefs, final_mt) = autoderef(fcx,
2252 UnresolvedTypeAction::Error,
2255 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2256 adj_ty, idx, false, lvalue_pref, idx_ty)
2259 if final_mt.is_some() {
2263 // After we have fully autoderef'd, if the resulting type is [T; n], then
2264 // do a final unsized coercion to yield [T].
2265 if let ty::TyArray(element_ty, _) = ty.sty {
2266 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2267 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2268 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2274 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2275 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2276 /// This loop implements one step in that search; the autoderef loop is implemented by
2277 /// `lookup_indexing`.
2278 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2279 method_call: MethodCall,
2281 base_expr: &'tcx hir::Expr,
2282 adjusted_ty: Ty<'tcx>,
2285 lvalue_pref: LvaluePreference,
2287 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2289 let tcx = fcx.tcx();
2290 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2291 autoderefs={}, unsize={}, index_ty={:?})",
2299 let input_ty = fcx.infcx().next_ty_var();
2301 // First, try built-in indexing.
2302 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2303 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2304 debug!("try_index_step: success, using built-in indexing");
2305 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2307 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2308 return Some((tcx.types.usize, ty));
2313 // Try `IndexMut` first, if preferred.
2314 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2315 (PreferMutLvalue, Some(trait_did)) => {
2316 method::lookup_in_trait_adjusted(fcx,
2319 token::intern("index_mut"),
2324 Some(vec![input_ty]))
2329 // Otherwise, fall back to `Index`.
2330 let method = match (method, tcx.lang_items.index_trait()) {
2331 (None, Some(trait_did)) => {
2332 method::lookup_in_trait_adjusted(fcx,
2335 token::intern("index"),
2340 Some(vec![input_ty]))
2342 (method, _) => method,
2345 // If some lookup succeeds, write callee into table and extract index/element
2346 // type from the method signature.
2347 // If some lookup succeeded, install method in table
2348 method.and_then(|method| {
2349 debug!("try_index_step: success, using overloaded indexing");
2350 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2351 map(|ret| (input_ty, ret.ty))
2355 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2357 method_fn_ty: Ty<'tcx>,
2358 callee_expr: &'tcx hir::Expr,
2359 args_no_rcvr: &'tcx [P<hir::Expr>],
2360 tuple_arguments: TupleArgumentsFlag,
2361 expected: Expectation<'tcx>)
2362 -> ty::FnOutput<'tcx> {
2363 if method_fn_ty.references_error() {
2364 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2366 let err_inputs = match tuple_arguments {
2367 DontTupleArguments => err_inputs,
2368 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2371 check_argument_types(fcx,
2378 ty::FnConverging(fcx.tcx().types.err)
2380 match method_fn_ty.sty {
2381 ty::TyBareFn(_, ref fty) => {
2382 // HACK(eddyb) ignore self in the definition (see above).
2383 let expected_arg_tys = expected_types_for_fn_args(fcx,
2387 &fty.sig.0.inputs[1..]);
2388 check_argument_types(fcx,
2390 &fty.sig.0.inputs[1..],
2391 &expected_arg_tys[..],
2398 fcx.tcx().sess.span_bug(callee_expr.span,
2399 "method without bare fn type");
2405 /// Generic function that factors out common logic from function calls, method calls and overloaded
2407 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2409 fn_inputs: &[Ty<'tcx>],
2410 expected_arg_tys: &[Ty<'tcx>],
2411 args: &'tcx [P<hir::Expr>],
2413 tuple_arguments: TupleArgumentsFlag) {
2414 let tcx = fcx.ccx.tcx;
2416 // Grab the argument types, supplying fresh type variables
2417 // if the wrong number of arguments were supplied
2418 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2424 // All the input types from the fn signature must outlive the call
2425 // so as to validate implied bounds.
2426 for &fn_input_ty in fn_inputs {
2427 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2430 let mut expected_arg_tys = expected_arg_tys;
2431 let expected_arg_count = fn_inputs.len();
2432 let formal_tys = if tuple_arguments == TupleArguments {
2433 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2434 match tuple_type.sty {
2435 ty::TyTuple(ref arg_types) => {
2436 if arg_types.len() != args.len() {
2437 span_err!(tcx.sess, sp, E0057,
2438 "this function takes {} parameter{} but {} parameter{} supplied",
2440 if arg_types.len() == 1 {""} else {"s"},
2442 if args.len() == 1 {" was"} else {"s were"});
2443 expected_arg_tys = &[];
2444 err_args(fcx.tcx(), args.len())
2446 expected_arg_tys = match expected_arg_tys.get(0) {
2447 Some(&ty) => match ty.sty {
2448 ty::TyTuple(ref tys) => &**tys,
2453 (*arg_types).clone()
2457 span_err!(tcx.sess, sp, E0059,
2458 "cannot use call notation; the first type parameter \
2459 for the function trait is neither a tuple nor unit");
2460 expected_arg_tys = &[];
2461 err_args(fcx.tcx(), args.len())
2464 } else if expected_arg_count == supplied_arg_count {
2466 } else if variadic {
2467 if supplied_arg_count >= expected_arg_count {
2470 span_err!(tcx.sess, sp, E0060,
2471 "this function takes at least {} parameter{} \
2472 but {} parameter{} supplied",
2474 if expected_arg_count == 1 {""} else {"s"},
2476 if supplied_arg_count == 1 {" was"} else {"s were"});
2477 expected_arg_tys = &[];
2478 err_args(fcx.tcx(), supplied_arg_count)
2481 span_err!(tcx.sess, sp, E0061,
2482 "this function takes {} parameter{} but {} parameter{} supplied",
2484 if expected_arg_count == 1 {""} else {"s"},
2486 if supplied_arg_count == 1 {" was"} else {"s were"});
2487 expected_arg_tys = &[];
2488 err_args(fcx.tcx(), supplied_arg_count)
2491 debug!("check_argument_types: formal_tys={:?}",
2492 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2494 // Check the arguments.
2495 // We do this in a pretty awful way: first we typecheck any arguments
2496 // that are not anonymous functions, then we typecheck the anonymous
2497 // functions. This is so that we have more information about the types
2498 // of arguments when we typecheck the functions. This isn't really the
2499 // right way to do this.
2500 let xs = [false, true];
2501 for check_blocks in &xs {
2502 let check_blocks = *check_blocks;
2503 debug!("check_blocks={}", check_blocks);
2505 // More awful hacks: before we check argument types, try to do
2506 // an "opportunistic" vtable resolution of any trait bounds on
2507 // the call. This helps coercions.
2509 fcx.select_new_obligations();
2512 // For variadic functions, we don't have a declared type for all of
2513 // the arguments hence we only do our usual type checking with
2514 // the arguments who's types we do know.
2515 let t = if variadic {
2517 } else if tuple_arguments == TupleArguments {
2522 for (i, arg) in args.iter().take(t).enumerate() {
2523 let is_block = match arg.node {
2524 hir::ExprClosure(..) => true,
2528 if is_block == check_blocks {
2529 debug!("checking the argument");
2530 let formal_ty = formal_tys[i];
2532 // The special-cased logic below has three functions:
2533 // 1. Provide as good of an expected type as possible.
2534 let expected = expected_arg_tys.get(i).map(|&ty| {
2535 Expectation::rvalue_hint(fcx.tcx(), ty)
2538 check_expr_with_unifier(fcx,
2540 expected.unwrap_or(ExpectHasType(formal_ty)),
2542 // 2. Coerce to the most detailed type that could be coerced
2543 // to, which is `expected_ty` if `rvalue_hint` returns an
2544 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2545 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2546 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2548 // 3. Relate the expected type and the formal one,
2549 // if the expected type was used for the coercion.
2550 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2556 // We also need to make sure we at least write the ty of the other
2557 // arguments which we skipped above.
2559 for arg in args.iter().skip(expected_arg_count) {
2560 check_expr(fcx, &**arg);
2562 // There are a few types which get autopromoted when passed via varargs
2563 // in C but we just error out instead and require explicit casts.
2564 let arg_ty = structurally_resolved_type(fcx, arg.span,
2565 fcx.expr_ty(&**arg));
2567 ty::TyFloat(ast::TyF32) => {
2568 fcx.type_error_message(arg.span,
2570 format!("can't pass an {} to variadic \
2571 function, cast to c_double", t)
2574 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
2575 fcx.type_error_message(arg.span, |t| {
2576 format!("can't pass {} to variadic \
2577 function, cast to c_int",
2581 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
2582 fcx.type_error_message(arg.span, |t| {
2583 format!("can't pass {} to variadic \
2584 function, cast to c_uint",
2594 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2595 fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2596 (0..len).map(|_| tcx.types.err).collect()
2599 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2600 call_expr: &hir::Expr,
2601 output: ty::FnOutput<'tcx>) {
2602 fcx.write_ty(call_expr.id, match output {
2603 ty::FnConverging(output_ty) => output_ty,
2604 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2608 // AST fragment checking
2609 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2611 expected: Expectation<'tcx>)
2614 let tcx = fcx.ccx.tcx;
2617 ast::LitStr(..) => tcx.mk_static_str(),
2618 ast::LitByteStr(ref v) => {
2619 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2620 tcx.mk_array(tcx.types.u8, v.len()))
2622 ast::LitByte(_) => tcx.types.u8,
2623 ast::LitChar(_) => tcx.types.char,
2624 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2625 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2626 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
2627 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2629 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2630 ty::TyChar => Some(tcx.types.u8),
2631 ty::TyRawPtr(..) => Some(tcx.types.usize),
2632 ty::TyBareFn(..) => Some(tcx.types.usize),
2636 opt_ty.unwrap_or_else(
2637 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2639 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2640 ast::LitFloatUnsuffixed(_) => {
2641 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2643 ty::TyFloat(_) => Some(ty),
2647 opt_ty.unwrap_or_else(
2648 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2650 ast::LitBool(_) => tcx.types.bool
2654 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2655 expr: &'tcx hir::Expr,
2656 expected: Ty<'tcx>) {
2657 check_expr_with_unifier(
2658 fcx, expr, ExpectHasType(expected), NoPreference,
2659 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2662 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2663 expr: &'tcx hir::Expr,
2664 expected: Ty<'tcx>) {
2665 check_expr_with_unifier(
2666 fcx, expr, ExpectHasType(expected), NoPreference,
2667 || demand::coerce(fcx, expr.span, expected, expr));
2670 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2671 expected: Ty<'tcx>) {
2672 check_expr_with_unifier(
2673 fcx, expr, ExpectHasType(expected), NoPreference,
2677 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2678 expr: &'tcx hir::Expr,
2679 expected: Expectation<'tcx>) {
2680 check_expr_with_unifier(
2681 fcx, expr, expected, NoPreference,
2685 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2686 expr: &'tcx hir::Expr,
2687 expected: Expectation<'tcx>,
2688 lvalue_pref: LvaluePreference)
2690 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2693 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2694 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2697 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2698 lvalue_pref: LvaluePreference) {
2699 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2702 // determine the `self` type, using fresh variables for all variables
2703 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2704 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2706 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2707 span: Span, // (potential) receiver for this impl
2709 -> TypeAndSubsts<'tcx> {
2710 let tcx = fcx.tcx();
2712 let ity = tcx.lookup_item_type(did);
2713 let (tps, rps, raw_ty) =
2714 (ity.generics.types.get_slice(subst::TypeSpace),
2715 ity.generics.regions.get_slice(subst::TypeSpace),
2718 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2720 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2721 let mut substs = subst::Substs::new(
2722 VecPerParamSpace::empty(),
2723 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2724 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2725 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2727 TypeAndSubsts { substs: substs, ty: substd_ty }
2730 /// Controls whether the arguments are tupled. This is used for the call
2733 /// Tupling means that all call-side arguments are packed into a tuple and
2734 /// passed as a single parameter. For example, if tupling is enabled, this
2737 /// fn f(x: (isize, isize))
2739 /// Can be called as:
2746 #[derive(Clone, Eq, PartialEq)]
2747 enum TupleArgumentsFlag {
2752 /// Unifies the return type with the expected type early, for more coercions
2753 /// and forward type information on the argument expressions.
2754 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2756 expected_ret: Expectation<'tcx>,
2757 formal_ret: ty::FnOutput<'tcx>,
2758 formal_args: &[Ty<'tcx>])
2760 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2761 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2762 fcx.infcx().commit_regions_if_ok(|| {
2763 // Attempt to apply a subtyping relationship between the formal
2764 // return type (likely containing type variables if the function
2765 // is polymorphic) and the expected return type.
2766 // No argument expectations are produced if unification fails.
2767 let origin = infer::Misc(call_span);
2768 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2769 // FIXME(#15760) can't use try! here, FromError doesn't default
2770 // to identity so the resulting type is not constrained.
2771 if let Err(e) = ures {
2775 // Record all the argument types, with the substitutions
2776 // produced from the above subtyping unification.
2777 Ok(formal_args.iter().map(|ty| {
2778 fcx.infcx().resolve_type_vars_if_possible(ty)
2784 }).unwrap_or(vec![]);
2785 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2786 formal_args, formal_ret,
2787 expected_args, expected_ret);
2792 /// If an expression has any sub-expressions that result in a type error,
2793 /// inspecting that expression's type with `ty.references_error()` will return
2794 /// true. Likewise, if an expression is known to diverge, inspecting its
2795 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2796 /// strict, _|_ can appear in the type of an expression that does not,
2797 /// itself, diverge: for example, fn() -> _|_.)
2798 /// Note that inspecting a type's structure *directly* may expose the fact
2799 /// that there are actually multiple representations for `TyError`, so avoid
2800 /// that when err needs to be handled differently.
2801 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
2802 expr: &'tcx hir::Expr,
2803 expected: Expectation<'tcx>,
2804 lvalue_pref: LvaluePreference,
2808 debug!(">> typechecking: expr={:?} expected={:?}",
2811 // Checks a method call.
2812 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2813 expr: &'tcx hir::Expr,
2814 method_name: Spanned<ast::Name>,
2815 args: &'tcx [P<hir::Expr>],
2817 expected: Expectation<'tcx>,
2818 lvalue_pref: LvaluePreference) {
2819 let rcvr = &*args[0];
2820 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2822 // no need to check for bot/err -- callee does that
2823 let expr_t = structurally_resolved_type(fcx,
2825 fcx.expr_ty(&*rcvr));
2827 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2828 let fn_ty = match method::lookup(fcx,
2836 let method_ty = method.ty;
2837 let method_call = MethodCall::expr(expr.id);
2838 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2842 method::report_error(fcx, method_name.span, expr_t,
2843 method_name.node, Some(rcvr), error);
2844 fcx.write_error(expr.id);
2849 // Call the generic checker.
2850 let ret_ty = check_method_argument_types(fcx,
2858 write_call(fcx, expr, ret_ty);
2861 // A generic function for checking the then and else in an if
2863 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2864 cond_expr: &'tcx hir::Expr,
2865 then_blk: &'tcx hir::Block,
2866 opt_else_expr: Option<&'tcx hir::Expr>,
2869 expected: Expectation<'tcx>) {
2870 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2872 let expected = expected.adjust_for_branches(fcx);
2873 check_block_with_expected(fcx, then_blk, expected);
2874 let then_ty = fcx.node_ty(then_blk.id);
2876 let branches_ty = match opt_else_expr {
2877 Some(ref else_expr) => {
2878 check_expr_with_expectation(fcx, &**else_expr, expected);
2879 let else_ty = fcx.expr_ty(&**else_expr);
2880 infer::common_supertype(fcx.infcx(),
2881 infer::IfExpression(sp),
2887 infer::common_supertype(fcx.infcx(),
2888 infer::IfExpressionWithNoElse(sp),
2895 let cond_ty = fcx.expr_ty(cond_expr);
2896 let if_ty = if cond_ty.references_error() {
2902 fcx.write_ty(id, if_ty);
2905 // Check field access expressions
2906 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2907 expr: &'tcx hir::Expr,
2908 lvalue_pref: LvaluePreference,
2909 base: &'tcx hir::Expr,
2910 field: &Spanned<ast::Name>) {
2911 let tcx = fcx.ccx.tcx;
2912 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2913 let expr_t = structurally_resolved_type(fcx, expr.span,
2915 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2916 let (_, autoderefs, field_ty) = autoderef(fcx,
2920 UnresolvedTypeAction::Error,
2924 ty::TyStruct(base_def, substs) => {
2925 debug!("struct named {:?}", base_t);
2926 base_def.struct_variant()
2927 .find_field_named(field.node)
2928 .map(|f| fcx.field_ty(expr.span, f, substs))
2935 fcx.write_ty(expr.id, field_ty);
2936 fcx.write_autoderef_adjustment(base.id, autoderefs);
2942 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2943 fcx.type_error_message(
2946 format!("attempted to take value of method `{}` on type \
2947 `{}`", field.node, actual)
2951 tcx.sess.fileline_help(field.span,
2952 "maybe a `()` to call it is missing? \
2953 If not, try an anonymous function");
2955 fcx.type_error_message(
2958 format!("attempted access of field `{}` on \
2959 type `{}`, but no field with that \
2965 if let ty::TyStruct(def, _) = expr_t.sty {
2966 suggest_field_names(def.struct_variant(), field, tcx, vec![]);
2970 fcx.write_error(expr.id);
2973 // displays hints about the closest matches in field names
2974 fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
2975 field: &Spanned<ast::Name>,
2976 tcx: &ty::ctxt<'tcx>,
2977 skip : Vec<InternedString>) {
2978 let name = field.node.as_str();
2979 // only find fits with at least one matching letter
2980 let mut best_dist = name.len();
2981 let mut best = None;
2982 for elem in &variant.fields {
2983 let n = elem.name.as_str();
2984 // ignore already set fields
2985 if skip.iter().any(|x| *x == n) {
2988 // ignore private fields from non-local crates
2989 if variant.did.krate != LOCAL_CRATE && elem.vis != Visibility::Public {
2992 let dist = lev_distance(&n, &name);
2993 if dist < best_dist {
2998 if let Some(n) = best {
2999 tcx.sess.span_help(field.span,
3000 &format!("did you mean `{}`?", n));
3004 // Check tuple index expressions
3005 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3006 expr: &'tcx hir::Expr,
3007 lvalue_pref: LvaluePreference,
3008 base: &'tcx hir::Expr,
3009 idx: codemap::Spanned<usize>) {
3010 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3011 let expr_t = structurally_resolved_type(fcx, expr.span,
3013 let mut tuple_like = false;
3014 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3015 let (_, autoderefs, field_ty) = autoderef(fcx,
3019 UnresolvedTypeAction::Error,
3023 ty::TyStruct(base_def, substs) => {
3024 tuple_like = base_def.struct_variant().is_tuple_struct();
3026 debug!("tuple struct named {:?}", base_t);
3027 base_def.struct_variant()
3030 .map(|f| fcx.field_ty(expr.span, f, substs))
3035 ty::TyTuple(ref v) => {
3037 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3044 fcx.write_ty(expr.id, field_ty);
3045 fcx.write_autoderef_adjustment(base.id, autoderefs);
3050 fcx.type_error_message(
3054 format!("attempted out-of-bounds tuple index `{}` on \
3059 format!("attempted tuple index `{}` on type `{}`, but the \
3060 type was not a tuple or tuple struct",
3067 fcx.write_error(expr.id);
3070 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3072 variant: ty::VariantDef<'tcx>,
3074 skip_fields: &[hir::Field]) {
3075 fcx.type_error_message(
3077 |actual| if let ty::TyEnum(..) = ty.sty {
3078 format!("struct variant `{}::{}` has no field named `{}`",
3079 actual, variant.name.as_str(), field.name.node)
3081 format!("structure `{}` has no field named `{}`",
3082 actual, field.name.node)
3086 // prevent all specified fields from being suggested
3087 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3088 suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
3091 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3094 variant: ty::VariantDef<'tcx>,
3095 ast_fields: &'tcx [hir::Field],
3096 check_completeness: bool) {
3097 let tcx = fcx.ccx.tcx;
3098 let substs = match adt_ty.sty {
3099 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3100 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3103 let mut remaining_fields = FnvHashMap();
3104 for field in &variant.fields {
3105 remaining_fields.insert(field.name, field);
3108 let mut error_happened = false;
3110 // Typecheck each field.
3111 for field in ast_fields {
3112 let expected_field_type;
3114 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3115 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3117 error_happened = true;
3118 expected_field_type = tcx.types.err;
3119 if let Some(_) = variant.find_field_named(field.name.node) {
3120 span_err!(fcx.tcx().sess, field.name.span, E0062,
3121 "field `{}` specified more than once",
3124 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3128 // Make sure to give a type to the field even if there's
3129 // an error, so we can continue typechecking
3130 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3133 // Make sure the programmer specified all the fields.
3134 if check_completeness &&
3136 !remaining_fields.is_empty()
3138 span_err!(tcx.sess, span, E0063,
3139 "missing field{}: {}",
3140 if remaining_fields.len() == 1 {""} else {"s"},
3141 remaining_fields.keys()
3142 .map(|n| format!("`{}`", n))
3143 .collect::<Vec<_>>()
3149 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3151 fields: &'tcx [hir::Field],
3152 base_expr: &'tcx Option<P<hir::Expr>>) {
3153 // Make sure to still write the types
3154 // otherwise we might ICE
3155 fcx.write_error(id);
3156 for field in fields {
3157 check_expr(fcx, &*field.expr);
3160 Some(ref base) => check_expr(fcx, &**base),
3165 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3168 fields: &'tcx [hir::Field],
3169 base_expr: &'tcx Option<P<hir::Expr>>)
3171 let tcx = fcx.tcx();
3173 // Find the relevant variant
3174 let def = lookup_full_def(tcx, path.span, expr.id);
3175 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
3176 Some((adt, variant)) => (adt, variant),
3178 span_err!(fcx.tcx().sess, path.span, E0071,
3179 "`{}` does not name a structure",
3180 pprust::path_to_string(path));
3181 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3186 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3187 fcx.write_ty(expr.id, expr_ty);
3189 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3190 base_expr.is_none());
3192 if let &Some(ref base_expr) = base_expr {
3193 check_expr_has_type(fcx, base_expr, expr_ty);
3194 if adt.adt_kind() == ty::AdtKind::Enum {
3195 span_err!(tcx.sess, base_expr.span, E0436,
3196 "functional record update syntax requires a struct");
3201 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3203 let tcx = fcx.ccx.tcx;
3206 hir::ExprBox(ref subexpr) => {
3207 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3209 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3213 check_expr_with_expectation(fcx, subexpr, expected_inner);
3214 let referent_ty = fcx.expr_ty(&**subexpr);
3215 fcx.write_ty(id, tcx.mk_box(referent_ty));
3218 hir::ExprLit(ref lit) => {
3219 let typ = check_lit(fcx, &**lit, expected);
3220 fcx.write_ty(id, typ);
3222 hir::ExprBinary(op, ref lhs, ref rhs) => {
3223 op::check_binop(fcx, expr, op, lhs, rhs);
3225 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3226 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3228 hir::ExprUnary(unop, ref oprnd) => {
3229 let expected_inner = match unop {
3230 hir::UnNot | hir::UnNeg => {
3237 let lvalue_pref = match unop {
3238 hir::UnDeref => lvalue_pref,
3241 check_expr_with_expectation_and_lvalue_pref(
3242 fcx, &**oprnd, expected_inner, lvalue_pref);
3243 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3245 if !oprnd_t.references_error() {
3248 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3249 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
3251 None => match try_overloaded_deref(fcx, expr.span,
3252 Some(MethodCall::expr(expr.id)),
3253 Some(&**oprnd), oprnd_t, lvalue_pref) {
3256 fcx.type_error_message(expr.span, |actual| {
3257 format!("type `{}` cannot be \
3258 dereferenced", actual)
3266 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3268 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3269 oprnd_t = op::check_user_unop(fcx, "!", "not",
3270 tcx.lang_items.not_trait(),
3271 expr, &**oprnd, oprnd_t, unop);
3275 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3277 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3278 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3279 tcx.lang_items.neg_trait(),
3280 expr, &**oprnd, oprnd_t, unop);
3285 fcx.write_ty(id, oprnd_t);
3287 hir::ExprAddrOf(mutbl, ref oprnd) => {
3288 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3290 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3291 if fcx.tcx().expr_is_lval(&**oprnd) {
3292 // Lvalues may legitimately have unsized types.
3293 // For example, dereferences of a fat pointer and
3294 // the last field of a struct can be unsized.
3295 ExpectHasType(mt.ty)
3297 Expectation::rvalue_hint(tcx, mt.ty)
3303 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3304 check_expr_with_expectation_and_lvalue_pref(fcx,
3309 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3310 let oprnd_t = if tm.ty.references_error() {
3313 // Note: at this point, we cannot say what the best lifetime
3314 // is to use for resulting pointer. We want to use the
3315 // shortest lifetime possible so as to avoid spurious borrowck
3316 // errors. Moreover, the longest lifetime will depend on the
3317 // precise details of the value whose address is being taken
3318 // (and how long it is valid), which we don't know yet until type
3319 // inference is complete.
3321 // Therefore, here we simply generate a region variable. The
3322 // region inferencer will then select the ultimate value.
3323 // Finally, borrowck is charged with guaranteeing that the
3324 // value whose address was taken can actually be made to live
3325 // as long as it needs to live.
3326 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3327 tcx.mk_ref(tcx.mk_region(region), tm)
3329 fcx.write_ty(id, oprnd_t);
3331 hir::ExprPath(ref maybe_qself, ref path) => {
3332 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3333 fcx.to_ty(&qself.ty)
3336 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3338 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3339 // Create some fake resolution that can't possibly be a type.
3340 def::PathResolution {
3341 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3342 last_private: LastMod(AllPublic),
3343 depth: path.segments.len()
3346 tcx.sess.span_bug(expr.span,
3347 &format!("unbound path {:?}", expr))
3350 if let Some((opt_ty, segments, def)) =
3351 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3352 expr.span, expr.id) {
3353 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3356 instantiate_path(fcx,
3366 // We always require that the type provided as the value for
3367 // a type parameter outlives the moment of instantiation.
3368 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3369 fcx.add_wf_bounds(&item_substs.substs, expr);
3372 hir::ExprInlineAsm(ref ia) => {
3373 for &(_, ref input) in &ia.inputs {
3374 check_expr(fcx, &**input);
3376 for &(_, ref out, _) in &ia.outputs {
3377 check_expr(fcx, &**out);
3381 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3382 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3383 hir::ExprRet(ref expr_opt) => {
3385 ty::FnConverging(result_type) => {
3388 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
3389 result_type, fcx.tcx().mk_nil()) {
3390 span_err!(tcx.sess, expr.span, E0069,
3391 "`return;` in a function whose return type is \
3395 check_expr_coercable_to_type(fcx, &**e, result_type);
3399 ty::FnDiverging => {
3400 if let Some(ref e) = *expr_opt {
3401 check_expr(fcx, &**e);
3403 span_err!(tcx.sess, expr.span, E0166,
3404 "`return` in a function declared as diverging");
3407 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3409 hir::ExprAssign(ref lhs, ref rhs) => {
3410 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3412 let tcx = fcx.tcx();
3413 if !tcx.expr_is_lval(&**lhs) {
3414 span_err!(tcx.sess, expr.span, E0070,
3415 "invalid left-hand side expression");
3418 let lhs_ty = fcx.expr_ty(&**lhs);
3419 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3420 let rhs_ty = fcx.expr_ty(&**rhs);
3422 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3424 if lhs_ty.references_error() || rhs_ty.references_error() {
3425 fcx.write_error(id);
3430 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3431 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3432 id, expr.span, expected);
3434 hir::ExprWhile(ref cond, ref body, _) => {
3435 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3436 check_block_no_value(fcx, &**body);
3437 let cond_ty = fcx.expr_ty(&**cond);
3438 let body_ty = fcx.node_ty(body.id);
3439 if cond_ty.references_error() || body_ty.references_error() {
3440 fcx.write_error(id);
3446 hir::ExprLoop(ref body, _) => {
3447 check_block_no_value(fcx, &**body);
3448 if !may_break(tcx, expr.id, &**body) {
3449 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3454 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3455 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
3457 hir::ExprClosure(capture, ref decl, ref body) => {
3458 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
3460 hir::ExprBlock(ref b) => {
3461 check_block_with_expected(fcx, &**b, expected);
3462 fcx.write_ty(id, fcx.node_ty(b.id));
3464 hir::ExprCall(ref callee, ref args) => {
3465 callee::check_call(fcx, expr, &**callee, &args[..], expected);
3467 // we must check that return type of called functions is WF:
3468 let ret_ty = fcx.expr_ty(expr);
3469 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3471 hir::ExprMethodCall(name, ref tps, ref args) => {
3472 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3473 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3474 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3476 fcx.write_error(id);
3479 hir::ExprCast(ref e, ref t) => {
3480 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3481 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3484 // Find the type of `e`. Supply hints based on the type we are casting to,
3486 let t_cast = fcx.to_ty(t);
3487 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3488 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3489 let t_expr = fcx.expr_ty(e);
3491 // Eagerly check for some obvious errors.
3492 if t_expr.references_error() {
3493 fcx.write_error(id);
3494 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3495 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3497 // Write a type for the whole expression, assuming everything is going
3499 fcx.write_ty(id, t_cast);
3501 // Defer other checks until we're done type checking.
3502 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3503 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
3504 deferred_cast_checks.push(cast_check);
3507 hir::ExprVec(ref args) => {
3508 let uty = expected.to_option(fcx).and_then(|uty| {
3510 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3515 let typ = match uty {
3518 check_expr_coercable_to_type(fcx, &**e, uty);
3523 let t: Ty = fcx.infcx().next_ty_var();
3525 check_expr_has_type(fcx, &**e, t);
3530 let typ = tcx.mk_array(typ, args.len());
3531 fcx.write_ty(id, typ);
3533 hir::ExprRepeat(ref element, ref count_expr) => {
3534 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
3535 let count = fcx.tcx().eval_repeat_count(&**count_expr);
3537 let uty = match expected {
3538 ExpectHasType(uty) => {
3540 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3547 let (element_ty, t) = match uty {
3549 check_expr_coercable_to_type(fcx, &**element, uty);
3553 let t: Ty = fcx.infcx().next_ty_var();
3554 check_expr_has_type(fcx, &**element, t);
3555 (fcx.expr_ty(&**element), t)
3560 // For [foo, ..n] where n > 1, `foo` must have
3562 fcx.require_type_meets(
3569 if element_ty.references_error() {
3570 fcx.write_error(id);
3572 let t = tcx.mk_array(t, count);
3573 fcx.write_ty(id, t);
3576 hir::ExprTup(ref elts) => {
3577 let flds = expected.only_has_type(fcx).and_then(|ty| {
3579 ty::TyTuple(ref flds) => Some(&flds[..]),
3583 let mut err_field = false;
3585 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3586 let t = match flds {
3587 Some(ref fs) if i < fs.len() => {
3589 check_expr_coercable_to_type(fcx, &**e, ety);
3593 check_expr_with_expectation(fcx, &**e, NoExpectation);
3597 err_field = err_field || t.references_error();
3601 fcx.write_error(id);
3603 let typ = tcx.mk_tup(elt_ts);
3604 fcx.write_ty(id, typ);
3607 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3608 check_expr_struct(fcx, expr, path, fields, base_expr);
3610 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3612 hir::ExprField(ref base, ref field) => {
3613 check_field(fcx, expr, lvalue_pref, &**base, field);
3615 hir::ExprTupField(ref base, idx) => {
3616 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3618 hir::ExprIndex(ref base, ref idx) => {
3619 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
3620 check_expr(fcx, &**idx);
3622 let base_t = fcx.expr_ty(&**base);
3623 let idx_t = fcx.expr_ty(&**idx);
3625 if base_t.references_error() {
3626 fcx.write_ty(id, base_t);
3627 } else if idx_t.references_error() {
3628 fcx.write_ty(id, idx_t);
3630 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3631 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3632 Some((index_ty, element_ty)) => {
3633 let idx_expr_ty = fcx.expr_ty(idx);
3634 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3635 fcx.write_ty(id, element_ty);
3638 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3639 fcx.type_error_message(
3642 format!("cannot index a value of type `{}`",
3647 fcx.write_ty(id, fcx.tcx().types.err);
3652 hir::ExprRange(ref start, ref end) => {
3653 let t_start = start.as_ref().map(|e| {
3654 check_expr(fcx, &**e);
3657 let t_end = end.as_ref().map(|e| {
3658 check_expr(fcx, &**e);
3662 let idx_type = match (t_start, t_end) {
3663 (Some(ty), None) | (None, Some(ty)) => {
3666 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3667 t_end.references_error()) => {
3668 Some(fcx.tcx().types.err)
3670 (Some(t_start), Some(t_end)) => {
3671 Some(infer::common_supertype(fcx.infcx(),
3672 infer::RangeExpression(expr.span),
3680 // Note that we don't check the type of start/end satisfy any
3681 // bounds because right now the range structs do not have any. If we add
3682 // some bounds, then we'll need to check `t_start` against them here.
3684 let range_type = match idx_type {
3685 Some(idx_type) if idx_type.references_error() => {
3689 // Find the did from the appropriate lang item.
3690 let did = match (start, end) {
3691 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3692 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3693 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3695 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3699 if let Some(did) = did {
3700 let def = tcx.lookup_adt_def(did);
3701 let predicates = tcx.lookup_predicates(did);
3702 let substs = Substs::new_type(vec![idx_type], vec![]);
3703 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
3704 fcx.add_obligations_for_parameters(
3705 traits::ObligationCause::new(expr.span,
3707 traits::ItemObligation(did)),
3710 tcx.mk_struct(def, tcx.mk_substs(substs))
3712 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
3717 // Neither start nor end => RangeFull
3718 if let Some(did) = tcx.lang_items.range_full_struct() {
3720 tcx.lookup_adt_def(did),
3721 tcx.mk_substs(Substs::empty())
3724 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
3730 fcx.write_ty(id, range_type);
3735 debug!("type of expr({}) {} is...", expr.id,
3736 pprust::expr_to_string(expr));
3737 debug!("... {:?}, expected is {:?}",
3744 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3745 path_res: def::PathResolution,
3746 opt_self_ty: Option<Ty<'tcx>>,
3747 path: &'a hir::Path,
3749 node_id: ast::NodeId)
3750 -> Option<(Option<Ty<'tcx>>,
3751 &'a [hir::PathSegment],
3755 // Associated constants can't depend on generic types.
3756 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3760 node_id: ast::NodeId) -> bool {
3762 def::DefAssociatedConst(..) => {
3763 if ty.has_param_types() || ty.has_self_ty() {
3764 span_err!(fcx.sess(), span, E0329,
3765 "Associated consts cannot depend \
3766 on type parameters or Self.");
3767 fcx.write_error(node_id);
3776 // If fully resolved already, we don't have to do anything.
3777 if path_res.depth == 0 {
3778 if let Some(ty) = opt_self_ty {
3779 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3784 Some((opt_self_ty, &path.segments, path_res.base_def))
3786 let mut def = path_res.base_def;
3787 let ty_segments = path.segments.split_last().unwrap().1;
3788 let base_ty_end = path.segments.len() - path_res.depth;
3789 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3790 PathParamMode::Optional,
3793 &ty_segments[..base_ty_end],
3794 &ty_segments[base_ty_end..]);
3795 let item_segment = path.segments.last().unwrap();
3796 let item_name = item_segment.identifier.name;
3797 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3799 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3802 // Write back the new resolution.
3803 fcx.ccx.tcx.def_map.borrow_mut()
3804 .insert(node_id, def::PathResolution {
3806 last_private: path_res.last_private.or(lp),
3809 Some((Some(ty), slice::ref_slice(item_segment), def))
3812 method::report_error(fcx, span, ty,
3813 item_name, None, error);
3814 fcx.write_error(node_id);
3821 impl<'tcx> Expectation<'tcx> {
3822 /// Provide an expectation for an rvalue expression given an *optional*
3823 /// hint, which is not required for type safety (the resulting type might
3824 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3825 /// is useful in determining the concrete type.
3827 /// The primary use case is where the expected type is a fat pointer,
3828 /// like `&[isize]`. For example, consider the following statement:
3830 /// let x: &[isize] = &[1, 2, 3];
3832 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3833 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3834 /// expectation `ExpectHasType([isize])`, that would be too strong --
3835 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3836 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3837 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3838 /// which still is useful, because it informs integer literals and the like.
3839 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3840 /// for examples of where this comes up,.
3841 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3842 match tcx.struct_tail(ty).sty {
3843 ty::TySlice(_) | ty::TyTrait(..) => {
3844 ExpectRvalueLikeUnsized(ty)
3846 _ => ExpectHasType(ty)
3850 // Resolves `expected` by a single level if it is a variable. If
3851 // there is no expected type or resolution is not possible (e.g.,
3852 // no constraints yet present), just returns `None`.
3853 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3858 ExpectCastableToType(t) => {
3859 ExpectCastableToType(
3860 fcx.infcx().resolve_type_vars_if_possible(&t))
3862 ExpectHasType(t) => {
3864 fcx.infcx().resolve_type_vars_if_possible(&t))
3866 ExpectRvalueLikeUnsized(t) => {
3867 ExpectRvalueLikeUnsized(
3868 fcx.infcx().resolve_type_vars_if_possible(&t))
3873 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3874 match self.resolve(fcx) {
3875 NoExpectation => None,
3876 ExpectCastableToType(ty) |
3878 ExpectRvalueLikeUnsized(ty) => Some(ty),
3882 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3883 match self.resolve(fcx) {
3884 ExpectHasType(ty) => Some(ty),
3890 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3891 local: &'tcx hir::Local,
3892 init: &'tcx hir::Expr)
3894 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3896 let local_ty = fcx.local_ty(init.span, local.id);
3897 if let Some(m) = ref_bindings {
3898 // Somewhat subtle: if we have a `ref` binding in the pattern,
3899 // we want to avoid introducing coercions for the RHS. This is
3900 // both because it helps preserve sanity and, in the case of
3901 // ref mut, for soundness (issue #23116). In particular, in
3902 // the latter case, we need to be clear that the type of the
3903 // referent for the reference that results is *equal to* the
3904 // type of the lvalue it is referencing, and not some
3905 // supertype thereof.
3906 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3907 let init_ty = fcx.expr_ty(init);
3908 demand::eqtype(fcx, init.span, init_ty, local_ty);
3910 check_expr_coercable_to_type(fcx, init, local_ty)
3914 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3915 let tcx = fcx.ccx.tcx;
3917 let t = fcx.local_ty(local.span, local.id);
3918 fcx.write_ty(local.id, t);
3920 if let Some(ref init) = local.init {
3921 check_decl_initializer(fcx, local, &**init);
3922 let init_ty = fcx.expr_ty(&**init);
3923 if init_ty.references_error() {
3924 fcx.write_ty(local.id, init_ty);
3928 let pcx = pat_ctxt {
3930 map: pat_id_map(&tcx.def_map, &*local.pat),
3932 _match::check_pat(&pcx, &*local.pat, t);
3933 let pat_ty = fcx.node_ty(local.pat.id);
3934 if pat_ty.references_error() {
3935 fcx.write_ty(local.id, pat_ty);
3939 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3941 let mut saw_bot = false;
3942 let mut saw_err = false;
3944 hir::StmtDecl(ref decl, id) => {
3947 hir::DeclLocal(ref l) => {
3948 check_decl_local(fcx, &**l);
3949 let l_t = fcx.node_ty(l.id);
3950 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3951 saw_err = saw_err || l_t.references_error();
3953 hir::DeclItem(_) => {/* ignore for now */ }
3956 hir::StmtExpr(ref expr, id) => {
3958 // Check with expected type of ()
3959 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
3960 let expr_ty = fcx.expr_ty(&**expr);
3961 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3962 saw_err = saw_err || expr_ty.references_error();
3964 hir::StmtSemi(ref expr, id) => {
3966 check_expr(fcx, &**expr);
3967 let expr_ty = fcx.expr_ty(&**expr);
3968 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3969 saw_err |= expr_ty.references_error();
3973 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3976 fcx.write_error(node_id);
3979 fcx.write_nil(node_id)
3983 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3984 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3985 let blkty = fcx.node_ty(blk.id);
3986 if blkty.references_error() {
3987 fcx.write_error(blk.id);
3989 let nilty = fcx.tcx().mk_nil();
3990 demand::suptype(fcx, blk.span, nilty, blkty);
3994 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3995 blk: &'tcx hir::Block,
3996 expected: Expectation<'tcx>) {
3998 let mut fcx_ps = fcx.ps.borrow_mut();
3999 let unsafety_state = fcx_ps.recurse(blk);
4000 replace(&mut *fcx_ps, unsafety_state)
4003 let mut warned = false;
4004 let mut any_diverges = false;
4005 let mut any_err = false;
4006 for s in &blk.stmts {
4007 check_stmt(fcx, &**s);
4008 let s_id = ::rustc_front::util::stmt_id(&**s);
4009 let s_ty = fcx.node_ty(s_id);
4010 if any_diverges && !warned && match s.node {
4011 hir::StmtDecl(ref decl, _) => {
4013 hir::DeclLocal(_) => true,
4017 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
4022 .add_lint(lint::builtin::UNREACHABLE_CODE,
4025 "unreachable statement".to_string());
4028 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
4029 any_err = any_err || s_ty.references_error();
4032 None => if any_err {
4033 fcx.write_error(blk.id);
4034 } else if any_diverges {
4035 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4037 fcx.write_nil(blk.id);
4040 if any_diverges && !warned {
4044 .add_lint(lint::builtin::UNREACHABLE_CODE,
4047 "unreachable expression".to_string());
4049 let ety = match expected {
4050 ExpectHasType(ety) => {
4051 check_expr_coercable_to_type(fcx, &**e, ety);
4055 check_expr_with_expectation(fcx, &**e, expected);
4061 fcx.write_error(blk.id);
4062 } else if any_diverges {
4063 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4065 fcx.write_ty(blk.id, ety);
4070 *fcx.ps.borrow_mut() = prev;
4073 /// Checks a constant appearing in a type. At the moment this is just the
4074 /// length expression in a fixed-length vector, but someday it might be
4075 /// extended to type-level numeric literals.
4076 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4077 expr: &'tcx hir::Expr,
4078 expected_type: Ty<'tcx>) {
4079 let tables = RefCell::new(ty::Tables::empty());
4080 let inh = static_inherited_fields(ccx, &tables);
4081 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4082 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4085 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4089 let tables = RefCell::new(ty::Tables::empty());
4090 let inh = static_inherited_fields(ccx, &tables);
4091 let rty = ccx.tcx.node_id_to_type(id);
4092 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4093 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4094 check_const_with_ty(&fcx, sp, e, declty);
4097 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4101 // Gather locals in statics (because of block expressions).
4102 // This is technically unnecessary because locals in static items are forbidden,
4103 // but prevents type checking from blowing up before const checking can properly
4105 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4107 check_expr_with_hint(fcx, e, declty);
4108 demand::coerce(fcx, e.span, declty, e);
4110 fcx.select_all_obligations_and_apply_defaults();
4111 upvar::closure_analyze_const(&fcx, e);
4112 fcx.select_obligations_where_possible();
4114 fcx.select_all_obligations_or_error();
4116 regionck::regionck_expr(fcx, e);
4117 writeback::resolve_type_vars_in_expr(fcx, e);
4120 /// Checks whether a type can be represented in memory. In particular, it
4121 /// identifies types that contain themselves without indirection through a
4122 /// pointer, which would mean their size is unbounded.
4123 pub fn check_representable(tcx: &ty::ctxt,
4125 item_id: ast::NodeId,
4126 designation: &str) -> bool {
4127 let rty = tcx.node_id_to_type(item_id);
4129 // Check that it is possible to represent this type. This call identifies
4130 // (1) types that contain themselves and (2) types that contain a different
4131 // recursive type. It is only necessary to throw an error on those that
4132 // contain themselves. For case 2, there must be an inner type that will be
4133 // caught by case 1.
4134 match rty.is_representable(tcx, sp) {
4135 Representability::SelfRecursive => {
4136 span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
4137 tcx.sess.fileline_help(
4138 sp, "wrap the inner value in a box to make it representable");
4141 Representability::Representable | Representability::ContainsRecursive => (),
4146 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
4147 let t = tcx.node_id_to_type(id);
4149 ty::TyStruct(def, substs) => {
4150 let fields = &def.struct_variant().fields;
4151 if fields.is_empty() {
4152 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4155 let e = fields[0].ty(tcx, substs);
4156 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4157 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4161 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4162 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4164 span_err!(tcx.sess, sp, E0077,
4165 "SIMD vector element type should be machine type");
4174 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4176 vs: &'tcx [P<hir::Variant>],
4179 fn disr_in_range(ccx: &CrateCtxt,
4181 disr: ty::Disr) -> bool {
4182 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4184 ast::TyU8 => disr as u8 as Disr == disr,
4185 ast::TyU16 => disr as u16 as Disr == disr,
4186 ast::TyU32 => disr as u32 as Disr == disr,
4187 ast::TyU64 => disr as u64 as Disr == disr,
4188 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4191 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4193 ast::TyI8 => disr as i8 as Disr == disr,
4194 ast::TyI16 => disr as i16 as Disr == disr,
4195 ast::TyI32 => disr as i32 as Disr == disr,
4196 ast::TyI64 => disr as i64 as Disr == disr,
4197 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4201 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4202 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4206 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4207 vs: &'tcx [P<hir::Variant>],
4209 hint: attr::ReprAttr) {
4210 #![allow(trivial_numeric_casts)]
4212 let rty = ccx.tcx.node_id_to_type(id);
4213 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4215 let tables = RefCell::new(ty::Tables::empty());
4216 let inh = static_inherited_fields(ccx, &tables);
4217 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4219 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4221 if let Some(ref e) = v.node.disr_expr {
4222 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4226 let def_id = ccx.tcx.map.local_def_id(id);
4228 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4229 for (v, variant) in vs.iter().zip(variants.iter()) {
4230 let current_disr_val = variant.disr_val;
4232 // Check for duplicate discriminant values
4233 match disr_vals.iter().position(|&x| x == current_disr_val) {
4235 span_err!(ccx.tcx.sess, v.span, E0081,
4236 "discriminant value `{}` already exists", disr_vals[i]);
4237 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4238 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
4239 "conflicting discriminant here")
4243 // Check for unrepresentable discriminant values
4245 attr::ReprAny | attr::ReprExtern => (),
4246 attr::ReprInt(sp, ity) => {
4247 if !disr_in_range(ccx, ity, current_disr_val) {
4248 span_err!(ccx.tcx.sess, v.span, E0082,
4249 "discriminant value outside specified type");
4250 span_note!(ccx.tcx.sess, sp,
4251 "discriminant type specified here");
4255 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4257 attr::ReprPacked => {
4258 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4261 disr_vals.push(current_disr_val);
4265 let def_id = ccx.tcx.map.local_def_id(id);
4266 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4268 if hint != attr::ReprAny && vs.len() <= 1 {
4270 span_err!(ccx.tcx.sess, sp, E0083,
4271 "unsupported representation for univariant enum");
4273 span_err!(ccx.tcx.sess, sp, E0084,
4274 "unsupported representation for zero-variant enum");
4278 do_check(ccx, vs, id, hint);
4280 check_representable(ccx.tcx, sp, id, "enum");
4283 // Returns the type parameter count and the type for the given definition.
4284 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4287 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4289 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
4290 let typ = fcx.local_ty(sp, nid);
4291 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4292 ty::GenericPredicates::empty())
4294 def::DefFn(id, _) | def::DefMethod(id) |
4295 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
4296 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4297 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4301 def::DefAssociatedTy(..) |
4303 def::DefTyParam(..) |
4305 def::DefForeignMod(..) |
4308 def::DefSelfTy(..) => {
4309 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4314 // Instantiates the given path, which must refer to an item with the given
4315 // number of type parameters and type.
4316 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4317 segments: &[hir::PathSegment],
4318 type_scheme: TypeScheme<'tcx>,
4319 type_predicates: &ty::GenericPredicates<'tcx>,
4320 opt_self_ty: Option<Ty<'tcx>>,
4323 node_id: ast::NodeId) {
4324 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4330 // We need to extract the type parameters supplied by the user in
4331 // the path `path`. Due to the current setup, this is a bit of a
4332 // tricky-process; the problem is that resolve only tells us the
4333 // end-point of the path resolution, and not the intermediate steps.
4334 // Luckily, we can (at least for now) deduce the intermediate steps
4335 // just from the end-point.
4337 // There are basically four cases to consider:
4339 // 1. Reference to a *type*, such as a struct or enum:
4341 // mod a { struct Foo<T> { ... } }
4343 // Because we don't allow types to be declared within one
4344 // another, a path that leads to a type will always look like
4345 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4346 // that only the final segment can have type parameters, and
4347 // they are located in the TypeSpace.
4349 // *Note:* Generally speaking, references to types don't
4350 // actually pass through this function, but rather the
4351 // `ast_ty_to_ty` function in `astconv`. However, in the case
4352 // of struct patterns (and maybe literals) we do invoke
4353 // `instantiate_path` to get the general type of an instance of
4354 // a struct. (In these cases, there are actually no type
4355 // parameters permitted at present, but perhaps we will allow
4356 // them in the future.)
4358 // 1b. Reference to an enum variant or tuple-like struct:
4360 // struct foo<T>(...)
4361 // enum E<T> { foo(...) }
4363 // In these cases, the parameters are declared in the type
4366 // 2. Reference to a *fn item*:
4370 // In this case, the path will again always have the form
4371 // `a::b::foo::<T>` where only the final segment should have
4372 // type parameters. However, in this case, those parameters are
4373 // declared on a value, and hence are in the `FnSpace`.
4375 // 3. Reference to a *method*:
4377 // impl<A> SomeStruct<A> {
4381 // Here we can have a path like
4382 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4383 // may appear in two places. The penultimate segment,
4384 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4385 // final segment, `foo::<B>` contains parameters in fn space.
4387 // 4. Reference to an *associated const*:
4389 // impl<A> AnotherStruct<A> {
4390 // const FOO: B = BAR;
4393 // The path in this case will look like
4394 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4395 // only will have parameters in TypeSpace.
4397 // The first step then is to categorize the segments appropriately.
4399 assert!(!segments.is_empty());
4401 let mut ufcs_associated = None;
4402 let mut segment_spaces: Vec<_>;
4404 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4405 def::DefSelfTy(..) |
4406 def::DefStruct(..) |
4407 def::DefVariant(..) |
4409 def::DefAssociatedTy(..) |
4411 def::DefPrimTy(..) |
4412 def::DefTyParam(..) => {
4413 // Everything but the final segment should have no
4414 // parameters at all.
4415 segment_spaces = vec![None; segments.len() - 1];
4416 segment_spaces.push(Some(subst::TypeSpace));
4419 // Case 2. Reference to a top-level value.
4422 def::DefStatic(..) => {
4423 segment_spaces = vec![None; segments.len() - 1];
4424 segment_spaces.push(Some(subst::FnSpace));
4427 // Case 3. Reference to a method.
4428 def::DefMethod(def_id) => {
4429 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4431 ty::TraitContainer(trait_did) => {
4432 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4434 ty::ImplContainer(_) => {}
4437 if segments.len() >= 2 {
4438 segment_spaces = vec![None; segments.len() - 2];
4439 segment_spaces.push(Some(subst::TypeSpace));
4440 segment_spaces.push(Some(subst::FnSpace));
4442 // `<T>::method` will end up here, and so can `T::method`.
4443 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4444 segment_spaces = vec![Some(subst::FnSpace)];
4445 ufcs_associated = Some((container, self_ty));
4449 def::DefAssociatedConst(def_id) => {
4450 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4452 ty::TraitContainer(trait_did) => {
4453 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4455 ty::ImplContainer(_) => {}
4458 if segments.len() >= 2 {
4459 segment_spaces = vec![None; segments.len() - 2];
4460 segment_spaces.push(Some(subst::TypeSpace));
4461 segment_spaces.push(None);
4463 // `<T>::CONST` will end up here, and so can `T::CONST`.
4464 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4465 segment_spaces = vec![None];
4466 ufcs_associated = Some((container, self_ty));
4470 // Other cases. Various nonsense that really shouldn't show up
4471 // here. If they do, an error will have been reported
4472 // elsewhere. (I hope)
4474 def::DefForeignMod(..) |
4478 def::DefUpvar(..) => {
4479 segment_spaces = vec![None; segments.len()];
4482 assert_eq!(segment_spaces.len(), segments.len());
4484 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4485 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4486 // type parameters are not mandatory.
4487 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4489 debug!("segment_spaces={:?}", segment_spaces);
4491 // Next, examine the definition, and determine how many type
4492 // parameters we expect from each space.
4493 let type_defs = &type_scheme.generics.types;
4494 let region_defs = &type_scheme.generics.regions;
4496 // Now that we have categorized what space the parameters for each
4497 // segment belong to, let's sort out the parameters that the user
4498 // provided (if any) into their appropriate spaces. We'll also report
4499 // errors if type parameters are provided in an inappropriate place.
4500 let mut substs = Substs::empty();
4501 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4504 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4508 push_explicit_parameters_from_segment_to_substs(fcx,
4518 if let Some(self_ty) = opt_self_ty {
4519 if type_defs.len(subst::SelfSpace) == 1 {
4520 substs.types.push(subst::SelfSpace, self_ty);
4524 // Now we have to compare the types that the user *actually*
4525 // provided against the types that were *expected*. If the user
4526 // did not provide any types, then we want to substitute inference
4527 // variables. If the user provided some types, we may still need
4528 // to add defaults. If the user provided *too many* types, that's
4530 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4531 adjust_type_parameters(fcx, span, space, type_defs,
4532 require_type_space, &mut substs);
4533 assert_eq!(substs.types.len(space), type_defs.len(space));
4535 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4536 assert_eq!(substs.regions().len(space), region_defs.len(space));
4539 // The things we are substituting into the type should not contain
4540 // escaping late-bound regions, and nor should the base type scheme.
4541 assert!(!substs.has_regions_escaping_depth(0));
4542 assert!(!type_scheme.has_escaping_regions());
4544 // Add all the obligations that are required, substituting and
4545 // normalized appropriately.
4546 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4547 fcx.add_obligations_for_parameters(
4548 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4551 // Substitute the values for the type parameters into the type of
4552 // the referenced item.
4553 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4556 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4557 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4558 // is inherent, there is no `Self` parameter, instead, the impl needs
4559 // type parameters, which we can infer by unifying the provided `Self`
4560 // with the substituted impl type.
4561 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4562 assert_eq!(substs.types.len(subst::TypeSpace),
4563 impl_scheme.generics.types.len(subst::TypeSpace));
4564 assert_eq!(substs.regions().len(subst::TypeSpace),
4565 impl_scheme.generics.regions.len(subst::TypeSpace));
4567 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4568 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4569 fcx.tcx().sess.span_bug(span,
4571 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4577 debug!("instantiate_path: type of {:?} is {:?}",
4580 fcx.write_ty(node_id, ty_substituted);
4581 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4584 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4585 /// parameters are provided, then reports an error and clears the output vector.
4587 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4588 /// use inference variables. This seems less likely to lead to derived errors.
4590 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4591 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4592 /// here because we can easily use the precise span of the N+1'th parameter.
4593 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4594 fcx: &FnCtxt<'a, 'tcx>,
4595 space: subst::ParamSpace,
4597 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4598 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4599 segment: &hir::PathSegment,
4600 substs: &mut Substs<'tcx>)
4602 match segment.parameters {
4603 hir::AngleBracketedParameters(ref data) => {
4604 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4605 fcx, space, type_defs, region_defs, data, substs);
4608 hir::ParenthesizedParameters(ref data) => {
4609 span_err!(fcx.tcx().sess, span, E0238,
4610 "parenthesized parameters may only be used with a trait");
4611 push_explicit_parenthesized_parameters_from_segment_to_substs(
4612 fcx, space, span, type_defs, data, substs);
4617 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4618 fcx: &FnCtxt<'a, 'tcx>,
4619 space: subst::ParamSpace,
4620 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4621 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4622 data: &hir::AngleBracketedParameterData,
4623 substs: &mut Substs<'tcx>)
4626 let type_count = type_defs.len(space);
4627 assert_eq!(substs.types.len(space), 0);
4628 for (i, typ) in data.types.iter().enumerate() {
4629 let t = fcx.to_ty(&**typ);
4631 substs.types.push(space, t);
4632 } else if i == type_count {
4633 span_err!(fcx.tcx().sess, typ.span, E0087,
4634 "too many type parameters provided: \
4635 expected at most {} parameter{}, \
4636 found {} parameter{}",
4638 if type_count == 1 {""} else {"s"},
4640 if data.types.len() == 1 {""} else {"s"});
4641 substs.types.truncate(space, 0);
4647 if !data.bindings.is_empty() {
4648 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4649 "unexpected binding of associated item in expression path \
4650 (only allowed in type paths)");
4654 let region_count = region_defs.len(space);
4655 assert_eq!(substs.regions().len(space), 0);
4656 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4657 let r = ast_region_to_region(fcx.tcx(), lifetime);
4658 if i < region_count {
4659 substs.mut_regions().push(space, r);
4660 } else if i == region_count {
4661 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4662 "too many lifetime parameters provided: \
4663 expected {} parameter{}, found {} parameter{}",
4665 if region_count == 1 {""} else {"s"},
4666 data.lifetimes.len(),
4667 if data.lifetimes.len() == 1 {""} else {"s"});
4668 substs.mut_regions().truncate(space, 0);
4676 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4677 /// but intended for `Foo(A,B) -> C` form. This expands to
4678 /// roughly the same thing as `Foo<(A,B),C>`. One important
4679 /// difference has to do with the treatment of anonymous
4680 /// regions, which are translated into bound regions (NYI).
4681 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4682 fcx: &FnCtxt<'a, 'tcx>,
4683 space: subst::ParamSpace,
4685 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4686 data: &hir::ParenthesizedParameterData,
4687 substs: &mut Substs<'tcx>)
4689 let type_count = type_defs.len(space);
4691 span_err!(fcx.tcx().sess, span, E0167,
4692 "parenthesized form always supplies 2 type parameters, \
4693 but only {} parameter(s) were expected",
4697 let input_tys: Vec<Ty> =
4698 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4700 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4702 if type_count >= 1 {
4703 substs.types.push(space, tuple_ty);
4706 let output_ty: Option<Ty> =
4707 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4710 output_ty.unwrap_or(fcx.tcx().mk_nil());
4712 if type_count >= 2 {
4713 substs.types.push(space, output_ty);
4717 fn adjust_type_parameters<'a, 'tcx>(
4718 fcx: &FnCtxt<'a, 'tcx>,
4721 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4722 require_type_space: bool,
4723 substs: &mut Substs<'tcx>)
4725 let provided_len = substs.types.len(space);
4726 let desired = defs.get_slice(space);
4727 let required_len = desired.iter()
4728 .take_while(|d| d.default.is_none())
4731 debug!("adjust_type_parameters(space={:?}, \
4740 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4741 assert!(provided_len <= desired.len());
4743 // Nothing specified at all: supply inference variables for
4745 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4746 substs.types.replace(space, Vec::new());
4747 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4751 // Too few parameters specified: report an error and use Err
4753 if provided_len < required_len {
4755 if desired.len() != required_len { "at least " } else { "" };
4756 span_err!(fcx.tcx().sess, span, E0089,
4757 "too few type parameters provided: expected {}{} parameter{}, \
4758 found {} parameter{}",
4759 qualifier, required_len,
4760 if required_len == 1 {""} else {"s"},
4762 if provided_len == 1 {""} else {"s"});
4763 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4767 // Otherwise, add in any optional parameters that the user
4768 // omitted. The case of *too many* parameters is handled
4770 // push_explicit_parameters_from_segment_to_substs(). Note
4771 // that the *default* type are expressed in terms of all prior
4772 // parameters, so we have to substitute as we go with the
4773 // partial substitution that we have built up.
4774 for i in provided_len..desired.len() {
4775 let default = desired[i].default.unwrap();
4776 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4777 substs.types.push(space, default);
4779 assert_eq!(substs.types.len(space), desired.len());
4781 debug!("Final substs: {:?}", substs);
4784 fn adjust_region_parameters(
4788 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4789 substs: &mut Substs)
4791 let provided_len = substs.mut_regions().len(space);
4792 let desired = defs.get_slice(space);
4794 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4795 assert!(provided_len <= desired.len());
4797 // If nothing was provided, just use inference variables.
4798 if provided_len == 0 {
4799 substs.mut_regions().replace(
4801 fcx.infcx().region_vars_for_defs(span, desired));
4805 // If just the right number were provided, everybody is happy.
4806 if provided_len == desired.len() {
4810 // Otherwise, too few were provided. Report an error and then
4811 // use inference variables.
4812 span_err!(fcx.tcx().sess, span, E0090,
4813 "too few lifetime parameters provided: expected {} parameter{}, \
4814 found {} parameter{}",
4816 if desired.len() == 1 {""} else {"s"},
4818 if provided_len == 1 {""} else {"s"});
4820 substs.mut_regions().replace(
4822 fcx.infcx().region_vars_for_defs(span, desired));
4826 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4830 where F: Fn() -> Ty<'tcx>
4832 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4835 let alternative = f();
4838 if alternative.is_ty_var() || alternative.references_error() {
4839 fcx.type_error_message(sp, |_actual| {
4840 "the type of this value must be known in this context".to_string()
4842 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4843 ty = fcx.tcx().types.err;
4845 demand::suptype(fcx, sp, alternative, ty);
4853 // Resolves `typ` by a single level if `typ` is a type variable. If no
4854 // resolution is possible, then an error is reported.
4855 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4860 structurally_resolve_type_or_else(fcx, sp, ty, || {
4865 // Returns true if b contains a break that can exit from b
4866 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
4867 // First: is there an unlabeled break immediately
4869 (loop_query(&*b, |e| {
4871 hir::ExprBreak(None) => true,
4875 // Second: is there a labeled break with label
4876 // <id> nested anywhere inside the loop?
4877 (block_query(b, |e| {
4878 if let hir::ExprBreak(Some(_)) = e.node {
4879 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4886 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4888 tps: &OwnedSlice<hir::TyParam>,
4890 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4893 // make a vector of booleans initially false, set to true when used
4894 if tps.is_empty() { return; }
4895 let mut tps_used = vec![false; tps.len()];
4897 for leaf_ty in ty.walk() {
4898 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4899 debug!("Found use of ty param num {}", idx);
4900 tps_used[idx as usize] = true;
4904 for (i, b) in tps_used.iter().enumerate() {
4906 span_err!(ccx.tcx.sess, span, E0091,
4907 "type parameter `{}` is unused",