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::{Disr, 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;
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};
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 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
676 Some(impl_trait_ref) => {
677 check_impl_items_against_trait(ccx,
685 hir::ItemTrait(_, ref generics, _, _) => {
686 check_trait_on_unimplemented(ccx, generics, it);
688 hir::ItemStruct(..) => {
689 check_struct(ccx, it.id, it.span);
691 hir::ItemTy(_, ref generics) => {
692 let pty_ty = ccx.tcx.node_id_to_type(it.id);
693 check_bounds_are_used(ccx, &generics.ty_params, pty_ty);
695 hir::ItemForeignMod(ref m) => {
696 if m.abi == Abi::RustIntrinsic {
697 for item in &m.items {
698 intrinsic::check_intrinsic_type(ccx, item);
700 } else if m.abi == Abi::PlatformIntrinsic {
701 for item in &m.items {
702 intrinsic::check_platform_intrinsic_type(ccx, item);
705 for item in &m.items {
706 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
707 if !pty.generics.types.is_empty() {
708 let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
709 "foreign items may not have type parameters");
710 span_help!(&mut err, item.span,
711 "consider using specialization instead of \
716 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
717 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
722 _ => {/* nothing to do */ }
726 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
727 debug!("check_item_body(it.id={}, it.name={})",
729 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
730 let _indenter = indenter();
732 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
733 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
734 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
735 check_bare_fn(ccx, &decl, &body, it.id, it.span, fn_pty.ty, param_env);
737 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
738 debug!("ItemImpl {} with id {}", it.name, it.id);
740 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
742 for impl_item in impl_items {
743 match impl_item.node {
744 hir::ImplItemKind::Const(_, ref expr) => {
745 check_const(ccx, impl_item.span, &expr, impl_item.id)
747 hir::ImplItemKind::Method(ref sig, ref body) => {
748 check_method_body(ccx, &impl_pty.generics, sig, body,
749 impl_item.id, impl_item.span);
751 hir::ImplItemKind::Type(_) => {
752 // Nothing to do here.
757 hir::ItemTrait(_, _, _, ref trait_items) => {
758 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
759 for trait_item in trait_items {
760 match trait_item.node {
761 hir::ConstTraitItem(_, Some(ref expr)) => {
762 check_const(ccx, trait_item.span, &expr, trait_item.id)
764 hir::MethodTraitItem(ref sig, Some(ref body)) => {
765 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
767 check_method_body(ccx, &trait_def.generics, sig, body,
768 trait_item.id, trait_item.span);
770 hir::MethodTraitItem(ref sig, None) => {
771 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
773 hir::ConstTraitItem(_, None) |
774 hir::TypeTraitItem(..) => {
780 _ => {/* nothing to do */ }
784 fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
786 constness: hir::Constness)
789 hir::Constness::NotConst => {
792 hir::Constness::Const => {
793 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
798 fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
799 generics: &hir::Generics,
801 if let Some(ref attr) = item.attrs.iter().find(|a| {
802 a.check_name("rustc_on_unimplemented")
804 if let Some(ref istring) = attr.value_str() {
805 let parser = Parser::new(&istring);
806 let types = &generics.ty_params;
807 for token in parser {
809 Piece::String(_) => (), // Normal string, no need to check it
810 Piece::NextArgument(a) => match a.position {
811 // `{Self}` is allowed
812 Position::ArgumentNamed(s) if s == "Self" => (),
813 // So is `{A}` if A is a type parameter
814 Position::ArgumentNamed(s) => match types.iter().find(|t| {
819 span_err!(ccx.tcx.sess, attr.span, E0230,
820 "there is no type parameter \
825 // `{:1}` and `{}` are not to be used
826 Position::ArgumentIs(_) | Position::ArgumentNext => {
827 span_err!(ccx.tcx.sess, attr.span, E0231,
828 "only named substitution \
829 parameters are allowed");
835 span_err!(ccx.tcx.sess, attr.span, E0232,
836 "this attribute must have a value, \
837 eg `#[rustc_on_unimplemented = \"foo\"]`")
842 /// Type checks a method body.
846 /// * `item_generics`: generics defined on the impl/trait that contains
848 /// * `self_bound`: bound for the `Self` type parameter, if any
849 /// * `method`: the method definition
850 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
851 item_generics: &ty::Generics<'tcx>,
852 sig: &'tcx hir::MethodSig,
853 body: &'tcx hir::Block,
854 id: ast::NodeId, span: Span) {
855 debug!("check_method_body(item_generics={:?}, id={})",
857 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
859 let fty = ccx.tcx.node_id_to_type(id);
860 debug!("check_method_body: fty={:?}", fty);
862 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
865 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
867 impl_trait_ref: &ty::TraitRef<'tcx>,
868 impl_items: &[hir::ImplItem]) {
869 // Locate trait methods
871 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
872 let mut overridden_associated_type = None;
874 // Check existing impl methods to see if they are both present in trait
875 // and compatible with trait signature
876 for impl_item in impl_items {
877 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
878 let ty_trait_item = trait_items.iter()
879 .find(|ac| ac.name() == ty_impl_item.name());
881 if let Some(ty_trait_item) = ty_trait_item {
882 match impl_item.node {
883 hir::ImplItemKind::Const(..) => {
884 let impl_const = match ty_impl_item {
885 ty::ConstTraitItem(ref cti) => cti,
886 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
889 // Find associated const definition.
890 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
891 compare_const_impl(ccx.tcx,
897 span_err!(tcx.sess, impl_item.span, E0323,
898 "item `{}` is an associated const, \
899 which doesn't match its trait `{:?}`",
904 hir::ImplItemKind::Method(ref sig, ref body) => {
905 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
907 let impl_method = match ty_impl_item {
908 ty::MethodTraitItem(ref mti) => mti,
909 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
912 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
913 compare_impl_method(ccx.tcx,
920 span_err!(tcx.sess, impl_item.span, E0324,
921 "item `{}` is an associated method, \
922 which doesn't match its trait `{:?}`",
927 hir::ImplItemKind::Type(_) => {
928 let impl_type = match ty_impl_item {
929 ty::TypeTraitItem(ref tti) => tti,
930 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
933 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
934 if let Some(_) = at.ty {
935 overridden_associated_type = Some(impl_item);
938 span_err!(tcx.sess, impl_item.span, E0325,
939 "item `{}` is an associated type, \
940 which doesn't match its trait `{:?}`",
949 // Check for missing items from trait
950 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
951 let mut missing_items = Vec::new();
952 let mut invalidated_items = Vec::new();
953 let associated_type_overridden = overridden_associated_type.is_some();
954 for trait_item in trait_items.iter() {
956 ty::ConstTraitItem(ref associated_const) => {
957 let is_implemented = impl_items.iter().any(|ii| {
959 hir::ImplItemKind::Const(..) => {
960 ii.name == associated_const.name
965 let is_provided = associated_const.has_value;
969 missing_items.push(associated_const.name);
970 } else if associated_type_overridden {
971 invalidated_items.push(associated_const.name);
975 ty::MethodTraitItem(ref trait_method) => {
977 impl_items.iter().any(|ii| {
979 hir::ImplItemKind::Method(..) => {
980 ii.name == trait_method.name
986 provided_methods.iter().any(|m| m.name == trait_method.name);
989 missing_items.push(trait_method.name);
990 } else if associated_type_overridden {
991 invalidated_items.push(trait_method.name);
995 ty::TypeTraitItem(ref associated_type) => {
996 let is_implemented = impl_items.iter().any(|ii| {
998 hir::ImplItemKind::Type(_) => {
999 ii.name == associated_type.name
1004 let is_provided = associated_type.ty.is_some();
1005 if !is_implemented {
1007 missing_items.push(associated_type.name);
1008 } else if associated_type_overridden {
1009 invalidated_items.push(associated_type.name);
1016 if !missing_items.is_empty() {
1017 span_err!(tcx.sess, impl_span, E0046,
1018 "not all trait items implemented, missing: `{}`",
1019 missing_items.iter()
1020 .map(|name| name.to_string())
1021 .collect::<Vec<_>>().join("`, `"))
1024 if !invalidated_items.is_empty() {
1025 let invalidator = overridden_associated_type.unwrap();
1026 span_err!(tcx.sess, invalidator.span, E0399,
1027 "the following trait items need to be reimplemented \
1028 as `{}` was overridden: `{}`",
1030 invalidated_items.iter()
1031 .map(|name| name.to_string())
1032 .collect::<Vec<_>>().join("`, `"))
1036 fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1043 if t_cast.references_error() || t_expr.references_error() {
1046 let tstr = fcx.infcx().ty_to_string(t_cast);
1047 let mut err = fcx.type_error_struct(span, |actual| {
1048 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
1051 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
1052 let mtstr = match mt {
1053 hir::MutMutable => "mut ",
1054 hir::MutImmutable => ""
1056 if t_cast.is_trait() {
1057 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1059 err.span_suggestion(t_span,
1060 "try casting to a reference instead:",
1061 format!("&{}{}", mtstr, s));
1064 span_help!(err, t_span,
1065 "did you mean `&{}{}`?", mtstr, tstr),
1068 span_help!(err, span,
1069 "consider using an implicit coercion to `&{}{}` instead",
1074 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1076 err.span_suggestion(t_span,
1077 "try casting to a `Box` instead:",
1078 format!("Box<{}>", s));
1081 span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
1085 span_help!(err, e_span,
1086 "consider using a box or reference as appropriate");
1090 fcx.write_error(id);
1094 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1095 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1097 fn get_item_type_scheme(&self, _: Span, id: DefId)
1098 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1100 Ok(self.tcx().lookup_item_type(id))
1103 fn get_trait_def(&self, _: Span, id: DefId)
1104 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
1106 Ok(self.tcx().lookup_trait_def(id))
1109 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
1110 // all super predicates are ensured during collect pass
1114 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
1115 Some(&self.inh.infcx.parameter_environment.free_substs)
1118 fn get_type_parameter_bounds(&self,
1120 node_id: ast::NodeId)
1121 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1123 let def = self.tcx().type_parameter_def(node_id);
1124 let r = self.inh.infcx.parameter_environment
1127 .filter_map(|predicate| {
1129 ty::Predicate::Trait(ref data) => {
1130 if data.0.self_ty().is_param(def.space, def.index) {
1131 Some(data.to_poly_trait_ref())
1145 fn trait_defines_associated_type_named(&self,
1146 trait_def_id: DefId,
1147 assoc_name: ast::Name)
1150 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
1151 trait_def.associated_type_names.contains(&assoc_name)
1155 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1156 substs: Option<&mut subst::Substs<'tcx>>,
1157 space: Option<subst::ParamSpace>,
1158 span: Span) -> Ty<'tcx> {
1159 // Grab the default doing subsitution
1160 let default = ty_param_def.and_then(|def| {
1161 def.default.map(|ty| type_variable::Default {
1162 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1164 def_id: def.default_def_id
1168 let ty_var = self.infcx().next_ty_var_with_default(default);
1170 // Finally we add the type variable to the substs
1173 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1177 fn projected_ty_from_poly_trait_ref(&self,
1179 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1180 item_name: ast::Name)
1183 let (trait_ref, _) =
1184 self.infcx().replace_late_bound_regions_with_fresh_var(
1186 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1189 self.normalize_associated_type(span, trait_ref, item_name)
1192 fn projected_ty(&self,
1194 trait_ref: ty::TraitRef<'tcx>,
1195 item_name: ast::Name)
1198 self.normalize_associated_type(span, trait_ref, item_name)
1202 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1203 fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
1205 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1209 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
1210 &self.inh.infcx.parameter_environment
1213 pub fn sess(&self) -> &Session {
1217 pub fn err_count_since_creation(&self) -> usize {
1218 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1221 /// Resolves type variables in `ty` if possible. Unlike the infcx
1222 /// version, this version will also select obligations if it seems
1223 /// useful, in an effort to get more type information.
1224 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
1225 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
1227 // No TyInfer()? Nothing needs doing.
1228 if !ty.has_infer_types() {
1229 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1233 // If `ty` is a type variable, see whether we already know what it is.
1234 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1235 if !ty.has_infer_types() {
1236 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1240 // If not, try resolving pending obligations as much as
1241 // possible. This can help substantially when there are
1242 // indirect dependencies that don't seem worth tracking
1244 self.select_obligations_where_possible();
1245 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1247 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
1251 fn record_deferred_call_resolution(&self,
1252 closure_def_id: DefId,
1253 r: DeferredCallResolutionHandler<'tcx>) {
1254 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1255 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
1258 fn remove_deferred_call_resolutions(&self,
1259 closure_def_id: DefId)
1260 -> Vec<DeferredCallResolutionHandler<'tcx>>
1262 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1263 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1266 pub fn tag(&self) -> String {
1267 let self_ptr: *const FnCtxt = self;
1268 format!("{:?}", self_ptr)
1271 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1272 match self.inh.locals.borrow().get(&nid) {
1275 span_err!(self.tcx().sess, span, E0513,
1276 "no type for local variable {}",
1278 self.tcx().types.err
1284 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
1285 debug!("write_ty({}, {:?}) in fcx {}",
1286 node_id, ty, self.tag());
1287 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1290 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1291 if !substs.substs.is_noop() {
1292 debug!("write_substs({}, {:?}) in fcx {}",
1297 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1301 pub fn write_autoderef_adjustment(&self,
1302 node_id: ast::NodeId,
1304 self.write_adjustment(
1306 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1314 pub fn write_adjustment(&self,
1315 node_id: ast::NodeId,
1316 adj: adjustment::AutoAdjustment<'tcx>) {
1317 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1319 if adj.is_identity() {
1323 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1326 /// Basically whenever we are converting from a type scheme into
1327 /// the fn body space, we always want to normalize associated
1328 /// types as well. This function combines the two.
1329 fn instantiate_type_scheme<T>(&self,
1331 substs: &Substs<'tcx>,
1334 where T : TypeFoldable<'tcx>
1336 let value = value.subst(self.tcx(), substs);
1337 let result = self.normalize_associated_types_in(span, &value);
1338 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1345 /// As `instantiate_type_scheme`, but for the bounds found in a
1346 /// generic type scheme.
1347 fn instantiate_bounds(&self,
1349 substs: &Substs<'tcx>,
1350 bounds: &ty::GenericPredicates<'tcx>)
1351 -> ty::InstantiatedPredicates<'tcx>
1353 ty::InstantiatedPredicates {
1354 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1359 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
1360 where T : TypeFoldable<'tcx>
1362 self.inh.normalize_associated_types_in(span, self.body_id, value)
1365 fn normalize_associated_type(&self,
1367 trait_ref: ty::TraitRef<'tcx>,
1368 item_name: ast::Name)
1371 let cause = traits::ObligationCause::new(span,
1373 traits::ObligationCauseCode::MiscObligation);
1377 .normalize_projection_type(self.infcx(),
1379 trait_ref: trait_ref,
1380 item_name: item_name,
1385 /// Instantiates the type in `did` with the generics in `path` and returns
1386 /// it (registering the necessary trait obligations along the way).
1388 /// Note that this function is only intended to be used with type-paths,
1389 /// not with value-paths.
1390 pub fn instantiate_type(&self,
1395 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1397 self.tcx().lookup_item_type(did);
1398 let type_predicates =
1399 self.tcx().lookup_predicates(did);
1400 let substs = astconv::ast_path_substs_for_ty(self, self,
1402 PathParamMode::Optional,
1403 &type_scheme.generics,
1404 path.segments.last().unwrap());
1405 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1407 self.instantiate_bounds(path.span, &substs, &type_predicates);
1408 self.add_obligations_for_parameters(
1409 traits::ObligationCause::new(
1412 traits::ItemObligation(did)),
1415 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1418 /// Return the dict-like variant corresponding to a given `Def`.
1419 pub fn def_struct_variant(&self,
1422 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1424 let (adt, variant) = match def {
1425 Def::Variant(enum_id, variant_id) => {
1426 let adt = self.tcx().lookup_adt_def(enum_id);
1427 (adt, adt.variant_with_id(variant_id))
1429 Def::Struct(did) | Def::TyAlias(did) => {
1430 let typ = self.tcx().lookup_item_type(did);
1431 if let ty::TyStruct(adt, _) = typ.ty.sty {
1432 (adt, adt.struct_variant())
1440 let var_kind = variant.kind();
1441 if var_kind == ty::VariantKind::Struct {
1442 Some((adt, variant))
1443 } else if var_kind == ty::VariantKind::Unit {
1444 Some((adt, variant))
1450 pub fn write_nil(&self, node_id: ast::NodeId) {
1451 self.write_ty(node_id, self.tcx().mk_nil());
1453 pub fn write_error(&self, node_id: ast::NodeId) {
1454 self.write_ty(node_id, self.tcx().types.err);
1457 pub fn require_type_meets(&self,
1460 code: traits::ObligationCauseCode<'tcx>,
1461 bound: ty::BuiltinBound)
1463 self.register_builtin_bound(
1466 traits::ObligationCause::new(span, self.body_id, code));
1469 pub fn require_type_is_sized(&self,
1472 code: traits::ObligationCauseCode<'tcx>)
1474 self.require_type_meets(ty, span, code, ty::BoundSized);
1477 pub fn require_expr_have_sized_type(&self,
1479 code: traits::ObligationCauseCode<'tcx>)
1481 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1484 pub fn type_is_known_to_be_sized(&self,
1489 traits::type_known_to_meet_builtin_bound(self.infcx(),
1495 pub fn register_builtin_bound(&self,
1497 builtin_bound: ty::BuiltinBound,
1498 cause: traits::ObligationCause<'tcx>)
1500 self.inh.fulfillment_cx.borrow_mut()
1501 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1504 pub fn register_predicate(&self,
1505 obligation: traits::PredicateObligation<'tcx>)
1507 debug!("register_predicate({:?})",
1509 self.inh.fulfillment_cx
1511 .register_predicate_obligation(self.infcx(), obligation);
1514 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1515 let t = ast_ty_to_ty(self, self, ast_t);
1516 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1520 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
1521 match self.inh.tables.borrow().node_types.get(&ex.id) {
1524 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
1530 /// Apply `adjustment` to the type of `expr`
1531 pub fn adjust_expr_ty(&self,
1533 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1536 let raw_ty = self.expr_ty(expr);
1537 let raw_ty = self.infcx().shallow_resolve(raw_ty);
1538 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
1539 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1540 self.inh.tables.borrow().method_map.get(&method_call)
1541 .map(|method| resolve_ty(method.ty))
1545 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
1546 match self.inh.tables.borrow().node_types.get(&id) {
1548 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1550 self.tcx().sess.bug(
1551 &format!("no type for node {}: {} in fcx {}",
1552 id, self.tcx().map.node_to_string(id),
1558 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
1559 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1560 // it changes when we upgrade the snapshot compiler
1561 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1562 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1566 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1569 pub fn opt_node_ty_substs<F>(&self,
1572 F: FnOnce(&ty::ItemSubsts<'tcx>),
1574 match self.inh.tables.borrow().item_substs.get(&id) {
1580 pub fn mk_subty(&self,
1581 a_is_expected: bool,
1585 -> Result<(), TypeError<'tcx>> {
1586 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1589 pub fn mk_eqty(&self,
1590 a_is_expected: bool,
1594 -> Result<(), TypeError<'tcx>> {
1595 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1598 pub fn mk_subr(&self,
1599 origin: infer::SubregionOrigin<'tcx>,
1602 infer::mk_subr(self.infcx(), origin, sub, sup)
1605 pub fn type_error_message<M>(&self,
1608 actual_ty: Ty<'tcx>,
1609 err: Option<&TypeError<'tcx>>)
1610 where M: FnOnce(String) -> String,
1612 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1615 pub fn type_error_struct<M>(&self,
1618 actual_ty: Ty<'tcx>,
1619 err: Option<&TypeError<'tcx>>)
1620 -> DiagnosticBuilder<'tcx>
1621 where M: FnOnce(String) -> String,
1623 self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
1626 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1627 /// outlive the region `r`.
1628 pub fn register_region_obligation(&self,
1631 cause: traits::ObligationCause<'tcx>)
1633 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1634 fulfillment_cx.register_region_obligation(ty, region, cause);
1637 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1638 /// outlive the region `r`.
1639 pub fn register_wf_obligation(&self,
1642 code: traits::ObligationCauseCode<'tcx>)
1644 // WF obligations never themselves fail, so no real need to give a detailed cause:
1645 let cause = traits::ObligationCause::new(span, self.body_id, code);
1646 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1649 pub fn register_old_wf_obligation(&self,
1652 code: traits::ObligationCauseCode<'tcx>)
1654 // Registers an "old-style" WF obligation that uses the
1655 // implicator code. This is basically a buggy version of
1656 // `register_wf_obligation` that is being kept around
1657 // temporarily just to help with phasing in the newer rules.
1659 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1660 let cause = traits::ObligationCause::new(span, self.body_id, code);
1661 self.register_region_obligation(ty, ty::ReEmpty, cause);
1664 /// Registers obligations that all types appearing in `substs` are well-formed.
1665 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1667 for &ty in &substs.types {
1668 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1672 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1673 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1674 /// trait/region obligations.
1676 /// For example, if there is a function:
1679 /// fn foo<'a,T:'a>(...)
1682 /// and a reference:
1688 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1689 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1690 pub fn add_obligations_for_parameters(&self,
1691 cause: traits::ObligationCause<'tcx>,
1692 predicates: &ty::InstantiatedPredicates<'tcx>)
1694 assert!(!predicates.has_escaping_regions());
1696 debug!("add_obligations_for_parameters(predicates={:?})",
1699 for obligation in traits::predicates_for_generics(cause, predicates) {
1700 self.register_predicate(obligation);
1704 // FIXME(arielb1): use this instead of field.ty everywhere
1705 // Only for fields! Returns <none> for methods>
1706 // Indifferent to privacy flags
1707 pub fn field_ty(&self,
1709 field: ty::FieldDef<'tcx>,
1710 substs: &Substs<'tcx>)
1713 self.normalize_associated_types_in(span,
1714 &field.ty(self.tcx(), substs))
1717 fn check_casts(&self) {
1718 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
1719 for cast in deferred_cast_checks.drain(..) {
1724 /// Apply "fallbacks" to some types
1725 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1726 fn default_type_parameters(&self) {
1727 use middle::ty::error::UnconstrainedNumeric::Neither;
1728 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1729 for ty in &self.infcx().unsolved_variables() {
1730 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1731 if self.infcx().type_var_diverges(resolved) {
1732 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1734 match self.infcx().type_is_unconstrained_numeric(resolved) {
1735 UnconstrainedInt => {
1736 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1738 UnconstrainedFloat => {
1739 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1747 fn select_all_obligations_and_apply_defaults(&self) {
1748 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1749 self.new_select_all_obligations_and_apply_defaults();
1751 self.old_select_all_obligations_and_apply_defaults();
1755 // Implements old type inference fallback algorithm
1756 fn old_select_all_obligations_and_apply_defaults(&self) {
1757 self.select_obligations_where_possible();
1758 self.default_type_parameters();
1759 self.select_obligations_where_possible();
1762 fn new_select_all_obligations_and_apply_defaults(&self) {
1763 use middle::ty::error::UnconstrainedNumeric::Neither;
1764 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1766 // For the time being this errs on the side of being memory wasteful but provides better
1768 // let type_variables = self.infcx().type_variables.clone();
1770 // There is a possibility that this algorithm will have to run an arbitrary number of times
1771 // to terminate so we bound it by the compiler's recursion limit.
1772 for _ in 0..self.tcx().sess.recursion_limit.get() {
1773 // First we try to solve all obligations, it is possible that the last iteration
1774 // has made it possible to make more progress.
1775 self.select_obligations_where_possible();
1777 let mut conflicts = Vec::new();
1779 // Collect all unsolved type, integral and floating point variables.
1780 let unsolved_variables = self.inh.infcx.unsolved_variables();
1782 // We must collect the defaults *before* we do any unification. Because we have
1783 // directly attached defaults to the type variables any unification that occurs
1784 // will erase defaults causing conflicting defaults to be completely ignored.
1785 let default_map: FnvHashMap<_, _> =
1788 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1791 let mut unbound_tyvars = HashSet::new();
1793 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1795 // We loop over the unsolved variables, resolving them and if they are
1796 // and unconstrainted numeric type we add them to the set of unbound
1797 // variables. We do this so we only apply literal fallback to type
1798 // variables without defaults.
1799 for ty in &unsolved_variables {
1800 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1801 if self.infcx().type_var_diverges(resolved) {
1802 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1804 match self.infcx().type_is_unconstrained_numeric(resolved) {
1805 UnconstrainedInt | UnconstrainedFloat => {
1806 unbound_tyvars.insert(resolved);
1813 // We now remove any numeric types that also have defaults, and instead insert
1814 // the type variable with a defined fallback.
1815 for ty in &unsolved_variables {
1816 if let Some(_default) = default_map.get(ty) {
1817 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1819 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1822 match resolved.sty {
1823 ty::TyInfer(ty::TyVar(_)) => {
1824 unbound_tyvars.insert(ty);
1827 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1828 unbound_tyvars.insert(ty);
1829 if unbound_tyvars.contains(resolved) {
1830 unbound_tyvars.remove(resolved);
1839 // If there are no more fallbacks to apply at this point we have applied all possible
1840 // defaults and type inference will proceed as normal.
1841 if unbound_tyvars.is_empty() {
1845 // Finally we go through each of the unbound type variables and unify them with
1846 // the proper fallback, reporting a conflicting default error if any of the
1847 // unifications fail. We know it must be a conflicting default because the
1848 // variable would only be in `unbound_tyvars` and have a concrete value if
1849 // it had been solved by previously applying a default.
1851 // We wrap this in a transaction for error reporting, if we detect a conflict
1852 // we will rollback the inference context to its prior state so we can probe
1853 // for conflicts and correctly report them.
1856 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1857 for ty in &unbound_tyvars {
1858 if self.infcx().type_var_diverges(ty) {
1859 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1861 match self.infcx().type_is_unconstrained_numeric(ty) {
1862 UnconstrainedInt => {
1863 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1865 UnconstrainedFloat => {
1866 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1869 if let Some(default) = default_map.get(ty) {
1870 let default = default.clone();
1871 match infer::mk_eqty(self.infcx(), false,
1872 TypeOrigin::Misc(default.origin_span),
1876 conflicts.push((*ty, default));
1885 // If there are conflicts we rollback, otherwise commit
1886 if conflicts.len() > 0 {
1893 if conflicts.len() > 0 {
1894 // Loop through each conflicting default, figuring out the default that caused
1895 // a unification failure and then report an error for each.
1896 for (conflict, default) in conflicts {
1897 let conflicting_default =
1898 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1899 .unwrap_or(type_variable::Default {
1900 ty: self.infcx().next_ty_var(),
1901 origin_span: codemap::DUMMY_SP,
1902 def_id: self.tcx().map.local_def_id(0) // what do I put here?
1905 // This is to ensure that we elimnate any non-determinism from the error
1906 // reporting by fixing an order, it doesn't matter what order we choose
1907 // just that it is consistent.
1908 let (first_default, second_default) =
1909 if default.def_id < conflicting_default.def_id {
1910 (default, conflicting_default)
1912 (conflicting_default, default)
1916 self.infcx().report_conflicting_default_types(
1917 first_default.origin_span,
1924 self.select_obligations_where_possible();
1927 // For use in error handling related to default type parameter fallback. We explicitly
1928 // apply the default that caused conflict first to a local version of the type variable
1929 // table then apply defaults until we find a conflict. That default must be the one
1930 // that caused conflict earlier.
1931 fn find_conflicting_default(&self,
1932 unbound_vars: &HashSet<Ty<'tcx>>,
1933 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1935 -> Option<type_variable::Default<'tcx>> {
1936 use middle::ty::error::UnconstrainedNumeric::Neither;
1937 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1939 // Ensure that we apply the conflicting default first
1940 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1941 unbound_tyvars.push(conflict);
1942 unbound_tyvars.extend(unbound_vars.iter());
1944 let mut result = None;
1945 // We run the same code as above applying defaults in order, this time when
1946 // we find the conflict we just return it for error reporting above.
1948 // We also run this inside snapshot that never commits so we can do error
1949 // reporting for more then one conflict.
1950 for ty in &unbound_tyvars {
1951 if self.infcx().type_var_diverges(ty) {
1952 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1954 match self.infcx().type_is_unconstrained_numeric(ty) {
1955 UnconstrainedInt => {
1956 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1958 UnconstrainedFloat => {
1959 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1962 if let Some(default) = default_map.get(ty) {
1963 let default = default.clone();
1964 match infer::mk_eqty(self.infcx(), false,
1965 TypeOrigin::Misc(default.origin_span),
1969 result = Some(default);
1981 fn select_all_obligations_or_error(&self) {
1982 debug!("select_all_obligations_or_error");
1984 // upvar inference should have ensured that all deferred call
1985 // resolutions are handled by now.
1986 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
1988 self.select_all_obligations_and_apply_defaults();
1990 let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut();
1991 match fulfillment_cx.select_all_or_error(self.infcx()) {
1993 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
1997 /// Select as many obligations as we can at present.
1998 fn select_obligations_where_possible(&self) {
2000 self.inh.fulfillment_cx
2002 .select_where_possible(self.infcx())
2005 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2009 fn private_item_is_visible(&self, def_id: DefId) -> bool {
2010 match self.tcx().map.as_local_node_id(def_id) {
2011 Some(node_id) => self.tcx().map.private_item_is_visible_from(node_id, self.body_id),
2012 None => false, // Private items from other crates are never visible
2017 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
2018 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
2019 Some(self.base_object_lifetime_default(span))
2022 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
2023 // RFC #599 specifies that object lifetime defaults take
2024 // precedence over other defaults. But within a fn body we
2025 // don't have a *default* region, rather we use inference to
2026 // find the *correct* region, which is strictly more general
2027 // (and anyway, within a fn body the right region may not even
2028 // be something the user can write explicitly, since it might
2029 // be some expression).
2030 self.infcx().next_region_var(infer::MiscVariable(span))
2033 fn anon_regions(&self, span: Span, count: usize)
2034 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
2035 Ok((0..count).map(|_| {
2036 self.infcx().next_region_var(infer::MiscVariable(span))
2041 /// Whether `autoderef` requires types to resolve.
2042 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2043 pub enum UnresolvedTypeAction {
2044 /// Produce an error and return `TyError` whenever a type cannot
2045 /// be resolved (i.e. it is `TyInfer`).
2047 /// Go on without emitting any errors, and return the unresolved
2048 /// type. Useful for probing, e.g. in coercions.
2052 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2053 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2055 /// Note: this method does not modify the adjustments table. The caller is responsible for
2056 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2057 pub fn autoderef<'a, 'b, 'tcx, E, I, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2061 unresolved_type_action: UnresolvedTypeAction,
2062 mut lvalue_pref: LvaluePreference,
2064 -> (Ty<'tcx>, usize, Option<T>)
2065 // FIXME(eddyb) use copyable iterators when that becomes ergonomic.
2067 I: IntoIterator<Item=&'b hir::Expr>,
2068 F: FnMut(Ty<'tcx>, usize) -> Option<T>,
2070 debug!("autoderef(base_ty={:?}, lvalue_pref={:?})",
2071 base_ty, lvalue_pref);
2073 let mut t = base_ty;
2074 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2075 let resolved_t = match unresolved_type_action {
2076 UnresolvedTypeAction::Error => {
2077 structurally_resolved_type(fcx, sp, t)
2079 UnresolvedTypeAction::Ignore => {
2080 // We can continue even when the type cannot be resolved
2081 // (i.e. it is an inference variable) because `Ty::builtin_deref`
2082 // and `try_overloaded_deref` both simply return `None`
2083 // in such a case without producing spurious errors.
2084 fcx.infcx().resolve_type_vars_if_possible(&t)
2087 if resolved_t.references_error() {
2088 return (resolved_t, autoderefs, None);
2091 match should_stop(resolved_t, autoderefs) {
2092 Some(x) => return (resolved_t, autoderefs, Some(x)),
2096 // Otherwise, deref if type is derefable:
2098 // Super subtle: it might seem as though we should
2099 // pass `opt_expr` to `try_overloaded_deref`, so that
2100 // the (implicit) autoref of using an overloaded deref
2101 // would get added to the adjustment table. However we
2102 // do not do that, because it's kind of a
2103 // "meta-adjustment" -- instead, we just leave it
2104 // unrecorded and know that there "will be" an
2105 // autoref. regionck and other bits of the code base,
2106 // when they encounter an overloaded autoderef, have
2107 // to do some reconstructive surgery. This is a pretty
2108 // complex mess that is begging for a proper MIR.
2109 let mt = if let Some(mt) = resolved_t.builtin_deref(false, lvalue_pref) {
2111 } else if let Some(method) = try_overloaded_deref(fcx, sp, None,
2112 resolved_t, lvalue_pref) {
2113 for expr in maybe_exprs() {
2114 let method_call = MethodCall::autoderef(expr.id, autoderefs as u32);
2115 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2117 make_overloaded_lvalue_return_type(fcx.tcx(), method)
2119 return (resolved_t, autoderefs, None);
2123 if mt.mutbl == hir::MutImmutable {
2124 lvalue_pref = NoPreference;
2128 // We've reached the recursion limit, error gracefully.
2129 span_err!(fcx.tcx().sess, sp, E0055,
2130 "reached the recursion limit while auto-dereferencing {:?}",
2132 (fcx.tcx().types.err, 0, None)
2135 fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2137 base_expr: Option<&hir::Expr>,
2139 lvalue_pref: LvaluePreference)
2140 -> Option<MethodCallee<'tcx>>
2142 // Try DerefMut first, if preferred.
2143 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2144 (PreferMutLvalue, Some(trait_did)) => {
2145 method::lookup_in_trait(fcx, span, base_expr,
2146 token::intern("deref_mut"), trait_did,
2152 // Otherwise, fall back to Deref.
2153 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2154 (None, Some(trait_did)) => {
2155 method::lookup_in_trait(fcx, span, base_expr,
2156 token::intern("deref"), trait_did,
2159 (method, _) => method
2165 /// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2166 /// actual type we assign to the *expression* is `T`. So this function just peels off the return
2167 /// type by one layer to yield `T`.
2168 fn make_overloaded_lvalue_return_type<'tcx>(tcx: &TyCtxt<'tcx>,
2169 method: MethodCallee<'tcx>)
2170 -> ty::TypeAndMut<'tcx>
2172 // extract method return type, which will be &T;
2173 // all LB regions should have been instantiated during method lookup
2174 let ret_ty = method.ty.fn_ret();
2175 let ret_ty = tcx.no_late_bound_regions(&ret_ty).unwrap().unwrap();
2177 // method returns &T, but the type as visible to user is T, so deref
2178 ret_ty.builtin_deref(true, NoPreference).unwrap()
2181 fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2183 base_expr: &'tcx hir::Expr,
2186 lvalue_pref: LvaluePreference)
2187 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2189 // FIXME(#18741) -- this is almost but not quite the same as the
2190 // autoderef that normal method probing does. They could likely be
2193 let (ty, autoderefs, final_mt) = autoderef(fcx,
2197 UnresolvedTypeAction::Error,
2200 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2201 adj_ty, idx, false, lvalue_pref, idx_ty)
2204 if final_mt.is_some() {
2208 // After we have fully autoderef'd, if the resulting type is [T; n], then
2209 // do a final unsized coercion to yield [T].
2210 if let ty::TyArray(element_ty, _) = ty.sty {
2211 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
2212 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2213 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2219 /// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2220 /// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2221 /// This loop implements one step in that search; the autoderef loop is implemented by
2222 /// `lookup_indexing`.
2223 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2224 method_call: MethodCall,
2226 base_expr: &'tcx hir::Expr,
2227 adjusted_ty: Ty<'tcx>,
2230 lvalue_pref: LvaluePreference,
2232 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2234 let tcx = fcx.tcx();
2235 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2236 autoderefs={}, unsize={}, index_ty={:?})",
2244 let input_ty = fcx.infcx().next_ty_var();
2246 // First, try built-in indexing.
2247 match (adjusted_ty.builtin_index(), &index_ty.sty) {
2248 (Some(ty), &ty::TyUint(ast::UintTy::Us)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
2249 debug!("try_index_step: success, using built-in indexing");
2250 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2252 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
2253 return Some((tcx.types.usize, ty));
2258 // Try `IndexMut` first, if preferred.
2259 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2260 (PreferMutLvalue, Some(trait_did)) => {
2261 method::lookup_in_trait_adjusted(fcx,
2264 token::intern("index_mut"),
2269 Some(vec![input_ty]))
2274 // Otherwise, fall back to `Index`.
2275 let method = match (method, tcx.lang_items.index_trait()) {
2276 (None, Some(trait_did)) => {
2277 method::lookup_in_trait_adjusted(fcx,
2280 token::intern("index"),
2285 Some(vec![input_ty]))
2287 (method, _) => method,
2290 // If some lookup succeeds, write callee into table and extract index/element
2291 // type from the method signature.
2292 // If some lookup succeeded, install method in table
2293 method.map(|method| {
2294 debug!("try_index_step: success, using overloaded indexing");
2295 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2296 (input_ty, make_overloaded_lvalue_return_type(fcx.tcx(), method).ty)
2300 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2302 method_fn_ty: Ty<'tcx>,
2303 callee_expr: &'tcx hir::Expr,
2304 args_no_rcvr: &'tcx [P<hir::Expr>],
2305 tuple_arguments: TupleArgumentsFlag,
2306 expected: Expectation<'tcx>)
2307 -> ty::FnOutput<'tcx> {
2308 if method_fn_ty.references_error() {
2309 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2311 let err_inputs = match tuple_arguments {
2312 DontTupleArguments => err_inputs,
2313 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
2316 check_argument_types(fcx,
2323 ty::FnConverging(fcx.tcx().types.err)
2325 match method_fn_ty.sty {
2326 ty::TyFnDef(_, _, ref fty) => {
2327 // HACK(eddyb) ignore self in the definition (see above).
2328 let expected_arg_tys = expected_types_for_fn_args(fcx,
2332 &fty.sig.0.inputs[1..]);
2333 check_argument_types(fcx,
2335 &fty.sig.0.inputs[1..],
2336 &expected_arg_tys[..],
2343 fcx.tcx().sess.span_bug(callee_expr.span,
2344 "method without bare fn type");
2350 /// Generic function that factors out common logic from function calls, method calls and overloaded
2352 fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2354 fn_inputs: &[Ty<'tcx>],
2355 expected_arg_tys: &[Ty<'tcx>],
2356 args: &'tcx [P<hir::Expr>],
2358 tuple_arguments: TupleArgumentsFlag) {
2359 let tcx = fcx.ccx.tcx;
2361 // Grab the argument types, supplying fresh type variables
2362 // if the wrong number of arguments were supplied
2363 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2369 // All the input types from the fn signature must outlive the call
2370 // so as to validate implied bounds.
2371 for &fn_input_ty in fn_inputs {
2372 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2375 let mut expected_arg_tys = expected_arg_tys;
2376 let expected_arg_count = fn_inputs.len();
2377 let formal_tys = if tuple_arguments == TupleArguments {
2378 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2379 match tuple_type.sty {
2380 ty::TyTuple(ref arg_types) => {
2381 if arg_types.len() != args.len() {
2382 span_err!(tcx.sess, sp, E0057,
2383 "this function takes {} parameter{} but {} parameter{} supplied",
2385 if arg_types.len() == 1 {""} else {"s"},
2387 if args.len() == 1 {" was"} else {"s were"});
2388 expected_arg_tys = &[];
2389 err_args(fcx.tcx(), args.len())
2391 expected_arg_tys = match expected_arg_tys.get(0) {
2392 Some(&ty) => match ty.sty {
2393 ty::TyTuple(ref tys) => &tys,
2398 (*arg_types).clone()
2402 span_err!(tcx.sess, sp, E0059,
2403 "cannot use call notation; the first type parameter \
2404 for the function trait is neither a tuple nor unit");
2405 expected_arg_tys = &[];
2406 err_args(fcx.tcx(), args.len())
2409 } else if expected_arg_count == supplied_arg_count {
2411 } else if variadic {
2412 if supplied_arg_count >= expected_arg_count {
2415 span_err!(tcx.sess, sp, E0060,
2416 "this function takes at least {} parameter{} \
2417 but {} parameter{} supplied",
2419 if expected_arg_count == 1 {""} else {"s"},
2421 if supplied_arg_count == 1 {" was"} else {"s were"});
2422 expected_arg_tys = &[];
2423 err_args(fcx.tcx(), supplied_arg_count)
2426 span_err!(tcx.sess, sp, E0061,
2427 "this function takes {} parameter{} but {} parameter{} supplied",
2429 if expected_arg_count == 1 {""} else {"s"},
2431 if supplied_arg_count == 1 {" was"} else {"s were"});
2432 expected_arg_tys = &[];
2433 err_args(fcx.tcx(), supplied_arg_count)
2436 debug!("check_argument_types: formal_tys={:?}",
2437 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2439 // Check the arguments.
2440 // We do this in a pretty awful way: first we typecheck any arguments
2441 // that are not anonymous functions, then we typecheck the anonymous
2442 // functions. This is so that we have more information about the types
2443 // of arguments when we typecheck the functions. This isn't really the
2444 // right way to do this.
2445 let xs = [false, true];
2446 let mut any_diverges = false; // has any of the arguments diverged?
2447 let mut warned = false; // have we already warned about unreachable code?
2448 for check_blocks in &xs {
2449 let check_blocks = *check_blocks;
2450 debug!("check_blocks={}", check_blocks);
2452 // More awful hacks: before we check argument types, try to do
2453 // an "opportunistic" vtable resolution of any trait bounds on
2454 // the call. This helps coercions.
2456 fcx.select_obligations_where_possible();
2459 // For variadic functions, we don't have a declared type for all of
2460 // the arguments hence we only do our usual type checking with
2461 // the arguments who's types we do know.
2462 let t = if variadic {
2464 } else if tuple_arguments == TupleArguments {
2469 for (i, arg) in args.iter().take(t).enumerate() {
2470 if any_diverges && !warned {
2474 .add_lint(lint::builtin::UNREACHABLE_CODE,
2477 "unreachable expression".to_string());
2480 let is_block = match arg.node {
2481 hir::ExprClosure(..) => true,
2485 if is_block == check_blocks {
2486 debug!("checking the argument");
2487 let formal_ty = formal_tys[i];
2489 // The special-cased logic below has three functions:
2490 // 1. Provide as good of an expected type as possible.
2491 let expected = expected_arg_tys.get(i).map(|&ty| {
2492 Expectation::rvalue_hint(fcx.tcx(), ty)
2495 check_expr_with_expectation(fcx, &arg,
2496 expected.unwrap_or(ExpectHasType(formal_ty)));
2497 // 2. Coerce to the most detailed type that could be coerced
2498 // to, which is `expected_ty` if `rvalue_hint` returns an
2499 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2500 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2501 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &arg);
2503 // 3. Relate the expected type and the formal one,
2504 // if the expected type was used for the coercion.
2505 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2508 if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2509 any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2512 if any_diverges && !warned {
2513 let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2517 .add_lint(lint::builtin::UNREACHABLE_CODE,
2520 "unreachable call".to_string());
2526 // We also need to make sure we at least write the ty of the other
2527 // arguments which we skipped above.
2529 for arg in args.iter().skip(expected_arg_count) {
2530 check_expr(fcx, &arg);
2532 // There are a few types which get autopromoted when passed via varargs
2533 // in C but we just error out instead and require explicit casts.
2534 let arg_ty = structurally_resolved_type(fcx, arg.span,
2537 ty::TyFloat(ast::FloatTy::F32) => {
2538 fcx.type_error_message(arg.span,
2540 format!("can't pass an {} to variadic \
2541 function, cast to c_double", t)
2544 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
2545 fcx.type_error_message(arg.span, |t| {
2546 format!("can't pass {} to variadic \
2547 function, cast to c_int",
2551 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
2552 fcx.type_error_message(arg.span, |t| {
2553 format!("can't pass {} to variadic \
2554 function, cast to c_uint",
2564 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
2565 fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
2566 (0..len).map(|_| tcx.types.err).collect()
2569 fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2570 call_expr: &hir::Expr,
2571 output: ty::FnOutput<'tcx>) {
2572 fcx.write_ty(call_expr.id, match output {
2573 ty::FnConverging(output_ty) => output_ty,
2574 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2578 // AST fragment checking
2579 fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2581 expected: Expectation<'tcx>)
2584 let tcx = fcx.ccx.tcx;
2587 ast::LitKind::Str(..) => tcx.mk_static_str(),
2588 ast::LitKind::ByteStr(ref v) => {
2589 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2590 tcx.mk_array(tcx.types.u8, v.len()))
2592 ast::LitKind::Byte(_) => tcx.types.u8,
2593 ast::LitKind::Char(_) => tcx.types.char,
2594 ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(t),
2595 ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(t),
2596 ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
2597 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2599 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2600 ty::TyChar => Some(tcx.types.u8),
2601 ty::TyRawPtr(..) => Some(tcx.types.usize),
2602 ty::TyFnDef(..) | ty::TyFnPtr(_) => Some(tcx.types.usize),
2606 opt_ty.unwrap_or_else(
2607 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
2609 ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
2610 ast::LitKind::FloatUnsuffixed(_) => {
2611 let opt_ty = expected.to_option(fcx).and_then(|ty| {
2613 ty::TyFloat(_) => Some(ty),
2617 opt_ty.unwrap_or_else(
2618 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
2620 ast::LitKind::Bool(_) => tcx.types.bool
2624 fn check_expr_eq_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2625 expr: &'tcx hir::Expr,
2626 expected: Ty<'tcx>) {
2627 check_expr_with_hint(fcx, expr, expected);
2628 demand::eqtype(fcx, expr.span, expected, fcx.expr_ty(expr));
2631 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2632 expr: &'tcx hir::Expr,
2633 expected: Ty<'tcx>) {
2634 check_expr_with_hint(fcx, expr, expected);
2635 demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr));
2638 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2639 expr: &'tcx hir::Expr,
2640 expected: Ty<'tcx>) {
2641 check_expr_with_hint(fcx, expr, expected);
2642 demand::coerce(fcx, expr.span, expected, expr);
2645 fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
2646 expected: Ty<'tcx>) {
2647 check_expr_with_expectation(fcx, expr, ExpectHasType(expected))
2650 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2651 expr: &'tcx hir::Expr,
2652 expected: Expectation<'tcx>) {
2653 check_expr_with_expectation_and_lvalue_pref(fcx, expr, expected, NoPreference)
2656 fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
2657 check_expr_with_expectation(fcx, expr, NoExpectation)
2660 fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
2661 lvalue_pref: LvaluePreference) {
2662 check_expr_with_expectation_and_lvalue_pref(fcx, expr, NoExpectation, lvalue_pref)
2665 // determine the `self` type, using fresh variables for all variables
2666 // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
2667 // would return ($0, $1) where $0 and $1 are freshly instantiated type
2669 pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2670 span: Span, // (potential) receiver for this impl
2672 -> TypeAndSubsts<'tcx> {
2673 let tcx = fcx.tcx();
2675 let ity = tcx.lookup_item_type(did);
2676 let (tps, rps, raw_ty) =
2677 (ity.generics.types.get_slice(subst::TypeSpace),
2678 ity.generics.regions.get_slice(subst::TypeSpace),
2681 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2683 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
2684 let mut substs = subst::Substs::new(
2685 VecPerParamSpace::empty(),
2686 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2687 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
2688 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2690 TypeAndSubsts { substs: substs, ty: substd_ty }
2693 /// Controls whether the arguments are tupled. This is used for the call
2696 /// Tupling means that all call-side arguments are packed into a tuple and
2697 /// passed as a single parameter. For example, if tupling is enabled, this
2700 /// fn f(x: (isize, isize))
2702 /// Can be called as:
2709 #[derive(Clone, Eq, PartialEq)]
2710 enum TupleArgumentsFlag {
2715 /// Unifies the return type with the expected type early, for more coercions
2716 /// and forward type information on the argument expressions.
2717 fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2719 expected_ret: Expectation<'tcx>,
2720 formal_ret: ty::FnOutput<'tcx>,
2721 formal_args: &[Ty<'tcx>])
2723 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2724 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2725 fcx.infcx().commit_regions_if_ok(|| {
2726 // Attempt to apply a subtyping relationship between the formal
2727 // return type (likely containing type variables if the function
2728 // is polymorphic) and the expected return type.
2729 // No argument expectations are produced if unification fails.
2730 let origin = TypeOrigin::Misc(call_span);
2731 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2732 // FIXME(#15760) can't use try! here, FromError doesn't default
2733 // to identity so the resulting type is not constrained.
2734 if let Err(e) = ures {
2738 // Record all the argument types, with the substitutions
2739 // produced from the above subtyping unification.
2740 Ok(formal_args.iter().map(|ty| {
2741 fcx.infcx().resolve_type_vars_if_possible(ty)
2747 }).unwrap_or(vec![]);
2748 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2749 formal_args, formal_ret,
2750 expected_args, expected_ret);
2755 /// If an expression has any sub-expressions that result in a type error,
2756 /// inspecting that expression's type with `ty.references_error()` will return
2757 /// true. Likewise, if an expression is known to diverge, inspecting its
2758 /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2759 /// strict, _|_ can appear in the type of an expression that does not,
2760 /// itself, diverge: for example, fn() -> _|_.)
2761 /// Note that inspecting a type's structure *directly* may expose the fact
2762 /// that there are actually multiple representations for `TyError`, so avoid
2763 /// that when err needs to be handled differently.
2764 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2765 expr: &'tcx hir::Expr,
2766 expected: Expectation<'tcx>,
2767 lvalue_pref: LvaluePreference) {
2768 debug!(">> typechecking: expr={:?} expected={:?}",
2771 // Checks a method call.
2772 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2773 expr: &'tcx hir::Expr,
2774 method_name: Spanned<ast::Name>,
2775 args: &'tcx [P<hir::Expr>],
2777 expected: Expectation<'tcx>,
2778 lvalue_pref: LvaluePreference) {
2779 let rcvr = &args[0];
2780 check_expr_with_lvalue_pref(fcx, &rcvr, lvalue_pref);
2782 // no need to check for bot/err -- callee does that
2783 let expr_t = structurally_resolved_type(fcx,
2785 fcx.expr_ty(&rcvr));
2787 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&ast_ty)).collect::<Vec<_>>();
2788 let fn_ty = match method::lookup(fcx,
2796 let method_ty = method.ty;
2797 let method_call = MethodCall::expr(expr.id);
2798 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
2802 if method_name.node != special_idents::invalid.name {
2803 method::report_error(fcx, method_name.span, expr_t,
2804 method_name.node, Some(rcvr), error);
2806 fcx.write_error(expr.id);
2811 // Call the generic checker.
2812 let ret_ty = check_method_argument_types(fcx,
2820 write_call(fcx, expr, ret_ty);
2823 // A generic function for checking the then and else in an if
2825 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2826 cond_expr: &'tcx hir::Expr,
2827 then_blk: &'tcx hir::Block,
2828 opt_else_expr: Option<&'tcx hir::Expr>,
2831 expected: Expectation<'tcx>) {
2832 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2834 let expected = expected.adjust_for_branches(fcx);
2835 check_block_with_expected(fcx, then_blk, expected);
2836 let then_ty = fcx.node_ty(then_blk.id);
2838 let unit = fcx.tcx().mk_nil();
2839 let (origin, expected, found, result) =
2840 if let Some(else_expr) = opt_else_expr {
2841 check_expr_with_expectation(fcx, else_expr, expected);
2842 let else_ty = fcx.expr_ty(else_expr);
2843 let origin = TypeOrigin::IfExpression(sp);
2845 // Only try to coerce-unify if we have a then expression
2846 // to assign coercions to, otherwise it's () or diverging.
2847 let result = if let Some(ref then) = then_blk.expr {
2848 let res = coercion::try_find_lub(fcx, origin, || Some(&**then),
2849 then_ty, else_expr);
2851 // In case we did perform an adjustment, we have to update
2852 // the type of the block, because old trans still uses it.
2853 let adj = fcx.inh.tables.borrow().adjustments.get(&then.id).cloned();
2854 if res.is_ok() && adj.is_some() {
2855 fcx.write_ty(then_blk.id, fcx.adjust_expr_ty(then, adj.as_ref()));
2860 fcx.infcx().commit_if_ok(|_| {
2861 let trace = TypeTrace::types(origin, true, then_ty, else_ty);
2862 fcx.infcx().lub(true, trace).relate(&then_ty, &else_ty)
2865 (origin, then_ty, else_ty, result)
2867 let origin = TypeOrigin::IfExpressionWithNoElse(sp);
2868 (origin, unit, then_ty,
2869 fcx.infcx().eq_types(true, origin, unit, then_ty).map(|_| unit))
2872 let if_ty = match result {
2874 if fcx.expr_ty(cond_expr).references_error() {
2881 fcx.infcx().report_mismatched_types(origin, expected, found, e);
2886 fcx.write_ty(id, if_ty);
2889 // Check field access expressions
2890 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2891 expr: &'tcx hir::Expr,
2892 lvalue_pref: LvaluePreference,
2893 base: &'tcx hir::Expr,
2894 field: &Spanned<ast::Name>) {
2895 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2896 let expr_t = structurally_resolved_type(fcx, expr.span,
2898 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2899 let (_, autoderefs, field_ty) = autoderef(fcx,
2903 UnresolvedTypeAction::Error,
2907 ty::TyStruct(base_def, substs) => {
2908 debug!("struct named {:?}", base_t);
2909 base_def.struct_variant()
2910 .find_field_named(field.node)
2911 .map(|f| fcx.field_ty(expr.span, f, substs))
2918 fcx.write_ty(expr.id, field_ty);
2919 fcx.write_autoderef_adjustment(base.id, autoderefs);
2925 if field.node == special_idents::invalid.name {
2926 fcx.write_error(expr.id);
2930 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
2931 fcx.type_error_struct(field.span,
2933 format!("attempted to take value of method `{}` on type \
2934 `{}`", field.node, actual)
2937 .fileline_help(field.span,
2938 "maybe a `()` to call it is missing? \
2939 If not, try an anonymous function")
2942 let mut err = fcx.type_error_struct(
2945 format!("attempted access of field `{}` on \
2946 type `{}`, but no field with that \
2952 if let ty::TyStruct(def, _) = expr_t.sty {
2953 suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
2958 fcx.write_error(expr.id);
2961 // displays hints about the closest matches in field names
2962 fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
2963 variant: ty::VariantDef<'tcx>,
2964 field: &Spanned<ast::Name>,
2965 skip : Vec<InternedString>) {
2966 let name = field.node.as_str();
2967 let names = variant.fields
2969 .filter_map(|ref field| {
2970 // ignore already set fields and private fields from non-local crates
2971 if skip.iter().any(|x| *x == field.name.as_str()) ||
2972 (variant.did.krate != LOCAL_CRATE && field.vis != Visibility::Public) {
2979 // only find fits with at least one matching letter
2980 if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
2981 err.span_help(field.span,
2982 &format!("did you mean `{}`?", name));
2986 // Check tuple index expressions
2987 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2988 expr: &'tcx hir::Expr,
2989 lvalue_pref: LvaluePreference,
2990 base: &'tcx hir::Expr,
2991 idx: codemap::Spanned<usize>) {
2992 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2993 let expr_t = structurally_resolved_type(fcx, expr.span,
2995 let mut tuple_like = false;
2996 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
2997 let (_, autoderefs, field_ty) = autoderef(fcx,
3001 UnresolvedTypeAction::Error,
3005 ty::TyStruct(base_def, substs) => {
3006 tuple_like = base_def.struct_variant().is_tuple_struct();
3008 debug!("tuple struct named {:?}", base_t);
3009 base_def.struct_variant()
3012 .map(|f| fcx.field_ty(expr.span, f, substs))
3017 ty::TyTuple(ref v) => {
3019 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3026 fcx.write_ty(expr.id, field_ty);
3027 fcx.write_autoderef_adjustment(base.id, autoderefs);
3032 fcx.type_error_message(
3036 format!("attempted out-of-bounds tuple index `{}` on \
3041 format!("attempted tuple index `{}` on type `{}`, but the \
3042 type was not a tuple or tuple struct",
3049 fcx.write_error(expr.id);
3052 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3054 variant: ty::VariantDef<'tcx>,
3056 skip_fields: &[hir::Field]) {
3057 let mut err = fcx.type_error_struct(
3059 |actual| if let ty::TyEnum(..) = ty.sty {
3060 format!("struct variant `{}::{}` has no field named `{}`",
3061 actual, variant.name.as_str(), field.name.node)
3063 format!("structure `{}` has no field named `{}`",
3064 actual, field.name.node)
3068 // prevent all specified fields from being suggested
3069 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3070 suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
3074 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3077 variant: ty::VariantDef<'tcx>,
3078 ast_fields: &'tcx [hir::Field],
3079 check_completeness: bool) {
3080 let tcx = fcx.ccx.tcx;
3081 let substs = match adt_ty.sty {
3082 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3083 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3086 let mut remaining_fields = FnvHashMap();
3087 for field in &variant.fields {
3088 remaining_fields.insert(field.name, field);
3091 let mut error_happened = false;
3093 // Typecheck each field.
3094 for field in ast_fields {
3095 let expected_field_type;
3097 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
3098 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3100 error_happened = true;
3101 expected_field_type = tcx.types.err;
3102 if let Some(_) = variant.find_field_named(field.name.node) {
3103 span_err!(fcx.tcx().sess, field.name.span, E0062,
3104 "field `{}` specified more than once",
3107 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
3111 // Make sure to give a type to the field even if there's
3112 // an error, so we can continue typechecking
3113 check_expr_coercable_to_type(fcx, &field.expr, expected_field_type);
3116 // Make sure the programmer specified all the fields.
3117 if check_completeness &&
3119 !remaining_fields.is_empty()
3121 span_err!(tcx.sess, span, E0063,
3122 "missing field{} {} in initializer of `{}`",
3123 if remaining_fields.len() == 1 {""} else {"s"},
3124 remaining_fields.keys()
3125 .map(|n| format!("`{}`", n))
3126 .collect::<Vec<_>>()
3133 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3135 fields: &'tcx [hir::Field],
3136 base_expr: &'tcx Option<P<hir::Expr>>) {
3137 // Make sure to still write the types
3138 // otherwise we might ICE
3139 fcx.write_error(id);
3140 for field in fields {
3141 check_expr(fcx, &field.expr);
3144 Some(ref base) => check_expr(fcx, &base),
3149 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3152 fields: &'tcx [hir::Field],
3153 base_expr: &'tcx Option<P<hir::Expr>>)
3155 let tcx = fcx.tcx();
3157 // Find the relevant variant
3158 let def = lookup_full_def(tcx, path.span, expr.id);
3159 if def == Def::Err {
3160 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3163 let variant = match fcx.def_struct_variant(def, path.span) {
3164 Some((_, variant)) => variant,
3166 span_err!(fcx.tcx().sess, path.span, E0071,
3167 "`{}` does not name a structure",
3168 pprust::path_to_string(path));
3169 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3174 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3175 fcx.write_ty(expr.id, expr_ty);
3177 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3178 base_expr.is_none());
3179 if let &Some(ref base_expr) = base_expr {
3180 check_expr_has_type(fcx, base_expr, expr_ty);
3182 ty::TyStruct(adt, substs) => {
3183 fcx.inh.tables.borrow_mut().fru_field_types.insert(
3185 adt.struct_variant().fields.iter().map(|f| {
3186 fcx.normalize_associated_types_in(
3187 expr.span, &f.ty(tcx, substs)
3193 span_err!(tcx.sess, base_expr.span, E0436,
3194 "functional record update syntax requires a struct");
3200 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
3202 let tcx = fcx.ccx.tcx;
3205 hir::ExprBox(ref subexpr) => {
3206 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3208 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3212 check_expr_with_expectation(fcx, subexpr, expected_inner);
3213 let referent_ty = fcx.expr_ty(&subexpr);
3214 fcx.write_ty(id, tcx.mk_box(referent_ty));
3217 hir::ExprLit(ref lit) => {
3218 let typ = check_lit(fcx, &lit, expected);
3219 fcx.write_ty(id, typ);
3221 hir::ExprBinary(op, ref lhs, ref rhs) => {
3222 op::check_binop(fcx, expr, op, lhs, rhs);
3224 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
3225 op::check_binop_assign(fcx, expr, op, lhs, rhs);
3227 hir::ExprUnary(unop, ref oprnd) => {
3228 let expected_inner = match unop {
3229 hir::UnNot | hir::UnNeg => {
3236 let lvalue_pref = match unop {
3237 hir::UnDeref => lvalue_pref,
3240 check_expr_with_expectation_and_lvalue_pref(
3241 fcx, &oprnd, expected_inner, lvalue_pref);
3242 let mut oprnd_t = fcx.expr_ty(&oprnd);
3244 if !oprnd_t.references_error() {
3247 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
3249 if let Some(mt) = oprnd_t.builtin_deref(true, NoPreference) {
3251 } else if let Some(method) = try_overloaded_deref(
3252 fcx, expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
3253 oprnd_t = make_overloaded_lvalue_return_type(tcx, method).ty;
3254 fcx.inh.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
3257 fcx.type_error_message(expr.span, |actual| {
3258 format!("type `{}` cannot be \
3259 dereferenced", actual)
3261 oprnd_t = tcx.types.err;
3265 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3267 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
3268 oprnd_t = op::check_user_unop(fcx, "!", "not",
3269 tcx.lang_items.not_trait(),
3270 expr, &oprnd, oprnd_t, unop);
3274 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3276 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
3277 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3278 tcx.lang_items.neg_trait(),
3279 expr, &oprnd, oprnd_t, unop);
3284 fcx.write_ty(id, oprnd_t);
3286 hir::ExprAddrOf(mutbl, ref oprnd) => {
3287 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
3289 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
3290 if fcx.tcx().expr_is_lval(&oprnd) {
3291 // Lvalues may legitimately have unsized types.
3292 // For example, dereferences of a fat pointer and
3293 // the last field of a struct can be unsized.
3294 ExpectHasType(mt.ty)
3296 Expectation::rvalue_hint(tcx, mt.ty)
3302 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
3303 check_expr_with_expectation_and_lvalue_pref(fcx,
3308 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&oprnd), mutbl: mutbl };
3309 let oprnd_t = if tm.ty.references_error() {
3312 // Note: at this point, we cannot say what the best lifetime
3313 // is to use for resulting pointer. We want to use the
3314 // shortest lifetime possible so as to avoid spurious borrowck
3315 // errors. Moreover, the longest lifetime will depend on the
3316 // precise details of the value whose address is being taken
3317 // (and how long it is valid), which we don't know yet until type
3318 // inference is complete.
3320 // Therefore, here we simply generate a region variable. The
3321 // region inferencer will then select the ultimate value.
3322 // Finally, borrowck is charged with guaranteeing that the
3323 // value whose address was taken can actually be made to live
3324 // as long as it needs to live.
3325 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
3326 tcx.mk_ref(tcx.mk_region(region), tm)
3328 fcx.write_ty(id, oprnd_t);
3330 hir::ExprPath(ref maybe_qself, ref path) => {
3331 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3332 fcx.to_ty(&qself.ty)
3335 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3337 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3338 // Create some fake resolution that can't possibly be a type.
3339 def::PathResolution {
3340 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3341 depth: path.segments.len()
3344 tcx.sess.span_bug(expr.span,
3345 &format!("unbound path {:?}", expr))
3348 if let Some((opt_ty, segments, def)) =
3349 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3350 expr.span, expr.id) {
3351 if def != Def::Err {
3352 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3355 instantiate_path(fcx,
3364 fcx.write_ty(id, fcx.tcx().types.err);
3368 // We always require that the type provided as the value for
3369 // a type parameter outlives the moment of instantiation.
3370 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3371 fcx.add_wf_bounds(&item_substs.substs, expr);
3374 hir::ExprInlineAsm(ref ia) => {
3375 for &(_, ref input) in &ia.inputs {
3376 check_expr(fcx, &input);
3378 for out in &ia.outputs {
3379 check_expr(fcx, &out.expr);
3383 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3384 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3385 hir::ExprRet(ref expr_opt) => {
3387 ty::FnConverging(result_type) => {
3390 if let Err(_) = fcx.mk_eqty(false, TypeOrigin::Misc(expr.span),
3391 result_type, fcx.tcx().mk_nil()) {
3392 span_err!(tcx.sess, expr.span, E0069,
3393 "`return;` in a function whose return type is \
3397 check_expr_coercable_to_type(fcx, &e, result_type);
3401 ty::FnDiverging => {
3402 if let Some(ref e) = *expr_opt {
3403 check_expr(fcx, &e);
3405 span_err!(tcx.sess, expr.span, E0166,
3406 "`return` in a function declared as diverging");
3409 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3411 hir::ExprAssign(ref lhs, ref rhs) => {
3412 check_expr_with_lvalue_pref(fcx, &lhs, PreferMutLvalue);
3414 let tcx = fcx.tcx();
3415 if !tcx.expr_is_lval(&lhs) {
3416 span_err!(tcx.sess, expr.span, E0070,
3417 "invalid left-hand side expression");
3420 let lhs_ty = fcx.expr_ty(&lhs);
3421 check_expr_coercable_to_type(fcx, &rhs, lhs_ty);
3422 let rhs_ty = fcx.expr_ty(&rhs);
3424 fcx.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
3426 if lhs_ty.references_error() || rhs_ty.references_error() {
3427 fcx.write_error(id);
3432 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
3433 check_then_else(fcx, &cond, &then_blk, opt_else_expr.as_ref().map(|e| &**e),
3434 id, expr.span, expected);
3436 hir::ExprWhile(ref cond, ref body, _) => {
3437 check_expr_has_type(fcx, &cond, tcx.types.bool);
3438 check_block_no_value(fcx, &body);
3439 let cond_ty = fcx.expr_ty(&cond);
3440 let body_ty = fcx.node_ty(body.id);
3441 if cond_ty.references_error() || body_ty.references_error() {
3442 fcx.write_error(id);
3448 hir::ExprLoop(ref body, _) => {
3449 check_block_no_value(fcx, &body);
3450 if !may_break(tcx, expr.id, &body) {
3451 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3456 hir::ExprMatch(ref discrim, ref arms, match_src) => {
3457 _match::check_match(fcx, expr, &discrim, arms, expected, match_src);
3459 hir::ExprClosure(capture, ref decl, ref body) => {
3460 closure::check_expr_closure(fcx, expr, capture, &decl, &body, expected);
3462 hir::ExprBlock(ref b) => {
3463 check_block_with_expected(fcx, &b, expected);
3464 fcx.write_ty(id, fcx.node_ty(b.id));
3466 hir::ExprCall(ref callee, ref args) => {
3467 callee::check_call(fcx, expr, &callee, &args[..], expected);
3469 // we must check that return type of called functions is WF:
3470 let ret_ty = fcx.expr_ty(expr);
3471 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
3473 hir::ExprMethodCall(name, ref tps, ref args) => {
3474 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
3475 let arg_tys = args.iter().map(|a| fcx.expr_ty(&a));
3476 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3478 fcx.write_error(id);
3481 hir::ExprCast(ref e, ref t) => {
3482 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
3483 check_expr_with_hint(fcx, &count_expr, tcx.types.usize);
3486 // Find the type of `e`. Supply hints based on the type we are casting to,
3488 let t_cast = fcx.to_ty(t);
3489 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3490 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3491 let t_expr = fcx.expr_ty(e);
3492 let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
3494 // Eagerly check for some obvious errors.
3495 if t_expr.references_error() || t_cast.references_error() {
3496 fcx.write_error(id);
3497 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3498 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
3500 // Write a type for the whole expression, assuming everything is going
3502 fcx.write_ty(id, t_cast);
3504 // Defer other checks until we're done type checking.
3505 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
3506 let cast_check = cast::CastCheck::new(e, t_expr, t_cast, expr.span);
3507 deferred_cast_checks.push(cast_check);
3510 hir::ExprType(ref e, ref t) => {
3511 let typ = fcx.to_ty(&t);
3512 check_expr_eq_type(fcx, &e, typ);
3513 fcx.write_ty(id, typ);
3515 hir::ExprVec(ref args) => {
3516 let uty = expected.to_option(fcx).and_then(|uty| {
3518 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3523 let mut unified = fcx.infcx().next_ty_var();
3524 let coerce_to = uty.unwrap_or(unified);
3526 for (i, e) in args.iter().enumerate() {
3527 check_expr_with_hint(fcx, e, coerce_to);
3528 let e_ty = fcx.expr_ty(e);
3529 let origin = TypeOrigin::Misc(e.span);
3531 // Special-case the first element, as it has no "previous expressions".
3532 let result = if i == 0 {
3533 coercion::try(fcx, e, coerce_to)
3535 let prev_elems = || args[..i].iter().map(|e| &**e);
3536 coercion::try_find_lub(fcx, origin, prev_elems, unified, e)
3540 Ok(ty) => unified = ty,
3542 fcx.infcx().report_mismatched_types(origin, unified, e_ty, e);
3546 fcx.write_ty(id, tcx.mk_array(unified, args.len()));
3548 hir::ExprRepeat(ref element, ref count_expr) => {
3549 check_expr_has_type(fcx, &count_expr, tcx.types.usize);
3550 let count = fcx.tcx().eval_repeat_count(&count_expr);
3552 let uty = match expected {
3553 ExpectHasType(uty) => {
3555 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
3562 let (element_ty, t) = match uty {
3564 check_expr_coercable_to_type(fcx, &element, uty);
3568 let t: Ty = fcx.infcx().next_ty_var();
3569 check_expr_has_type(fcx, &element, t);
3570 (fcx.expr_ty(&element), t)
3575 // For [foo, ..n] where n > 1, `foo` must have
3577 fcx.require_type_meets(
3584 if element_ty.references_error() {
3585 fcx.write_error(id);
3587 let t = tcx.mk_array(t, count);
3588 fcx.write_ty(id, t);
3591 hir::ExprTup(ref elts) => {
3592 let flds = expected.only_has_type(fcx).and_then(|ty| {
3594 ty::TyTuple(ref flds) => Some(&flds[..]),
3598 let mut err_field = false;
3600 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3601 let t = match flds {
3602 Some(ref fs) if i < fs.len() => {
3604 check_expr_coercable_to_type(fcx, &e, ety);
3608 check_expr_with_expectation(fcx, &e, NoExpectation);
3612 err_field = err_field || t.references_error();
3616 fcx.write_error(id);
3618 let typ = tcx.mk_tup(elt_ts);
3619 fcx.write_ty(id, typ);
3622 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3623 check_expr_struct(fcx, expr, path, fields, base_expr);
3625 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3627 hir::ExprField(ref base, ref field) => {
3628 check_field(fcx, expr, lvalue_pref, &base, field);
3630 hir::ExprTupField(ref base, idx) => {
3631 check_tup_field(fcx, expr, lvalue_pref, &base, idx);
3633 hir::ExprIndex(ref base, ref idx) => {
3634 check_expr_with_lvalue_pref(fcx, &base, lvalue_pref);
3635 check_expr(fcx, &idx);
3637 let base_t = fcx.expr_ty(&base);
3638 let idx_t = fcx.expr_ty(&idx);
3640 if base_t.references_error() {
3641 fcx.write_ty(id, base_t);
3642 } else if idx_t.references_error() {
3643 fcx.write_ty(id, idx_t);
3645 let base_t = structurally_resolved_type(fcx, expr.span, base_t);
3646 match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
3647 Some((index_ty, element_ty)) => {
3648 let idx_expr_ty = fcx.expr_ty(idx);
3649 demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
3650 fcx.write_ty(id, element_ty);
3653 check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
3654 fcx.type_error_message(
3657 format!("cannot index a value of type `{}`",
3662 fcx.write_ty(id, fcx.tcx().types.err);
3669 debug!("type of expr({}) {} is...", expr.id,
3670 pprust::expr_to_string(expr));
3671 debug!("... {:?}, expected is {:?}",
3676 pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3677 path_res: def::PathResolution,
3678 opt_self_ty: Option<Ty<'tcx>>,
3679 path: &'a hir::Path,
3681 node_id: ast::NodeId)
3682 -> Option<(Option<Ty<'tcx>>,
3683 &'a [hir::PathSegment],
3687 // If fully resolved already, we don't have to do anything.
3688 if path_res.depth == 0 {
3689 Some((opt_self_ty, &path.segments, path_res.base_def))
3691 let mut def = path_res.base_def;
3692 let ty_segments = path.segments.split_last().unwrap().1;
3693 let base_ty_end = path.segments.len() - path_res.depth;
3694 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3695 PathParamMode::Optional,
3698 &ty_segments[..base_ty_end],
3699 &ty_segments[base_ty_end..]);
3700 let item_segment = path.segments.last().unwrap();
3701 let item_name = item_segment.identifier.name;
3702 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3704 // Write back the new resolution.
3705 fcx.ccx.tcx.def_map.borrow_mut()
3706 .insert(node_id, def::PathResolution {
3710 Some((Some(ty), slice::ref_slice(item_segment), def))
3713 if item_name != special_idents::invalid.name {
3714 method::report_error(fcx, span, ty, item_name, None, error);
3716 fcx.write_error(node_id);
3723 impl<'tcx> Expectation<'tcx> {
3724 /// Provide an expectation for an rvalue expression given an *optional*
3725 /// hint, which is not required for type safety (the resulting type might
3726 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3727 /// is useful in determining the concrete type.
3729 /// The primary use case is where the expected type is a fat pointer,
3730 /// like `&[isize]`. For example, consider the following statement:
3732 /// let x: &[isize] = &[1, 2, 3];
3734 /// In this case, the expected type for the `&[1, 2, 3]` expression is
3735 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3736 /// expectation `ExpectHasType([isize])`, that would be too strong --
3737 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
3738 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
3739 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
3740 /// which still is useful, because it informs integer literals and the like.
3741 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3742 /// for examples of where this comes up,.
3743 fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3744 match tcx.struct_tail(ty).sty {
3745 ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
3746 ExpectRvalueLikeUnsized(ty)
3748 _ => ExpectHasType(ty)
3752 // Resolves `expected` by a single level if it is a variable. If
3753 // there is no expected type or resolution is not possible (e.g.,
3754 // no constraints yet present), just returns `None`.
3755 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3760 ExpectCastableToType(t) => {
3761 ExpectCastableToType(
3762 fcx.infcx().resolve_type_vars_if_possible(&t))
3764 ExpectHasType(t) => {
3766 fcx.infcx().resolve_type_vars_if_possible(&t))
3768 ExpectRvalueLikeUnsized(t) => {
3769 ExpectRvalueLikeUnsized(
3770 fcx.infcx().resolve_type_vars_if_possible(&t))
3775 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3776 match self.resolve(fcx) {
3777 NoExpectation => None,
3778 ExpectCastableToType(ty) |
3780 ExpectRvalueLikeUnsized(ty) => Some(ty),
3784 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
3785 match self.resolve(fcx) {
3786 ExpectHasType(ty) => Some(ty),
3792 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3793 local: &'tcx hir::Local,
3794 init: &'tcx hir::Expr)
3796 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3798 let local_ty = fcx.local_ty(init.span, local.id);
3799 if let Some(m) = ref_bindings {
3800 // Somewhat subtle: if we have a `ref` binding in the pattern,
3801 // we want to avoid introducing coercions for the RHS. This is
3802 // both because it helps preserve sanity and, in the case of
3803 // ref mut, for soundness (issue #23116). In particular, in
3804 // the latter case, we need to be clear that the type of the
3805 // referent for the reference that results is *equal to* the
3806 // type of the lvalue it is referencing, and not some
3807 // supertype thereof.
3808 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
3809 let init_ty = fcx.expr_ty(init);
3810 demand::eqtype(fcx, init.span, init_ty, local_ty);
3812 check_expr_coercable_to_type(fcx, init, local_ty)
3816 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
3817 let tcx = fcx.ccx.tcx;
3819 let t = fcx.local_ty(local.span, local.id);
3820 fcx.write_ty(local.id, t);
3822 if let Some(ref init) = local.init {
3823 check_decl_initializer(fcx, local, &init);
3824 let init_ty = fcx.expr_ty(&init);
3825 if init_ty.references_error() {
3826 fcx.write_ty(local.id, init_ty);
3830 let pcx = pat_ctxt {
3832 map: pat_id_map(&tcx.def_map, &local.pat),
3834 _match::check_pat(&pcx, &local.pat, t);
3835 let pat_ty = fcx.node_ty(local.pat.id);
3836 if pat_ty.references_error() {
3837 fcx.write_ty(local.id, pat_ty);
3841 pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
3843 let mut saw_bot = false;
3844 let mut saw_err = false;
3846 hir::StmtDecl(ref decl, id) => {
3849 hir::DeclLocal(ref l) => {
3850 check_decl_local(fcx, &l);
3851 let l_t = fcx.node_ty(l.id);
3852 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
3853 saw_err = saw_err || l_t.references_error();
3855 hir::DeclItem(_) => {/* ignore for now */ }
3858 hir::StmtExpr(ref expr, id) => {
3860 // Check with expected type of ()
3861 check_expr_has_type(fcx, &expr, fcx.tcx().mk_nil());
3862 let expr_ty = fcx.expr_ty(&expr);
3863 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
3864 saw_err = saw_err || expr_ty.references_error();
3866 hir::StmtSemi(ref expr, id) => {
3868 check_expr(fcx, &expr);
3869 let expr_ty = fcx.expr_ty(&expr);
3870 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
3871 saw_err |= expr_ty.references_error();
3875 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3878 fcx.write_error(node_id);
3881 fcx.write_nil(node_id)
3885 pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
3886 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
3887 let blkty = fcx.node_ty(blk.id);
3888 if blkty.references_error() {
3889 fcx.write_error(blk.id);
3891 let nilty = fcx.tcx().mk_nil();
3892 demand::suptype(fcx, blk.span, nilty, blkty);
3896 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3897 blk: &'tcx hir::Block,
3898 expected: Expectation<'tcx>) {
3900 let mut fcx_ps = fcx.ps.borrow_mut();
3901 let unsafety_state = fcx_ps.recurse(blk);
3902 replace(&mut *fcx_ps, unsafety_state)
3905 let mut warned = false;
3906 let mut any_diverges = false;
3907 let mut any_err = false;
3908 for s in &blk.stmts {
3910 let s_id = ::rustc_front::util::stmt_id(s);
3911 let s_ty = fcx.node_ty(s_id);
3912 if any_diverges && !warned && match s.node {
3913 hir::StmtDecl(ref decl, _) => {
3915 hir::DeclLocal(_) => true,
3919 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
3924 .add_lint(lint::builtin::UNREACHABLE_CODE,
3927 "unreachable statement".to_string());
3930 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
3931 any_err = any_err || s_ty.references_error();
3934 None => if any_err {
3935 fcx.write_error(blk.id);
3936 } else if any_diverges {
3937 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3939 fcx.write_nil(blk.id);
3942 if any_diverges && !warned {
3946 .add_lint(lint::builtin::UNREACHABLE_CODE,
3949 "unreachable expression".to_string());
3951 let ety = match expected {
3952 ExpectHasType(ety) => {
3953 check_expr_coercable_to_type(fcx, &e, ety);
3957 check_expr_with_expectation(fcx, &e, expected);
3963 fcx.write_error(blk.id);
3964 } else if any_diverges {
3965 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
3967 fcx.write_ty(blk.id, ety);
3972 *fcx.ps.borrow_mut() = prev;
3975 /// Checks a constant appearing in a type. At the moment this is just the
3976 /// length expression in a fixed-length vector, but someday it might be
3977 /// extended to type-level numeric literals.
3978 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
3979 expr: &'tcx hir::Expr,
3980 expected_type: Ty<'tcx>) {
3981 let tables = RefCell::new(ty::Tables::empty());
3982 let inh = static_inherited_fields(ccx, &tables);
3983 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
3984 check_const_with_ty(&fcx, expr.span, expr, expected_type);
3987 fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
3991 let tables = RefCell::new(ty::Tables::empty());
3992 let inh = static_inherited_fields(ccx, &tables);
3993 let rty = ccx.tcx.node_id_to_type(id);
3994 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
3995 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
3996 check_const_with_ty(&fcx, sp, e, declty);
3999 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4003 // Gather locals in statics (because of block expressions).
4004 // This is technically unnecessary because locals in static items are forbidden,
4005 // but prevents type checking from blowing up before const checking can properly
4007 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4009 check_expr_with_hint(fcx, e, declty);
4010 demand::coerce(fcx, e.span, declty, e);
4012 fcx.select_all_obligations_and_apply_defaults();
4013 upvar::closure_analyze_const(&fcx, e);
4014 fcx.select_obligations_where_possible();
4016 fcx.select_all_obligations_or_error();
4018 regionck::regionck_expr(fcx, e);
4019 writeback::resolve_type_vars_in_expr(fcx, e);
4022 /// Checks whether a type can be represented in memory. In particular, it
4023 /// identifies types that contain themselves without indirection through a
4024 /// pointer, which would mean their size is unbounded.
4025 pub fn check_representable(tcx: &TyCtxt,
4027 item_id: ast::NodeId,
4028 _designation: &str) -> bool {
4029 let rty = tcx.node_id_to_type(item_id);
4031 // Check that it is possible to represent this type. This call identifies
4032 // (1) types that contain themselves and (2) types that contain a different
4033 // recursive type. It is only necessary to throw an error on those that
4034 // contain themselves. For case 2, there must be an inner type that will be
4035 // caught by case 1.
4036 match rty.is_representable(tcx, sp) {
4037 Representability::SelfRecursive => {
4038 let item_def_id = tcx.map.local_def_id(item_id);
4039 traits::recursive_type_with_infinite_size_error(tcx, item_def_id).emit();
4042 Representability::Representable | Representability::ContainsRecursive => (),
4047 pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
4048 let t = tcx.node_id_to_type(id);
4050 ty::TyStruct(def, substs) => {
4051 let fields = &def.struct_variant().fields;
4052 if fields.is_empty() {
4053 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4056 let e = fields[0].ty(tcx, substs);
4057 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
4058 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4062 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4063 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4065 span_err!(tcx.sess, sp, E0077,
4066 "SIMD vector element type should be machine type");
4075 pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4077 vs: &'tcx [hir::Variant],
4079 // disr_in_range should be removed once we have forced type hints for consts
4080 fn disr_in_range(ccx: &CrateCtxt,
4082 disr: ty::Disr) -> bool {
4083 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
4085 ast::UintTy::U8 => disr as u8 as Disr == disr,
4086 ast::UintTy::U16 => disr as u16 as Disr == disr,
4087 ast::UintTy::U32 => disr as u32 as Disr == disr,
4088 ast::UintTy::U64 => disr as u64 as Disr == disr,
4089 ast::UintTy::Us => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
4092 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
4094 ast::IntTy::I8 => disr as i8 as Disr == disr,
4095 ast::IntTy::I16 => disr as i16 as Disr == disr,
4096 ast::IntTy::I32 => disr as i32 as Disr == disr,
4097 ast::IntTy::I64 => disr as i64 as Disr == disr,
4098 ast::IntTy::Is => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
4102 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4103 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4107 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4108 vs: &'tcx [hir::Variant],
4110 hint: attr::ReprAttr) {
4111 #![allow(trivial_numeric_casts)]
4113 let rty = ccx.tcx.node_id_to_type(id);
4114 let mut disr_vals: Vec<ty::Disr> = Vec::new();
4116 let tables = RefCell::new(ty::Tables::empty());
4117 let inh = static_inherited_fields(ccx, &tables);
4118 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4120 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
4122 if let Some(ref e) = v.node.disr_expr {
4123 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4127 let def_id = ccx.tcx.map.local_def_id(id);
4129 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
4130 for (v, variant) in vs.iter().zip(variants.iter()) {
4131 let current_disr_val = variant.disr_val;
4133 // Check for duplicate discriminant values
4134 match disr_vals.iter().position(|&x| x == current_disr_val) {
4136 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
4137 "discriminant value `{}` already exists", disr_vals[i]);
4138 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4139 span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
4140 "conflicting discriminant here");
4145 // Check for unrepresentable discriminant values
4147 attr::ReprAny | attr::ReprExtern => {
4148 disr_vals.push(current_disr_val);
4150 attr::ReprInt(sp, ity) => {
4151 if !disr_in_range(ccx, ity, current_disr_val) {
4152 let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
4153 "discriminant value outside specified type");
4154 span_note!(&mut err, sp,
4155 "discriminant type specified here");
4159 // Error reported elsewhere.
4160 attr::ReprSimd | attr::ReprPacked => {}
4165 let def_id = ccx.tcx.map.local_def_id(id);
4166 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
4168 if hint != attr::ReprAny && vs.is_empty() {
4169 span_err!(ccx.tcx.sess, sp, E0084,
4170 "unsupported representation for zero-variant enum");
4173 do_check(ccx, vs, id, hint);
4175 check_representable(ccx.tcx, sp, id, "enum");
4178 // Returns the type parameter count and the type for the given definition.
4179 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4182 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
4184 Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
4185 let typ = fcx.local_ty(sp, nid);
4186 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4187 ty::GenericPredicates::empty())
4189 Def::Fn(id) | Def::Method(id) |
4190 Def::Static(id, _) | Def::Variant(_, id) |
4191 Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
4192 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
4197 Def::AssociatedTy(..) |
4201 Def::ForeignMod(..) |
4205 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4210 // Instantiates the given path, which must refer to an item with the given
4211 // number of type parameters and type.
4212 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4213 segments: &[hir::PathSegment],
4214 type_scheme: TypeScheme<'tcx>,
4215 type_predicates: &ty::GenericPredicates<'tcx>,
4216 opt_self_ty: Option<Ty<'tcx>>,
4219 node_id: ast::NodeId) {
4220 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
4226 // We need to extract the type parameters supplied by the user in
4227 // the path `path`. Due to the current setup, this is a bit of a
4228 // tricky-process; the problem is that resolve only tells us the
4229 // end-point of the path resolution, and not the intermediate steps.
4230 // Luckily, we can (at least for now) deduce the intermediate steps
4231 // just from the end-point.
4233 // There are basically four cases to consider:
4235 // 1. Reference to a *type*, such as a struct or enum:
4237 // mod a { struct Foo<T> { ... } }
4239 // Because we don't allow types to be declared within one
4240 // another, a path that leads to a type will always look like
4241 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4242 // that only the final segment can have type parameters, and
4243 // they are located in the TypeSpace.
4245 // *Note:* Generally speaking, references to types don't
4246 // actually pass through this function, but rather the
4247 // `ast_ty_to_ty` function in `astconv`. However, in the case
4248 // of struct patterns (and maybe literals) we do invoke
4249 // `instantiate_path` to get the general type of an instance of
4250 // a struct. (In these cases, there are actually no type
4251 // parameters permitted at present, but perhaps we will allow
4252 // them in the future.)
4254 // 1b. Reference to an enum variant or tuple-like struct:
4256 // struct foo<T>(...)
4257 // enum E<T> { foo(...) }
4259 // In these cases, the parameters are declared in the type
4262 // 2. Reference to a *fn item*:
4266 // In this case, the path will again always have the form
4267 // `a::b::foo::<T>` where only the final segment should have
4268 // type parameters. However, in this case, those parameters are
4269 // declared on a value, and hence are in the `FnSpace`.
4271 // 3. Reference to a *method*:
4273 // impl<A> SomeStruct<A> {
4277 // Here we can have a path like
4278 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4279 // may appear in two places. The penultimate segment,
4280 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4281 // final segment, `foo::<B>` contains parameters in fn space.
4283 // 4. Reference to an *associated const*:
4285 // impl<A> AnotherStruct<A> {
4286 // const FOO: B = BAR;
4289 // The path in this case will look like
4290 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4291 // only will have parameters in TypeSpace.
4293 // The first step then is to categorize the segments appropriately.
4295 assert!(!segments.is_empty());
4297 let mut ufcs_associated = None;
4298 let mut segment_spaces: Vec<_>;
4300 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4306 Def::AssociatedTy(..) |
4309 Def::TyParam(..) => {
4310 // Everything but the final segment should have no
4311 // parameters at all.
4312 segment_spaces = vec![None; segments.len() - 1];
4313 segment_spaces.push(Some(subst::TypeSpace));
4316 // Case 2. Reference to a top-level value.
4319 Def::Static(..) => {
4320 segment_spaces = vec![None; segments.len() - 1];
4321 segment_spaces.push(Some(subst::FnSpace));
4324 // Case 3. Reference to a method.
4325 Def::Method(def_id) => {
4326 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4328 ty::TraitContainer(trait_did) => {
4329 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4331 ty::ImplContainer(_) => {}
4334 if segments.len() >= 2 {
4335 segment_spaces = vec![None; segments.len() - 2];
4336 segment_spaces.push(Some(subst::TypeSpace));
4337 segment_spaces.push(Some(subst::FnSpace));
4339 // `<T>::method` will end up here, and so can `T::method`.
4340 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4341 segment_spaces = vec![Some(subst::FnSpace)];
4342 ufcs_associated = Some((container, self_ty));
4346 Def::AssociatedConst(def_id) => {
4347 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4349 ty::TraitContainer(trait_did) => {
4350 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4352 ty::ImplContainer(_) => {}
4355 if segments.len() >= 2 {
4356 segment_spaces = vec![None; segments.len() - 2];
4357 segment_spaces.push(Some(subst::TypeSpace));
4358 segment_spaces.push(None);
4360 // `<T>::CONST` will end up here, and so can `T::CONST`.
4361 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
4362 segment_spaces = vec![None];
4363 ufcs_associated = Some((container, self_ty));
4367 // Other cases. Various nonsense that really shouldn't show up
4368 // here. If they do, an error will have been reported
4369 // elsewhere. (I hope)
4371 Def::ForeignMod(..) |
4376 segment_spaces = vec![None; segments.len()];
4379 assert_eq!(segment_spaces.len(), segments.len());
4381 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4382 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4383 // type parameters are not mandatory.
4384 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
4386 debug!("segment_spaces={:?}", segment_spaces);
4388 // Next, examine the definition, and determine how many type
4389 // parameters we expect from each space.
4390 let type_defs = &type_scheme.generics.types;
4391 let region_defs = &type_scheme.generics.regions;
4393 // Now that we have categorized what space the parameters for each
4394 // segment belong to, let's sort out the parameters that the user
4395 // provided (if any) into their appropriate spaces. We'll also report
4396 // errors if type parameters are provided in an inappropriate place.
4397 let mut substs = Substs::empty();
4398 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
4401 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
4405 push_explicit_parameters_from_segment_to_substs(fcx,
4415 if let Some(self_ty) = opt_self_ty {
4416 if type_defs.len(subst::SelfSpace) == 1 {
4417 substs.types.push(subst::SelfSpace, self_ty);
4421 // Now we have to compare the types that the user *actually*
4422 // provided against the types that were *expected*. If the user
4423 // did not provide any types, then we want to substitute inference
4424 // variables. If the user provided some types, we may still need
4425 // to add defaults. If the user provided *too many* types, that's
4427 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
4428 adjust_type_parameters(fcx, span, space, type_defs,
4429 require_type_space, &mut substs);
4430 assert_eq!(substs.types.len(space), type_defs.len(space));
4432 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4433 assert_eq!(substs.regions().len(space), region_defs.len(space));
4436 // The things we are substituting into the type should not contain
4437 // escaping late-bound regions, and nor should the base type scheme.
4438 assert!(!substs.has_regions_escaping_depth(0));
4439 assert!(!type_scheme.has_escaping_regions());
4441 // Add all the obligations that are required, substituting and
4442 // normalized appropriately.
4443 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
4444 fcx.add_obligations_for_parameters(
4445 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4448 // Substitute the values for the type parameters into the type of
4449 // the referenced item.
4450 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4453 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
4454 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4455 // is inherent, there is no `Self` parameter, instead, the impl needs
4456 // type parameters, which we can infer by unifying the provided `Self`
4457 // with the substituted impl type.
4458 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
4459 assert_eq!(substs.types.len(subst::TypeSpace),
4460 impl_scheme.generics.types.len(subst::TypeSpace));
4461 assert_eq!(substs.regions().len(subst::TypeSpace),
4462 impl_scheme.generics.regions.len(subst::TypeSpace));
4464 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4465 if fcx.mk_subty(false, TypeOrigin::Misc(span), self_ty, impl_ty).is_err() {
4466 fcx.tcx().sess.span_bug(span,
4468 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4474 debug!("instantiate_path: type of {:?} is {:?}",
4477 fcx.write_ty(node_id, ty_substituted);
4478 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4481 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4482 /// parameters are provided, then reports an error and clears the output vector.
4484 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4485 /// use inference variables. This seems less likely to lead to derived errors.
4487 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4488 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4489 /// here because we can easily use the precise span of the N+1'th parameter.
4490 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4491 fcx: &FnCtxt<'a, 'tcx>,
4492 space: subst::ParamSpace,
4494 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4495 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4496 segment: &hir::PathSegment,
4497 substs: &mut Substs<'tcx>)
4499 match segment.parameters {
4500 hir::AngleBracketedParameters(ref data) => {
4501 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4502 fcx, space, type_defs, region_defs, data, substs);
4505 hir::ParenthesizedParameters(ref data) => {
4506 span_err!(fcx.tcx().sess, span, E0238,
4507 "parenthesized parameters may only be used with a trait");
4508 push_explicit_parenthesized_parameters_from_segment_to_substs(
4509 fcx, space, span, type_defs, data, substs);
4514 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4515 fcx: &FnCtxt<'a, 'tcx>,
4516 space: subst::ParamSpace,
4517 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4518 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
4519 data: &hir::AngleBracketedParameterData,
4520 substs: &mut Substs<'tcx>)
4523 let type_count = type_defs.len(space);
4524 assert_eq!(substs.types.len(space), 0);
4525 for (i, typ) in data.types.iter().enumerate() {
4526 let t = fcx.to_ty(&typ);
4528 substs.types.push(space, t);
4529 } else if i == type_count {
4530 span_err!(fcx.tcx().sess, typ.span, E0087,
4531 "too many type parameters provided: \
4532 expected at most {} parameter{}, \
4533 found {} parameter{}",
4535 if type_count == 1 {""} else {"s"},
4537 if data.types.len() == 1 {""} else {"s"});
4538 substs.types.truncate(space, 0);
4544 if !data.bindings.is_empty() {
4545 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4546 "unexpected binding of associated item in expression path \
4547 (only allowed in type paths)");
4551 let region_count = region_defs.len(space);
4552 assert_eq!(substs.regions().len(space), 0);
4553 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4554 let r = ast_region_to_region(fcx.tcx(), lifetime);
4555 if i < region_count {
4556 substs.mut_regions().push(space, r);
4557 } else if i == region_count {
4558 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4559 "too many lifetime parameters provided: \
4560 expected {} parameter{}, found {} parameter{}",
4562 if region_count == 1 {""} else {"s"},
4563 data.lifetimes.len(),
4564 if data.lifetimes.len() == 1 {""} else {"s"});
4565 substs.mut_regions().truncate(space, 0);
4573 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4574 /// but intended for `Foo(A,B) -> C` form. This expands to
4575 /// roughly the same thing as `Foo<(A,B),C>`. One important
4576 /// difference has to do with the treatment of anonymous
4577 /// regions, which are translated into bound regions (NYI).
4578 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4579 fcx: &FnCtxt<'a, 'tcx>,
4580 space: subst::ParamSpace,
4582 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4583 data: &hir::ParenthesizedParameterData,
4584 substs: &mut Substs<'tcx>)
4586 let type_count = type_defs.len(space);
4588 span_err!(fcx.tcx().sess, span, E0167,
4589 "parenthesized form always supplies 2 type parameters, \
4590 but only {} parameter(s) were expected",
4594 let input_tys: Vec<Ty> =
4595 data.inputs.iter().map(|ty| fcx.to_ty(&ty)).collect();
4597 let tuple_ty = fcx.tcx().mk_tup(input_tys);
4599 if type_count >= 1 {
4600 substs.types.push(space, tuple_ty);
4603 let output_ty: Option<Ty> =
4604 data.output.as_ref().map(|ty| fcx.to_ty(&ty));
4607 output_ty.unwrap_or(fcx.tcx().mk_nil());
4609 if type_count >= 2 {
4610 substs.types.push(space, output_ty);
4614 fn adjust_type_parameters<'a, 'tcx>(
4615 fcx: &FnCtxt<'a, 'tcx>,
4618 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4619 require_type_space: bool,
4620 substs: &mut Substs<'tcx>)
4622 let provided_len = substs.types.len(space);
4623 let desired = defs.get_slice(space);
4624 let required_len = desired.iter()
4625 .take_while(|d| d.default.is_none())
4628 debug!("adjust_type_parameters(space={:?}, \
4637 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4638 assert!(provided_len <= desired.len());
4640 // Nothing specified at all: supply inference variables for
4642 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
4643 substs.types.replace(space, Vec::new());
4644 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
4648 // Too few parameters specified: report an error and use Err
4650 if provided_len < required_len {
4652 if desired.len() != required_len { "at least " } else { "" };
4653 span_err!(fcx.tcx().sess, span, E0089,
4654 "too few type parameters provided: expected {}{} parameter{}, \
4655 found {} parameter{}",
4656 qualifier, required_len,
4657 if required_len == 1 {""} else {"s"},
4659 if provided_len == 1 {""} else {"s"});
4660 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
4664 // Otherwise, add in any optional parameters that the user
4665 // omitted. The case of *too many* parameters is handled
4667 // push_explicit_parameters_from_segment_to_substs(). Note
4668 // that the *default* type are expressed in terms of all prior
4669 // parameters, so we have to substitute as we go with the
4670 // partial substitution that we have built up.
4671 for i in provided_len..desired.len() {
4672 let default = desired[i].default.unwrap();
4673 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4674 substs.types.push(space, default);
4676 assert_eq!(substs.types.len(space), desired.len());
4678 debug!("Final substs: {:?}", substs);
4681 fn adjust_region_parameters(
4685 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4686 substs: &mut Substs)
4688 let provided_len = substs.mut_regions().len(space);
4689 let desired = defs.get_slice(space);
4691 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4692 assert!(provided_len <= desired.len());
4694 // If nothing was provided, just use inference variables.
4695 if provided_len == 0 {
4696 substs.mut_regions().replace(
4698 fcx.infcx().region_vars_for_defs(span, desired));
4702 // If just the right number were provided, everybody is happy.
4703 if provided_len == desired.len() {
4707 // Otherwise, too few were provided. Report an error and then
4708 // use inference variables.
4709 span_err!(fcx.tcx().sess, span, E0090,
4710 "too few lifetime parameters provided: expected {} parameter{}, \
4711 found {} parameter{}",
4713 if desired.len() == 1 {""} else {"s"},
4715 if provided_len == 1 {""} else {"s"});
4717 substs.mut_regions().replace(
4719 fcx.infcx().region_vars_for_defs(span, desired));
4723 fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4727 where F: Fn() -> Ty<'tcx>
4729 let mut ty = fcx.resolve_type_vars_if_possible(ty);
4732 let alternative = f();
4735 if alternative.is_ty_var() || alternative.references_error() {
4736 fcx.type_error_message(sp, |_actual| {
4737 "the type of this value must be known in this context".to_string()
4739 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4740 ty = fcx.tcx().types.err;
4742 demand::suptype(fcx, sp, alternative, ty);
4750 // Resolves `typ` by a single level if `typ` is a type variable. If no
4751 // resolution is possible, then an error is reported.
4752 pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4757 structurally_resolve_type_or_else(fcx, sp, ty, || {
4762 // Returns true if b contains a break that can exit from b
4763 pub fn may_break(cx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
4764 // First: is there an unlabeled break immediately
4766 (loop_query(&b, |e| {
4768 hir::ExprBreak(None) => true,
4772 // Second: is there a labeled break with label
4773 // <id> nested anywhere inside the loop?
4774 (block_query(b, |e| {
4775 if let hir::ExprBreak(Some(_)) = e.node {
4776 lookup_full_def(cx, e.span, e.id) == Def::Label(id)
4783 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4784 tps: &[hir::TyParam],
4786 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4789 // make a vector of booleans initially false, set to true when used
4790 if tps.is_empty() { return; }
4791 let mut tps_used = vec![false; tps.len()];
4793 for leaf_ty in ty.walk() {
4794 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4795 debug!("Found use of ty param num {}", idx);
4796 tps_used[idx as usize] = true;
4800 for (i, b) in tps_used.iter().enumerate() {
4802 span_err!(ccx.tcx.sess, tps[i].span, E0091,
4803 "type parameter `{}` is unused",