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 dep_graph::DepNode;
86 use fmt_macros::{Parser, Piece, Position};
87 use middle::astconv_util::prohibit_type_params;
88 use middle::cstore::LOCAL_CRATE;
89 use middle::def::{self, Def};
90 use middle::def_id::DefId;
92 use middle::infer::{TypeOrigin, TypeTrace, type_variable};
93 use middle::pat_util::{self, pat_id_map};
94 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
95 use middle::traits::{self, report_fulfillment_errors};
96 use middle::ty::{GenericPredicates, TypeScheme};
97 use middle::ty::{ParamTy, ParameterEnvironment};
98 use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
99 use middle::ty::{self, ToPolyTraitRef, Ty, TyCtxt};
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::relate::TypeRelation;
105 use middle::ty::util::{Representability, IntTypeExt};
106 use require_c_abi_if_variadic;
107 use rscope::{ElisionFailureInfo, RegionScope};
108 use session::{Session, CompileResult};
109 use {CrateCtxt, lookup_full_def};
112 use util::common::{block_query, ErrorReported, indenter, loop_query};
113 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
115 use std::cell::{Cell, Ref, RefCell};
116 use std::collections::{HashSet};
117 use std::mem::replace;
118 use syntax::abi::Abi;
121 use syntax::attr::AttrMetaMethods;
122 use syntax::codemap::{self, Span, Spanned};
123 use syntax::errors::DiagnosticBuilder;
124 use syntax::parse::token::{self, InternedString, special_idents};
126 use syntax::util::lev_distance::find_best_match_for_name;
128 use rustc_front::intravisit::{self, Visitor};
129 use rustc_front::hir;
130 use rustc_front::hir::{Visibility, PatKind, Defaultness};
131 use rustc_front::print::pprust;
132 use rustc_back::slice;
151 /// closures defined within the function. For example:
154 /// bar(move|| { ... })
157 /// Here, the function `foo()` and the closure passed to
158 /// `bar()` will each have their own `FnCtxt`, but they will
159 /// share the inherited fields.
160 pub struct Inherited<'a, 'tcx: 'a> {
161 infcx: infer::InferCtxt<'a, 'tcx>,
162 locals: RefCell<NodeMap<Ty<'tcx>>>,
164 fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
166 tables: &'a RefCell<ty::Tables<'tcx>>,
168 // When we process a call like `c()` where `c` is a closure type,
169 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
170 // `FnOnce` closure. In that case, we defer full resolution of the
171 // call until upvar inference can kick in and make the
172 // decision. We keep these deferred resolutions grouped by the
173 // def-id of the closure, so that once we decide, we can easily go
174 // back and process them.
175 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
177 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
180 trait DeferredCallResolution<'tcx> {
181 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
184 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
186 /// When type-checking an expression, we propagate downward
187 /// whatever type hint we are able in the form of an `Expectation`.
188 #[derive(Copy, Clone, Debug)]
189 pub enum Expectation<'tcx> {
190 /// We know nothing about what type this expression should have.
193 /// This expression should have the type given (or some subtype)
194 ExpectHasType(Ty<'tcx>),
196 /// This expression will be cast to the `Ty`
197 ExpectCastableToType(Ty<'tcx>),
199 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
200 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
201 ExpectRvalueLikeUnsized(Ty<'tcx>),
204 impl<'tcx> Expectation<'tcx> {
205 // Disregard "castable to" expectations because they
206 // can lead us astray. Consider for example `if cond
207 // {22} else {c} as u8` -- if we propagate the
208 // "castable to u8" constraint to 22, it will pick the
209 // type 22u8, which is overly constrained (c might not
210 // be a u8). In effect, the problem is that the
211 // "castable to" expectation is not the tightest thing
212 // we can say, so we want to drop it in this case.
213 // The tightest thing we can say is "must unify with
214 // else branch". Note that in the case of a "has type"
215 // constraint, this limitation does not hold.
217 // If the expected type is just a type variable, then don't use
218 // an expected type. Otherwise, we might write parts of the type
219 // when checking the 'then' block which are incompatible with the
221 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
223 ExpectHasType(ety) => {
224 let ety = fcx.infcx().shallow_resolve(ety);
225 if !ety.is_ty_var() {
231 ExpectRvalueLikeUnsized(ety) => {
232 ExpectRvalueLikeUnsized(ety)
239 #[derive(Copy, Clone)]
240 pub struct UnsafetyState {
241 pub def: ast::NodeId,
242 pub unsafety: hir::Unsafety,
243 pub unsafe_push_count: u32,
248 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
249 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
252 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
253 match self.unsafety {
254 // If this unsafe, then if the outer function was already marked as
255 // unsafe we shouldn't attribute the unsafe'ness to the block. This
256 // way the block can be warned about instead of ignoring this
257 // extraneous block (functions are never warned about).
258 hir::Unsafety::Unsafe if self.from_fn => *self,
261 let (unsafety, def, count) = match blk.rules {
262 hir::PushUnsafeBlock(..) =>
263 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
264 hir::PopUnsafeBlock(..) =>
265 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
266 hir::UnsafeBlock(..) =>
267 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
268 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
269 (unsafety, self.def, self.unsafe_push_count),
271 UnsafetyState{ def: def,
273 unsafe_push_count: count,
281 pub struct FnCtxt<'a, 'tcx: 'a> {
282 body_id: ast::NodeId,
284 // This flag is set to true if, during the writeback phase, we encounter
285 // a type error in this function.
286 writeback_errors: Cell<bool>,
288 // Number of errors that had been reported when we started
289 // checking this function. On exit, if we find that *more* errors
290 // have been reported, we will skip regionck and other work that
291 // expects the types within the function to be consistent.
292 err_count_on_creation: usize,
294 ret_ty: ty::FnOutput<'tcx>,
296 ps: RefCell<UnsafetyState>,
298 inh: &'a Inherited<'a, 'tcx>,
300 ccx: &'a CrateCtxt<'a, 'tcx>,
303 impl<'a, 'tcx> Inherited<'a, 'tcx> {
304 fn new(tcx: &'a TyCtxt<'tcx>,
305 tables: &'a RefCell<ty::Tables<'tcx>>,
306 param_env: ty::ParameterEnvironment<'a, 'tcx>)
307 -> Inherited<'a, 'tcx> {
310 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
311 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
312 locals: RefCell::new(NodeMap()),
314 deferred_call_resolutions: RefCell::new(DefIdMap()),
315 deferred_cast_checks: RefCell::new(Vec::new()),
319 fn normalize_associated_types_in<T>(&self,
321 body_id: ast::NodeId,
324 where T : TypeFoldable<'tcx>
326 assoc::normalize_associated_types_in(&self.infcx,
327 &mut self.fulfillment_cx.borrow_mut(),
335 // Used by check_const and check_enum_variants
336 pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
337 inh: &'a Inherited<'a, 'tcx>,
338 rty: ty::FnOutput<'tcx>,
339 body_id: ast::NodeId)
340 -> FnCtxt<'a, 'tcx> {
343 writeback_errors: Cell::new(false),
344 err_count_on_creation: ccx.tcx.sess.err_count(),
346 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
352 fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
353 tables: &'a RefCell<ty::Tables<'tcx>>)
354 -> Inherited<'a, 'tcx> {
355 // It's kind of a kludge to manufacture a fake function context
356 // and statement context, but we might as well do write the code only once
357 let param_env = ccx.tcx.empty_parameter_environment();
358 Inherited::new(ccx.tcx, &tables, param_env)
361 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
362 struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
364 impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
365 fn visit_item(&mut self, i: &'tcx hir::Item) {
366 check_item_type(self.ccx, i);
367 intravisit::walk_item(self, i);
370 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
372 hir::TyFixedLengthVec(_, ref expr) => {
373 check_const_in_type(self.ccx, &expr, self.ccx.tcx.types.usize);
378 intravisit::walk_ty(self, t);
382 impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
383 fn visit_item(&mut self, i: &'tcx hir::Item) {
384 check_item_body(self.ccx, i);
388 pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
389 ccx.tcx.sess.track_errors(|| {
390 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
391 ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
395 pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
396 ccx.tcx.sess.track_errors(|| {
397 let mut visit = CheckItemTypesVisitor { ccx: ccx };
398 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
402 pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
403 ccx.tcx.sess.track_errors(|| {
404 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
405 ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
409 pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
410 ccx.tcx.sess.track_errors(|| {
411 let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
412 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
413 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
415 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
416 let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
417 if drop_impl_did.is_local() {
418 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
421 assert!(ccx.tcx.sess.has_errors());
429 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
430 decl: &'tcx hir::FnDecl,
431 body: &'tcx hir::Block,
435 param_env: ty::ParameterEnvironment<'a, 'tcx>)
438 ty::TyFnDef(_, _, ref fn_ty) => {
439 let tables = RefCell::new(ty::Tables::empty());
440 let inh = Inherited::new(ccx.tcx, &tables, param_env);
442 // Compute the fty from point of view of inside fn.
443 let fn_scope = ccx.tcx.region_maps.call_site_extent(fn_id, body.id);
445 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
447 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
449 inh.normalize_associated_types_in(body.span,
453 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
454 decl, fn_id, body, &inh);
456 fcx.select_all_obligations_and_apply_defaults();
457 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
458 fcx.select_obligations_where_possible();
460 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
462 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
463 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
465 _ => ccx.tcx.sess.impossible_case(body.span,
466 "check_bare_fn: function type expected")
470 struct GatherLocalsVisitor<'a, 'tcx: 'a> {
471 fcx: &'a FnCtxt<'a, 'tcx>
474 impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
475 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
478 // infer the variable's type
479 let var_ty = self.fcx.infcx().next_ty_var();
480 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
484 // take type that the user specified
485 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
492 impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
493 // Add explicitly-declared locals.
494 fn visit_local(&mut self, local: &'tcx hir::Local) {
495 let o_ty = match local.ty {
496 Some(ref ty) => Some(self.fcx.to_ty(&ty)),
499 self.assign(local.span, local.id, o_ty);
500 debug!("Local variable {:?} is assigned type {}",
502 self.fcx.infcx().ty_to_string(
503 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
504 intravisit::walk_local(self, local);
507 // Add pattern bindings.
508 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
509 if let PatKind::Ident(_, ref path1, _) = p.node {
510 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
511 let var_ty = self.assign(p.span, p.id, None);
513 self.fcx.require_type_is_sized(var_ty, p.span,
514 traits::VariableType(p.id));
516 debug!("Pattern binding {} is assigned to {} with type {:?}",
518 self.fcx.infcx().ty_to_string(
519 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
523 intravisit::walk_pat(self, p);
526 fn visit_block(&mut self, b: &'tcx hir::Block) {
527 // non-obvious: the `blk` variable maps to region lb, so
528 // we have to keep this up-to-date. This
529 // is... unfortunate. It'd be nice to not need this.
530 intravisit::walk_block(self, b);
533 // Since an expr occurs as part of the type fixed size arrays we
534 // need to record the type for that node
535 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
537 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
539 check_expr_with_hint(self.fcx, &count_expr, self.fcx.tcx().types.usize);
541 hir::TyBareFn(ref function_declaration) => {
542 intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
543 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
545 _ => intravisit::walk_ty(self, t)
549 // Don't descend into the bodies of nested closures
550 fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
551 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
554 /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
555 /// body and returns the function context used for that purpose, since in the case of a fn item
556 /// there is still a bit more to do.
559 /// * inherited: other fields inherited from the enclosing fn (if any)
560 fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
561 unsafety: hir::Unsafety,
562 unsafety_id: ast::NodeId,
563 fn_sig: &ty::FnSig<'tcx>,
564 decl: &'tcx hir::FnDecl,
566 body: &'tcx hir::Block,
567 inherited: &'a Inherited<'a, 'tcx>)
571 let err_count_on_creation = tcx.sess.err_count();
573 let arg_tys = &fn_sig.inputs;
574 let ret_ty = fn_sig.output;
576 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
581 // Create the function context. This is either derived from scratch or,
582 // in the case of function expressions, based on the outer context.
585 writeback_errors: Cell::new(false),
586 err_count_on_creation: err_count_on_creation,
588 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
593 if let ty::FnConverging(ret_ty) = ret_ty {
594 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
597 debug!("fn-sig-map: fn_id={} fn_sig={:?}", fn_id, fn_sig);
599 inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig.clone());
602 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
604 // Add formal parameters.
605 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
606 // The type of the argument must be well-formed.
608 // NB -- this is now checked in wfcheck, but that
609 // currently only results in warnings, so we issue an
610 // old-style WF obligation here so that we still get the
611 // errors that we used to get.
612 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
614 // Create type variables for each argument.
615 pat_util::pat_bindings(
618 |_bm, pat_id, sp, _path| {
619 let var_ty = visit.assign(sp, pat_id, None);
620 fcx.require_type_is_sized(var_ty, sp,
621 traits::VariableType(pat_id));
624 // Check the pattern.
627 map: pat_id_map(&tcx.def_map, &input.pat),
629 _match::check_pat(&pcx, &input.pat, *arg_ty);
632 visit.visit_block(body);
635 check_block_with_expected(&fcx, body, match ret_ty {
636 ty::FnConverging(result_type) => ExpectHasType(result_type),
637 ty::FnDiverging => NoExpectation
640 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
641 fcx.write_ty(input.id, arg);
647 pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
650 check_representable(tcx, span, id, "struct");
652 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
653 check_simd(tcx, span, id);
657 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
658 debug!("check_item_type(it.id={}, it.name={})",
660 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
661 let _indenter = indenter();
663 // Consts can play a role in type-checking, so they are included here.
664 hir::ItemStatic(_, _, ref e) |
665 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &e, it.id),
666 hir::ItemEnum(ref enum_definition, _) => {
667 check_enum_variants(ccx,
669 &enum_definition.variants,
672 hir::ItemFn(..) => {} // entirely within check_item_body
673 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
674 debug!("ItemImpl {} with id {}", it.name, it.id);
675 let impl_def_id = ccx.tcx.map.local_def_id(it.id);
676 match ccx.tcx.impl_trait_ref(impl_def_id) {
677 Some(impl_trait_ref) => {
678 check_impl_items_against_trait(ccx,
687 hir::ItemTrait(_, ref generics, _, _) => {
688 check_trait_on_unimplemented(ccx, generics, it);
690 hir::ItemStruct(..) => {
691 check_struct(ccx, it.id, it.span);
693 hir::ItemTy(_, ref generics) => {
694 let pty_ty = ccx.tcx.node_id_to_type(it.id);
695 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
697 hir::ItemForeignMod(ref m) => {
698 if m.abi == Abi::RustIntrinsic {
699 for item in &m.items {
700 intrinsic::check_intrinsic_type(ccx, item);
702 } else if m.abi == Abi::PlatformIntrinsic {
703 for item in &m.items {
704 intrinsic::check_platform_intrinsic_type(ccx, item);
707 for item in &m.items {
708 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
709 if !pty.generics.types.is_empty() {
710 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
711 "foreign items may not have type parameters");
712 span_help!(&mut err, item.span,
713 "consider using specialization instead of \
718 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
719 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
724 _ => {/* nothing to do */ }
728 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
729 debug!("check_item_body(it.id={}, it.name={})",
731 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
732 let _indenter = indenter();
734 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
735 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
736 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
737 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
739 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
740 debug!("ItemImpl {} with id {}", it.name, it.id);
742 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
744 for impl_item in impl_items {
745 match impl_item.node {
746 hir::ImplItemKind::Const(_, ref expr) => {
747 check_const(ccx, impl_item.span, &expr, impl_item.id)
749 hir::ImplItemKind::Method(ref sig, ref body) => {
750 check_method_body(ccx, &impl_pty.generics, sig, body,
751 impl_item.id, impl_item.span);
753 hir::ImplItemKind::Type(_) => {
754 // Nothing to do here.
759 hir::ItemTrait(_, _, _, ref trait_items) => {
760 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
761 for trait_item in trait_items {
762 match trait_item.node {
763 hir::ConstTraitItem(_, Some(ref expr)) => {
764 check_const(ccx, trait_item.span, &expr, trait_item.id)
766 hir::MethodTraitItem(ref sig, Some(ref body)) => {
767 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
769 check_method_body(ccx, &trait_def.generics, sig, body,
770 trait_item.id, trait_item.span);
772 hir::MethodTraitItem(ref sig, None) => {
773 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
775 hir::ConstTraitItem(_, None) |
776 hir::TypeTraitItem(..) => {
782 _ => {/* nothing to do */ }
786 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
788 constness: hir::Constness)
791 hir::Constness::NotConst => {
794 hir::Constness::Const => {
795 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
800 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
801 generics: &hir::Generics,
803 if let Some(ref attr) = item.attrs.iter().find(|a| {
804 a.check_name("rustc_on_unimplemented")
806 if let Some(ref istring) = attr.value_str() {
807 let parser = Parser::new(&istring);
808 let types = &generics.ty_params;
809 for token in parser {
811 Piece::String(_) => (), // Normal string, no need to check it
812 Piece::NextArgument(a) => match a.position {
813 // `{Self}` is allowed
814 Position::ArgumentNamed(s) if s == "Self" => (),
815 // So is `{A}` if A is a type parameter
816 Position::ArgumentNamed(s) => match types.iter().find(|t| {
821 span_err!(ccx.tcx.sess, attr.span, E0230,
822 "there is no type parameter \
827 // `{:1}` and `{}` are not to be used
828 Position::ArgumentIs(_) | Position::ArgumentNext => {
829 span_err!(ccx.tcx.sess, attr.span, E0231,
830 "only named substitution \
831 parameters are allowed");
837 span_err!(ccx.tcx.sess, attr.span, E0232,
838 "this attribute must have a value, \
839 eg `#[rustc_on_unimplemented = \"foo\"]`")
844 /// Type checks a method body.
848 /// * `item_generics`: generics defined on the impl/trait that contains
850 /// * `self_bound`: bound for the `Self` type parameter, if any
851 /// * `method`: the method definition
852 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
853 item_generics: &ty::Generics<'tcx>,
854 sig: &'tcx hir::MethodSig,
855 body: &'tcx hir::Block,
856 id: ast::NodeId, span: Span) {
857 debug!("check_method_body(item_generics={:?}, id={})",
859 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
861 let fty = ccx.tcx.node_id_to_type(id);
862 debug!("check_method_body: fty={:?}", fty);
864 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
867 fn check_specialization_validity<'tcx, F>(tcx: &ty::ctxt<'tcx>,
869 impl_item: &hir::ImplItem,
871 where F: FnMut(&ty::ImplOrTraitItem<'tcx>) -> Option<hir::Defaultness>
873 let parent_item_opt = traits::get_parent_impl_item(tcx, impl_id, f);
874 if let Some((Defaultness::Final, parent_impl)) = parent_item_opt {
875 span_err!(tcx.sess, impl_item.span, E0520,
876 "item `{}` is provided by an implementation that \
877 specializes another, but the item in the parent \
878 implementations is not marked `default` and so it \
879 cannot be specialized.",
882 match tcx.span_of_impl(parent_impl) {
884 span_note!(tcx.sess, span, "parent implementation is here:");
887 tcx.sess.note(&format!("parent implementation is in crate `{}`",
894 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
897 impl_trait_ref: &ty::TraitRef<'tcx>,
898 impl_items: &[hir::ImplItem]) {
899 // Locate trait methods
901 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
902 let mut overridden_associated_type = None;
904 // Check existing impl methods to see if they are both present in trait
905 // and compatible with trait signature
906 for impl_item in impl_items {
907 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
908 let ty_trait_item = trait_items.iter()
909 .find(|ac| ac.name() == ty_impl_item.name());
911 if let Some(ty_trait_item) = ty_trait_item {
912 match impl_item.node {
913 hir::ImplItemKind::Const(..) => {
914 let impl_const = match ty_impl_item {
915 ty::ConstTraitItem(ref cti) => cti,
916 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
919 // Find associated const definition.
920 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
921 compare_const_impl(ccx.tcx,
927 span_err!(tcx.sess, impl_item.span, E0323,
928 "item `{}` is an associated const, \
929 which doesn't match its trait `{:?}`",
934 check_specialization_validity(ccx.tcx, impl_id, impl_item, |cand| {
935 if let &ty::ConstTraitItem(ref trait_const) = cand {
936 if trait_const.name == impl_item.name {
937 return Some(trait_const.defaultness);
943 hir::ImplItemKind::Method(ref sig, ref body) => {
944 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
946 let impl_method = match ty_impl_item {
947 ty::MethodTraitItem(ref mti) => mti,
948 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
951 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
952 compare_impl_method(ccx.tcx,
959 span_err!(tcx.sess, impl_item.span, E0324,
960 "item `{}` is an associated method, \
961 which doesn't match its trait `{:?}`",
966 check_specialization_validity(ccx.tcx, impl_id, impl_item, |cand| {
967 if let &ty::MethodTraitItem(ref meth) = cand {
968 if meth.name == impl_method.name {
969 return Some(meth.defaultness);
975 hir::ImplItemKind::Type(_) => {
976 let impl_type = match ty_impl_item {
977 ty::TypeTraitItem(ref tti) => tti,
978 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
981 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
982 if let Some(_) = at.ty {
983 overridden_associated_type = Some(impl_item);
986 span_err!(tcx.sess, impl_item.span, E0325,
987 "item `{}` is an associated type, \
988 which doesn't match its trait `{:?}`",
993 check_specialization_validity(ccx.tcx, impl_id, impl_item, |cand| {
994 if let &ty::TypeTraitItem(ref at) = cand {
995 if at.name == impl_item.name {
996 return Some(at.defaultness);
1006 // Check for missing items from trait
1007 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
1008 let mut missing_items = Vec::new();
1009 let mut invalidated_items = Vec::new();
1010 let associated_type_overridden = overridden_associated_type.is_some();
1011 for trait_item in trait_items.iter() {
1013 ty::ConstTraitItem(ref associated_const) => {
1014 let is_implemented = impl_items.iter().any(|ii| {
1016 hir::ImplItemKind::Const(..) => {
1017 ii.name == associated_const.name
1022 let is_provided = associated_const.has_value;
1024 if !is_implemented {
1026 missing_items.push(associated_const.name);
1027 } else if associated_type_overridden {
1028 invalidated_items.push(associated_const.name);
1032 ty::MethodTraitItem(ref trait_method) => {
1033 let search_result = traits::get_impl_item_or_default(tcx, impl_id, |cand| {
1034 if let &ty::MethodTraitItem(ref meth) = cand {
1035 if meth.name == trait_method.name {
1042 if let Some((_, source)) = search_result {
1043 if source.is_from_trait() {
1045 provided_methods.iter().any(|m| m.name == trait_method.name);
1047 missing_items.push(trait_method.name);
1048 } else if associated_type_overridden {
1049 invalidated_items.push(trait_method.name);
1053 missing_items.push(trait_method.name);
1056 ty::TypeTraitItem(ref associated_type) => {
1057 let is_implemented = impl_items.iter().any(|ii| {
1059 hir::ImplItemKind::Type(_) => {
1060 ii.name == associated_type.name
1065 let is_provided = associated_type.ty.is_some();
1066 if !is_implemented {
1068 missing_items.push(associated_type.name);
1069 } else if associated_type_overridden {
1070 invalidated_items.push(associated_type.name);
1077 if !missing_items.is_empty() {
1078 span_err!(tcx.sess, impl_span, E0046,
1079 "not all trait items implemented, missing: `{}`",
1080 missing_items.iter()
1081 .map(|name| name.to_string())
1082 .collect::<Vec<_>>().join("`, `"))
1085 if !invalidated_items.is_empty() {
1086 let invalidator = overridden_associated_type.unwrap();
1087 span_err!(tcx.sess, invalidator.span, E0399,
1088 "the following trait items need to be reimplemented \
1089 as `{}` was overridden: `{}`",
1091 invalidated_items.iter()
1092 .map(|name| name.to_string())
1093 .collect::<Vec<_>>().join("`, `"))
1097 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1104 if t_cast.references_error() || t_expr.references_error() {
1107 let tstr = fcx.infcx().ty_to_string(t_cast);
1108 let mut err = fcx.type_error_struct(span, |actual| {
1109 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1112 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1113 let mtstr = match mt {
1114 hir::MutMutable => "mut ",
1115 hir::MutImmutable => ""
1117 if t_cast.is_trait() {
1118 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1120 err.span_suggestion(t_span,
1121 "try casting to a reference instead:",
1122 format!("&{}{}", mtstr, s));
1125 span_help!(err, t_span,
1126 "did you mean `&{}{}`?", mtstr, tstr),
1129 span_help!(err, span,
1130 "consider using an implicit coercion to `&{}{}` instead",
1135 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1137 err.span_suggestion(t_span,
1138 "try casting to a `Box` instead:",
1139 format!("Box<{}>", s));
1142 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1146 span_help!(err, e_span,
1147 "consider using a box or reference as appropriate");
1151 fcx.write_error(id);
1155 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1156 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1158 fn get_item_type_scheme(&self, _: Span, id: DefId)
1159 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1161 Ok(self.tcx().lookup_item_type(id))
1164 fn get_trait_def(&self, _: Span, id: DefId)
1165 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1167 Ok(self.tcx().lookup_trait_def(id))
1170 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1171 // all super predicates are ensured during collect pass
1175 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1176 Some(&self.inh.infcx.parameter_environment.free_substs)
1179 fn get_type_parameter_bounds(&self,
1181 node_id: ast::NodeId)
1182 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1184 let def = self.tcx().type_parameter_def(node_id);
1185 let r = self.inh.infcx.parameter_environment
1188 .filter_map(|predicate| {
1190 ty::Predicate::Trait(ref data) => {
1191 if data.0.self_ty().is_param(def.space, def.index) {
1192 Some(data.to_poly_trait_ref())
1206 fn trait_defines_associated_type_named(&self,
1207 trait_def_id: DefId,
1208 assoc_name: ast::Name)
1211 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1212 trait_def.associated_type_names.contains(&assoc_name)
1216 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1217 substs: Option<&mut subst::Substs<'tcx>>,
1218 space: Option<subst::ParamSpace>,
1219 span: Span) -> Ty<'tcx> {
1220 // Grab the default doing subsitution
1221 let default = ty_param_def.and_then(|def| {
1222 def.default.map(|ty| type_variable::Default {
1223 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1225 def_id: def.default_def_id
1229 let ty_var = self.infcx().next_ty_var_with_default(default);
1231 // Finally we add the type variable to the substs
1234 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1238 fn projected_ty_from_poly_trait_ref(&self,
1240 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1241 item_name: ast::Name)
1244 let (trait_ref, _) =
1245 self.infcx().replace_late_bound_regions_with_fresh_var(
1247 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1250 self.normalize_associated_type(span, trait_ref, item_name)
1253 fn projected_ty(&self,
1255 trait_ref: ty::TraitRef<'tcx>,
1256 item_name: ast::Name)
1259 self.normalize_associated_type(span, trait_ref, item_name)
1263 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1264 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1266 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1270 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1271 &self.inh.infcx.parameter_environment
1274 pub fn sess(&self) -> &Session {
1278 pub fn err_count_since_creation(&self) -> usize {
1279 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1282 /// Resolves type variables in `ty` if possible. Unlike the infcx
1283 /// version, this version will also select obligations if it seems
1284 /// useful, in an effort to get more type information.
1285 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1286 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1288 // No TyInfer()? Nothing needs doing.
1289 if !ty.has_infer_types() {
1290 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1294 // If `ty` is a type variable, see whether we already know what it is.
1295 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1296 if !ty.has_infer_types() {
1297 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1301 // If not, try resolving pending obligations as much as
1302 // possible. This can help substantially when there are
1303 // indirect dependencies that don't seem worth tracking
1305 self.select_obligations_where_possible();
1306 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1308 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1312 fn record_deferred_call_resolution(&self,
1313 closure_def_id: DefId,
1314 r: DeferredCallResolutionHandler<'tcx>) {
1315 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1316 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1319 fn remove_deferred_call_resolutions(&self,
1320 closure_def_id: DefId)
1321 -> Vec<DeferredCallResolutionHandler<'tcx>>
1323 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1324 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1327 pub fn tag(&self) -> String {
1328 let self_ptr: *const FnCtxt = self;
1329 format!("{:?}", self_ptr)
1332 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1333 match self.inh.locals.borrow().get(&nid) {
1336 span_err!(self.tcx().sess, span, E0513,
1337 "no type for local variable {}",
1339 self.tcx().types.err
1345 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1346 debug!("write_ty({}, {:?}) in fcx {}",
1347 node_id, ty, self.tag());
1348 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1351 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1352 if !substs.substs.is_noop() {
1353 debug!("write_substs({}, {:?}) in fcx {}",
1358 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1362 pub fn write_autoderef_adjustment(&self,
1363 node_id: ast::NodeId,
1365 self.write_adjustment(
1367 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1375 pub fn write_adjustment(&self,
1376 node_id: ast::NodeId,
1377 adj: adjustment::AutoAdjustment<'tcx>) {
1378 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1380 if adj.is_identity() {
1384 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1387 /// Basically whenever we are converting from a type scheme into
1388 /// the fn body space, we always want to normalize associated
1389 /// types as well. This function combines the two.
1390 fn instantiate_type_scheme<T>(&self,
1392 substs: &Substs<'tcx>,
1395 where T : TypeFoldable<'tcx>
1397 let value = value.subst(self.tcx(), substs);
1398 let result = self.normalize_associated_types_in(span, &value);
1399 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1406 /// As `instantiate_type_scheme`, but for the bounds found in a
1407 /// generic type scheme.
1408 fn instantiate_bounds(&self,
1410 substs: &Substs<'tcx>,
1411 bounds: &ty::GenericPredicates<'tcx>)
1412 -> ty::InstantiatedPredicates<'tcx>
1414 ty::InstantiatedPredicates {
1415 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1420 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1421 where T : TypeFoldable<'tcx>
1423 self.inh.normalize_associated_types_in(span, self.body_id, value)
1426 fn normalize_associated_type(&self,
1428 trait_ref: ty::TraitRef<'tcx>,
1429 item_name: ast::Name)
1432 let cause = traits::ObligationCause::new(span,
1434 traits::ObligationCauseCode::MiscObligation);
1438 .normalize_projection_type(self.infcx(),
1440 trait_ref: trait_ref,
1441 item_name: item_name,
1446 /// Instantiates the type in `did` with the generics in `path` and returns
1447 /// it (registering the necessary trait obligations along the way).
1449 /// Note that this function is only intended to be used with type-paths,
1450 /// not with value-paths.
1451 pub fn instantiate_type(&self,
1456 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1458 self.tcx().lookup_item_type(did);
1459 let type_predicates =
1460 self.tcx().lookup_predicates(did);
1461 let substs = astconv::ast_path_substs_for_ty(self, self,
1463 PathParamMode::Optional,
1464 &type_scheme.generics,
1465 path.segments.last().unwrap());
1466 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1468 self.instantiate_bounds(path.span, &substs, &type_predicates);
1469 self.add_obligations_for_parameters(
1470 traits::ObligationCause::new(
1473 traits::ItemObligation(did)),
1476 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1479 /// Return the dict-like variant corresponding to a given `Def`.
1480 pub fn def_struct_variant(&self,
1483 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1485 let (adt, variant) = match def {
1486 Def::Variant(enum_id, variant_id) => {
1487 let adt = self.tcx().lookup_adt_def(enum_id);
1488 (adt, adt.variant_with_id(variant_id))
1490 Def::Struct(did) | Def::TyAlias(did) => {
1491 let typ = self.tcx().lookup_item_type(did);
1492 if let ty::TyStruct(adt, _) = typ.ty.sty {
1493 (adt, adt.struct_variant())
1501 let var_kind = variant.kind();
1502 if var_kind == ty::VariantKind::Struct {
1503 Some((adt, variant))
1504 } else if var_kind == ty::VariantKind::Unit {
1505 Some((adt, variant))
1511 pub fn write_nil(&self, node_id: ast::NodeId) {
1512 self.write_ty(node_id, self.tcx().mk_nil());
1514 pub fn write_error(&self, node_id: ast::NodeId) {
1515 self.write_ty(node_id, self.tcx().types.err);
1518 pub fn require_type_meets(&self,
1521 code: traits::ObligationCauseCode<'tcx>,
1522 bound: ty::BuiltinBound)
1524 self.register_builtin_bound(
1527 traits::ObligationCause::new(span, self.body_id, code));
1530 pub fn require_type_is_sized(&self,
1533 code: traits::ObligationCauseCode<'tcx>)
1535 self.require_type_meets(ty, span, code, ty::BoundSized);
1538 pub fn require_expr_have_sized_type(&self,
1540 code: traits::ObligationCauseCode<'tcx>)
1542 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1545 pub fn type_is_known_to_be_sized(&self,
1550 traits::type_known_to_meet_builtin_bound(self.infcx(),
1556 pub fn register_builtin_bound(&self,
1558 builtin_bound: ty::BuiltinBound,
1559 cause: traits::ObligationCause<'tcx>)
1561 self.inh.fulfillment_cx.borrow_mut()
1562 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1565 pub fn register_predicate(&self,
1566 obligation: traits::PredicateObligation<'tcx>)
1568 debug!("register_predicate({:?})",
1570 self.inh.fulfillment_cx
1572 .register_predicate_obligation(self.infcx(), obligation);
1575 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1576 let t = ast_ty_to_ty(self, self, ast_t);
1577 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1581 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1582 match self.inh.tables.borrow().node_types.get(&ex.id) {
1585 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1591 /// Apply `adjustment` to the type of `expr`
1592 pub fn adjust_expr_ty(&self,
1594 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1597 let raw_ty = self.expr_ty(expr);
1598 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1599 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1600 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1601 self.inh.tables.borrow().method_map.get(&method_call)
1602 .map(|method| resolve_ty(method.ty))
1606 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1607 match self.inh.tables.borrow().node_types.get(&id) {
1609 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1611 self.tcx().sess.bug(
1612 &format!("no type for node {}: {} in fcx {}",
1613 id, self.tcx().map.node_to_string(id),
1619 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1620 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1621 // it changes when we upgrade the snapshot compiler
1622 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1623 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1627 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1630 pub fn opt_node_ty_substs<F>(&self,
1633 F: FnOnce(&ty::ItemSubsts<'tcx>),
1635 match self.inh.tables.borrow().item_substs.get(&id) {
1641 pub fn mk_subty(&self,
1642 a_is_expected: bool,
1646 -> Result<(), TypeError<'tcx>> {
1647 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1650 pub fn mk_eqty(&self,
1651 a_is_expected: bool,
1655 -> Result<(), TypeError<'tcx>> {
1656 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1659 pub fn mk_subr(&self,
1660 origin: infer::SubregionOrigin<'tcx>,
1663 infer::mk_subr(self.infcx(), origin, sub, sup)
1666 pub fn type_error_message<M>(&self,
1669 actual_ty: Ty<'tcx>,
1670 err: Option<&TypeError<'tcx>>)
1671 where M: FnOnce(String) -> String,
1673 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1676 pub fn type_error_struct<M>(&self,
1679 actual_ty: Ty<'tcx>,
1680 err: Option<&TypeError<'tcx>>)
1681 -> DiagnosticBuilder<'tcx>
1682 where M: FnOnce(String) -> String,
1684 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1687 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1688 /// outlive the region `r`.
1689 pub fn register_region_obligation(&self,
1692 cause: traits::ObligationCause<'tcx>)
1694 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1695 fulfillment_cx.register_region_obligation(ty, region, cause);
1698 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1699 /// outlive the region `r`.
1700 pub fn register_wf_obligation(&self,
1703 code: traits::ObligationCauseCode<'tcx>)
1705 // WF obligations never themselves fail, so no real need to give a detailed cause:
1706 let cause = traits::ObligationCause::new(span, self.body_id, code);
1707 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1710 pub fn register_old_wf_obligation(&self,
1713 code: traits::ObligationCauseCode<'tcx>)
1715 // Registers an "old-style" WF obligation that uses the
1716 // implicator code. This is basically a buggy version of
1717 // `register_wf_obligation` that is being kept around
1718 // temporarily just to help with phasing in the newer rules.
1720 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1721 let cause = traits::ObligationCause::new(span, self.body_id, code);
1722 self.register_region_obligation(ty, ty::ReEmpty, cause);
1725 /// Registers obligations that all types appearing in `substs` are well-formed.
1726 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1728 for &ty in &substs.types {
1729 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1733 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1734 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1735 /// trait/region obligations.
1737 /// For example, if there is a function:
1740 /// fn foo<'a,T:'a>(...)
1743 /// and a reference:
1749 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1750 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1751 pub fn add_obligations_for_parameters(&self,
1752 cause: traits::ObligationCause<'tcx>,
1753 predicates: &ty::InstantiatedPredicates<'tcx>)
1755 assert!(!predicates.has_escaping_regions());
1757 debug!("add_obligations_for_parameters(predicates={:?})",
1760 for obligation in traits::predicates_for_generics(cause, predicates) {
1761 self.register_predicate(obligation);
1765 // FIXME(arielb1): use this instead of field.ty everywhere
1766 // Only for fields! Returns <none> for methods>
1767 // Indifferent to privacy flags
1768 pub fn field_ty(&self,
1770 field: ty::FieldDef<'tcx>,
1771 substs: &Substs<'tcx>)
1774 self.normalize_associated_types_in(span,
1775 &field.ty(self.tcx(), substs))
1778 fn check_casts(&self) {
1779 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1780 for cast in deferred_cast_checks.drain(..) {
1785 /// Apply "fallbacks" to some types
1786 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1787 fn default_type_parameters(&self) {
1788 use middle::ty::error::UnconstrainedNumeric::Neither;
1789 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1790 for ty in &self.infcx().unsolved_variables() {
1791 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1792 if self.infcx().type_var_diverges(resolved) {
1793 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1795 match self.infcx().type_is_unconstrained_numeric(resolved) {
1796 UnconstrainedInt => {
1797 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1799 UnconstrainedFloat => {
1800 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1808 fn select_all_obligations_and_apply_defaults(&self) {
1809 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1810 self.new_select_all_obligations_and_apply_defaults();
1812 self.old_select_all_obligations_and_apply_defaults();
1816 // Implements old type inference fallback algorithm
1817 fn old_select_all_obligations_and_apply_defaults(&self) {
1818 self.select_obligations_where_possible();
1819 self.default_type_parameters();
1820 self.select_obligations_where_possible();
1823 fn new_select_all_obligations_and_apply_defaults(&self) {
1824 use middle::ty::error::UnconstrainedNumeric::Neither;
1825 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1827 // For the time being this errs on the side of being memory wasteful but provides better
1829 // let type_variables = self.infcx().type_variables.clone();
1831 // There is a possibility that this algorithm will have to run an arbitrary number of times
1832 // to terminate so we bound it by the compiler's recursion limit.
1833 for _ in 0..self.tcx().sess.recursion_limit.get() {
1834 // First we try to solve all obligations, it is possible that the last iteration
1835 // has made it possible to make more progress.
1836 self.select_obligations_where_possible();
1838 let mut conflicts = Vec::new();
1840 // Collect all unsolved type, integral and floating point variables.
1841 let unsolved_variables = self.inh.infcx.unsolved_variables();
1843 // We must collect the defaults *before* we do any unification. Because we have
1844 // directly attached defaults to the type variables any unification that occurs
1845 // will erase defaults causing conflicting defaults to be completely ignored.
1846 let default_map: FnvHashMap<_, _> =
1849 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1852 let mut unbound_tyvars = HashSet::new();
1854 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1856 // We loop over the unsolved variables, resolving them and if they are
1857 // and unconstrainted numeric type we add them to the set of unbound
1858 // variables. We do this so we only apply literal fallback to type
1859 // variables without defaults.
1860 for ty in &unsolved_variables {
1861 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1862 if self.infcx().type_var_diverges(resolved) {
1863 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1865 match self.infcx().type_is_unconstrained_numeric(resolved) {
1866 UnconstrainedInt | UnconstrainedFloat => {
1867 unbound_tyvars.insert(resolved);
1874 // We now remove any numeric types that also have defaults, and instead insert
1875 // the type variable with a defined fallback.
1876 for ty in &unsolved_variables {
1877 if let Some(_default) = default_map.get(ty) {
1878 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1880 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1883 match resolved.sty {
1884 ty::TyInfer(ty::TyVar(_)) => {
1885 unbound_tyvars.insert(ty);
1888 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1889 unbound_tyvars.insert(ty);
1890 if unbound_tyvars.contains(resolved) {
1891 unbound_tyvars.remove(resolved);
1900 // If there are no more fallbacks to apply at this point we have applied all possible
1901 // defaults and type inference will proceed as normal.
1902 if unbound_tyvars.is_empty() {
1906 // Finally we go through each of the unbound type variables and unify them with
1907 // the proper fallback, reporting a conflicting default error if any of the
1908 // unifications fail. We know it must be a conflicting default because the
1909 // variable would only be in `unbound_tyvars` and have a concrete value if
1910 // it had been solved by previously applying a default.
1912 // We wrap this in a transaction for error reporting, if we detect a conflict
1913 // we will rollback the inference context to its prior state so we can probe
1914 // for conflicts and correctly report them.
1917 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1918 for ty in &unbound_tyvars {
1919 if self.infcx().type_var_diverges(ty) {
1920 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1922 match self.infcx().type_is_unconstrained_numeric(ty) {
1923 UnconstrainedInt => {
1924 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1926 UnconstrainedFloat => {
1927 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1930 if let Some(default) = default_map.get(ty) {
1931 let default = default.clone();
1932 match infer::mk_eqty(self.infcx(), false,
1933 TypeOrigin::Misc(default.origin_span),
1937 conflicts.push((*ty, default));
1946 // If there are conflicts we rollback, otherwise commit
1947 if conflicts.len() > 0 {
1954 if conflicts.len() > 0 {
1955 // Loop through each conflicting default, figuring out the default that caused
1956 // a unification failure and then report an error for each.
1957 for (conflict, default) in conflicts {
1958 let conflicting_default =
1959 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1960 .unwrap_or(type_variable::Default {
1961 ty: self.infcx().next_ty_var(),
1962 origin_span: codemap::DUMMY_SP,
1963 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1966 // This is to ensure that we elimnate any non-determinism from the error
1967 // reporting by fixing an order, it doesn't matter what order we choose
1968 // just that it is consistent.
1969 let (first_default, second_default) =
1970 if default.def_id < conflicting_default.def_id {
1971 (default, conflicting_default)
1973 (conflicting_default, default)
1977 self.infcx().report_conflicting_default_types(
1978 first_default.origin_span,
1985 self.select_obligations_where_possible();
1988 // For use in error handling related to default type parameter fallback. We explicitly
1989 // apply the default that caused conflict first to a local version of the type variable
1990 // table then apply defaults until we find a conflict. That default must be the one
1991 // that caused conflict earlier.
1992 fn find_conflicting_default(&self,
1993 unbound_vars: &HashSet<Ty<'tcx>>,
1994 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1996 -> Option<type_variable::Default<'tcx>> {
1997 use middle::ty::error::UnconstrainedNumeric::Neither;
1998 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
2000 // Ensure that we apply the conflicting default first
2001 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2002 unbound_tyvars.push(conflict);
2003 unbound_tyvars.extend(unbound_vars.iter());
2005 let mut result = None;
2006 // We run the same code as above applying defaults in order, this time when
2007 // we find the conflict we just return it for error reporting above.
2009 // We also run this inside snapshot that never commits so we can do error
2010 // reporting for more then one conflict.
2011 for ty in &unbound_tyvars {
2012 if self.infcx().type_var_diverges(ty) {
2013 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
2015 match self.infcx().type_is_unconstrained_numeric(ty) {
2016 UnconstrainedInt => {
2017 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
2019 UnconstrainedFloat => {
2020 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
2023 if let Some(default) = default_map.get(ty) {
2024 let default = default.clone();
2025 match infer::mk_eqty(self.infcx(), false,
2026 TypeOrigin::Misc(default.origin_span),
2030 result = Some(default);
2042 fn select_all_obligations_or_error(&self) {
2043 debug!("select_all_obligations_or_error");
2045 // upvar inference should have ensured that all deferred call
2046 // resolutions are handled by now.
2047 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2049 self.select_all_obligations_and_apply_defaults();
2051 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
2052 match fulfillment_cx.select_all_or_error(self.infcx()) {
2054 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2058 /// Select as many obligations as we can at present.
2059 fn select_obligations_where_possible(&self) {
2061 self.inh.fulfillment_cx
2063 .select_where_possible(self.infcx())
2066 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2070 fn private_item_is_visible(&self, def_id: DefId) -> bool {
2071 match self.tcx().map.as_local_node_id(def_id) {
2072 Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2073 None => false, // Private items from other crates are never visible
2078 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2079 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2080 Some(self.base_object_lifetime_default(span))
2083 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2084 // RFC #599 specifies that object lifetime defaults take
2085 // precedence over other defaults. But within a fn body we
2086 // don't have a *default* region, rather we use inference to
2087 // find the *correct* region, which is strictly more general
2088 // (and anyway, within a fn body the right region may not even
2089 // be something the user can write explicitly, since it might
2090 // be some expression).
2091 self.infcx().next_region_var(infer::MiscVariable(span))
2094 fn anon_regions(&self, span: Span, count: usize)
2095 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2096 Ok((0..count).map(|_| {
2097 self.infcx().next_region_var(infer::MiscVariable(span))
2102 /// Whether `autoderef` requires types to resolve.
2103 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2104 pub enum UnresolvedTypeAction {
2105 /// Produce an error and return `TyError` whenever a type cannot
2106 /// be resolved (i.e. it is `TyInfer`).
2108 /// Go on without emitting any errors, and return the unresolved
2109 /// type. Useful for probing, e.g. in coercions.
2113 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2114 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2116 /// Note: this method does not modify the adjustments table. The caller is responsible for
2117 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2118 pub fn autoderef<'a, 'b, 'tcx, E, I, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2122 unresolved_type_action: UnresolvedTypeAction,
2123 mut lvalue_pref: LvaluePreference,
2125 -> (Ty<'tcx>, usize, Option<T>)
2126 // FIXME(eddyb) use copyable iterators when that becomes ergonomic.
2128 I: IntoIterator<Item=&'b hir::Expr>,
2129 F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2131 debug!("autoderef(base_ty={:?}, lvalue_pref={:?})",
2132 base_ty, lvalue_pref);
2134 let mut t = base_ty;
2135 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2136 let resolved_t = match unresolved_type_action {
2137 UnresolvedTypeAction::Error => {
2138 structurally_resolved_type(fcx, sp, t)
2140 UnresolvedTypeAction::Ignore => {
2141 // We can continue even when the type cannot be resolved
2142 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2143 // and `try_overloaded_deref` both simply return `None`
2144 // in such a case without producing spurious errors.
2145 fcx.infcx().resolve_type_vars_if_possible(&t)
2148 if resolved_t.references_error() {
2149 return (resolved_t, autoderefs, None);
2152 match should_stop(resolved_t, autoderefs) {
2153 Some(x) => return (resolved_t, autoderefs, Some(x)),
2157 // Otherwise, deref if type is derefable:
2159 // Super subtle: it might seem as though we should
2160 // pass `opt_expr` to `try_overloaded_deref`, so that
2161 // the (implicit) autoref of using an overloaded deref
2162 // would get added to the adjustment table. However we
2163 // do not do that, because it's kind of a
2164 // "meta-adjustment" -- instead, we just leave it
2165 // unrecorded and know that there "will be" an
2166 // autoref. regionck and other bits of the code base,
2167 // when they encounter an overloaded autoderef, have
2168 // to do some reconstructive surgery. This is a pretty
2169 // complex mess that is begging for a proper MIR.
2170 let mt = if let Some(mt) = resolved_t.builtin_deref(false, lvalue_pref) {
2172 } else if let Some(method) = try_overloaded_deref(fcx, sp, None,
2173 resolved_t, lvalue_pref) {
2174 for expr in maybe_exprs() {
2175 let method_call = MethodCall::autoderef(expr.id, autoderefs as u32);
2176 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2178 make_overloaded_lvalue_return_type(fcx.tcx(), method)
2180 return (resolved_t, autoderefs, None);
2184 if mt.mutbl == hir::MutImmutable {
2185 lvalue_pref = NoPreference;
2189 // We've reached the recursion limit, error gracefully.
2190 span_err!(fcx.tcx().sess, sp, E0055,
2191 "reached the recursion limit while auto-dereferencing {:?}",
2193 (fcx.tcx().types.err, 0, None)
2196 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2198 base_expr: Option<&hir::Expr>,
2200 lvalue_pref: LvaluePreference)
2201 -> Option<MethodCallee<'tcx>>
2203 // Try DerefMut first, if preferred.
2204 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2205 (PreferMutLvalue, Some(trait_did)) => {
2206 method::lookup_in_trait(fcx, span, base_expr,
2207 token::intern("deref_mut"), trait_did,
2213 // Otherwise, fall back to Deref.
2214 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2215 (None, Some(trait_did)) => {
2216 method::lookup_in_trait(fcx, span, base_expr,
2217 token::intern("deref"), trait_did,
2220 (method, _) => method
2226 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2227 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2228 /// type by one layer to yield `T`.
2229 fn make_overloaded_lvalue_return_type<'tcx>(tcx: &TyCtxt<'tcx>,
2230 method: MethodCallee<'tcx>)
2231 -> ty::TypeAndMut<'tcx>
2233 // extract method return type, which will be &T;
2234 // all LB regions should have been instantiated during method lookup
2235 let ret_ty = method.ty.fn_ret();
2236 let ret_ty = tcx.no_late_bound_regions(&ret_ty).unwrap().unwrap();
2238 // method returns &T, but the type as visible to user is T, so deref
2239 ret_ty.builtin_deref(true, NoPreference).unwrap()
2242 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2244 base_expr: &'tcx hir::Expr,
2247 lvalue_pref: LvaluePreference)
2248 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2250 // FIXME(#18741) -- this is almost but not quite the same as the
2251 // autoderef that normal method probing does. They could likely be
2254 let (ty, autoderefs, final_mt) = autoderef(fcx,
2258 UnresolvedTypeAction::Error,
2261 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2262 adj_ty, idx, false, lvalue_pref, idx_ty)
2265 if final_mt.is_some() {
2269 // After we have fully autoderef'd, if the resulting type is [T; n], then
2270 // do a final unsized coercion to yield [T].
2271 if let ty::TyArray(element_ty, _) = ty.sty {
2272 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2273 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2274 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2280 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2281 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2282 /// This loop implements one step in that search; the autoderef loop is implemented by
2283 /// `lookup_indexing`.
2284 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2285 method_call: MethodCall,
2287 base_expr: &'tcx hir::Expr,
2288 adjusted_ty: Ty<'tcx>,
2291 lvalue_pref: LvaluePreference,
2293 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2295 let tcx = fcx.tcx();
2296 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2297 autoderefs={}, unsize={}, index_ty={:?})",
2305 let input_ty = fcx.infcx().next_ty_var();
2307 // First, try built-in indexing.
2308 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2309 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2310 debug!("try_index_step: success, using built-in indexing");
2311 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2313 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2314 return Some((tcx.types.usize, ty));
2319 // Try `IndexMut` first, if preferred.
2320 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2321 (PreferMutLvalue, Some(trait_did)) => {
2322 method::lookup_in_trait_adjusted(fcx,
2325 token::intern("index_mut"),
2330 Some(vec![input_ty]))
2335 // Otherwise, fall back to `Index`.
2336 let method = match (method, tcx.lang_items.index_trait()) {
2337 (None, Some(trait_did)) => {
2338 method::lookup_in_trait_adjusted(fcx,
2341 token::intern("index"),
2346 Some(vec![input_ty]))
2348 (method, _) => method,
2351 // If some lookup succeeds, write callee into table and extract index/element
2352 // type from the method signature.
2353 // If some lookup succeeded, install method in table
2354 method.map(|method| {
2355 debug!("try_index_step: success, using overloaded indexing");
2356 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2357 (input_ty, make_overloaded_lvalue_return_type(fcx.tcx(), method).ty)
2361 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2363 method_fn_ty: Ty<'tcx>,
2364 callee_expr: &'tcx hir::Expr,
2365 args_no_rcvr: &'tcx [P<hir::Expr>],
2366 tuple_arguments: TupleArgumentsFlag,
2367 expected: Expectation<'tcx>)
2368 -> ty::FnOutput<'tcx> {
2369 if method_fn_ty.references_error() {
2370 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2372 let err_inputs = match tuple_arguments {
2373 DontTupleArguments => err_inputs,
2374 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2377 check_argument_types(fcx,
2384 ty::FnConverging(fcx.tcx().types.err)
2386 match method_fn_ty.sty {
2387 ty::TyFnDef(_, _, ref fty) => {
2388 // HACK(eddyb) ignore self in the definition (see above).
2389 let expected_arg_tys = expected_types_for_fn_args(fcx,
2393 &fty.sig.0.inputs[1..]);
2394 check_argument_types(fcx,
2396 &fty.sig.0.inputs[1..],
2397 &expected_arg_tys[..],
2404 fcx.tcx().sess.span_bug(callee_expr.span,
2405 "method without bare fn type");
2411 /// Generic function that factors out common logic from function calls, method calls and overloaded
2413 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2415 fn_inputs: &[Ty<'tcx>],
2416 expected_arg_tys: &[Ty<'tcx>],
2417 args: &'tcx [P<hir::Expr>],
2419 tuple_arguments: TupleArgumentsFlag) {
2420 let tcx = fcx.ccx.tcx;
2422 // Grab the argument types, supplying fresh type variables
2423 // if the wrong number of arguments were supplied
2424 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2430 // All the input types from the fn signature must outlive the call
2431 // so as to validate implied bounds.
2432 for &fn_input_ty in fn_inputs {
2433 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2436 let mut expected_arg_tys = expected_arg_tys;
2437 let expected_arg_count = fn_inputs.len();
2438 let formal_tys = if tuple_arguments == TupleArguments {
2439 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2440 match tuple_type.sty {
2441 ty::TyTuple(ref arg_types) => {
2442 if arg_types.len() != args.len() {
2443 span_err!(tcx.sess, sp, E0057,
2444 "this function takes {} parameter{} but {} parameter{} supplied",
2446 if arg_types.len() == 1 {""} else {"s"},
2448 if args.len() == 1 {" was"} else {"s were"});
2449 expected_arg_tys = &[];
2450 err_args(fcx.tcx(), args.len())
2452 expected_arg_tys = match expected_arg_tys.get(0) {
2453 Some(&ty) => match ty.sty {
2454 ty::TyTuple(ref tys) => &tys,
2459 (*arg_types).clone()
2463 span_err!(tcx.sess, sp, E0059,
2464 "cannot use call notation; the first type parameter \
2465 for the function trait is neither a tuple nor unit");
2466 expected_arg_tys = &[];
2467 err_args(fcx.tcx(), args.len())
2470 } else if expected_arg_count == supplied_arg_count {
2472 } else if variadic {
2473 if supplied_arg_count >= expected_arg_count {
2476 span_err!(tcx.sess, sp, E0060,
2477 "this function takes at least {} parameter{} \
2478 but {} parameter{} supplied",
2480 if expected_arg_count == 1 {""} else {"s"},
2482 if supplied_arg_count == 1 {" was"} else {"s were"});
2483 expected_arg_tys = &[];
2484 err_args(fcx.tcx(), supplied_arg_count)
2487 span_err!(tcx.sess, sp, E0061,
2488 "this function takes {} parameter{} but {} parameter{} supplied",
2490 if expected_arg_count == 1 {""} else {"s"},
2492 if supplied_arg_count == 1 {" was"} else {"s were"});
2493 expected_arg_tys = &[];
2494 err_args(fcx.tcx(), supplied_arg_count)
2497 debug!("check_argument_types: formal_tys={:?}",
2498 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2500 // Check the arguments.
2501 // We do this in a pretty awful way: first we typecheck any arguments
2502 // that are not anonymous functions, then we typecheck the anonymous
2503 // functions. This is so that we have more information about the types
2504 // of arguments when we typecheck the functions. This isn't really the
2505 // right way to do this.
2506 let xs = [false, true];
2507 let mut any_diverges = false; // has any of the arguments diverged?
2508 let mut warned = false; // have we already warned about unreachable code?
2509 for check_blocks in &xs {
2510 let check_blocks = *check_blocks;
2511 debug!("check_blocks={}", check_blocks);
2513 // More awful hacks: before we check argument types, try to do
2514 // an "opportunistic" vtable resolution of any trait bounds on
2515 // the call. This helps coercions.
2517 fcx.select_obligations_where_possible();
2520 // For variadic functions, we don't have a declared type for all of
2521 // the arguments hence we only do our usual type checking with
2522 // the arguments who's types we do know.
2523 let t = if variadic {
2525 } else if tuple_arguments == TupleArguments {
2530 for (i, arg) in args.iter().take(t).enumerate() {
2531 if any_diverges && !warned {
2535 .add_lint(lint::builtin::UNREACHABLE_CODE,
2538 "unreachable expression".to_string());
2541 let is_block = match arg.node {
2542 hir::ExprClosure(..) => true,
2546 if is_block == check_blocks {
2547 debug!("checking the argument");
2548 let formal_ty = formal_tys[i];
2550 // The special-cased logic below has three functions:
2551 // 1. Provide as good of an expected type as possible.
2552 let expected = expected_arg_tys.get(i).map(|&ty| {
2553 Expectation::rvalue_hint(fcx.tcx(), ty)
2556 check_expr_with_expectation(fcx, &arg,
2557 expected.unwrap_or(ExpectHasType(formal_ty)));
2558 // 2. Coerce to the most detailed type that could be coerced
2559 // to, which is `expected_ty` if `rvalue_hint` returns an
2560 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2561 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2562 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2564 // 3. Relate the expected type and the formal one,
2565 // if the expected type was used for the coercion.
2566 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2569 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2570 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2573 if any_diverges && !warned {
2574 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2578 .add_lint(lint::builtin::UNREACHABLE_CODE,
2581 "unreachable call".to_string());
2587 // We also need to make sure we at least write the ty of the other
2588 // arguments which we skipped above.
2590 for arg in args.iter().skip(expected_arg_count) {
2591 check_expr(fcx, &arg);
2593 // There are a few types which get autopromoted when passed via varargs
2594 // in C but we just error out instead and require explicit casts.
2595 let arg_ty = structurally_resolved_type(fcx, arg.span,
2598 ty::TyFloat(ast::FloatTy::F32) => {
2599 fcx.type_error_message(arg.span,
2601 format!("can't pass an {} to variadic \
2602 function, cast to c_double", t)
2605 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2606 fcx.type_error_message(arg.span, |t| {
2607 format!("can't pass {} to variadic \
2608 function, cast to c_int",
2612 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2613 fcx.type_error_message(arg.span, |t| {
2614 format!("can't pass {} to variadic \
2615 function, cast to c_uint",
2625 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2626 fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2627 (0..len).map(|_| tcx.types.err).collect()
2630 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2631 call_expr: &hir::Expr,
2632 output: ty::FnOutput<'tcx>) {
2633 fcx.write_ty(call_expr.id, match output {
2634 ty::FnConverging(output_ty) => output_ty,
2635 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2639 // AST fragment checking
2640 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2642 expected: Expectation<'tcx>)
2645 let tcx = fcx.ccx.tcx;
2648 ast::LitKind::Str(..) => tcx.mk_static_str(),
2649 ast::LitKind::ByteStr(ref v) => {
2650 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2651 tcx.mk_array(tcx.types.u8, v.len()))
2653 ast::LitKind::Byte(_) => tcx.types.u8,
2654 ast::LitKind::Char(_) => tcx.types.char,
2655 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2656 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2657 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2658 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2660 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2661 ty::TyChar => Some(tcx.types.u8),
2662 ty::TyRawPtr(..) => Some(tcx.types.usize),
2663 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2667 opt_ty.unwrap_or_else(
2668 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2670 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2671 ast::LitKind::FloatUnsuffixed(_) => {
2672 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2674 ty::TyFloat(_) => Some(ty),
2678 opt_ty.unwrap_or_else(
2679 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2681 ast::LitKind::Bool(_) => tcx.types.bool
2685 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2686 expr: &'tcx hir::Expr,
2687 expected: Ty<'tcx>) {
2688 check_expr_with_hint(fcx, expr, expected);
2689 demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr));
2692 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2693 expr: &'tcx hir::Expr,
2694 expected: Ty<'tcx>) {
2695 check_expr_with_hint(fcx, expr, expected);
2696 demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr));
2699 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2700 expr: &'tcx hir::Expr,
2701 expected: Ty<'tcx>) {
2702 check_expr_with_hint(fcx, expr, expected);
2703 demand::coerce(fcx, expr.span, expected, expr);
2706 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2707 expected: Ty<'tcx>) {
2708 check_expr_with_expectation(fcx, expr, ExpectHasType(expected))
2711 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2712 expr: &'tcx hir::Expr,
2713 expected: Expectation<'tcx>) {
2714 check_expr_with_expectation_and_lvalue_pref(fcx, expr, expected, NoPreference)
2717 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2718 check_expr_with_expectation(fcx, expr, NoExpectation)
2721 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2722 lvalue_pref: LvaluePreference) {
2723 check_expr_with_expectation_and_lvalue_pref(fcx, expr, NoExpectation, lvalue_pref)
2726 // determine the `self` type, using fresh variables for all variables
2727 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2728 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2730 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2731 span: Span, // (potential) receiver for this impl
2733 -> TypeAndSubsts<'tcx> {
2734 let tcx = fcx.tcx();
2736 let ity = tcx.lookup_item_type(did);
2737 let (tps, rps, raw_ty) =
2738 (ity.generics.types.get_slice(subst::TypeSpace),
2739 ity.generics.regions.get_slice(subst::TypeSpace),
2742 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2744 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2745 let mut substs = subst::Substs::new(
2746 VecPerParamSpace::empty(),
2747 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2748 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2749 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2751 TypeAndSubsts { substs: substs, ty: substd_ty }
2754 /// Controls whether the arguments are tupled. This is used for the call
2757 /// Tupling means that all call-side arguments are packed into a tuple and
2758 /// passed as a single parameter. For example, if tupling is enabled, this
2761 /// fn f(x: (isize, isize))
2763 /// Can be called as:
2770 #[derive(Clone, Eq, PartialEq)]
2771 enum TupleArgumentsFlag {
2776 /// Unifies the return type with the expected type early, for more coercions
2777 /// and forward type information on the argument expressions.
2778 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2780 expected_ret: Expectation<'tcx>,
2781 formal_ret: ty::FnOutput<'tcx>,
2782 formal_args: &[Ty<'tcx>])
2784 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2785 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2786 fcx.infcx().commit_regions_if_ok(|| {
2787 // Attempt to apply a subtyping relationship between the formal
2788 // return type (likely containing type variables if the function
2789 // is polymorphic) and the expected return type.
2790 // No argument expectations are produced if unification fails.
2791 let origin = TypeOrigin::Misc(call_span);
2792 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2793 // FIXME(#15760) can't use try! here, FromError doesn't default
2794 // to identity so the resulting type is not constrained.
2795 if let Err(e) = ures {
2799 // Record all the argument types, with the substitutions
2800 // produced from the above subtyping unification.
2801 Ok(formal_args.iter().map(|ty| {
2802 fcx.infcx().resolve_type_vars_if_possible(ty)
2808 }).unwrap_or(vec![]);
2809 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2810 formal_args, formal_ret,
2811 expected_args, expected_ret);
2816 /// If an expression has any sub-expressions that result in a type error,
2817 /// inspecting that expression's type with `ty.references_error()` will return
2818 /// true. Likewise, if an expression is known to diverge, inspecting its
2819 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2820 /// strict, _|_ can appear in the type of an expression that does not,
2821 /// itself, diverge: for example, fn() -> _|_.)
2822 /// Note that inspecting a type's structure *directly* may expose the fact
2823 /// that there are actually multiple representations for `TyError`, so avoid
2824 /// that when err needs to be handled differently.
2825 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2826 expr: &'tcx hir::Expr,
2827 expected: Expectation<'tcx>,
2828 lvalue_pref: LvaluePreference) {
2829 debug!(">> typechecking: expr={:?} expected={:?}",
2832 // Checks a method call.
2833 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2834 expr: &'tcx hir::Expr,
2835 method_name: Spanned<ast::Name>,
2836 args: &'tcx [P<hir::Expr>],
2838 expected: Expectation<'tcx>,
2839 lvalue_pref: LvaluePreference) {
2840 let rcvr = &args[0];
2841 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2843 // no need to check for bot/err -- callee does that
2844 let expr_t = structurally_resolved_type(fcx,
2846 fcx.expr_ty(&rcvr));
2848 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2849 let fn_ty = match method::lookup(fcx,
2857 let method_ty = method.ty;
2858 let method_call = MethodCall::expr(expr.id);
2859 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2863 if method_name.node != special_idents::invalid.name {
2864 method::report_error(fcx, method_name.span, expr_t,
2865 method_name.node, Some(rcvr), error);
2867 fcx.write_error(expr.id);
2872 // Call the generic checker.
2873 let ret_ty = check_method_argument_types(fcx,
2881 write_call(fcx, expr, ret_ty);
2884 // A generic function for checking the then and else in an if
2886 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2887 cond_expr: &'tcx hir::Expr,
2888 then_blk: &'tcx hir::Block,
2889 opt_else_expr: Option<&'tcx hir::Expr>,
2892 expected: Expectation<'tcx>) {
2893 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2895 let expected = expected.adjust_for_branches(fcx);
2896 check_block_with_expected(fcx, then_blk, expected);
2897 let then_ty = fcx.node_ty(then_blk.id);
2899 let unit = fcx.tcx().mk_nil();
2900 let (origin, expected, found, result) =
2901 if let Some(else_expr) = opt_else_expr {
2902 check_expr_with_expectation(fcx, else_expr, expected);
2903 let else_ty = fcx.expr_ty(else_expr);
2904 let origin = TypeOrigin::IfExpression(sp);
2906 // Only try to coerce-unify if we have a then expression
2907 // to assign coercions to, otherwise it's () or diverging.
2908 let result = if let Some(ref then) = then_blk.expr {
2909 let res = coercion::try_find_lub(fcx, origin, || Some(&**then),
2910 then_ty, else_expr);
2912 // In case we did perform an adjustment, we have to update
2913 // the type of the block, because old trans still uses it.
2914 let adj = fcx.inh.tables.borrow().adjustments.get(&then.id).cloned();
2915 if res.is_ok() && adj.is_some() {
2916 fcx.write_ty(then_blk.id, fcx.adjust_expr_ty(then, adj.as_ref()));
2921 fcx.infcx().commit_if_ok(|_| {
2922 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2923 fcx.infcx().lub(true, trace).relate(&then_ty, &else_ty)
2926 (origin, then_ty, else_ty, result)
2928 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2929 (origin, unit, then_ty,
2930 fcx.infcx().eq_types(true, origin, unit, then_ty).map(|_| unit))
2933 let if_ty = match result {
2935 if fcx.expr_ty(cond_expr).references_error() {
2942 fcx.infcx().report_mismatched_types(origin, expected, found, e);
2947 fcx.write_ty(id, if_ty);
2950 // Check field access expressions
2951 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2952 expr: &'tcx hir::Expr,
2953 lvalue_pref: LvaluePreference,
2954 base: &'tcx hir::Expr,
2955 field: &Spanned<ast::Name>) {
2956 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2957 let expr_t = structurally_resolved_type(fcx, expr.span,
2959 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2960 let (_, autoderefs, field_ty) = autoderef(fcx,
2964 UnresolvedTypeAction::Error,
2968 ty::TyStruct(base_def, substs) => {
2969 debug!("struct named {:?}", base_t);
2970 base_def.struct_variant()
2971 .find_field_named(field.node)
2972 .map(|f| fcx.field_ty(expr.span, f, substs))
2979 fcx.write_ty(expr.id, field_ty);
2980 fcx.write_autoderef_adjustment(base.id, autoderefs);
2986 if field.node == special_idents::invalid.name {
2987 fcx.write_error(expr.id);
2991 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2992 fcx.type_error_struct(field.span,
2994 format!("attempted to take value of method `{}` on type \
2995 `{}`", field.node, actual)
2998 .fileline_help(field.span,
2999 "maybe a `()` to call it is missing? \
3000 If not, try an anonymous function")
3003 let mut err = fcx.type_error_struct(
3006 format!("attempted access of field `{}` on \
3007 type `{}`, but no field with that \
3013 if let ty::TyStruct(def, _) = expr_t.sty {
3014 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
3019 fcx.write_error(expr.id);
3022 // displays hints about the closest matches in field names
3023 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
3024 variant: ty::VariantDef<'tcx>,
3025 field: &Spanned<ast::Name>,
3026 skip : Vec<InternedString>) {
3027 let name = field.node.as_str();
3028 let names = variant.fields
3030 .filter_map(|ref field| {
3031 // ignore already set fields and private fields from non-local crates
3032 if skip.iter().any(|x| *x == field.name.as_str()) ||
3033 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
3040 // only find fits with at least one matching letter
3041 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
3042 err.span_help(field.span,
3043 &format!("did you mean `{}`?", name));
3047 // Check tuple index expressions
3048 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3049 expr: &'tcx hir::Expr,
3050 lvalue_pref: LvaluePreference,
3051 base: &'tcx hir::Expr,
3052 idx: codemap::Spanned<usize>) {
3053 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3054 let expr_t = structurally_resolved_type(fcx, expr.span,
3056 let mut tuple_like = false;
3057 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3058 let (_, autoderefs, field_ty) = autoderef(fcx,
3062 UnresolvedTypeAction::Error,
3066 ty::TyStruct(base_def, substs) => {
3067 tuple_like = base_def.struct_variant().is_tuple_struct();
3069 debug!("tuple struct named {:?}", base_t);
3070 base_def.struct_variant()
3073 .map(|f| fcx.field_ty(expr.span, f, substs))
3078 ty::TyTuple(ref v) => {
3080 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3087 fcx.write_ty(expr.id, field_ty);
3088 fcx.write_autoderef_adjustment(base.id, autoderefs);
3093 fcx.type_error_message(
3097 format!("attempted out-of-bounds tuple index `{}` on \
3102 format!("attempted tuple index `{}` on type `{}`, but the \
3103 type was not a tuple or tuple struct",
3110 fcx.write_error(expr.id);
3113 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3115 variant: ty::VariantDef<'tcx>,
3117 skip_fields: &[hir::Field]) {
3118 let mut err = fcx.type_error_struct(
3120 |actual| if let ty::TyEnum(..) = ty.sty {
3121 format!("struct variant `{}::{}` has no field named `{}`",
3122 actual, variant.name.as_str(), field.name.node)
3124 format!("structure `{}` has no field named `{}`",
3125 actual, field.name.node)
3129 // prevent all specified fields from being suggested
3130 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3131 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3135 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3138 variant: ty::VariantDef<'tcx>,
3139 ast_fields: &'tcx [hir::Field],
3140 check_completeness: bool) {
3141 let tcx = fcx.ccx.tcx;
3142 let substs = match adt_ty.sty {
3143 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3144 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3147 let mut remaining_fields = FnvHashMap();
3148 for field in &variant.fields {
3149 remaining_fields.insert(field.name, field);
3152 let mut error_happened = false;
3154 // Typecheck each field.
3155 for field in ast_fields {
3156 let expected_field_type;
3158 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3159 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3161 error_happened = true;
3162 expected_field_type = tcx.types.err;
3163 if let Some(_) = variant.find_field_named(field.name.node) {
3164 span_err!(fcx.tcx().sess, field.name.span, E0062,
3165 "field `{}` specified more than once",
3168 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3172 // Make sure to give a type to the field even if there's
3173 // an error, so we can continue typechecking
3174 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3177 // Make sure the programmer specified all the fields.
3178 if check_completeness &&
3180 !remaining_fields.is_empty()
3182 span_err!(tcx.sess, span, E0063,
3183 "missing field{} {} in initializer of `{}`",
3184 if remaining_fields.len() == 1 {""} else {"s"},
3185 remaining_fields.keys()
3186 .map(|n| format!("`{}`", n))
3187 .collect::<Vec<_>>()
3194 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3196 fields: &'tcx [hir::Field],
3197 base_expr: &'tcx Option<P<hir::Expr>>) {
3198 // Make sure to still write the types
3199 // otherwise we might ICE
3200 fcx.write_error(id);
3201 for field in fields {
3202 check_expr(fcx, &field.expr);
3205 Some(ref base) => check_expr(fcx, &base),
3210 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3213 fields: &'tcx [hir::Field],
3214 base_expr: &'tcx Option<P<hir::Expr>>)
3216 let tcx = fcx.tcx();
3218 // Find the relevant variant
3219 let def = lookup_full_def(tcx, path.span, expr.id);
3220 if def == Def::Err {
3221 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3224 let variant = match fcx.def_struct_variant(def, path.span) {
3225 Some((_, variant)) => variant,
3227 span_err!(fcx.tcx().sess, path.span, E0071,
3228 "`{}` does not name a structure",
3229 pprust::path_to_string(path));
3230 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3235 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3236 fcx.write_ty(expr.id, expr_ty);
3238 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3239 base_expr.is_none());
3240 if let &Some(ref base_expr) = base_expr {
3241 check_expr_has_type(fcx, base_expr, expr_ty);
3243 ty::TyStruct(adt, substs) => {
3244 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3246 adt.struct_variant().fields.iter().map(|f| {
3247 fcx.normalize_associated_types_in(
3248 expr.span, &f.ty(tcx, substs)
3254 span_err!(tcx.sess, base_expr.span, E0436,
3255 "functional record update syntax requires a struct");
3261 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3263 let tcx = fcx.ccx.tcx;
3266 hir::ExprBox(ref subexpr) => {
3267 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3269 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3273 check_expr_with_expectation(fcx, subexpr, expected_inner);
3274 let referent_ty = fcx.expr_ty(&subexpr);
3275 fcx.write_ty(id, tcx.mk_box(referent_ty));
3278 hir::ExprLit(ref lit) => {
3279 let typ = check_lit(fcx, &lit, expected);
3280 fcx.write_ty(id, typ);
3282 hir::ExprBinary(op, ref lhs, ref rhs) => {
3283 op::check_binop(fcx, expr, op, lhs, rhs);
3285 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3286 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3288 hir::ExprUnary(unop, ref oprnd) => {
3289 let expected_inner = match unop {
3290 hir::UnNot | hir::UnNeg => {
3297 let lvalue_pref = match unop {
3298 hir::UnDeref => lvalue_pref,
3301 check_expr_with_expectation_and_lvalue_pref(
3302 fcx, &oprnd, expected_inner, lvalue_pref);
3303 let mut oprnd_t = fcx.expr_ty(&oprnd);
3305 if !oprnd_t.references_error() {
3308 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3310 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3312 } else if let Some(method) = try_overloaded_deref(
3313 fcx, expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3314 oprnd_t = make_overloaded_lvalue_return_type(tcx, method).ty;
3315 fcx.inh.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3318 fcx.type_error_message(expr.span, |actual| {
3319 format!("type `{}` cannot be \
3320 dereferenced", actual)
3322 oprnd_t = tcx.types.err;
3326 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3328 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3329 oprnd_t = op::check_user_unop(fcx, "!", "not",
3330 tcx.lang_items.not_trait(),
3331 expr, &oprnd, oprnd_t, unop);
3335 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3337 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3338 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3339 tcx.lang_items.neg_trait(),
3340 expr, &oprnd, oprnd_t, unop);
3345 fcx.write_ty(id, oprnd_t);
3347 hir::ExprAddrOf(mutbl, ref oprnd) => {
3348 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3350 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3351 if fcx.tcx().expr_is_lval(&oprnd) {
3352 // Lvalues may legitimately have unsized types.
3353 // For example, dereferences of a fat pointer and
3354 // the last field of a struct can be unsized.
3355 ExpectHasType(mt.ty)
3357 Expectation::rvalue_hint(tcx, mt.ty)
3363 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3364 check_expr_with_expectation_and_lvalue_pref(fcx,
3369 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3370 let oprnd_t = if tm.ty.references_error() {
3373 // Note: at this point, we cannot say what the best lifetime
3374 // is to use for resulting pointer. We want to use the
3375 // shortest lifetime possible so as to avoid spurious borrowck
3376 // errors. Moreover, the longest lifetime will depend on the
3377 // precise details of the value whose address is being taken
3378 // (and how long it is valid), which we don't know yet until type
3379 // inference is complete.
3381 // Therefore, here we simply generate a region variable. The
3382 // region inferencer will then select the ultimate value.
3383 // Finally, borrowck is charged with guaranteeing that the
3384 // value whose address was taken can actually be made to live
3385 // as long as it needs to live.
3386 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3387 tcx.mk_ref(tcx.mk_region(region), tm)
3389 fcx.write_ty(id, oprnd_t);
3391 hir::ExprPath(ref maybe_qself, ref path) => {
3392 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3393 fcx.to_ty(&qself.ty)
3396 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3398 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3399 // Create some fake resolution that can't possibly be a type.
3400 def::PathResolution {
3401 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3402 depth: path.segments.len()
3405 tcx.sess.span_bug(expr.span,
3406 &format!("unbound path {:?}", expr))
3409 if let Some((opt_ty, segments, def)) =
3410 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3411 expr.span, expr.id) {
3412 if def != Def::Err {
3413 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3416 instantiate_path(fcx,
3425 fcx.write_ty(id, fcx.tcx().types.err);
3429 // We always require that the type provided as the value for
3430 // a type parameter outlives the moment of instantiation.
3431 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3432 fcx.add_wf_bounds(&item_substs.substs, expr);
3435 hir::ExprInlineAsm(ref ia) => {
3436 for &(_, ref input) in &ia.inputs {
3437 check_expr(fcx, &input);
3439 for out in &ia.outputs {
3440 check_expr(fcx, &out.expr);
3444 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3445 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3446 hir::ExprRet(ref expr_opt) => {
3448 ty::FnConverging(result_type) => {
3451 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3452 result_type, fcx.tcx().mk_nil()) {
3453 span_err!(tcx.sess, expr.span, E0069,
3454 "`return;` in a function whose return type is \
3458 check_expr_coercable_to_type(fcx, &e, result_type);
3462 ty::FnDiverging => {
3463 if let Some(ref e) = *expr_opt {
3464 check_expr(fcx, &e);
3466 span_err!(tcx.sess, expr.span, E0166,
3467 "`return` in a function declared as diverging");
3470 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3472 hir::ExprAssign(ref lhs, ref rhs) => {
3473 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3475 let tcx = fcx.tcx();
3476 if !tcx.expr_is_lval(&lhs) {
3477 span_err!(tcx.sess, expr.span, E0070,
3478 "invalid left-hand side expression");
3481 let lhs_ty = fcx.expr_ty(&lhs);
3482 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3483 let rhs_ty = fcx.expr_ty(&rhs);
3485 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3487 if lhs_ty.references_error() || rhs_ty.references_error() {
3488 fcx.write_error(id);
3493 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3494 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3495 id, expr.span, expected);
3497 hir::ExprWhile(ref cond, ref body, _) => {
3498 check_expr_has_type(fcx, &cond, tcx.types.bool);
3499 check_block_no_value(fcx, &body);
3500 let cond_ty = fcx.expr_ty(&cond);
3501 let body_ty = fcx.node_ty(body.id);
3502 if cond_ty.references_error() || body_ty.references_error() {
3503 fcx.write_error(id);
3509 hir::ExprLoop(ref body, _) => {
3510 check_block_no_value(fcx, &body);
3511 if !may_break(tcx, expr.id, &body) {
3512 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3517 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3518 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3520 hir::ExprClosure(capture, ref decl, ref body) => {
3521 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3523 hir::ExprBlock(ref b) => {
3524 check_block_with_expected(fcx, &b, expected);
3525 fcx.write_ty(id, fcx.node_ty(b.id));
3527 hir::ExprCall(ref callee, ref args) => {
3528 callee::check_call(fcx, expr, &callee, &args[..], expected);
3530 // we must check that return type of called functions is WF:
3531 let ret_ty = fcx.expr_ty(expr);
3532 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3534 hir::ExprMethodCall(name, ref tps, ref args) => {
3535 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3536 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3537 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3539 fcx.write_error(id);
3542 hir::ExprCast(ref e, ref t) => {
3543 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3544 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3547 // Find the type of `e`. Supply hints based on the type we are casting to,
3549 let t_cast = fcx.to_ty(t);
3550 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3551 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3552 let t_expr = fcx.expr_ty(e);
3553 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3555 // Eagerly check for some obvious errors.
3556 if t_expr.references_error() || t_cast.references_error() {
3557 fcx.write_error(id);
3558 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3559 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3561 // Write a type for the whole expression, assuming everything is going
3563 fcx.write_ty(id, t_cast);
3565 // Defer other checks until we're done type checking.
3566 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3567 let cast_check = cast::CastCheck::new(e, t_expr, t_cast, expr.span);
3568 deferred_cast_checks.push(cast_check);
3571 hir::ExprType(ref e, ref t) => {
3572 let typ = fcx.to_ty(&t);
3573 check_expr_eq_type(fcx, &e, typ);
3574 fcx.write_ty(id, typ);
3576 hir::ExprVec(ref args) => {
3577 let uty = expected.to_option(fcx).and_then(|uty| {
3579 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3584 let mut unified = fcx.infcx().next_ty_var();
3585 let coerce_to = uty.unwrap_or(unified);
3587 for (i, e) in args.iter().enumerate() {
3588 check_expr_with_hint(fcx, e, coerce_to);
3589 let e_ty = fcx.expr_ty(e);
3590 let origin = TypeOrigin::Misc(e.span);
3592 // Special-case the first element, as it has no "previous expressions".
3593 let result = if i == 0 {
3594 coercion::try(fcx, e, coerce_to)
3596 let prev_elems = || args[..i].iter().map(|e| &**e);
3597 coercion::try_find_lub(fcx, origin, prev_elems, unified, e)
3601 Ok(ty) => unified = ty,
3603 fcx.infcx().report_mismatched_types(origin, unified, e_ty, e);
3607 fcx.write_ty(id, tcx.mk_array(unified, args.len()));
3609 hir::ExprRepeat(ref element, ref count_expr) => {
3610 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3611 let count = fcx.tcx().eval_repeat_count(&count_expr);
3613 let uty = match expected {
3614 ExpectHasType(uty) => {
3616 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3623 let (element_ty, t) = match uty {
3625 check_expr_coercable_to_type(fcx, &element, uty);
3629 let t: Ty = fcx.infcx().next_ty_var();
3630 check_expr_has_type(fcx, &element, t);
3631 (fcx.expr_ty(&element), t)
3636 // For [foo, ..n] where n > 1, `foo` must have
3638 fcx.require_type_meets(
3645 if element_ty.references_error() {
3646 fcx.write_error(id);
3648 let t = tcx.mk_array(t, count);
3649 fcx.write_ty(id, t);
3652 hir::ExprTup(ref elts) => {
3653 let flds = expected.only_has_type(fcx).and_then(|ty| {
3655 ty::TyTuple(ref flds) => Some(&flds[..]),
3659 let mut err_field = false;
3661 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3662 let t = match flds {
3663 Some(ref fs) if i < fs.len() => {
3665 check_expr_coercable_to_type(fcx, &e, ety);
3669 check_expr_with_expectation(fcx, &e, NoExpectation);
3673 err_field = err_field || t.references_error();
3677 fcx.write_error(id);
3679 let typ = tcx.mk_tup(elt_ts);
3680 fcx.write_ty(id, typ);
3683 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3684 check_expr_struct(fcx, expr, path, fields, base_expr);
3686 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3688 hir::ExprField(ref base, ref field) => {
3689 check_field(fcx, expr, lvalue_pref, &base, field);
3691 hir::ExprTupField(ref base, idx) => {
3692 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3694 hir::ExprIndex(ref base, ref idx) => {
3695 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3696 check_expr(fcx, &idx);
3698 let base_t = fcx.expr_ty(&base);
3699 let idx_t = fcx.expr_ty(&idx);
3701 if base_t.references_error() {
3702 fcx.write_ty(id, base_t);
3703 } else if idx_t.references_error() {
3704 fcx.write_ty(id, idx_t);
3706 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3707 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3708 Some((index_ty, element_ty)) => {
3709 let idx_expr_ty = fcx.expr_ty(idx);
3710 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3711 fcx.write_ty(id, element_ty);
3714 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3715 fcx.type_error_message(
3718 format!("cannot index a value of type `{}`",
3723 fcx.write_ty(id, fcx.tcx().types.err);
3730 debug!("type of expr({}) {} is...", expr.id,
3731 pprust::expr_to_string(expr));
3732 debug!("... {:?}, expected is {:?}",
3737 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3738 path_res: def::PathResolution,
3739 opt_self_ty: Option<Ty<'tcx>>,
3740 path: &'a hir::Path,
3742 node_id: ast::NodeId)
3743 -> Option<(Option<Ty<'tcx>>,
3744 &'a [hir::PathSegment],
3748 // If fully resolved already, we don't have to do anything.
3749 if path_res.depth == 0 {
3750 Some((opt_self_ty, &path.segments, path_res.base_def))
3752 let mut def = path_res.base_def;
3753 let ty_segments = path.segments.split_last().unwrap().1;
3754 let base_ty_end = path.segments.len() - path_res.depth;
3755 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3756 PathParamMode::Optional,
3759 &ty_segments[..base_ty_end],
3760 &ty_segments[base_ty_end..]);
3761 let item_segment = path.segments.last().unwrap();
3762 let item_name = item_segment.identifier.name;
3763 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3765 // Write back the new resolution.
3766 fcx.ccx.tcx.def_map.borrow_mut()
3767 .insert(node_id, def::PathResolution {
3771 Some((Some(ty), slice::ref_slice(item_segment), def))
3774 if item_name != special_idents::invalid.name {
3775 method::report_error(fcx, span, ty, item_name, None, error);
3777 fcx.write_error(node_id);
3784 impl<'tcx> Expectation<'tcx> {
3785 /// Provide an expectation for an rvalue expression given an *optional*
3786 /// hint, which is not required for type safety (the resulting type might
3787 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3788 /// is useful in determining the concrete type.
3790 /// The primary use case is where the expected type is a fat pointer,
3791 /// like `&[isize]`. For example, consider the following statement:
3793 /// let x: &[isize] = &[1, 2, 3];
3795 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3796 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3797 /// expectation `ExpectHasType([isize])`, that would be too strong --
3798 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3799 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3800 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3801 /// which still is useful, because it informs integer literals and the like.
3802 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3803 /// for examples of where this comes up,.
3804 fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3805 match tcx.struct_tail(ty).sty {
3806 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3807 ExpectRvalueLikeUnsized(ty)
3809 _ => ExpectHasType(ty)
3813 // Resolves `expected` by a single level if it is a variable. If
3814 // there is no expected type or resolution is not possible (e.g.,
3815 // no constraints yet present), just returns `None`.
3816 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3821 ExpectCastableToType(t) => {
3822 ExpectCastableToType(
3823 fcx.infcx().resolve_type_vars_if_possible(&t))
3825 ExpectHasType(t) => {
3827 fcx.infcx().resolve_type_vars_if_possible(&t))
3829 ExpectRvalueLikeUnsized(t) => {
3830 ExpectRvalueLikeUnsized(
3831 fcx.infcx().resolve_type_vars_if_possible(&t))
3836 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3837 match self.resolve(fcx) {
3838 NoExpectation => None,
3839 ExpectCastableToType(ty) |
3841 ExpectRvalueLikeUnsized(ty) => Some(ty),
3845 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3846 match self.resolve(fcx) {
3847 ExpectHasType(ty) => Some(ty),
3853 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3854 local: &'tcx hir::Local,
3855 init: &'tcx hir::Expr)
3857 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3859 let local_ty = fcx.local_ty(init.span, local.id);
3860 if let Some(m) = ref_bindings {
3861 // Somewhat subtle: if we have a `ref` binding in the pattern,
3862 // we want to avoid introducing coercions for the RHS. This is
3863 // both because it helps preserve sanity and, in the case of
3864 // ref mut, for soundness (issue #23116). In particular, in
3865 // the latter case, we need to be clear that the type of the
3866 // referent for the reference that results is *equal to* the
3867 // type of the lvalue it is referencing, and not some
3868 // supertype thereof.
3869 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3870 let init_ty = fcx.expr_ty(init);
3871 demand::eqtype(fcx, init.span, init_ty, local_ty);
3873 check_expr_coercable_to_type(fcx, init, local_ty)
3877 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3878 let tcx = fcx.ccx.tcx;
3880 let t = fcx.local_ty(local.span, local.id);
3881 fcx.write_ty(local.id, t);
3883 if let Some(ref init) = local.init {
3884 check_decl_initializer(fcx, local, &init);
3885 let init_ty = fcx.expr_ty(&init);
3886 if init_ty.references_error() {
3887 fcx.write_ty(local.id, init_ty);
3891 let pcx = pat_ctxt {
3893 map: pat_id_map(&tcx.def_map, &local.pat),
3895 _match::check_pat(&pcx, &local.pat, t);
3896 let pat_ty = fcx.node_ty(local.pat.id);
3897 if pat_ty.references_error() {
3898 fcx.write_ty(local.id, pat_ty);
3902 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3904 let mut saw_bot = false;
3905 let mut saw_err = false;
3907 hir::StmtDecl(ref decl, id) => {
3910 hir::DeclLocal(ref l) => {
3911 check_decl_local(fcx, &l);
3912 let l_t = fcx.node_ty(l.id);
3913 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3914 saw_err = saw_err || l_t.references_error();
3916 hir::DeclItem(_) => {/* ignore for now */ }
3919 hir::StmtExpr(ref expr, id) => {
3921 // Check with expected type of ()
3922 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3923 let expr_ty = fcx.expr_ty(&expr);
3924 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3925 saw_err = saw_err || expr_ty.references_error();
3927 hir::StmtSemi(ref expr, id) => {
3929 check_expr(fcx, &expr);
3930 let expr_ty = fcx.expr_ty(&expr);
3931 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3932 saw_err |= expr_ty.references_error();
3936 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3939 fcx.write_error(node_id);
3942 fcx.write_nil(node_id)
3946 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3947 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3948 let blkty = fcx.node_ty(blk.id);
3949 if blkty.references_error() {
3950 fcx.write_error(blk.id);
3952 let nilty = fcx.tcx().mk_nil();
3953 demand::suptype(fcx, blk.span, nilty, blkty);
3957 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3958 blk: &'tcx hir::Block,
3959 expected: Expectation<'tcx>) {
3961 let mut fcx_ps = fcx.ps.borrow_mut();
3962 let unsafety_state = fcx_ps.recurse(blk);
3963 replace(&mut *fcx_ps, unsafety_state)
3966 let mut warned = false;
3967 let mut any_diverges = false;
3968 let mut any_err = false;
3969 for s in &blk.stmts {
3971 let s_id = ::rustc_front::util::stmt_id(s);
3972 let s_ty = fcx.node_ty(s_id);
3973 if any_diverges && !warned && match s.node {
3974 hir::StmtDecl(ref decl, _) => {
3976 hir::DeclLocal(_) => true,
3980 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3985 .add_lint(lint::builtin::UNREACHABLE_CODE,
3988 "unreachable statement".to_string());
3991 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3992 any_err = any_err || s_ty.references_error();
3995 None => if any_err {
3996 fcx.write_error(blk.id);
3997 } else if any_diverges {
3998 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4000 fcx.write_nil(blk.id);
4003 if any_diverges && !warned {
4007 .add_lint(lint::builtin::UNREACHABLE_CODE,
4010 "unreachable expression".to_string());
4012 let ety = match expected {
4013 ExpectHasType(ety) => {
4014 check_expr_coercable_to_type(fcx, &e, ety);
4018 check_expr_with_expectation(fcx, &e, expected);
4024 fcx.write_error(blk.id);
4025 } else if any_diverges {
4026 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4028 fcx.write_ty(blk.id, ety);
4033 *fcx.ps.borrow_mut() = prev;
4036 /// Checks a constant appearing in a type. At the moment this is just the
4037 /// length expression in a fixed-length vector, but someday it might be
4038 /// extended to type-level numeric literals.
4039 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
4040 expr: &'tcx hir::Expr,
4041 expected_type: Ty<'tcx>) {
4042 let tables = RefCell::new(ty::Tables::empty());
4043 let inh = static_inherited_fields(ccx, &tables);
4044 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4045 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4048 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4052 let tables = RefCell::new(ty::Tables::empty());
4053 let inh = static_inherited_fields(ccx, &tables);
4054 let rty = ccx.tcx.node_id_to_type(id);
4055 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
4056 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
4057 check_const_with_ty(&fcx, sp, e, declty);
4060 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4064 // Gather locals in statics (because of block expressions).
4065 // This is technically unnecessary because locals in static items are forbidden,
4066 // but prevents type checking from blowing up before const checking can properly
4068 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4070 check_expr_with_hint(fcx, e, declty);
4071 demand::coerce(fcx, e.span, declty, e);
4073 fcx.select_all_obligations_and_apply_defaults();
4074 upvar::closure_analyze_const(&fcx, e);
4075 fcx.select_obligations_where_possible();
4077 fcx.select_all_obligations_or_error();
4079 regionck::regionck_expr(fcx, e);
4080 writeback::resolve_type_vars_in_expr(fcx, e);
4083 /// Checks whether a type can be represented in memory. In particular, it
4084 /// identifies types that contain themselves without indirection through a
4085 /// pointer, which would mean their size is unbounded.
4086 pub fn check_representable(tcx: &TyCtxt,
4088 item_id: ast::NodeId,
4089 _designation: &str) -> bool {
4090 let rty = tcx.node_id_to_type(item_id);
4092 // Check that it is possible to represent this type. This call identifies
4093 // (1) types that contain themselves and (2) types that contain a different
4094 // recursive type. It is only necessary to throw an error on those that
4095 // contain themselves. For case 2, there must be an inner type that will be
4096 // caught by case 1.
4097 match rty.is_representable(tcx, sp) {
4098 Representability::SelfRecursive => {
4099 let item_def_id = tcx.map.local_def_id(item_id);
4100 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4103 Representability::Representable | Representability::ContainsRecursive => (),
4108 pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
4109 let t = tcx.node_id_to_type(id);
4111 ty::TyStruct(def, substs) => {
4112 let fields = &def.struct_variant().fields;
4113 if fields.is_empty() {
4114 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4117 let e = fields[0].ty(tcx, substs);
4118 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4119 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4123 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4124 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4126 span_err!(tcx.sess, sp, E0077,
4127 "SIMD vector element type should be machine type");
4136 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4138 vs: &'tcx [hir::Variant],
4140 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4141 vs: &'tcx [hir::Variant],
4143 hint: attr::ReprAttr) {
4144 #![allow(trivial_numeric_casts)]
4146 let rty = ccx.tcx.node_id_to_type(id);
4147 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4149 let tables = RefCell::new(ty::Tables::empty());
4150 let inh = static_inherited_fields(ccx, &tables);
4151 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4153 let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(&ccx.tcx);
4155 if let Some(ref e) = v.node.disr_expr {
4156 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4160 let def_id = ccx.tcx.map.local_def_id(id);
4162 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4163 for (v, variant) in vs.iter().zip(variants.iter()) {
4164 let current_disr_val = variant.disr_val;
4166 // Check for duplicate discriminant values
4167 match disr_vals.iter().position(|&x| x == current_disr_val) {
4169 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4170 "discriminant value `{}` already exists", disr_vals[i]);
4171 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4172 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4173 "conflicting discriminant here");
4178 disr_vals.push(current_disr_val);
4182 let def_id = ccx.tcx.map.local_def_id(id);
4183 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4185 if hint != attr::ReprAny && vs.is_empty() {
4186 span_err!(ccx.tcx.sess, sp, E0084,
4187 "unsupported representation for zero-variant enum");
4190 do_check(ccx, vs, id, hint);
4192 check_representable(ccx.tcx, sp, id, "enum");
4195 // Returns the type parameter count and the type for the given definition.
4196 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4199 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4201 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4202 let typ = fcx.local_ty(sp, nid);
4203 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4204 ty::GenericPredicates::empty())
4206 Def::Fn(id) | Def::Method(id) |
4207 Def::Static(id, _) | Def::Variant(_, id) |
4208 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4209 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4214 Def::AssociatedTy(..) |
4218 Def::ForeignMod(..) |
4222 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4227 // Instantiates the given path, which must refer to an item with the given
4228 // number of type parameters and type.
4229 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4230 segments: &[hir::PathSegment],
4231 type_scheme: TypeScheme<'tcx>,
4232 type_predicates: &ty::GenericPredicates<'tcx>,
4233 opt_self_ty: Option<Ty<'tcx>>,
4236 node_id: ast::NodeId) {
4237 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4243 // We need to extract the type parameters supplied by the user in
4244 // the path `path`. Due to the current setup, this is a bit of a
4245 // tricky-process; the problem is that resolve only tells us the
4246 // end-point of the path resolution, and not the intermediate steps.
4247 // Luckily, we can (at least for now) deduce the intermediate steps
4248 // just from the end-point.
4250 // There are basically four cases to consider:
4252 // 1. Reference to a *type*, such as a struct or enum:
4254 // mod a { struct Foo<T> { ... } }
4256 // Because we don't allow types to be declared within one
4257 // another, a path that leads to a type will always look like
4258 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4259 // that only the final segment can have type parameters, and
4260 // they are located in the TypeSpace.
4262 // *Note:* Generally speaking, references to types don't
4263 // actually pass through this function, but rather the
4264 // `ast_ty_to_ty` function in `astconv`. However, in the case
4265 // of struct patterns (and maybe literals) we do invoke
4266 // `instantiate_path` to get the general type of an instance of
4267 // a struct. (In these cases, there are actually no type
4268 // parameters permitted at present, but perhaps we will allow
4269 // them in the future.)
4271 // 1b. Reference to an enum variant or tuple-like struct:
4273 // struct foo<T>(...)
4274 // enum E<T> { foo(...) }
4276 // In these cases, the parameters are declared in the type
4279 // 2. Reference to a *fn item*:
4283 // In this case, the path will again always have the form
4284 // `a::b::foo::<T>` where only the final segment should have
4285 // type parameters. However, in this case, those parameters are
4286 // declared on a value, and hence are in the `FnSpace`.
4288 // 3. Reference to a *method*:
4290 // impl<A> SomeStruct<A> {
4294 // Here we can have a path like
4295 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4296 // may appear in two places. The penultimate segment,
4297 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4298 // final segment, `foo::<B>` contains parameters in fn space.
4300 // 4. Reference to an *associated const*:
4302 // impl<A> AnotherStruct<A> {
4303 // const FOO: B = BAR;
4306 // The path in this case will look like
4307 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4308 // only will have parameters in TypeSpace.
4310 // The first step then is to categorize the segments appropriately.
4312 assert!(!segments.is_empty());
4314 let mut ufcs_associated = None;
4315 let mut segment_spaces: Vec<_>;
4317 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4323 Def::AssociatedTy(..) |
4326 Def::TyParam(..) => {
4327 // Everything but the final segment should have no
4328 // parameters at all.
4329 segment_spaces = vec![None; segments.len() - 1];
4330 segment_spaces.push(Some(subst::TypeSpace));
4333 // Case 2. Reference to a top-level value.
4336 Def::Static(..) => {
4337 segment_spaces = vec![None; segments.len() - 1];
4338 segment_spaces.push(Some(subst::FnSpace));
4341 // Case 3. Reference to a method.
4342 Def::Method(def_id) => {
4343 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4345 ty::TraitContainer(trait_did) => {
4346 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4348 ty::ImplContainer(_) => {}
4351 if segments.len() >= 2 {
4352 segment_spaces = vec![None; segments.len() - 2];
4353 segment_spaces.push(Some(subst::TypeSpace));
4354 segment_spaces.push(Some(subst::FnSpace));
4356 // `<T>::method` will end up here, and so can `T::method`.
4357 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4358 segment_spaces = vec![Some(subst::FnSpace)];
4359 ufcs_associated = Some((container, self_ty));
4363 Def::AssociatedConst(def_id) => {
4364 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4366 ty::TraitContainer(trait_did) => {
4367 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4369 ty::ImplContainer(_) => {}
4372 if segments.len() >= 2 {
4373 segment_spaces = vec![None; segments.len() - 2];
4374 segment_spaces.push(Some(subst::TypeSpace));
4375 segment_spaces.push(None);
4377 // `<T>::CONST` will end up here, and so can `T::CONST`.
4378 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4379 segment_spaces = vec![None];
4380 ufcs_associated = Some((container, self_ty));
4384 // Other cases. Various nonsense that really shouldn't show up
4385 // here. If they do, an error will have been reported
4386 // elsewhere. (I hope)
4388 Def::ForeignMod(..) |
4393 segment_spaces = vec![None; segments.len()];
4396 assert_eq!(segment_spaces.len(), segments.len());
4398 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4399 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4400 // type parameters are not mandatory.
4401 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4403 debug!("segment_spaces={:?}", segment_spaces);
4405 // Next, examine the definition, and determine how many type
4406 // parameters we expect from each space.
4407 let type_defs = &type_scheme.generics.types;
4408 let region_defs = &type_scheme.generics.regions;
4410 // Now that we have categorized what space the parameters for each
4411 // segment belong to, let's sort out the parameters that the user
4412 // provided (if any) into their appropriate spaces. We'll also report
4413 // errors if type parameters are provided in an inappropriate place.
4414 let mut substs = Substs::empty();
4415 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4418 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4422 push_explicit_parameters_from_segment_to_substs(fcx,
4432 if let Some(self_ty) = opt_self_ty {
4433 if type_defs.len(subst::SelfSpace) == 1 {
4434 substs.types.push(subst::SelfSpace, self_ty);
4438 // Now we have to compare the types that the user *actually*
4439 // provided against the types that were *expected*. If the user
4440 // did not provide any types, then we want to substitute inference
4441 // variables. If the user provided some types, we may still need
4442 // to add defaults. If the user provided *too many* types, that's
4444 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4445 adjust_type_parameters(fcx, span, space, type_defs,
4446 require_type_space, &mut substs);
4447 assert_eq!(substs.types.len(space), type_defs.len(space));
4449 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4450 assert_eq!(substs.regions().len(space), region_defs.len(space));
4453 // The things we are substituting into the type should not contain
4454 // escaping late-bound regions, and nor should the base type scheme.
4455 assert!(!substs.has_regions_escaping_depth(0));
4456 assert!(!type_scheme.has_escaping_regions());
4458 // Add all the obligations that are required, substituting and
4459 // normalized appropriately.
4460 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4461 fcx.add_obligations_for_parameters(
4462 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4465 // Substitute the values for the type parameters into the type of
4466 // the referenced item.
4467 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4470 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4471 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4472 // is inherent, there is no `Self` parameter, instead, the impl needs
4473 // type parameters, which we can infer by unifying the provided `Self`
4474 // with the substituted impl type.
4475 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4476 assert_eq!(substs.types.len(subst::TypeSpace),
4477 impl_scheme.generics.types.len(subst::TypeSpace));
4478 assert_eq!(substs.regions().len(subst::TypeSpace),
4479 impl_scheme.generics.regions.len(subst::TypeSpace));
4481 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4482 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4483 fcx.tcx().sess.span_bug(span,
4485 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4491 debug!("instantiate_path: type of {:?} is {:?}",
4494 fcx.write_ty(node_id, ty_substituted);
4495 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4498 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4499 /// parameters are provided, then reports an error and clears the output vector.
4501 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4502 /// use inference variables. This seems less likely to lead to derived errors.
4504 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4505 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4506 /// here because we can easily use the precise span of the N+1'th parameter.
4507 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4508 fcx: &FnCtxt<'a, 'tcx>,
4509 space: subst::ParamSpace,
4511 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4512 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4513 segment: &hir::PathSegment,
4514 substs: &mut Substs<'tcx>)
4516 match segment.parameters {
4517 hir::AngleBracketedParameters(ref data) => {
4518 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4519 fcx, space, type_defs, region_defs, data, substs);
4522 hir::ParenthesizedParameters(ref data) => {
4523 span_err!(fcx.tcx().sess, span, E0238,
4524 "parenthesized parameters may only be used with a trait");
4525 push_explicit_parenthesized_parameters_from_segment_to_substs(
4526 fcx, space, span, type_defs, data, substs);
4531 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4532 fcx: &FnCtxt<'a, 'tcx>,
4533 space: subst::ParamSpace,
4534 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4535 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4536 data: &hir::AngleBracketedParameterData,
4537 substs: &mut Substs<'tcx>)
4540 let type_count = type_defs.len(space);
4541 assert_eq!(substs.types.len(space), 0);
4542 for (i, typ) in data.types.iter().enumerate() {
4543 let t = fcx.to_ty(&typ);
4545 substs.types.push(space, t);
4546 } else if i == type_count {
4547 span_err!(fcx.tcx().sess, typ.span, E0087,
4548 "too many type parameters provided: \
4549 expected at most {} parameter{}, \
4550 found {} parameter{}",
4552 if type_count == 1 {""} else {"s"},
4554 if data.types.len() == 1 {""} else {"s"});
4555 substs.types.truncate(space, 0);
4561 if !data.bindings.is_empty() {
4562 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4563 "unexpected binding of associated item in expression path \
4564 (only allowed in type paths)");
4568 let region_count = region_defs.len(space);
4569 assert_eq!(substs.regions().len(space), 0);
4570 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4571 let r = ast_region_to_region(fcx.tcx(), lifetime);
4572 if i < region_count {
4573 substs.mut_regions().push(space, r);
4574 } else if i == region_count {
4575 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4576 "too many lifetime parameters provided: \
4577 expected {} parameter{}, found {} parameter{}",
4579 if region_count == 1 {""} else {"s"},
4580 data.lifetimes.len(),
4581 if data.lifetimes.len() == 1 {""} else {"s"});
4582 substs.mut_regions().truncate(space, 0);
4590 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4591 /// but intended for `Foo(A,B) -> C` form. This expands to
4592 /// roughly the same thing as `Foo<(A,B),C>`. One important
4593 /// difference has to do with the treatment of anonymous
4594 /// regions, which are translated into bound regions (NYI).
4595 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4596 fcx: &FnCtxt<'a, 'tcx>,
4597 space: subst::ParamSpace,
4599 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4600 data: &hir::ParenthesizedParameterData,
4601 substs: &mut Substs<'tcx>)
4603 let type_count = type_defs.len(space);
4605 span_err!(fcx.tcx().sess, span, E0167,
4606 "parenthesized form always supplies 2 type parameters, \
4607 but only {} parameter(s) were expected",
4611 let input_tys: Vec<Ty> =
4612 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4614 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4616 if type_count >= 1 {
4617 substs.types.push(space, tuple_ty);
4620 let output_ty: Option<Ty> =
4621 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4624 output_ty.unwrap_or(fcx.tcx().mk_nil());
4626 if type_count >= 2 {
4627 substs.types.push(space, output_ty);
4631 fn adjust_type_parameters<'a, 'tcx>(
4632 fcx: &FnCtxt<'a, 'tcx>,
4635 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4636 require_type_space: bool,
4637 substs: &mut Substs<'tcx>)
4639 let provided_len = substs.types.len(space);
4640 let desired = defs.get_slice(space);
4641 let required_len = desired.iter()
4642 .take_while(|d| d.default.is_none())
4645 debug!("adjust_type_parameters(space={:?}, \
4654 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4655 assert!(provided_len <= desired.len());
4657 // Nothing specified at all: supply inference variables for
4659 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4660 substs.types.replace(space, Vec::new());
4661 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4665 // Too few parameters specified: report an error and use Err
4667 if provided_len < required_len {
4669 if desired.len() != required_len { "at least " } else { "" };
4670 span_err!(fcx.tcx().sess, span, E0089,
4671 "too few type parameters provided: expected {}{} parameter{}, \
4672 found {} parameter{}",
4673 qualifier, required_len,
4674 if required_len == 1 {""} else {"s"},
4676 if provided_len == 1 {""} else {"s"});
4677 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4681 // Otherwise, add in any optional parameters that the user
4682 // omitted. The case of *too many* parameters is handled
4684 // push_explicit_parameters_from_segment_to_substs(). Note
4685 // that the *default* type are expressed in terms of all prior
4686 // parameters, so we have to substitute as we go with the
4687 // partial substitution that we have built up.
4688 for i in provided_len..desired.len() {
4689 let default = desired[i].default.unwrap();
4690 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4691 substs.types.push(space, default);
4693 assert_eq!(substs.types.len(space), desired.len());
4695 debug!("Final substs: {:?}", substs);
4698 fn adjust_region_parameters(
4702 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4703 substs: &mut Substs)
4705 let provided_len = substs.mut_regions().len(space);
4706 let desired = defs.get_slice(space);
4708 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4709 assert!(provided_len <= desired.len());
4711 // If nothing was provided, just use inference variables.
4712 if provided_len == 0 {
4713 substs.mut_regions().replace(
4715 fcx.infcx().region_vars_for_defs(span, desired));
4719 // If just the right number were provided, everybody is happy.
4720 if provided_len == desired.len() {
4724 // Otherwise, too few were provided. Report an error and then
4725 // use inference variables.
4726 span_err!(fcx.tcx().sess, span, E0090,
4727 "too few lifetime parameters provided: expected {} parameter{}, \
4728 found {} parameter{}",
4730 if desired.len() == 1 {""} else {"s"},
4732 if provided_len == 1 {""} else {"s"});
4734 substs.mut_regions().replace(
4736 fcx.infcx().region_vars_for_defs(span, desired));
4740 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4744 where F: Fn() -> Ty<'tcx>
4746 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4749 let alternative = f();
4752 if alternative.is_ty_var() || alternative.references_error() {
4753 fcx.type_error_message(sp, |_actual| {
4754 "the type of this value must be known in this context".to_string()
4756 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4757 ty = fcx.tcx().types.err;
4759 demand::suptype(fcx, sp, alternative, ty);
4767 // Resolves `typ` by a single level if `typ` is a type variable. If no
4768 // resolution is possible, then an error is reported.
4769 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4774 structurally_resolve_type_or_else(fcx, sp, ty, || {
4779 // Returns true if b contains a break that can exit from b
4780 pub fn may_break(cx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4781 // First: is there an unlabeled break immediately
4783 (loop_query(&b, |e| {
4785 hir::ExprBreak(None) => true,
4789 // Second: is there a labeled break with label
4790 // <id> nested anywhere inside the loop?
4791 (block_query(b, |e| {
4792 if let hir::ExprBreak(Some(_)) = e.node {
4793 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4800 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4801 tps: &[hir::TyParam],
4803 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4806 // make a vector of booleans initially false, set to true when used
4807 if tps.is_empty() { return; }
4808 let mut tps_used = vec![false; tps.len()];
4810 for leaf_ty in ty.walk() {
4811 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4812 debug!("Found use of ty param num {}", idx);
4813 tps_used[idx as usize] = true;
4817 for (i, b) in tps_used.iter().enumerate() {
4819 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4820 "type parameter `{}` is unused",