]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/check/mod.rs
Merge tag 'upstream/1.5.0+dfsg1'
[rustc.git] / src / librustc_typeck / check / mod.rs
CommitLineData
85aaf69f 1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
1a4d82fc
JJ
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
11/*
12
13# check.rs
14
15Within 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
17function). Inference is used to supply types wherever they are
18unknown.
19
20By far the most complex case is checking the body of a function. This
21can be broken down into several distinct phases:
22
23- gather: creates type variables to represent the type of each local
24 variable and pattern binding.
25
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.
31
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.
36
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
41 flexibility.
42
43- vtable: find and records the impls to use for each trait bound that
44 appears on a type parameter.
45
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.
50
51## Intermediate types
52
53While type checking a function, the intermediate types for the
54expressions, blocks, and so forth contained within the function are
55stored in `fcx.node_types` and `fcx.item_substs`. These types
56may contain unresolved type variables. After type checking is
57complete, the functions in the writeback module are used to take the
58types from this table, resolve them, and then write them into their
59permanent home in the type context `ccx.tcx`.
60
61This means that during inferencing you should use `fcx.write_ty()`
62and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
63nodes within the function.
64
65The types of top-level items, which never contain unbound type
66variables, are stored directly into the `tcx` tables.
67
68n.b.: A type variable is not the same thing as a type parameter. A
69type variable is rather an "instance" of a type parameter: that is,
70given a generic function `fn foo<T>(t: T)`: while checking the
71function `foo`, the type `ty_param(0)` refers to the type `T`, which
72is treated in abstract. When `foo()` is called, however, `T` will be
73substituted for a fresh type variable `N`. This variable will
74eventually be resolved to some concrete type (which might itself be
75type parameter).
76
77*/
78
1a4d82fc 79pub use self::Expectation::*;
d9579d0f 80pub use self::compare_method::{compare_impl_method, compare_const_impl};
1a4d82fc
JJ
81use self::TupleArgumentsFlag::*;
82
c34b1796 83use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
1a4d82fc 84use check::_match::pat_ctxt;
85aaf69f 85use fmt_macros::{Parser, Piece, Position};
b039eaaf 86use metadata::cstore::LOCAL_CRATE;
e9174d1e 87use middle::astconv_util::prohibit_type_params;
c34b1796 88use middle::def;
b039eaaf 89use middle::def_id::DefId;
1a4d82fc 90use middle::infer;
c1a9b12d 91use middle::infer::type_variable;
1a4d82fc 92use middle::pat_util::{self, pat_id_map};
c34b1796 93use middle::privacy::{AllPublic, LastMod};
1a4d82fc 94use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
d9579d0f 95use middle::traits::{self, report_fulfillment_errors};
c34b1796 96use middle::ty::{FnSig, GenericPredicates, TypeScheme};
1a4d82fc 97use middle::ty::{Disr, ParamTy, ParameterEnvironment};
e9174d1e 98use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
c1a9b12d
SL
99use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
100use middle::ty::{MethodCall, MethodCallee};
e9174d1e
SL
101use middle::ty::adjustment;
102use middle::ty::error::TypeError;
103use middle::ty::fold::{TypeFolder, TypeFoldable};
104use middle::ty::util::Representability;
c1a9b12d
SL
105use require_c_abi_if_variadic;
106use rscope::{ElisionFailureInfo, RegionScope};
1a4d82fc 107use session::Session;
e9174d1e 108use {CrateCtxt, lookup_full_def};
1a4d82fc 109use TypeAndSubsts;
1a4d82fc 110use lint;
c34b1796 111use util::common::{block_query, ErrorReported, indenter, loop_query};
1a4d82fc 112use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
85aaf69f 113use util::lev_distance::lev_distance;
1a4d82fc
JJ
114
115use std::cell::{Cell, Ref, RefCell};
e9174d1e 116use std::collections::{HashSet};
1a4d82fc 117use std::mem::replace;
e9174d1e
SL
118use syntax::abi;
119use syntax::ast;
b039eaaf
SL
120use syntax::attr;
121use syntax::attr::AttrMetaMethods;
122use syntax::codemap::{self, Span, Spanned};
1a4d82fc 123use syntax::owned_slice::OwnedSlice;
c1a9b12d 124use syntax::parse::token::{self, InternedString};
1a4d82fc 125use syntax::ptr::P;
e9174d1e
SL
126
127use rustc_front::visit::{self, Visitor};
128use rustc_front::hir;
129use rustc_front::hir::Visibility;
e9174d1e
SL
130use rustc_front::hir::{Item, ItemImpl};
131use rustc_front::print::pprust;
b039eaaf 132use rustc_back::slice;
1a4d82fc
JJ
133
134mod assoc;
85aaf69f 135pub mod dropck;
1a4d82fc 136pub mod _match;
1a4d82fc 137pub mod writeback;
1a4d82fc 138pub mod regionck;
85aaf69f 139pub mod coercion;
1a4d82fc
JJ
140pub mod demand;
141pub mod method;
142mod upvar;
e9174d1e
SL
143mod wf;
144mod wfcheck;
9346a6ac 145mod cast;
1a4d82fc
JJ
146mod closure;
147mod callee;
85aaf69f 148mod compare_method;
e9174d1e 149mod intrinsic;
c34b1796 150mod op;
1a4d82fc 151
1a4d82fc
JJ
152/// closures defined within the function. For example:
153///
154/// fn foo() {
155/// bar(move|| { ... })
156/// }
157///
158/// Here, the function `foo()` and the closure passed to
159/// `bar()` will each have their own `FnCtxt`, but they will
160/// share the inherited fields.
161pub struct Inherited<'a, 'tcx: 'a> {
162 infcx: infer::InferCtxt<'a, 'tcx>,
163 locals: RefCell<NodeMap<Ty<'tcx>>>,
1a4d82fc 164
c1a9b12d 165 tables: &'a RefCell<ty::Tables<'tcx>>,
1a4d82fc
JJ
166
167 // A mapping from each fn's id to its signature, with all bound
168 // regions replaced with free ones. Unlike the other tables, this
169 // one is never copied into the tcx: it is only used by regionck.
170 fn_sig_map: RefCell<NodeMap<Vec<Ty<'tcx>>>>,
171
85aaf69f
SL
172 // When we process a call like `c()` where `c` is a closure type,
173 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
174 // `FnOnce` closure. In that case, we defer full resolution of the
175 // call until upvar inference can kick in and make the
176 // decision. We keep these deferred resolutions grouped by the
177 // def-id of the closure, so that once we decide, we can easily go
178 // back and process them.
179 deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
c34b1796 180
9346a6ac 181 deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
85aaf69f
SL
182}
183
184trait DeferredCallResolution<'tcx> {
185 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>);
1a4d82fc
JJ
186}
187
85aaf69f
SL
188type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
189
1a4d82fc
JJ
190/// When type-checking an expression, we propagate downward
191/// whatever type hint we are able in the form of an `Expectation`.
62682a34 192#[derive(Copy, Clone, Debug)]
c34b1796 193pub enum Expectation<'tcx> {
1a4d82fc
JJ
194 /// We know nothing about what type this expression should have.
195 NoExpectation,
196
197 /// This expression should have the type given (or some subtype)
198 ExpectHasType(Ty<'tcx>),
199
200 /// This expression will be cast to the `Ty`
201 ExpectCastableToType(Ty<'tcx>),
202
203 /// This rvalue expression will be wrapped in `&` or `Box` and coerced
204 /// to `&Ty` or `Box<Ty>`, respectively. `Ty` is `[A]` or `Trait`.
205 ExpectRvalueLikeUnsized(Ty<'tcx>),
206}
207
208impl<'tcx> Expectation<'tcx> {
209 // Disregard "castable to" expectations because they
210 // can lead us astray. Consider for example `if cond
211 // {22} else {c} as u8` -- if we propagate the
212 // "castable to u8" constraint to 22, it will pick the
213 // type 22u8, which is overly constrained (c might not
214 // be a u8). In effect, the problem is that the
215 // "castable to" expectation is not the tightest thing
216 // we can say, so we want to drop it in this case.
217 // The tightest thing we can say is "must unify with
218 // else branch". Note that in the case of a "has type"
219 // constraint, this limitation does not hold.
220
221 // If the expected type is just a type variable, then don't use
222 // an expected type. Otherwise, we might write parts of the type
223 // when checking the 'then' block which are incompatible with the
224 // 'else' branch.
225 fn adjust_for_branches<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
226 match *self {
227 ExpectHasType(ety) => {
228 let ety = fcx.infcx().shallow_resolve(ety);
c1a9b12d 229 if !ety.is_ty_var() {
1a4d82fc
JJ
230 ExpectHasType(ety)
231 } else {
232 NoExpectation
233 }
234 }
235 ExpectRvalueLikeUnsized(ety) => {
236 ExpectRvalueLikeUnsized(ety)
237 }
238 _ => NoExpectation
239 }
240 }
241}
242
243#[derive(Copy, Clone)]
244pub struct UnsafetyState {
245 pub def: ast::NodeId,
e9174d1e 246 pub unsafety: hir::Unsafety,
c1a9b12d 247 pub unsafe_push_count: u32,
1a4d82fc
JJ
248 from_fn: bool
249}
250
251impl UnsafetyState {
e9174d1e 252 pub fn function(unsafety: hir::Unsafety, def: ast::NodeId) -> UnsafetyState {
c1a9b12d 253 UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
1a4d82fc
JJ
254 }
255
e9174d1e 256 pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
1a4d82fc
JJ
257 match self.unsafety {
258 // If this unsafe, then if the outer function was already marked as
259 // unsafe we shouldn't attribute the unsafe'ness to the block. This
260 // way the block can be warned about instead of ignoring this
261 // extraneous block (functions are never warned about).
e9174d1e 262 hir::Unsafety::Unsafe if self.from_fn => *self,
1a4d82fc
JJ
263
264 unsafety => {
c1a9b12d 265 let (unsafety, def, count) = match blk.rules {
e9174d1e 266 hir::PushUnsafeBlock(..) =>
c1a9b12d 267 (unsafety, blk.id, self.unsafe_push_count.checked_add(1).unwrap()),
e9174d1e 268 hir::PopUnsafeBlock(..) =>
c1a9b12d 269 (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
e9174d1e
SL
270 hir::UnsafeBlock(..) =>
271 (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
b039eaaf 272 hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
c1a9b12d 273 (unsafety, self.def, self.unsafe_push_count),
1a4d82fc
JJ
274 };
275 UnsafetyState{ def: def,
c1a9b12d
SL
276 unsafety: unsafety,
277 unsafe_push_count: count,
278 from_fn: false }
1a4d82fc
JJ
279 }
280 }
281 }
282}
283
1a4d82fc
JJ
284#[derive(Clone)]
285pub struct FnCtxt<'a, 'tcx: 'a> {
286 body_id: ast::NodeId,
287
288 // This flag is set to true if, during the writeback phase, we encounter
289 // a type error in this function.
290 writeback_errors: Cell<bool>,
291
292 // Number of errors that had been reported when we started
293 // checking this function. On exit, if we find that *more* errors
294 // have been reported, we will skip regionck and other work that
295 // expects the types within the function to be consistent.
c34b1796 296 err_count_on_creation: usize,
1a4d82fc
JJ
297
298 ret_ty: ty::FnOutput<'tcx>,
299
300 ps: RefCell<UnsafetyState>,
301
302 inh: &'a Inherited<'a, 'tcx>,
303
304 ccx: &'a CrateCtxt<'a, 'tcx>,
305}
306
1a4d82fc
JJ
307impl<'a, 'tcx> Inherited<'a, 'tcx> {
308 fn new(tcx: &'a ty::ctxt<'tcx>,
c1a9b12d 309 tables: &'a RefCell<ty::Tables<'tcx>>,
1a4d82fc
JJ
310 param_env: ty::ParameterEnvironment<'a, 'tcx>)
311 -> Inherited<'a, 'tcx> {
c1a9b12d 312
1a4d82fc 313 Inherited {
c1a9b12d 314 infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true),
85aaf69f 315 locals: RefCell::new(NodeMap()),
c1a9b12d 316 tables: tables,
85aaf69f 317 fn_sig_map: RefCell::new(NodeMap()),
85aaf69f 318 deferred_call_resolutions: RefCell::new(DefIdMap()),
c34b1796 319 deferred_cast_checks: RefCell::new(Vec::new()),
1a4d82fc
JJ
320 }
321 }
322
323 fn normalize_associated_types_in<T>(&self,
1a4d82fc
JJ
324 span: Span,
325 body_id: ast::NodeId,
326 value: &T)
327 -> T
c1a9b12d 328 where T : TypeFoldable<'tcx> + HasTypeFlags
1a4d82fc 329 {
c1a9b12d 330 let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut();
1a4d82fc 331 assoc::normalize_associated_types_in(&self.infcx,
c1a9b12d
SL
332 &mut fulfillment_cx,
333 span,
1a4d82fc
JJ
334 body_id,
335 value)
336 }
337
338}
339
340// Used by check_const and check_enum_variants
341pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
342 inh: &'a Inherited<'a, 'tcx>,
343 rty: ty::FnOutput<'tcx>,
344 body_id: ast::NodeId)
345 -> FnCtxt<'a, 'tcx> {
346 FnCtxt {
347 body_id: body_id,
348 writeback_errors: Cell::new(false),
349 err_count_on_creation: ccx.tcx.sess.err_count(),
350 ret_ty: rty,
e9174d1e 351 ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, 0)),
1a4d82fc
JJ
352 inh: inh,
353 ccx: ccx
354 }
355}
356
c1a9b12d
SL
357fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
358 tables: &'a RefCell<ty::Tables<'tcx>>)
1a4d82fc
JJ
359 -> Inherited<'a, 'tcx> {
360 // It's kind of a kludge to manufacture a fake function context
361 // and statement context, but we might as well do write the code only once
c1a9b12d
SL
362 let param_env = ccx.tcx.empty_parameter_environment();
363 Inherited::new(ccx.tcx, &tables, param_env)
1a4d82fc
JJ
364}
365
366struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
9346a6ac 367struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
1a4d82fc 368
85aaf69f 369impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
e9174d1e 370 fn visit_item(&mut self, i: &'tcx hir::Item) {
9346a6ac 371 check_item_type(self.ccx, i);
1a4d82fc
JJ
372 visit::walk_item(self, i);
373 }
374
e9174d1e 375 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
1a4d82fc 376 match t.node {
e9174d1e 377 hir::TyFixedLengthVec(_, ref expr) => {
c34b1796 378 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
1a4d82fc 379 }
b039eaaf
SL
380 hir::TyBareFn(ref function_declaration) => {
381 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
382 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
383 return
384 }
1a4d82fc
JJ
385 _ => {}
386 }
387
388 visit::walk_ty(self, t);
389 }
390}
391
9346a6ac 392impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
e9174d1e 393 fn visit_item(&mut self, i: &'tcx hir::Item) {
9346a6ac
AL
394 check_item_body(self.ccx, i);
395 visit::walk_item(self, i);
396 }
397}
398
e9174d1e
SL
399pub fn check_wf_old(ccx: &CrateCtxt) {
400 // FIXME(#25759). The new code below is much more reliable but (for now)
401 // only generates warnings. So as to ensure that we continue
402 // getting errors where we used to get errors, we run the old wf
403 // code first and abort if it encounters any errors. If no abort
404 // comes, we run the new code and issue warnings.
1a4d82fc
JJ
405 let krate = ccx.tcx.map.krate();
406 let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
407 visit::walk_crate(&mut visit, krate);
408
409 // If types are not well-formed, it leads to all manner of errors
410 // downstream, so stop reporting errors at this point.
411 ccx.tcx.sess.abort_if_errors();
e9174d1e 412}
1a4d82fc 413
e9174d1e
SL
414pub fn check_wf_new(ccx: &CrateCtxt) {
415 let krate = ccx.tcx.map.krate();
416 let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
1a4d82fc
JJ
417 visit::walk_crate(&mut visit, krate);
418
e9174d1e
SL
419 // If types are not well-formed, it leads to all manner of errors
420 // downstream, so stop reporting errors at this point.
1a4d82fc 421 ccx.tcx.sess.abort_if_errors();
e9174d1e 422}
c34b1796 423
e9174d1e
SL
424pub fn check_item_types(ccx: &CrateCtxt) {
425 let krate = ccx.tcx.map.krate();
426 let mut visit = CheckItemTypesVisitor { ccx: ccx };
427 visit::walk_crate(&mut visit, krate);
428 ccx.tcx.sess.abort_if_errors();
429}
430
431pub fn check_item_bodies(ccx: &CrateCtxt) {
432 let krate = ccx.tcx.map.krate();
9346a6ac
AL
433 let mut visit = CheckItemBodiesVisitor { ccx: ccx };
434 visit::walk_crate(&mut visit, krate);
435
436 ccx.tcx.sess.abort_if_errors();
e9174d1e 437}
9346a6ac 438
e9174d1e
SL
439pub fn check_drop_impls(ccx: &CrateCtxt) {
440 let drop_trait = match ccx.tcx.lang_items.drop_trait() {
441 Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
442 };
443 drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
444 if drop_impl_did.is_local() {
c34b1796
AL
445 match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
446 Ok(()) => {}
447 Err(()) => {
448 assert!(ccx.tcx.sess.has_errors());
449 }
450 }
451 }
e9174d1e 452 });
c34b1796
AL
453
454 ccx.tcx.sess.abort_if_errors();
1a4d82fc
JJ
455}
456
457fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
e9174d1e
SL
458 decl: &'tcx hir::FnDecl,
459 body: &'tcx hir::Block,
85aaf69f
SL
460 fn_id: ast::NodeId,
461 fn_span: Span,
1a4d82fc 462 raw_fty: Ty<'tcx>,
85aaf69f
SL
463 param_env: ty::ParameterEnvironment<'a, 'tcx>)
464{
1a4d82fc 465 match raw_fty.sty {
62682a34 466 ty::TyBareFn(_, ref fn_ty) => {
c1a9b12d
SL
467 let tables = RefCell::new(ty::Tables::empty());
468 let inh = Inherited::new(ccx.tcx, &tables, param_env);
1a4d82fc
JJ
469
470 // Compute the fty from point of view of inside fn.
e9174d1e 471 let fn_scope = ccx.tcx.region_maps.item_extent(body.id);
1a4d82fc 472 let fn_sig =
c1a9b12d 473 fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
1a4d82fc 474 let fn_sig =
e9174d1e 475 ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
1a4d82fc 476 let fn_sig =
c1a9b12d
SL
477 inh.normalize_associated_types_in(body.span,
478 body.id,
479 &fn_sig);
1a4d82fc 480
85aaf69f
SL
481 let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
482 decl, fn_id, body, &inh);
1a4d82fc 483
d9579d0f 484 fcx.select_all_obligations_and_apply_defaults();
85aaf69f 485 upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
e9174d1e 486 fcx.select_obligations_where_possible();
c34b1796 487 fcx.check_casts();
62682a34
SL
488 fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
489
85aaf69f 490 regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
1a4d82fc
JJ
491 writeback::resolve_type_vars_in_fn(&fcx, decl, body);
492 }
493 _ => ccx.tcx.sess.impossible_case(body.span,
494 "check_bare_fn: function type expected")
495 }
496}
497
498struct GatherLocalsVisitor<'a, 'tcx: 'a> {
499 fcx: &'a FnCtxt<'a, 'tcx>
500}
501
502impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
503 fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
504 match ty_opt {
505 None => {
506 // infer the variable's type
507 let var_ty = self.fcx.infcx().next_ty_var();
508 self.fcx.inh.locals.borrow_mut().insert(nid, var_ty);
509 var_ty
510 }
511 Some(typ) => {
512 // take type that the user specified
513 self.fcx.inh.locals.borrow_mut().insert(nid, typ);
514 typ
515 }
516 }
517 }
518}
519
85aaf69f 520impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
1a4d82fc 521 // Add explicitly-declared locals.
e9174d1e 522 fn visit_local(&mut self, local: &'tcx hir::Local) {
1a4d82fc
JJ
523 let o_ty = match local.ty {
524 Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
525 None => None
526 };
527 self.assign(local.span, local.id, o_ty);
62682a34
SL
528 debug!("Local variable {:?} is assigned type {}",
529 local.pat,
1a4d82fc 530 self.fcx.infcx().ty_to_string(
c34b1796 531 self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
1a4d82fc
JJ
532 visit::walk_local(self, local);
533 }
534
535 // Add pattern bindings.
e9174d1e
SL
536 fn visit_pat(&mut self, p: &'tcx hir::Pat) {
537 if let hir::PatIdent(_, ref path1, _) = p.node {
1a4d82fc
JJ
538 if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
539 let var_ty = self.assign(p.span, p.id, None);
540
541 self.fcx.require_type_is_sized(var_ty, p.span,
542 traits::VariableType(p.id));
543
62682a34 544 debug!("Pattern binding {} is assigned to {} with type {:?}",
c1a9b12d 545 path1.node,
1a4d82fc 546 self.fcx.infcx().ty_to_string(
c34b1796 547 self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
62682a34 548 var_ty);
1a4d82fc
JJ
549 }
550 }
551 visit::walk_pat(self, p);
552 }
553
e9174d1e 554 fn visit_block(&mut self, b: &'tcx hir::Block) {
1a4d82fc
JJ
555 // non-obvious: the `blk` variable maps to region lb, so
556 // we have to keep this up-to-date. This
557 // is... unfortunate. It'd be nice to not need this.
558 visit::walk_block(self, b);
559 }
560
561 // Since an expr occurs as part of the type fixed size arrays we
562 // need to record the type for that node
e9174d1e 563 fn visit_ty(&mut self, t: &'tcx hir::Ty) {
1a4d82fc 564 match t.node {
e9174d1e 565 hir::TyFixedLengthVec(ref ty, ref count_expr) => {
1a4d82fc 566 self.visit_ty(&**ty);
c34b1796 567 check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
1a4d82fc 568 }
b039eaaf
SL
569 hir::TyBareFn(ref function_declaration) => {
570 visit::walk_fn_decl_nopat(self, &function_declaration.decl);
571 walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
572 }
1a4d82fc
JJ
573 _ => visit::walk_ty(self, t)
574 }
575 }
576
577 // Don't descend into fns and items
e9174d1e
SL
578 fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx hir::FnDecl,
579 _: &'tcx hir::Block, _: Span, _: ast::NodeId) { }
580 fn visit_item(&mut self, _: &hir::Item) { }
1a4d82fc
JJ
581
582}
583
584/// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function
585/// body and returns the function context used for that purpose, since in the case of a fn item
586/// there is still a bit more to do.
587///
588/// * ...
589/// * inherited: other fields inherited from the enclosing fn (if any)
590fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
e9174d1e 591 unsafety: hir::Unsafety,
1a4d82fc
JJ
592 unsafety_id: ast::NodeId,
593 fn_sig: &ty::FnSig<'tcx>,
e9174d1e 594 decl: &'tcx hir::FnDecl,
1a4d82fc 595 fn_id: ast::NodeId,
e9174d1e 596 body: &'tcx hir::Block,
1a4d82fc
JJ
597 inherited: &'a Inherited<'a, 'tcx>)
598 -> FnCtxt<'a, 'tcx>
599{
600 let tcx = ccx.tcx;
601 let err_count_on_creation = tcx.sess.err_count();
602
c34b1796 603 let arg_tys = &fn_sig.inputs;
1a4d82fc
JJ
604 let ret_ty = fn_sig.output;
605
62682a34
SL
606 debug!("check_fn(arg_tys={:?}, ret_ty={:?}, fn_id={})",
607 arg_tys,
608 ret_ty,
1a4d82fc
JJ
609 fn_id);
610
611 // Create the function context. This is either derived from scratch or,
612 // in the case of function expressions, based on the outer context.
613 let fcx = FnCtxt {
614 body_id: body.id,
615 writeback_errors: Cell::new(false),
616 err_count_on_creation: err_count_on_creation,
617 ret_ty: ret_ty,
618 ps: RefCell::new(UnsafetyState::function(unsafety, unsafety_id)),
619 inh: inherited,
620 ccx: ccx
621 };
622
623 // Remember return type so that regionck can access it later.
624 let mut fn_sig_tys: Vec<Ty> =
625 arg_tys.iter()
85aaf69f 626 .cloned()
1a4d82fc
JJ
627 .collect();
628
629 if let ty::FnConverging(ret_ty) = ret_ty {
630 fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
e9174d1e 631 fn_sig_tys.push(ret_ty); // FIXME(#25759) just take implied bounds from the arguments
1a4d82fc
JJ
632 }
633
62682a34 634 debug!("fn-sig-map: fn_id={} fn_sig_tys={:?}",
1a4d82fc 635 fn_id,
62682a34 636 fn_sig_tys);
1a4d82fc
JJ
637
638 inherited.fn_sig_map.borrow_mut().insert(fn_id, fn_sig_tys);
639
640 {
641 let mut visit = GatherLocalsVisitor { fcx: &fcx, };
642
643 // Add formal parameters.
62682a34 644 for (arg_ty, input) in arg_tys.iter().zip(&decl.inputs) {
e9174d1e
SL
645 // The type of the argument must be well-formed.
646 //
647 // NB -- this is now checked in wfcheck, but that
648 // currently only results in warnings, so we issue an
649 // old-style WF obligation here so that we still get the
650 // errors that we used to get.
651 fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
652
1a4d82fc
JJ
653 // Create type variables for each argument.
654 pat_util::pat_bindings(
655 &tcx.def_map,
656 &*input.pat,
657 |_bm, pat_id, sp, _path| {
658 let var_ty = visit.assign(sp, pat_id, None);
659 fcx.require_type_is_sized(var_ty, sp,
660 traits::VariableType(pat_id));
661 });
662
663 // Check the pattern.
664 let pcx = pat_ctxt {
665 fcx: &fcx,
666 map: pat_id_map(&tcx.def_map, &*input.pat),
667 };
668 _match::check_pat(&pcx, &*input.pat, *arg_ty);
669 }
670
671 visit.visit_block(body);
672 }
673
674 check_block_with_expected(&fcx, body, match ret_ty {
675 ty::FnConverging(result_type) => ExpectHasType(result_type),
676 ty::FnDiverging => NoExpectation
677 });
678
62682a34
SL
679 for (input, arg) in decl.inputs.iter().zip(arg_tys) {
680 fcx.write_ty(input.id, arg);
1a4d82fc
JJ
681 }
682
683 fcx
684}
685
686pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
687 let tcx = ccx.tcx;
688
689 check_representable(tcx, span, id, "struct");
1a4d82fc 690
b039eaaf 691 if tcx.lookup_simd(ccx.tcx.map.local_def_id(id)) {
1a4d82fc
JJ
692 check_simd(tcx, span, id);
693 }
694}
695
e9174d1e 696pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
b039eaaf 697 debug!("check_item_type(it.id={}, it.name={})",
1a4d82fc 698 it.id,
b039eaaf 699 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
1a4d82fc 700 let _indenter = indenter();
1a4d82fc 701 match it.node {
9346a6ac 702 // Consts can play a role in type-checking, so they are included here.
e9174d1e
SL
703 hir::ItemStatic(_, _, ref e) |
704 hir::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
705 hir::ItemEnum(ref enum_definition, _) => {
1a4d82fc
JJ
706 check_enum_variants(ccx,
707 it.span,
c34b1796 708 &enum_definition.variants,
1a4d82fc
JJ
709 it.id);
710 }
e9174d1e
SL
711 hir::ItemFn(..) => {} // entirely within check_item_body
712 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
b039eaaf
SL
713 debug!("ItemImpl {} with id {}", it.name, it.id);
714 match ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(it.id)) {
1a4d82fc
JJ
715 Some(impl_trait_ref) => {
716 check_impl_items_against_trait(ccx,
717 it.span,
d9579d0f 718 &impl_trait_ref,
85aaf69f 719 impl_items);
1a4d82fc
JJ
720 }
721 None => { }
722 }
1a4d82fc 723 }
e9174d1e 724 hir::ItemTrait(_, ref generics, _, _) => {
85aaf69f 725 check_trait_on_unimplemented(ccx, generics, it);
1a4d82fc 726 }
e9174d1e 727 hir::ItemStruct(..) => {
1a4d82fc
JJ
728 check_struct(ccx, it.id, it.span);
729 }
e9174d1e 730 hir::ItemTy(ref t, ref generics) => {
c1a9b12d 731 let pty_ty = ccx.tcx.node_id_to_type(it.id);
1a4d82fc
JJ
732 check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
733 }
e9174d1e 734 hir::ItemForeignMod(ref m) => {
1a4d82fc 735 if m.abi == abi::RustIntrinsic {
85aaf69f 736 for item in &m.items {
e9174d1e
SL
737 intrinsic::check_intrinsic_type(ccx, &**item);
738 }
739 } else if m.abi == abi::PlatformIntrinsic {
740 for item in &m.items {
741 intrinsic::check_platform_intrinsic_type(ccx, &**item);
1a4d82fc
JJ
742 }
743 } else {
85aaf69f 744 for item in &m.items {
b039eaaf 745 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
1a4d82fc
JJ
746 if !pty.generics.types.is_empty() {
747 span_err!(ccx.tcx.sess, item.span, E0044,
748 "foreign items may not have type parameters");
e9174d1e
SL
749 span_help!(ccx.tcx.sess, item.span,
750 "consider using specialization instead of \
751 type parameters");
1a4d82fc
JJ
752 }
753
e9174d1e 754 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
c1a9b12d 755 require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
1a4d82fc
JJ
756 }
757 }
758 }
759 }
760 _ => {/* nothing to do */ }
761 }
762}
763
e9174d1e 764pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
b039eaaf 765 debug!("check_item_body(it.id={}, it.name={})",
9346a6ac 766 it.id,
b039eaaf 767 ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id)));
9346a6ac
AL
768 let _indenter = indenter();
769 match it.node {
e9174d1e 770 hir::ItemFn(ref decl, _, _, _, _, ref body) => {
b039eaaf 771 let fn_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
9346a6ac
AL
772 let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
773 check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
774 }
e9174d1e 775 hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
b039eaaf 776 debug!("ItemImpl {} with id {}", it.name, it.id);
9346a6ac 777
b039eaaf 778 let impl_pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(it.id));
9346a6ac
AL
779
780 for impl_item in impl_items {
781 match impl_item.node {
e9174d1e 782 hir::ConstImplItem(_, ref expr) => {
d9579d0f
AL
783 check_const(ccx, impl_item.span, &*expr, impl_item.id)
784 }
e9174d1e 785 hir::MethodImplItem(ref sig, ref body) => {
9346a6ac
AL
786 check_method_body(ccx, &impl_pty.generics, sig, body,
787 impl_item.id, impl_item.span);
788 }
e9174d1e 789 hir::TypeImplItem(_) => {
9346a6ac
AL
790 // Nothing to do here.
791 }
792 }
793 }
794 }
e9174d1e 795 hir::ItemTrait(_, _, _, ref trait_items) => {
b039eaaf 796 let trait_def = ccx.tcx.lookup_trait_def(ccx.tcx.map.local_def_id(it.id));
9346a6ac
AL
797 for trait_item in trait_items {
798 match trait_item.node {
e9174d1e 799 hir::ConstTraitItem(_, Some(ref expr)) => {
d9579d0f 800 check_const(ccx, trait_item.span, &*expr, trait_item.id)
9346a6ac 801 }
e9174d1e 802 hir::MethodTraitItem(ref sig, Some(ref body)) => {
62682a34
SL
803 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
804
9346a6ac
AL
805 check_method_body(ccx, &trait_def.generics, sig, body,
806 trait_item.id, trait_item.span);
807 }
e9174d1e 808 hir::MethodTraitItem(ref sig, None) => {
62682a34
SL
809 check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
810 }
e9174d1e
SL
811 hir::ConstTraitItem(_, None) |
812 hir::TypeTraitItem(..) => {
9346a6ac
AL
813 // Nothing to do.
814 }
815 }
816 }
817 }
818 _ => {/* nothing to do */ }
819 }
820}
821
62682a34
SL
822fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
823 span: Span,
e9174d1e 824 constness: hir::Constness)
62682a34
SL
825{
826 match constness {
e9174d1e 827 hir::Constness::NotConst => {
62682a34
SL
828 // good
829 }
e9174d1e 830 hir::Constness::Const => {
62682a34
SL
831 span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
832 }
833 }
834}
835
85aaf69f 836fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
e9174d1e
SL
837 generics: &hir::Generics,
838 item: &hir::Item) {
85aaf69f
SL
839 if let Some(ref attr) = item.attrs.iter().find(|a| {
840 a.check_name("rustc_on_unimplemented")
841 }) {
842 if let Some(ref istring) = attr.value_str() {
843 let parser = Parser::new(&istring);
844 let types = &*generics.ty_params;
845 for token in parser {
846 match token {
847 Piece::String(_) => (), // Normal string, no need to check it
848 Piece::NextArgument(a) => match a.position {
849 // `{Self}` is allowed
850 Position::ArgumentNamed(s) if s == "Self" => (),
851 // So is `{A}` if A is a type parameter
852 Position::ArgumentNamed(s) => match types.iter().find(|t| {
b039eaaf 853 t.name.as_str() == s
85aaf69f
SL
854 }) {
855 Some(_) => (),
856 None => {
857 span_err!(ccx.tcx.sess, attr.span, E0230,
858 "there is no type parameter \
859 {} on trait {}",
b039eaaf 860 s, item.name);
85aaf69f
SL
861 }
862 },
863 // `{:1}` and `{}` are not to be used
864 Position::ArgumentIs(_) | Position::ArgumentNext => {
865 span_err!(ccx.tcx.sess, attr.span, E0231,
866 "only named substitution \
867 parameters are allowed");
868 }
869 }
870 }
871 }
872 } else {
873 span_err!(ccx.tcx.sess, attr.span, E0232,
874 "this attribute must have a value, \
875 eg `#[rustc_on_unimplemented = \"foo\"]`")
876 }
877 }
878}
879
1a4d82fc
JJ
880/// Type checks a method body.
881///
882/// # Parameters
883///
884/// * `item_generics`: generics defined on the impl/trait that contains
885/// the method
886/// * `self_bound`: bound for the `Self` type parameter, if any
887/// * `method`: the method definition
888fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
889 item_generics: &ty::Generics<'tcx>,
e9174d1e
SL
890 sig: &'tcx hir::MethodSig,
891 body: &'tcx hir::Block,
c34b1796 892 id: ast::NodeId, span: Span) {
62682a34
SL
893 debug!("check_method_body(item_generics={:?}, id={})",
894 item_generics, id);
c34b1796
AL
895 let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
896
c1a9b12d 897 let fty = ccx.tcx.node_id_to_type(id);
62682a34 898 debug!("check_method_body: fty={:?}", fty);
1a4d82fc 899
c34b1796 900 check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
1a4d82fc
JJ
901}
902
903fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
904 impl_span: Span,
905 impl_trait_ref: &ty::TraitRef<'tcx>,
e9174d1e 906 impl_items: &[P<hir::ImplItem>]) {
1a4d82fc
JJ
907 // Locate trait methods
908 let tcx = ccx.tcx;
c1a9b12d
SL
909 let trait_items = tcx.trait_items(impl_trait_ref.def_id);
910 let mut overridden_associated_type = None;
1a4d82fc
JJ
911
912 // Check existing impl methods to see if they are both present in trait
913 // and compatible with trait signature
85aaf69f 914 for impl_item in impl_items {
b039eaaf 915 let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
c1a9b12d
SL
916 let ty_trait_item = trait_items.iter()
917 .find(|ac| ac.name() == ty_impl_item.name())
918 .unwrap_or_else(|| {
919 // This is checked by resolve
920 tcx.sess.span_bug(impl_item.span,
921 &format!("impl-item `{}` is not a member of `{:?}`",
922 ty_impl_item.name(),
923 impl_trait_ref));
924 });
c34b1796 925 match impl_item.node {
e9174d1e 926 hir::ConstImplItem(..) => {
c1a9b12d
SL
927 let impl_const = match ty_impl_item {
928 ty::ConstTraitItem(ref cti) => cti,
929 _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
930 };
d9579d0f
AL
931
932 // Find associated const definition.
c1a9b12d
SL
933 if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
934 compare_const_impl(ccx.tcx,
935 &impl_const,
936 impl_item.span,
937 trait_const,
938 &*impl_trait_ref);
939 } else {
940 span_err!(tcx.sess, impl_item.span, E0323,
941 "item `{}` is an associated const, \
942 which doesn't match its trait `{:?}`",
943 impl_const.name,
944 impl_trait_ref)
d9579d0f
AL
945 }
946 }
e9174d1e 947 hir::MethodImplItem(ref sig, ref body) => {
62682a34
SL
948 check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
949
c1a9b12d
SL
950 let impl_method = match ty_impl_item {
951 ty::MethodTraitItem(ref mti) => mti,
952 _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
953 };
954
955 if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
956 compare_impl_method(ccx.tcx,
957 &impl_method,
958 impl_item.span,
959 body.id,
960 &trait_method,
961 &impl_trait_ref);
962 } else {
963 span_err!(tcx.sess, impl_item.span, E0324,
964 "item `{}` is an associated method, \
965 which doesn't match its trait `{:?}`",
966 impl_method.name,
967 impl_trait_ref)
1a4d82fc
JJ
968 }
969 }
e9174d1e 970 hir::TypeImplItem(_) => {
c1a9b12d
SL
971 let impl_type = match ty_impl_item {
972 ty::TypeTraitItem(ref tti) => tti,
973 _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
974 };
975
976 if let &ty::TypeTraitItem(ref at) = ty_trait_item {
977 if let Some(_) = at.ty {
978 overridden_associated_type = Some(impl_item);
1a4d82fc 979 }
c1a9b12d
SL
980 } else {
981 span_err!(tcx.sess, impl_item.span, E0325,
982 "item `{}` is an associated type, \
983 which doesn't match its trait `{:?}`",
984 impl_type.name,
985 impl_trait_ref)
1a4d82fc
JJ
986 }
987 }
988 }
989 }
990
991 // Check for missing items from trait
c1a9b12d 992 let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
62682a34 993 let mut missing_items = Vec::new();
c1a9b12d
SL
994 let mut invalidated_items = Vec::new();
995 let associated_type_overridden = overridden_associated_type.is_some();
62682a34 996 for trait_item in trait_items.iter() {
1a4d82fc 997 match *trait_item {
d9579d0f
AL
998 ty::ConstTraitItem(ref associated_const) => {
999 let is_implemented = impl_items.iter().any(|ii| {
1000 match ii.node {
e9174d1e 1001 hir::ConstImplItem(..) => {
b039eaaf 1002 ii.name == associated_const.name
d9579d0f
AL
1003 }
1004 _ => false,
1005 }
1006 });
b039eaaf
SL
1007 let is_provided = associated_const.has_value;
1008
c1a9b12d
SL
1009 if !is_implemented {
1010 if !is_provided {
1011 missing_items.push(associated_const.name);
1012 } else if associated_type_overridden {
1013 invalidated_items.push(associated_const.name);
1014 }
d9579d0f
AL
1015 }
1016 }
1a4d82fc
JJ
1017 ty::MethodTraitItem(ref trait_method) => {
1018 let is_implemented =
1019 impl_items.iter().any(|ii| {
c34b1796 1020 match ii.node {
e9174d1e 1021 hir::MethodImplItem(..) => {
b039eaaf 1022 ii.name == trait_method.name
1a4d82fc 1023 }
d9579d0f 1024 _ => false,
1a4d82fc
JJ
1025 }
1026 });
1027 let is_provided =
1028 provided_methods.iter().any(|m| m.name == trait_method.name);
c1a9b12d
SL
1029 if !is_implemented {
1030 if !is_provided {
1031 missing_items.push(trait_method.name);
1032 } else if associated_type_overridden {
1033 invalidated_items.push(trait_method.name);
1034 }
1a4d82fc
JJ
1035 }
1036 }
1037 ty::TypeTraitItem(ref associated_type) => {
1038 let is_implemented = impl_items.iter().any(|ii| {
c34b1796 1039 match ii.node {
e9174d1e 1040 hir::TypeImplItem(_) => {
b039eaaf 1041 ii.name == associated_type.name
1a4d82fc 1042 }
d9579d0f 1043 _ => false,
1a4d82fc
JJ
1044 }
1045 });
62682a34 1046 let is_provided = associated_type.ty.is_some();
c1a9b12d
SL
1047 if !is_implemented {
1048 if !is_provided {
1049 missing_items.push(associated_type.name);
1050 } else if associated_type_overridden {
1051 invalidated_items.push(associated_type.name);
1052 }
1a4d82fc
JJ
1053 }
1054 }
1055 }
1056 }
1057
62682a34 1058 if !missing_items.is_empty() {
1a4d82fc 1059 span_err!(tcx.sess, impl_span, E0046,
c1a9b12d
SL
1060 "not all trait items implemented, missing: `{}`",
1061 missing_items.iter()
1062 .map(|name| name.to_string())
1063 .collect::<Vec<_>>().join("`, `"))
1064 }
1065
1066 if !invalidated_items.is_empty() {
1067 let invalidator = overridden_associated_type.unwrap();
1068 span_err!(tcx.sess, invalidator.span, E0399,
1069 "the following trait items need to be reimplemented \
1070 as `{}` was overridden: `{}`",
b039eaaf 1071 invalidator.name,
c1a9b12d
SL
1072 invalidated_items.iter()
1073 .map(|name| name.to_string())
1074 .collect::<Vec<_>>().join("`, `"))
1a4d82fc
JJ
1075 }
1076}
1077
85aaf69f
SL
1078fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
1079 span: Span,
1080 t_span: Span,
1081 e_span: Span,
62682a34
SL
1082 t_cast: Ty<'tcx>,
1083 t_expr: Ty<'tcx>,
85aaf69f 1084 id: ast::NodeId) {
62682a34 1085 let tstr = fcx.infcx().ty_to_string(t_cast);
85aaf69f
SL
1086 fcx.type_error_message(span, |actual| {
1087 format!("cast to unsized type: `{}` as `{}`", actual, tstr)
62682a34
SL
1088 }, t_expr, None);
1089 match t_expr.sty {
c1a9b12d 1090 ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
85aaf69f 1091 let mtstr = match mt {
e9174d1e
SL
1092 hir::MutMutable => "mut ",
1093 hir::MutImmutable => ""
85aaf69f 1094 };
c1a9b12d 1095 if t_cast.is_trait() {
d9579d0f
AL
1096 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1097 Ok(s) => {
1098 fcx.tcx().sess.span_suggestion(t_span,
1099 "try casting to a reference instead:",
1100 format!("&{}{}", mtstr, s));
1101 },
1102 Err(_) =>
1103 span_help!(fcx.tcx().sess, t_span,
1104 "did you mean `&{}{}`?", mtstr, tstr),
1105 }
85aaf69f
SL
1106 } else {
1107 span_help!(fcx.tcx().sess, span,
1108 "consider using an implicit coercion to `&{}{}` instead",
1109 mtstr, tstr);
1a4d82fc
JJ
1110 }
1111 }
62682a34 1112 ty::TyBox(..) => {
d9579d0f
AL
1113 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
1114 Ok(s) => {
1115 fcx.tcx().sess.span_suggestion(t_span,
1116 "try casting to a `Box` instead:",
1117 format!("Box<{}>", s));
1118 },
1119 Err(_) =>
1120 span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
1121 }
1a4d82fc 1122 }
85aaf69f
SL
1123 _ => {
1124 span_help!(fcx.tcx().sess, e_span,
1125 "consider using a box or reference as appropriate");
1a4d82fc 1126 }
1a4d82fc 1127 }
85aaf69f 1128 fcx.write_error(id);
1a4d82fc
JJ
1129}
1130
1a4d82fc 1131
1a4d82fc
JJ
1132impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
1133 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1134
e9174d1e 1135 fn get_item_type_scheme(&self, _: Span, id: DefId)
c34b1796
AL
1136 -> Result<ty::TypeScheme<'tcx>, ErrorReported>
1137 {
c1a9b12d 1138 Ok(self.tcx().lookup_item_type(id))
1a4d82fc
JJ
1139 }
1140
e9174d1e 1141 fn get_trait_def(&self, _: Span, id: DefId)
d9579d0f 1142 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
c34b1796 1143 {
c1a9b12d 1144 Ok(self.tcx().lookup_trait_def(id))
c34b1796
AL
1145 }
1146
e9174d1e 1147 fn ensure_super_predicates(&self, _: Span, _: DefId) -> Result<(), ErrorReported> {
c34b1796
AL
1148 // all super predicates are ensured during collect pass
1149 Ok(())
1a4d82fc
JJ
1150 }
1151
1152 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
c1a9b12d 1153 Some(&self.inh.infcx.parameter_environment.free_substs)
1a4d82fc
JJ
1154 }
1155
c34b1796
AL
1156 fn get_type_parameter_bounds(&self,
1157 _: Span,
1158 node_id: ast::NodeId)
1159 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
1160 {
1161 let def = self.tcx().type_parameter_def(node_id);
c1a9b12d
SL
1162 let r = self.inh.infcx.parameter_environment
1163 .caller_bounds
c34b1796
AL
1164 .iter()
1165 .filter_map(|predicate| {
1166 match *predicate {
1167 ty::Predicate::Trait(ref data) => {
1168 if data.0.self_ty().is_param(def.space, def.index) {
1169 Some(data.to_poly_trait_ref())
1170 } else {
1171 None
1172 }
1173 }
1174 _ => {
1175 None
1176 }
1177 }
1178 })
1179 .collect();
1180 Ok(r)
1181 }
1182
1183 fn trait_defines_associated_type_named(&self,
e9174d1e 1184 trait_def_id: DefId,
c34b1796
AL
1185 assoc_name: ast::Name)
1186 -> bool
1187 {
c1a9b12d 1188 let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
c34b1796
AL
1189 trait_def.associated_type_names.contains(&assoc_name)
1190 }
1191
c1a9b12d
SL
1192 fn ty_infer(&self,
1193 ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
1194 substs: Option<&mut subst::Substs<'tcx>>,
1195 space: Option<subst::ParamSpace>,
1196 span: Span) -> Ty<'tcx> {
1197 // Grab the default doing subsitution
1198 let default = ty_param_def.and_then(|def| {
1199 def.default.map(|ty| type_variable::Default {
1200 ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
1201 origin_span: span,
1202 def_id: def.default_def_id
1203 })
1204 });
1205
1206 let ty_var = self.infcx().next_ty_var_with_default(default);
1207
1208 // Finally we add the type variable to the substs
1209 match substs {
1210 None => ty_var,
1211 Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
1212 }
1a4d82fc
JJ
1213 }
1214
1215 fn projected_ty_from_poly_trait_ref(&self,
1216 span: Span,
1217 poly_trait_ref: ty::PolyTraitRef<'tcx>,
1218 item_name: ast::Name)
1219 -> Ty<'tcx>
1220 {
1221 let (trait_ref, _) =
1222 self.infcx().replace_late_bound_regions_with_fresh_var(
1223 span,
1224 infer::LateBoundRegionConversionTime::AssocTypeProjection(item_name),
1225 &poly_trait_ref);
1226
1227 self.normalize_associated_type(span, trait_ref, item_name)
1228 }
1229
1230 fn projected_ty(&self,
1231 span: Span,
d9579d0f 1232 trait_ref: ty::TraitRef<'tcx>,
1a4d82fc
JJ
1233 item_name: ast::Name)
1234 -> Ty<'tcx>
1235 {
1236 self.normalize_associated_type(span, trait_ref, item_name)
1237 }
1238}
1239
1240impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1241 fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
1242
1243 pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
1244 &self.inh.infcx
1245 }
1246
1247 pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
c1a9b12d 1248 &self.inh.infcx.parameter_environment
1a4d82fc
JJ
1249 }
1250
1251 pub fn sess(&self) -> &Session {
1252 &self.tcx().sess
1253 }
1254
c34b1796 1255 pub fn err_count_since_creation(&self) -> usize {
1a4d82fc
JJ
1256 self.ccx.tcx.sess.err_count() - self.err_count_on_creation
1257 }
1258
85aaf69f
SL
1259 /// Resolves type variables in `ty` if possible. Unlike the infcx
1260 /// version, this version will also select obligations if it seems
1261 /// useful, in an effort to get more type information.
1262 fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
62682a34 1263 debug!("resolve_type_vars_if_possible(ty={:?})", ty);
c34b1796 1264
c1a9b12d
SL
1265 // No TyInfer()? Nothing needs doing.
1266 if !ty.has_infer_types() {
62682a34 1267 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
85aaf69f
SL
1268 return ty;
1269 }
1270
1271 // If `ty` is a type variable, see whether we already know what it is.
1272 ty = self.infcx().resolve_type_vars_if_possible(&ty);
c1a9b12d 1273 if !ty.has_infer_types() {
62682a34 1274 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
85aaf69f
SL
1275 return ty;
1276 }
1277
1278 // If not, try resolving any new fcx obligations that have cropped up.
d9579d0f 1279 self.select_new_obligations();
85aaf69f 1280 ty = self.infcx().resolve_type_vars_if_possible(&ty);
c1a9b12d 1281 if !ty.has_infer_types() {
62682a34 1282 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
85aaf69f
SL
1283 return ty;
1284 }
1285
1286 // If not, try resolving *all* pending obligations as much as
1287 // possible. This can help substantially when there are
1288 // indirect dependencies that don't seem worth tracking
1289 // precisely.
d9579d0f 1290 self.select_obligations_where_possible();
c34b1796
AL
1291 ty = self.infcx().resolve_type_vars_if_possible(&ty);
1292
62682a34 1293 debug!("resolve_type_vars_if_possible: ty={:?}", ty);
c34b1796 1294 ty
85aaf69f
SL
1295 }
1296
85aaf69f 1297 fn record_deferred_call_resolution(&self,
e9174d1e 1298 closure_def_id: DefId,
85aaf69f
SL
1299 r: DeferredCallResolutionHandler<'tcx>) {
1300 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
c34b1796 1301 deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
85aaf69f
SL
1302 }
1303
1304 fn remove_deferred_call_resolutions(&self,
e9174d1e 1305 closure_def_id: DefId)
85aaf69f
SL
1306 -> Vec<DeferredCallResolutionHandler<'tcx>>
1307 {
1308 let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
1309 deferred_call_resolutions.remove(&closure_def_id).unwrap_or(Vec::new())
1310 }
1311
1a4d82fc 1312 pub fn tag(&self) -> String {
c34b1796
AL
1313 let self_ptr: *const FnCtxt = self;
1314 format!("{:?}", self_ptr)
1a4d82fc
JJ
1315 }
1316
1317 pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
1318 match self.inh.locals.borrow().get(&nid) {
1319 Some(&t) => t,
1320 None => {
b039eaaf
SL
1321 span_err!(self.tcx().sess, span, E0513,
1322 "no type for local variable {}",
1323 nid);
c34b1796 1324 self.tcx().types.err
1a4d82fc
JJ
1325 }
1326 }
1327 }
1328
1a4d82fc
JJ
1329 #[inline]
1330 pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
62682a34
SL
1331 debug!("write_ty({}, {:?}) in fcx {}",
1332 node_id, ty, self.tag());
c1a9b12d 1333 self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
1a4d82fc
JJ
1334 }
1335
1a4d82fc
JJ
1336 pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
1337 if !substs.substs.is_noop() {
62682a34 1338 debug!("write_substs({}, {:?}) in fcx {}",
1a4d82fc 1339 node_id,
62682a34 1340 substs,
1a4d82fc
JJ
1341 self.tag());
1342
c1a9b12d 1343 self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
1a4d82fc
JJ
1344 }
1345 }
1346
1347 pub fn write_autoderef_adjustment(&self,
1348 node_id: ast::NodeId,
c34b1796 1349 derefs: usize) {
1a4d82fc
JJ
1350 self.write_adjustment(
1351 node_id,
e9174d1e 1352 adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
1a4d82fc 1353 autoderefs: derefs,
9346a6ac
AL
1354 autoref: None,
1355 unsize: None
1356 })
1a4d82fc
JJ
1357 );
1358 }
1359
1360 pub fn write_adjustment(&self,
1361 node_id: ast::NodeId,
e9174d1e 1362 adj: adjustment::AutoAdjustment<'tcx>) {
62682a34 1363 debug!("write_adjustment(node_id={}, adj={:?})", node_id, adj);
1a4d82fc
JJ
1364
1365 if adj.is_identity() {
1366 return;
1367 }
1368
c1a9b12d 1369 self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
1a4d82fc
JJ
1370 }
1371
1372 /// Basically whenever we are converting from a type scheme into
1373 /// the fn body space, we always want to normalize associated
1374 /// types as well. This function combines the two.
1375 fn instantiate_type_scheme<T>(&self,
1376 span: Span,
1377 substs: &Substs<'tcx>,
1378 value: &T)
1379 -> T
c1a9b12d 1380 where T : TypeFoldable<'tcx> + HasTypeFlags
1a4d82fc
JJ
1381 {
1382 let value = value.subst(self.tcx(), substs);
1383 let result = self.normalize_associated_types_in(span, &value);
62682a34
SL
1384 debug!("instantiate_type_scheme(value={:?}, substs={:?}) = {:?}",
1385 value,
1386 substs,
1387 result);
1a4d82fc
JJ
1388 result
1389 }
1390
1391 /// As `instantiate_type_scheme`, but for the bounds found in a
1392 /// generic type scheme.
1393 fn instantiate_bounds(&self,
1394 span: Span,
1395 substs: &Substs<'tcx>,
85aaf69f
SL
1396 bounds: &ty::GenericPredicates<'tcx>)
1397 -> ty::InstantiatedPredicates<'tcx>
1a4d82fc 1398 {
85aaf69f
SL
1399 ty::InstantiatedPredicates {
1400 predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
1a4d82fc
JJ
1401 }
1402 }
1403
1404
1405 fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
c1a9b12d 1406 where T : TypeFoldable<'tcx> + HasTypeFlags
1a4d82fc 1407 {
c1a9b12d 1408 self.inh.normalize_associated_types_in(span, self.body_id, value)
1a4d82fc
JJ
1409 }
1410
1411 fn normalize_associated_type(&self,
1412 span: Span,
d9579d0f 1413 trait_ref: ty::TraitRef<'tcx>,
1a4d82fc
JJ
1414 item_name: ast::Name)
1415 -> Ty<'tcx>
1416 {
1417 let cause = traits::ObligationCause::new(span,
1418 self.body_id,
1419 traits::ObligationCauseCode::MiscObligation);
c1a9b12d
SL
1420 self.inh
1421 .infcx
1422 .fulfillment_cx
1a4d82fc
JJ
1423 .borrow_mut()
1424 .normalize_projection_type(self.infcx(),
1a4d82fc
JJ
1425 ty::ProjectionTy {
1426 trait_ref: trait_ref,
1427 item_name: item_name,
1428 },
1429 cause)
1430 }
1431
e9174d1e
SL
1432 /// Instantiates the type in `did` with the generics in `path` and returns
1433 /// it (registering the necessary trait obligations along the way).
1a4d82fc 1434 ///
e9174d1e
SL
1435 /// Note that this function is only intended to be used with type-paths,
1436 /// not with value-paths.
1a4d82fc 1437 pub fn instantiate_type(&self,
e9174d1e
SL
1438 did: DefId,
1439 path: &hir::Path)
1440 -> Ty<'tcx>
1a4d82fc 1441 {
e9174d1e 1442 debug!("instantiate_type(did={:?}, path={:?})", did, path);
1a4d82fc 1443 let type_scheme =
e9174d1e 1444 self.tcx().lookup_item_type(did);
85aaf69f 1445 let type_predicates =
e9174d1e
SL
1446 self.tcx().lookup_predicates(did);
1447 let substs = astconv::ast_path_substs_for_ty(self, self,
1448 path.span,
1449 PathParamMode::Optional,
1450 &type_scheme.generics,
1451 path.segments.last().unwrap());
1452 debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs);
1a4d82fc 1453 let bounds =
e9174d1e 1454 self.instantiate_bounds(path.span, &substs, &type_predicates);
1a4d82fc
JJ
1455 self.add_obligations_for_parameters(
1456 traits::ObligationCause::new(
e9174d1e 1457 path.span,
1a4d82fc 1458 self.body_id,
e9174d1e 1459 traits::ItemObligation(did)),
1a4d82fc 1460 &bounds);
1a4d82fc 1461
e9174d1e 1462 self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty)
1a4d82fc
JJ
1463 }
1464
e9174d1e
SL
1465 /// Return the dict-like variant corresponding to a given `Def`.
1466 pub fn def_struct_variant(&self,
b039eaaf
SL
1467 def: def::Def,
1468 span: Span)
e9174d1e 1469 -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
1a4d82fc 1470 {
e9174d1e
SL
1471 let (adt, variant) = match def {
1472 def::DefVariant(enum_id, variant_id, true) => {
1473 let adt = self.tcx().lookup_adt_def(enum_id);
1474 (adt, adt.variant_with_id(variant_id))
1475 }
1476 def::DefTy(did, _) | def::DefStruct(did) => {
1477 let typ = self.tcx().lookup_item_type(did);
1478 if let ty::TyStruct(adt, _) = typ.ty.sty {
1479 (adt, adt.struct_variant())
1480 } else {
1481 return None;
1482 }
1483 }
1484 _ => return None
1485 };
1a4d82fc 1486
b039eaaf
SL
1487 let var_kind = variant.kind();
1488 if var_kind == ty::VariantKind::Struct {
e9174d1e 1489 Some((adt, variant))
b039eaaf
SL
1490 } else if var_kind == ty::VariantKind::Unit {
1491 if !self.tcx().sess.features.borrow().braced_empty_structs {
1492 self.tcx().sess.span_err(span, "empty structs and enum variants \
1493 with braces are unstable");
1494 fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
1495 the crate features to enable");
1496 }
1a4d82fc 1497
b039eaaf
SL
1498 Some((adt, variant))
1499 } else {
1500 None
1501 }
1502 }
e9174d1e 1503
1a4d82fc 1504 pub fn write_nil(&self, node_id: ast::NodeId) {
c1a9b12d 1505 self.write_ty(node_id, self.tcx().mk_nil());
1a4d82fc
JJ
1506 }
1507 pub fn write_error(&self, node_id: ast::NodeId) {
1508 self.write_ty(node_id, self.tcx().types.err);
1509 }
1510
1511 pub fn require_type_meets(&self,
1512 ty: Ty<'tcx>,
1513 span: Span,
1514 code: traits::ObligationCauseCode<'tcx>,
1515 bound: ty::BuiltinBound)
1516 {
1517 self.register_builtin_bound(
1518 ty,
1519 bound,
1520 traits::ObligationCause::new(span, self.body_id, code));
1521 }
1522
1523 pub fn require_type_is_sized(&self,
1524 ty: Ty<'tcx>,
1525 span: Span,
1526 code: traits::ObligationCauseCode<'tcx>)
1527 {
1528 self.require_type_meets(ty, span, code, ty::BoundSized);
1529 }
1530
1531 pub fn require_expr_have_sized_type(&self,
e9174d1e 1532 expr: &hir::Expr,
1a4d82fc
JJ
1533 code: traits::ObligationCauseCode<'tcx>)
1534 {
1535 self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
1536 }
1537
1538 pub fn type_is_known_to_be_sized(&self,
1539 ty: Ty<'tcx>,
1540 span: Span)
1541 -> bool
1542 {
1543 traits::type_known_to_meet_builtin_bound(self.infcx(),
1a4d82fc
JJ
1544 ty,
1545 ty::BoundSized,
1546 span)
1547 }
1548
1549 pub fn register_builtin_bound(&self,
1550 ty: Ty<'tcx>,
1551 builtin_bound: ty::BuiltinBound,
1552 cause: traits::ObligationCause<'tcx>)
1553 {
c1a9b12d 1554 self.inh.infcx.fulfillment_cx.borrow_mut()
1a4d82fc
JJ
1555 .register_builtin_bound(self.infcx(), ty, builtin_bound, cause);
1556 }
1557
1558 pub fn register_predicate(&self,
1559 obligation: traits::PredicateObligation<'tcx>)
1560 {
62682a34
SL
1561 debug!("register_predicate({:?})",
1562 obligation);
c1a9b12d 1563 self.inh.infcx.fulfillment_cx
1a4d82fc
JJ
1564 .borrow_mut()
1565 .register_predicate_obligation(self.infcx(), obligation);
1566 }
1567
e9174d1e 1568 pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
1a4d82fc 1569 let t = ast_ty_to_ty(self, self, ast_t);
b039eaaf 1570 self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
1a4d82fc
JJ
1571 t
1572 }
1573
e9174d1e 1574 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
c1a9b12d 1575 match self.inh.tables.borrow().node_types.get(&ex.id) {
1a4d82fc
JJ
1576 Some(&t) => t,
1577 None => {
1578 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
c34b1796 1579 self.tag()));
1a4d82fc
JJ
1580 }
1581 }
1582 }
1583
1584 /// Apply `adjustment` to the type of `expr`
1585 pub fn adjust_expr_ty(&self,
e9174d1e
SL
1586 expr: &hir::Expr,
1587 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
1a4d82fc
JJ
1588 -> Ty<'tcx>
1589 {
1590 let raw_ty = self.expr_ty(expr);
1591 let raw_ty = self.infcx().shallow_resolve(raw_ty);
85aaf69f 1592 let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
c1a9b12d
SL
1593 raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
1594 self.inh.tables.borrow().method_map.get(&method_call)
1595 .map(|method| resolve_ty(method.ty))
1596 })
1a4d82fc
JJ
1597 }
1598
1599 pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
c1a9b12d 1600 match self.inh.tables.borrow().node_types.get(&id) {
1a4d82fc 1601 Some(&t) => t,
85aaf69f 1602 None if self.err_count_since_creation() != 0 => self.tcx().types.err,
1a4d82fc
JJ
1603 None => {
1604 self.tcx().sess.bug(
1605 &format!("no type for node {}: {} in fcx {}",
1606 id, self.tcx().map.node_to_string(id),
c34b1796 1607 self.tag()));
1a4d82fc
JJ
1608 }
1609 }
1610 }
1611
1612 pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
c1a9b12d
SL
1613 // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
1614 // it changes when we upgrade the snapshot compiler
1615 fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
1616 -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
1617 &tables.item_substs
1618 }
1619
1620 Ref::map(self.inh.tables.borrow(), project_item_susbts)
1a4d82fc
JJ
1621 }
1622
1623 pub fn opt_node_ty_substs<F>(&self,
1624 id: ast::NodeId,
1625 f: F) where
1626 F: FnOnce(&ty::ItemSubsts<'tcx>),
1627 {
c1a9b12d 1628 match self.inh.tables.borrow().item_substs.get(&id) {
1a4d82fc
JJ
1629 Some(s) => { f(s) }
1630 None => { }
1631 }
1632 }
1633
1634 pub fn mk_subty(&self,
1635 a_is_expected: bool,
1636 origin: infer::TypeOrigin,
1637 sub: Ty<'tcx>,
1638 sup: Ty<'tcx>)
e9174d1e 1639 -> Result<(), TypeError<'tcx>> {
1a4d82fc
JJ
1640 infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1641 }
1642
1a4d82fc
JJ
1643 pub fn mk_eqty(&self,
1644 a_is_expected: bool,
1645 origin: infer::TypeOrigin,
1646 sub: Ty<'tcx>,
1647 sup: Ty<'tcx>)
e9174d1e 1648 -> Result<(), TypeError<'tcx>> {
1a4d82fc
JJ
1649 infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1650 }
1651
1652 pub fn mk_subr(&self,
1653 origin: infer::SubregionOrigin<'tcx>,
1654 sub: ty::Region,
1655 sup: ty::Region) {
1656 infer::mk_subr(self.infcx(), origin, sub, sup)
1657 }
1658
1659 pub fn type_error_message<M>(&self,
1660 sp: Span,
1661 mk_msg: M,
1662 actual_ty: Ty<'tcx>,
e9174d1e 1663 err: Option<&TypeError<'tcx>>) where
1a4d82fc
JJ
1664 M: FnOnce(String) -> String,
1665 {
1666 self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
1667 }
1668
1669 pub fn report_mismatched_types(&self,
1670 sp: Span,
1671 e: Ty<'tcx>,
1672 a: Ty<'tcx>,
e9174d1e 1673 err: &TypeError<'tcx>) {
1a4d82fc
JJ
1674 self.infcx().report_mismatched_types(sp, e, a, err)
1675 }
1676
1677 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1678 /// outlive the region `r`.
1679 pub fn register_region_obligation(&self,
1680 ty: Ty<'tcx>,
1681 region: ty::Region,
1682 cause: traits::ObligationCause<'tcx>)
1683 {
c1a9b12d 1684 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
62682a34 1685 fulfillment_cx.register_region_obligation(ty, region, cause);
1a4d82fc
JJ
1686 }
1687
e9174d1e
SL
1688 /// Registers an obligation for checking later, during regionck, that the type `ty` must
1689 /// outlive the region `r`.
1690 pub fn register_wf_obligation(&self,
1691 ty: Ty<'tcx>,
1692 span: Span,
1693 code: traits::ObligationCauseCode<'tcx>)
1694 {
1695 // WF obligations never themselves fail, so no real need to give a detailed cause:
1696 let cause = traits::ObligationCause::new(span, self.body_id, code);
1697 self.register_predicate(traits::Obligation::new(cause, ty::Predicate::WellFormed(ty)));
1698 }
1699
1700 pub fn register_old_wf_obligation(&self,
1701 ty: Ty<'tcx>,
1702 span: Span,
1703 code: traits::ObligationCauseCode<'tcx>)
1704 {
1705 // Registers an "old-style" WF obligation that uses the
1706 // implicator code. This is basically a buggy version of
1707 // `register_wf_obligation` that is being kept around
1708 // temporarily just to help with phasing in the newer rules.
1709 //
1710 // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
1711 let cause = traits::ObligationCause::new(span, self.body_id, code);
1712 self.register_region_obligation(ty, ty::ReEmpty, cause);
1713 }
1714
1715 /// Registers obligations that all types appearing in `substs` are well-formed.
1716 pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
1a4d82fc 1717 {
62682a34 1718 for &ty in &substs.types {
e9174d1e 1719 self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
1a4d82fc
JJ
1720 }
1721 }
1722
1723 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
1724 /// type/region parameter was instantiated (`substs`), creates and registers suitable
1725 /// trait/region obligations.
1726 ///
1727 /// For example, if there is a function:
1728 ///
1729 /// ```
1730 /// fn foo<'a,T:'a>(...)
1731 /// ```
1732 ///
1733 /// and a reference:
1734 ///
1735 /// ```
1736 /// let f = foo;
1737 /// ```
1738 ///
1739 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
1740 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
1741 pub fn add_obligations_for_parameters(&self,
1742 cause: traits::ObligationCause<'tcx>,
85aaf69f 1743 predicates: &ty::InstantiatedPredicates<'tcx>)
1a4d82fc 1744 {
85aaf69f 1745 assert!(!predicates.has_escaping_regions());
1a4d82fc 1746
62682a34
SL
1747 debug!("add_obligations_for_parameters(predicates={:?})",
1748 predicates);
1a4d82fc 1749
62682a34
SL
1750 for obligation in traits::predicates_for_generics(cause, predicates) {
1751 self.register_predicate(obligation);
1752 }
1a4d82fc 1753 }
85aaf69f 1754
e9174d1e
SL
1755 // FIXME(arielb1): use this instead of field.ty everywhere
1756 pub fn field_ty(&self,
1757 span: Span,
1758 field: ty::FieldDef<'tcx>,
1759 substs: &Substs<'tcx>)
1760 -> Ty<'tcx>
85aaf69f 1761 {
e9174d1e
SL
1762 self.normalize_associated_types_in(span,
1763 &field.ty(self.tcx(), substs))
85aaf69f 1764 }
c34b1796 1765
e9174d1e
SL
1766 // Only for fields! Returns <none> for methods>
1767 // Indifferent to privacy flags
c34b1796
AL
1768 fn check_casts(&self) {
1769 let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
62682a34
SL
1770 for cast in deferred_cast_checks.drain(..) {
1771 cast.check(self);
c34b1796 1772 }
c34b1796 1773 }
d9579d0f 1774
c1a9b12d
SL
1775 /// Apply "fallbacks" to some types
1776 /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1777 fn default_type_parameters(&self) {
e9174d1e
SL
1778 use middle::ty::error::UnconstrainedNumeric::Neither;
1779 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
c1a9b12d
SL
1780 for ty in &self.infcx().unsolved_variables() {
1781 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1782 if self.infcx().type_var_diverges(resolved) {
1783 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1784 } else {
1785 match self.infcx().type_is_unconstrained_numeric(resolved) {
1786 UnconstrainedInt => {
1787 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1788 },
1789 UnconstrainedFloat => {
1790 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1791 }
1792 Neither => { }
1793 }
1794 }
1795 }
1796 }
1797
d9579d0f 1798 fn select_all_obligations_and_apply_defaults(&self) {
c1a9b12d
SL
1799 if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1800 self.new_select_all_obligations_and_apply_defaults();
1801 } else {
1802 self.old_select_all_obligations_and_apply_defaults();
1803 }
1804 }
d9579d0f 1805
c1a9b12d
SL
1806 // Implements old type inference fallback algorithm
1807 fn old_select_all_obligations_and_apply_defaults(&self) {
d9579d0f
AL
1808 self.select_obligations_where_possible();
1809 self.default_type_parameters();
1810 self.select_obligations_where_possible();
1811 }
1812
c1a9b12d 1813 fn new_select_all_obligations_and_apply_defaults(&self) {
e9174d1e
SL
1814 use middle::ty::error::UnconstrainedNumeric::Neither;
1815 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
c1a9b12d 1816
e9174d1e 1817 // For the time being this errs on the side of being memory wasteful but provides better
c1a9b12d
SL
1818 // error reporting.
1819 // let type_variables = self.infcx().type_variables.clone();
1820
1821 // There is a possibility that this algorithm will have to run an arbitrary number of times
1822 // to terminate so we bound it by the compiler's recursion limit.
b039eaaf 1823 for _ in 0..self.tcx().sess.recursion_limit.get() {
c1a9b12d
SL
1824 // First we try to solve all obligations, it is possible that the last iteration
1825 // has made it possible to make more progress.
1826 self.select_obligations_where_possible();
1827
1828 let mut conflicts = Vec::new();
1829
1830 // Collect all unsolved type, integral and floating point variables.
1831 let unsolved_variables = self.inh.infcx.unsolved_variables();
1832
1833 // We must collect the defaults *before* we do any unification. Because we have
1834 // directly attached defaults to the type variables any unification that occurs
1835 // will erase defaults causing conflicting defaults to be completely ignored.
1836 let default_map: FnvHashMap<_, _> =
1837 unsolved_variables
1838 .iter()
1839 .filter_map(|t| self.infcx().default(t).map(|d| (t, d)))
1840 .collect();
1841
1842 let mut unbound_tyvars = HashSet::new();
1843
1844 debug!("select_all_obligations_and_apply_defaults: defaults={:?}", default_map);
1845
1846 // We loop over the unsolved variables, resolving them and if they are
1847 // and unconstrainted numberic type we add them to the set of unbound
1848 // variables. We do this so we only apply literal fallback to type
1849 // variables without defaults.
1850 for ty in &unsolved_variables {
1851 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1852 if self.infcx().type_var_diverges(resolved) {
1853 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1854 } else {
1855 match self.infcx().type_is_unconstrained_numeric(resolved) {
1856 UnconstrainedInt | UnconstrainedFloat => {
1857 unbound_tyvars.insert(resolved);
1858 },
1859 Neither => {}
1860 }
1861 }
1862 }
1863
1864 // We now remove any numeric types that also have defaults, and instead insert
1865 // the type variable with a defined fallback.
1866 for ty in &unsolved_variables {
1867 if let Some(_default) = default_map.get(ty) {
1868 let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1869
1870 debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1871 ty, _default);
1872
1873 match resolved.sty {
1874 ty::TyInfer(ty::TyVar(_)) => {
1875 unbound_tyvars.insert(ty);
1876 }
1877
1878 ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) => {
1879 unbound_tyvars.insert(ty);
1880 if unbound_tyvars.contains(resolved) {
1881 unbound_tyvars.remove(resolved);
1882 }
1883 }
1884
1885 _ => {}
1886 }
1887 }
1888 }
1889
1890 // If there are no more fallbacks to apply at this point we have applied all possible
b039eaaf 1891 // defaults and type inference will proceed as normal.
c1a9b12d
SL
1892 if unbound_tyvars.is_empty() {
1893 break;
1894 }
1895
1896 // Finally we go through each of the unbound type variables and unify them with
1897 // the proper fallback, reporting a conflicting default error if any of the
1898 // unifications fail. We know it must be a conflicting default because the
1899 // variable would only be in `unbound_tyvars` and have a concrete value if
1900 // it had been solved by previously applying a default.
1901
1902 // We wrap this in a transaction for error reporting, if we detect a conflict
1903 // we will rollback the inference context to its prior state so we can probe
1904 // for conflicts and correctly report them.
1905
1906
1907 let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1908 for ty in &unbound_tyvars {
1909 if self.infcx().type_var_diverges(ty) {
1910 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1911 } else {
1912 match self.infcx().type_is_unconstrained_numeric(ty) {
1913 UnconstrainedInt => {
1914 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1915 },
1916 UnconstrainedFloat => {
1917 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1918 }
1919 Neither => {
1920 if let Some(default) = default_map.get(ty) {
1921 let default = default.clone();
1922 match infer::mk_eqty(self.infcx(), false,
1923 infer::Misc(default.origin_span),
1924 ty, default.ty) {
1925 Ok(()) => {}
1926 Err(_) => {
1927 conflicts.push((*ty, default));
1928 }
1929 }
1930 }
1931 }
1932 }
1933 }
1934 }
1935
1936 // If there are conflicts we rollback, otherwise commit
1937 if conflicts.len() > 0 {
1938 Err(())
1939 } else {
1940 Ok(())
1941 }
1942 });
1943
1944 if conflicts.len() > 0 {
1945 // Loop through each conflicting default, figuring out the default that caused
1946 // a unification failure and then report an error for each.
1947 for (conflict, default) in conflicts {
1948 let conflicting_default =
1949 self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
1950 .unwrap_or(type_variable::Default {
1951 ty: self.infcx().next_ty_var(),
1952 origin_span: codemap::DUMMY_SP,
b039eaaf 1953 def_id: self.tcx().map.local_def_id(0) // what do I put here?
c1a9b12d
SL
1954 });
1955
1956 // This is to ensure that we elimnate any non-determinism from the error
1957 // reporting by fixing an order, it doesn't matter what order we choose
1958 // just that it is consistent.
1959 let (first_default, second_default) =
1960 if default.def_id < conflicting_default.def_id {
1961 (default, conflicting_default)
1962 } else {
1963 (conflicting_default, default)
1964 };
1965
1966
1967 self.infcx().report_conflicting_default_types(
1968 first_default.origin_span,
1969 first_default,
1970 second_default)
1971 }
1972 }
1973 }
1974
1975 self.select_obligations_where_possible();
1976 }
1977
1978 // For use in error handling related to default type parameter fallback. We explicitly
1979 // apply the default that caused conflict first to a local version of the type variable
1980 // table then apply defaults until we find a conflict. That default must be the one
1981 // that caused conflict earlier.
1982 fn find_conflicting_default(&self,
1983 unbound_vars: &HashSet<Ty<'tcx>>,
1984 default_map: &FnvHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
1985 conflict: Ty<'tcx>)
1986 -> Option<type_variable::Default<'tcx>> {
e9174d1e
SL
1987 use middle::ty::error::UnconstrainedNumeric::Neither;
1988 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
c1a9b12d
SL
1989
1990 // Ensure that we apply the conflicting default first
1991 let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
1992 unbound_tyvars.push(conflict);
1993 unbound_tyvars.extend(unbound_vars.iter());
1994
1995 let mut result = None;
1996 // We run the same code as above applying defaults in order, this time when
1997 // we find the conflict we just return it for error reporting above.
1998
1999 // We also run this inside snapshot that never commits so we can do error
2000 // reporting for more then one conflict.
2001 for ty in &unbound_tyvars {
2002 if self.infcx().type_var_diverges(ty) {
2003 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
2004 } else {
2005 match self.infcx().type_is_unconstrained_numeric(ty) {
2006 UnconstrainedInt => {
2007 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
2008 },
2009 UnconstrainedFloat => {
2010 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
2011 },
2012 Neither => {
2013 if let Some(default) = default_map.get(ty) {
2014 let default = default.clone();
2015 match infer::mk_eqty(self.infcx(), false,
2016 infer::Misc(default.origin_span),
2017 ty, default.ty) {
2018 Ok(()) => {}
2019 Err(_) => {
2020 result = Some(default);
2021 }
2022 }
2023 }
2024 }
2025 }
2026 }
2027 }
2028
2029 return result;
2030 }
2031
d9579d0f
AL
2032 fn select_all_obligations_or_error(&self) {
2033 debug!("select_all_obligations_or_error");
2034
2035 // upvar inference should have ensured that all deferred call
2036 // resolutions are handled by now.
2037 assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
2038
2039 self.select_all_obligations_and_apply_defaults();
c1a9b12d
SL
2040
2041 let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
2042 match fulfillment_cx.select_all_or_error(self.infcx()) {
d9579d0f
AL
2043 Ok(()) => { }
2044 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2045 }
2046 }
2047
2048 /// Select as many obligations as we can at present.
2049 fn select_obligations_where_possible(&self) {
2050 match
c1a9b12d 2051 self.inh.infcx.fulfillment_cx
d9579d0f 2052 .borrow_mut()
c1a9b12d 2053 .select_where_possible(self.infcx())
d9579d0f
AL
2054 {
2055 Ok(()) => { }
2056 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2057 }
2058 }
2059
2060 /// Try to select any fcx obligation that we haven't tried yet, in an effort
2061 /// to improve inference. You could just call
2062 /// `select_obligations_where_possible` except that it leads to repeated
2063 /// work.
2064 fn select_new_obligations(&self) {
2065 match
c1a9b12d 2066 self.inh.infcx.fulfillment_cx
d9579d0f 2067 .borrow_mut()
c1a9b12d 2068 .select_new_obligations(self.infcx())
d9579d0f
AL
2069 {
2070 Ok(()) => { }
2071 Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); }
2072 }
2073 }
2074
1a4d82fc
JJ
2075}
2076
2077impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
85aaf69f 2078 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
62682a34
SL
2079 Some(self.base_object_lifetime_default(span))
2080 }
2081
2082 fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
85aaf69f
SL
2083 // RFC #599 specifies that object lifetime defaults take
2084 // precedence over other defaults. But within a fn body we
2085 // don't have a *default* region, rather we use inference to
2086 // find the *correct* region, which is strictly more general
2087 // (and anyway, within a fn body the right region may not even
2088 // be something the user can write explicitly, since it might
2089 // be some expression).
62682a34 2090 self.infcx().next_region_var(infer::MiscVariable(span))
1a4d82fc
JJ
2091 }
2092
c34b1796 2093 fn anon_regions(&self, span: Span, count: usize)
c1a9b12d 2094 -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
85aaf69f 2095 Ok((0..count).map(|_| {
1a4d82fc
JJ
2096 self.infcx().next_region_var(infer::MiscVariable(span))
2097 }).collect())
2098 }
2099}
2100
85aaf69f 2101/// Whether `autoderef` requires types to resolve.
c34b1796 2102#[derive(Copy, Clone, Debug, PartialEq, Eq)]
85aaf69f 2103pub enum UnresolvedTypeAction {
62682a34
SL
2104 /// Produce an error and return `TyError` whenever a type cannot
2105 /// be resolved (i.e. it is `TyInfer`).
85aaf69f
SL
2106 Error,
2107 /// Go on without emitting any errors, and return the unresolved
2108 /// type. Useful for probing, e.g. in coercions.
2109 Ignore
2110}
2111
1a4d82fc
JJ
2112/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
2113/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
2114///
2115/// Note: this method does not modify the adjustments table. The caller is responsible for
2116/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
2117pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
2118 sp: Span,
2119 base_ty: Ty<'tcx>,
e9174d1e 2120 opt_expr: Option<&hir::Expr>,
85aaf69f 2121 unresolved_type_action: UnresolvedTypeAction,
1a4d82fc
JJ
2122 mut lvalue_pref: LvaluePreference,
2123 mut should_stop: F)
c34b1796
AL
2124 -> (Ty<'tcx>, usize, Option<T>)
2125 where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
1a4d82fc 2126{
62682a34
SL
2127 debug!("autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})",
2128 base_ty,
2129 opt_expr,
1a4d82fc
JJ
2130 lvalue_pref);
2131
2132 let mut t = base_ty;
85aaf69f
SL
2133 for autoderefs in 0..fcx.tcx().sess.recursion_limit.get() {
2134 let resolved_t = match unresolved_type_action {
2135 UnresolvedTypeAction::Error => {
d9579d0f 2136 structurally_resolved_type(fcx, sp, t)
85aaf69f
SL
2137 }
2138 UnresolvedTypeAction::Ignore => {
2139 // We can continue even when the type cannot be resolved
c1a9b12d 2140 // (i.e. it is an inference variable) because `Ty::builtin_deref`
85aaf69f
SL
2141 // and `try_overloaded_deref` both simply return `None`
2142 // in such a case without producing spurious errors.
2143 fcx.resolve_type_vars_if_possible(t)
2144 }
2145 };
c1a9b12d 2146 if resolved_t.references_error() {
d9579d0f
AL
2147 return (resolved_t, autoderefs, None);
2148 }
1a4d82fc
JJ
2149
2150 match should_stop(resolved_t, autoderefs) {
2151 Some(x) => return (resolved_t, autoderefs, Some(x)),
2152 None => {}
2153 }
2154
2155 // Otherwise, deref if type is derefable:
e9174d1e 2156 let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
1a4d82fc
JJ
2157 Some(mt) => Some(mt),
2158 None => {
9346a6ac
AL
2159 let method_call =
2160 opt_expr.map(|expr| MethodCall::autoderef(expr.id, autoderefs as u32));
1a4d82fc
JJ
2161
2162 // Super subtle: it might seem as though we should
2163 // pass `opt_expr` to `try_overloaded_deref`, so that
2164 // the (implicit) autoref of using an overloaded deref
2165 // would get added to the adjustment table. However we
2166 // do not do that, because it's kind of a
2167 // "meta-adjustment" -- instead, we just leave it
2168 // unrecorded and know that there "will be" an
2169 // autoref. regionck and other bits of the code base,
2170 // when they encounter an overloaded autoderef, have
2171 // to do some reconstructive surgery. This is a pretty
2172 // complex mess that is begging for a proper MIR.
2173 try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
2174 }
2175 };
2176 match mt {
2177 Some(mt) => {
2178 t = mt.ty;
e9174d1e 2179 if mt.mutbl == hir::MutImmutable {
1a4d82fc
JJ
2180 lvalue_pref = NoPreference;
2181 }
2182 }
2183 None => return (resolved_t, autoderefs, None)
2184 }
2185 }
2186
2187 // We've reached the recursion limit, error gracefully.
2188 span_err!(fcx.tcx().sess, sp, E0055,
62682a34
SL
2189 "reached the recursion limit while auto-dereferencing {:?}",
2190 base_ty);
1a4d82fc
JJ
2191 (fcx.tcx().types.err, 0, None)
2192}
2193
2194fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2195 span: Span,
2196 method_call: Option<MethodCall>,
e9174d1e 2197 base_expr: Option<&hir::Expr>,
1a4d82fc
JJ
2198 base_ty: Ty<'tcx>,
2199 lvalue_pref: LvaluePreference)
c1a9b12d 2200 -> Option<ty::TypeAndMut<'tcx>>
1a4d82fc
JJ
2201{
2202 // Try DerefMut first, if preferred.
2203 let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
2204 (PreferMutLvalue, Some(trait_did)) => {
2205 method::lookup_in_trait(fcx, span, base_expr,
2206 token::intern("deref_mut"), trait_did,
2207 base_ty, None)
2208 }
2209 _ => None
2210 };
2211
2212 // Otherwise, fall back to Deref.
2213 let method = match (method, fcx.tcx().lang_items.deref_trait()) {
2214 (None, Some(trait_did)) => {
2215 method::lookup_in_trait(fcx, span, base_expr,
2216 token::intern("deref"), trait_did,
2217 base_ty, None)
2218 }
2219 (method, _) => method
2220 };
2221
2222 make_overloaded_lvalue_return_type(fcx, method_call, method)
2223}
2224
2225/// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
2226/// actual type we assign to the *expression* is `T`. So this function just peels off the return
2227/// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
2228fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2229 method_call: Option<MethodCall>,
2230 method: Option<MethodCallee<'tcx>>)
c1a9b12d 2231 -> Option<ty::TypeAndMut<'tcx>>
1a4d82fc
JJ
2232{
2233 match method {
2234 Some(method) => {
b039eaaf 2235 // extract method return type, which will be &T;
c34b1796 2236 // all LB regions should have been instantiated during method lookup
c1a9b12d
SL
2237 let ret_ty = method.ty.fn_ret();
2238 let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
c34b1796
AL
2239
2240 if let Some(method_call) = method_call {
c1a9b12d 2241 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
1a4d82fc 2242 }
c34b1796
AL
2243
2244 // method returns &T, but the type as visible to user is T, so deref
e9174d1e 2245 ret_ty.builtin_deref(true, NoPreference)
1a4d82fc
JJ
2246 }
2247 None => None,
2248 }
2249}
2250
9346a6ac 2251fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e
SL
2252 expr: &hir::Expr,
2253 base_expr: &'tcx hir::Expr,
9346a6ac
AL
2254 base_ty: Ty<'tcx>,
2255 idx_ty: Ty<'tcx>,
2256 lvalue_pref: LvaluePreference)
2257 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
1a4d82fc
JJ
2258{
2259 // FIXME(#18741) -- this is almost but not quite the same as the
2260 // autoderef that normal method probing does. They could likely be
2261 // consolidated.
2262
85aaf69f
SL
2263 let (ty, autoderefs, final_mt) = autoderef(fcx,
2264 base_expr.span,
2265 base_ty,
2266 Some(base_expr),
2267 UnresolvedTypeAction::Error,
2268 lvalue_pref,
2269 |adj_ty, idx| {
9346a6ac
AL
2270 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2271 adj_ty, idx, false, lvalue_pref, idx_ty)
2272 });
1a4d82fc
JJ
2273
2274 if final_mt.is_some() {
2275 return final_mt;
2276 }
2277
62682a34 2278 // After we have fully autoderef'd, if the resulting type is [T; n], then
1a4d82fc 2279 // do a final unsized coercion to yield [T].
62682a34 2280 if let ty::TyArray(element_ty, _) = ty.sty {
c1a9b12d 2281 let adjusted_ty = fcx.tcx().mk_slice(element_ty);
9346a6ac
AL
2282 try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr,
2283 adjusted_ty, autoderefs, true, lvalue_pref, idx_ty)
2284 } else {
2285 None
1a4d82fc
JJ
2286 }
2287}
2288
2289/// To type-check `base_expr[index_expr]`, we progressively autoderef (and otherwise adjust)
2290/// `base_expr`, looking for a type which either supports builtin indexing or overloaded indexing.
2291/// This loop implements one step in that search; the autoderef loop is implemented by
9346a6ac 2292/// `lookup_indexing`.
1a4d82fc
JJ
2293fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2294 method_call: MethodCall,
e9174d1e
SL
2295 expr: &hir::Expr,
2296 base_expr: &'tcx hir::Expr,
1a4d82fc 2297 adjusted_ty: Ty<'tcx>,
9346a6ac
AL
2298 autoderefs: usize,
2299 unsize: bool,
1a4d82fc
JJ
2300 lvalue_pref: LvaluePreference,
2301 index_ty: Ty<'tcx>)
2302 -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)>
2303{
2304 let tcx = fcx.tcx();
62682a34
SL
2305 debug!("try_index_step(expr={:?}, base_expr.id={:?}, adjusted_ty={:?}, \
2306 autoderefs={}, unsize={}, index_ty={:?})",
2307 expr,
2308 base_expr,
2309 adjusted_ty,
9346a6ac
AL
2310 autoderefs,
2311 unsize,
62682a34 2312 index_ty);
1a4d82fc
JJ
2313
2314 let input_ty = fcx.infcx().next_ty_var();
2315
2316 // First, try built-in indexing.
c1a9b12d 2317 match (adjusted_ty.builtin_index(), &index_ty.sty) {
b039eaaf 2318 (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
1a4d82fc 2319 debug!("try_index_step: success, using built-in indexing");
9346a6ac
AL
2320 // If we had `[T; N]`, we should've caught it before unsizing to `[T]`.
2321 assert!(!unsize);
2322 fcx.write_autoderef_adjustment(base_expr.id, autoderefs);
c34b1796 2323 return Some((tcx.types.usize, ty));
1a4d82fc
JJ
2324 }
2325 _ => {}
2326 }
2327
2328 // Try `IndexMut` first, if preferred.
2329 let method = match (lvalue_pref, tcx.lang_items.index_mut_trait()) {
2330 (PreferMutLvalue, Some(trait_did)) => {
2331 method::lookup_in_trait_adjusted(fcx,
2332 expr.span,
2333 Some(&*base_expr),
2334 token::intern("index_mut"),
2335 trait_did,
9346a6ac
AL
2336 autoderefs,
2337 unsize,
1a4d82fc
JJ
2338 adjusted_ty,
2339 Some(vec![input_ty]))
2340 }
2341 _ => None,
2342 };
2343
2344 // Otherwise, fall back to `Index`.
2345 let method = match (method, tcx.lang_items.index_trait()) {
2346 (None, Some(trait_did)) => {
2347 method::lookup_in_trait_adjusted(fcx,
2348 expr.span,
2349 Some(&*base_expr),
2350 token::intern("index"),
2351 trait_did,
9346a6ac
AL
2352 autoderefs,
2353 unsize,
1a4d82fc
JJ
2354 adjusted_ty,
2355 Some(vec![input_ty]))
2356 }
2357 (method, _) => method,
2358 };
2359
2360 // If some lookup succeeds, write callee into table and extract index/element
2361 // type from the method signature.
2362 // If some lookup succeeded, install method in table
2363 method.and_then(|method| {
2364 debug!("try_index_step: success, using overloaded indexing");
2365 make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
2366 map(|ret| (input_ty, ret.ty))
2367 })
2368}
2369
1a4d82fc
JJ
2370fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2371 sp: Span,
2372 method_fn_ty: Ty<'tcx>,
e9174d1e
SL
2373 callee_expr: &'tcx hir::Expr,
2374 args_no_rcvr: &'tcx [P<hir::Expr>],
85aaf69f
SL
2375 tuple_arguments: TupleArgumentsFlag,
2376 expected: Expectation<'tcx>)
1a4d82fc 2377 -> ty::FnOutput<'tcx> {
c1a9b12d 2378 if method_fn_ty.references_error() {
1a4d82fc
JJ
2379 let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
2380
2381 let err_inputs = match tuple_arguments {
2382 DontTupleArguments => err_inputs,
c1a9b12d 2383 TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)],
1a4d82fc
JJ
2384 };
2385
2386 check_argument_types(fcx,
2387 sp,
85aaf69f
SL
2388 &err_inputs[..],
2389 &[],
1a4d82fc 2390 args_no_rcvr,
1a4d82fc
JJ
2391 false,
2392 tuple_arguments);
2393 ty::FnConverging(fcx.tcx().types.err)
2394 } else {
2395 match method_fn_ty.sty {
62682a34 2396 ty::TyBareFn(_, ref fty) => {
1a4d82fc 2397 // HACK(eddyb) ignore self in the definition (see above).
85aaf69f
SL
2398 let expected_arg_tys = expected_types_for_fn_args(fcx,
2399 sp,
2400 expected,
2401 fty.sig.0.output,
2402 &fty.sig.0.inputs[1..]);
1a4d82fc
JJ
2403 check_argument_types(fcx,
2404 sp,
85aaf69f
SL
2405 &fty.sig.0.inputs[1..],
2406 &expected_arg_tys[..],
1a4d82fc 2407 args_no_rcvr,
1a4d82fc
JJ
2408 fty.sig.0.variadic,
2409 tuple_arguments);
2410 fty.sig.0.output
2411 }
2412 _ => {
2413 fcx.tcx().sess.span_bug(callee_expr.span,
2414 "method without bare fn type");
2415 }
2416 }
2417 }
2418}
2419
2420/// Generic function that factors out common logic from function calls, method calls and overloaded
2421/// operators.
2422fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2423 sp: Span,
2424 fn_inputs: &[Ty<'tcx>],
85aaf69f 2425 expected_arg_tys: &[Ty<'tcx>],
e9174d1e 2426 args: &'tcx [P<hir::Expr>],
1a4d82fc
JJ
2427 variadic: bool,
2428 tuple_arguments: TupleArgumentsFlag) {
2429 let tcx = fcx.ccx.tcx;
2430
2431 // Grab the argument types, supplying fresh type variables
2432 // if the wrong number of arguments were supplied
2433 let supplied_arg_count = if tuple_arguments == DontTupleArguments {
2434 args.len()
2435 } else {
2436 1
2437 };
2438
e9174d1e
SL
2439 // All the input types from the fn signature must outlive the call
2440 // so as to validate implied bounds.
2441 for &fn_input_ty in fn_inputs {
2442 fcx.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
2443 }
2444
85aaf69f 2445 let mut expected_arg_tys = expected_arg_tys;
1a4d82fc
JJ
2446 let expected_arg_count = fn_inputs.len();
2447 let formal_tys = if tuple_arguments == TupleArguments {
2448 let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
2449 match tuple_type.sty {
62682a34 2450 ty::TyTuple(ref arg_types) => {
1a4d82fc
JJ
2451 if arg_types.len() != args.len() {
2452 span_err!(tcx.sess, sp, E0057,
2453 "this function takes {} parameter{} but {} parameter{} supplied",
2454 arg_types.len(),
2455 if arg_types.len() == 1 {""} else {"s"},
2456 args.len(),
2457 if args.len() == 1 {" was"} else {"s were"});
c34b1796 2458 expected_arg_tys = &[];
1a4d82fc
JJ
2459 err_args(fcx.tcx(), args.len())
2460 } else {
85aaf69f
SL
2461 expected_arg_tys = match expected_arg_tys.get(0) {
2462 Some(&ty) => match ty.sty {
62682a34 2463 ty::TyTuple(ref tys) => &**tys,
85aaf69f
SL
2464 _ => &[]
2465 },
2466 None => &[]
2467 };
1a4d82fc
JJ
2468 (*arg_types).clone()
2469 }
2470 }
2471 _ => {
2472 span_err!(tcx.sess, sp, E0059,
2473 "cannot use call notation; the first type parameter \
2474 for the function trait is neither a tuple nor unit");
c34b1796 2475 expected_arg_tys = &[];
1a4d82fc
JJ
2476 err_args(fcx.tcx(), args.len())
2477 }
2478 }
2479 } else if expected_arg_count == supplied_arg_count {
85aaf69f 2480 fn_inputs.to_vec()
1a4d82fc
JJ
2481 } else if variadic {
2482 if supplied_arg_count >= expected_arg_count {
85aaf69f 2483 fn_inputs.to_vec()
1a4d82fc
JJ
2484 } else {
2485 span_err!(tcx.sess, sp, E0060,
2486 "this function takes at least {} parameter{} \
2487 but {} parameter{} supplied",
2488 expected_arg_count,
2489 if expected_arg_count == 1 {""} else {"s"},
2490 supplied_arg_count,
2491 if supplied_arg_count == 1 {" was"} else {"s were"});
c34b1796 2492 expected_arg_tys = &[];
1a4d82fc
JJ
2493 err_args(fcx.tcx(), supplied_arg_count)
2494 }
2495 } else {
2496 span_err!(tcx.sess, sp, E0061,
2497 "this function takes {} parameter{} but {} parameter{} supplied",
2498 expected_arg_count,
2499 if expected_arg_count == 1 {""} else {"s"},
2500 supplied_arg_count,
2501 if supplied_arg_count == 1 {" was"} else {"s were"});
c34b1796 2502 expected_arg_tys = &[];
1a4d82fc
JJ
2503 err_args(fcx.tcx(), supplied_arg_count)
2504 };
2505
2506 debug!("check_argument_types: formal_tys={:?}",
2507 formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
2508
2509 // Check the arguments.
2510 // We do this in a pretty awful way: first we typecheck any arguments
2511 // that are not anonymous functions, then we typecheck the anonymous
2512 // functions. This is so that we have more information about the types
2513 // of arguments when we typecheck the functions. This isn't really the
2514 // right way to do this.
2515 let xs = [false, true];
85aaf69f 2516 for check_blocks in &xs {
1a4d82fc
JJ
2517 let check_blocks = *check_blocks;
2518 debug!("check_blocks={}", check_blocks);
2519
85aaf69f
SL
2520 // More awful hacks: before we check argument types, try to do
2521 // an "opportunistic" vtable resolution of any trait bounds on
2522 // the call. This helps coercions.
1a4d82fc 2523 if check_blocks {
d9579d0f 2524 fcx.select_new_obligations();
1a4d82fc
JJ
2525 }
2526
2527 // For variadic functions, we don't have a declared type for all of
2528 // the arguments hence we only do our usual type checking with
2529 // the arguments who's types we do know.
2530 let t = if variadic {
2531 expected_arg_count
2532 } else if tuple_arguments == TupleArguments {
2533 args.len()
2534 } else {
2535 supplied_arg_count
2536 };
2537 for (i, arg) in args.iter().take(t).enumerate() {
2538 let is_block = match arg.node {
e9174d1e 2539 hir::ExprClosure(..) => true,
1a4d82fc
JJ
2540 _ => false
2541 };
2542
2543 if is_block == check_blocks {
2544 debug!("checking the argument");
c34b1796 2545 let formal_ty = formal_tys[i];
1a4d82fc 2546
85aaf69f
SL
2547 // The special-cased logic below has three functions:
2548 // 1. Provide as good of an expected type as possible.
2549 let expected = expected_arg_tys.get(i).map(|&ty| {
c1a9b12d 2550 Expectation::rvalue_hint(fcx.tcx(), ty)
85aaf69f
SL
2551 });
2552
e9174d1e
SL
2553 check_expr_with_unifier(fcx,
2554 &**arg,
85aaf69f
SL
2555 expected.unwrap_or(ExpectHasType(formal_ty)),
2556 NoPreference, || {
2557 // 2. Coerce to the most detailed type that could be coerced
2558 // to, which is `expected_ty` if `rvalue_hint` returns an
2559 // `ExprHasType(expected_ty)`, or the `formal_ty` otherwise.
2560 let coerce_ty = expected.and_then(|e| e.only_has_type(fcx));
2561 demand::coerce(fcx, arg.span, coerce_ty.unwrap_or(formal_ty), &**arg);
2562
2563 // 3. Relate the expected type and the formal one,
2564 // if the expected type was used for the coercion.
2565 coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
2566 });
1a4d82fc
JJ
2567 }
2568 }
2569 }
2570
2571 // We also need to make sure we at least write the ty of the other
2572 // arguments which we skipped above.
2573 if variadic {
2574 for arg in args.iter().skip(expected_arg_count) {
85aaf69f 2575 check_expr(fcx, &**arg);
1a4d82fc
JJ
2576
2577 // There are a few types which get autopromoted when passed via varargs
2578 // in C but we just error out instead and require explicit casts.
2579 let arg_ty = structurally_resolved_type(fcx, arg.span,
85aaf69f 2580 fcx.expr_ty(&**arg));
1a4d82fc 2581 match arg_ty.sty {
b039eaaf 2582 ty::TyFloat(ast::TyF32) => {
1a4d82fc
JJ
2583 fcx.type_error_message(arg.span,
2584 |t| {
2585 format!("can't pass an {} to variadic \
2586 function, cast to c_double", t)
2587 }, arg_ty, None);
2588 }
b039eaaf 2589 ty::TyInt(ast::TyI8) | ty::TyInt(ast::TyI16) | ty::TyBool => {
1a4d82fc
JJ
2590 fcx.type_error_message(arg.span, |t| {
2591 format!("can't pass {} to variadic \
2592 function, cast to c_int",
2593 t)
2594 }, arg_ty, None);
2595 }
b039eaaf 2596 ty::TyUint(ast::TyU8) | ty::TyUint(ast::TyU16) => {
1a4d82fc
JJ
2597 fcx.type_error_message(arg.span, |t| {
2598 format!("can't pass {} to variadic \
2599 function, cast to c_uint",
2600 t)
2601 }, arg_ty, None);
2602 }
2603 _ => {}
2604 }
2605 }
2606 }
2607}
2608
2609// FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
c34b1796 2610fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
85aaf69f 2611 (0..len).map(|_| tcx.types.err).collect()
1a4d82fc
JJ
2612}
2613
2614fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2615 call_expr: &hir::Expr,
1a4d82fc
JJ
2616 output: ty::FnOutput<'tcx>) {
2617 fcx.write_ty(call_expr.id, match output {
2618 ty::FnConverging(output_ty) => output_ty,
2619 ty::FnDiverging => fcx.infcx().next_diverging_ty_var()
2620 });
2621}
2622
2623// AST fragment checking
2624fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
b039eaaf 2625 lit: &ast::Lit,
1a4d82fc
JJ
2626 expected: Expectation<'tcx>)
2627 -> Ty<'tcx>
2628{
2629 let tcx = fcx.ccx.tcx;
2630
2631 match lit.node {
b039eaaf
SL
2632 ast::LitStr(..) => tcx.mk_static_str(),
2633 ast::LitByteStr(ref v) => {
c1a9b12d
SL
2634 tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
2635 tcx.mk_array(tcx.types.u8, v.len()))
1a4d82fc 2636 }
b039eaaf
SL
2637 ast::LitByte(_) => tcx.types.u8,
2638 ast::LitChar(_) => tcx.types.char,
2639 ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
2640 ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
2641 ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
85aaf69f 2642 let opt_ty = expected.to_option(fcx).and_then(|ty| {
1a4d82fc 2643 match ty.sty {
62682a34
SL
2644 ty::TyInt(_) | ty::TyUint(_) => Some(ty),
2645 ty::TyChar => Some(tcx.types.u8),
2646 ty::TyRawPtr(..) => Some(tcx.types.usize),
2647 ty::TyBareFn(..) => Some(tcx.types.usize),
1a4d82fc
JJ
2648 _ => None
2649 }
2650 });
2651 opt_ty.unwrap_or_else(
c1a9b12d 2652 || tcx.mk_int_var(fcx.infcx().next_int_var_id()))
1a4d82fc 2653 }
b039eaaf
SL
2654 ast::LitFloat(_, t) => tcx.mk_mach_float(t),
2655 ast::LitFloatUnsuffixed(_) => {
85aaf69f 2656 let opt_ty = expected.to_option(fcx).and_then(|ty| {
1a4d82fc 2657 match ty.sty {
62682a34 2658 ty::TyFloat(_) => Some(ty),
1a4d82fc
JJ
2659 _ => None
2660 }
2661 });
2662 opt_ty.unwrap_or_else(
c1a9b12d 2663 || tcx.mk_float_var(fcx.infcx().next_float_var_id()))
1a4d82fc 2664 }
b039eaaf 2665 ast::LitBool(_) => tcx.types.bool
1a4d82fc
JJ
2666 }
2667}
2668
1a4d82fc 2669pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2670 expr: &'tcx hir::Expr,
1a4d82fc
JJ
2671 expected: Ty<'tcx>) {
2672 check_expr_with_unifier(
2673 fcx, expr, ExpectHasType(expected), NoPreference,
2674 || demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr)));
2675}
2676
2677fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2678 expr: &'tcx hir::Expr,
1a4d82fc
JJ
2679 expected: Ty<'tcx>) {
2680 check_expr_with_unifier(
2681 fcx, expr, ExpectHasType(expected), NoPreference,
2682 || demand::coerce(fcx, expr.span, expected, expr));
2683}
2684
e9174d1e 2685fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx hir::Expr,
1a4d82fc
JJ
2686 expected: Ty<'tcx>) {
2687 check_expr_with_unifier(
2688 fcx, expr, ExpectHasType(expected), NoPreference,
2689 || ())
2690}
2691
2692fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2693 expr: &'tcx hir::Expr,
1a4d82fc
JJ
2694 expected: Expectation<'tcx>) {
2695 check_expr_with_unifier(
2696 fcx, expr, expected, NoPreference,
2697 || ())
2698}
2699
2700fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2701 expr: &'tcx hir::Expr,
1a4d82fc
JJ
2702 expected: Expectation<'tcx>,
2703 lvalue_pref: LvaluePreference)
2704{
2705 check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
2706}
2707
e9174d1e 2708fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr) {
1a4d82fc
JJ
2709 check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
2710}
2711
e9174d1e 2712fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx hir::Expr,
85aaf69f 2713 lvalue_pref: LvaluePreference) {
1a4d82fc
JJ
2714 check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
2715}
2716
2717// determine the `self` type, using fresh variables for all variables
d9579d0f 2718// declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
1a4d82fc
JJ
2719// would return ($0, $1) where $0 and $1 are freshly instantiated type
2720// variables.
2721pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2722 span: Span, // (potential) receiver for this impl
e9174d1e 2723 did: DefId)
1a4d82fc
JJ
2724 -> TypeAndSubsts<'tcx> {
2725 let tcx = fcx.tcx();
2726
c1a9b12d
SL
2727 let ity = tcx.lookup_item_type(did);
2728 let (tps, rps, raw_ty) =
2729 (ity.generics.types.get_slice(subst::TypeSpace),
1a4d82fc
JJ
2730 ity.generics.regions.get_slice(subst::TypeSpace),
2731 ity.ty);
2732
c1a9b12d
SL
2733 debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
2734
1a4d82fc 2735 let rps = fcx.inh.infcx.region_vars_for_defs(span, rps);
c1a9b12d
SL
2736 let mut substs = subst::Substs::new(
2737 VecPerParamSpace::empty(),
2738 VecPerParamSpace::new(rps, Vec::new(), Vec::new()));
2739 fcx.inh.infcx.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
1a4d82fc
JJ
2740 let substd_ty = fcx.instantiate_type_scheme(span, &substs, &raw_ty);
2741
2742 TypeAndSubsts { substs: substs, ty: substd_ty }
2743}
2744
1a4d82fc
JJ
2745/// Controls whether the arguments are tupled. This is used for the call
2746/// operator.
2747///
2748/// Tupling means that all call-side arguments are packed into a tuple and
2749/// passed as a single parameter. For example, if tupling is enabled, this
2750/// function:
2751///
c34b1796 2752/// fn f(x: (isize, isize))
1a4d82fc
JJ
2753///
2754/// Can be called as:
2755///
2756/// f(1, 2);
2757///
2758/// Instead of:
2759///
2760/// f((1, 2));
2761#[derive(Clone, Eq, PartialEq)]
2762enum TupleArgumentsFlag {
2763 DontTupleArguments,
2764 TupleArguments,
2765}
2766
85aaf69f
SL
2767/// Unifies the return type with the expected type early, for more coercions
2768/// and forward type information on the argument expressions.
2769fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
2770 call_span: Span,
2771 expected_ret: Expectation<'tcx>,
2772 formal_ret: ty::FnOutput<'tcx>,
2773 formal_args: &[Ty<'tcx>])
2774 -> Vec<Ty<'tcx>> {
2775 let expected_args = expected_ret.only_has_type(fcx).and_then(|ret_ty| {
2776 if let ty::FnConverging(formal_ret_ty) = formal_ret {
2777 fcx.infcx().commit_regions_if_ok(|| {
2778 // Attempt to apply a subtyping relationship between the formal
2779 // return type (likely containing type variables if the function
2780 // is polymorphic) and the expected return type.
2781 // No argument expectations are produced if unification fails.
2782 let origin = infer::Misc(call_span);
2783 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
2784 // FIXME(#15760) can't use try! here, FromError doesn't default
2785 // to identity so the resulting type is not constrained.
2786 if let Err(e) = ures {
2787 return Err(e);
2788 }
2789
2790 // Record all the argument types, with the substitutions
2791 // produced from the above subtyping unification.
2792 Ok(formal_args.iter().map(|ty| {
2793 fcx.infcx().resolve_type_vars_if_possible(ty)
2794 }).collect())
2795 }).ok()
2796 } else {
2797 None
2798 }
2799 }).unwrap_or(vec![]);
62682a34
SL
2800 debug!("expected_types_for_fn_args(formal={:?} -> {:?}, expected={:?} -> {:?})",
2801 formal_args, formal_ret,
2802 expected_args, expected_ret);
85aaf69f
SL
2803 expected_args
2804}
2805
1a4d82fc
JJ
2806/// Invariant:
2807/// If an expression has any sub-expressions that result in a type error,
c1a9b12d 2808/// inspecting that expression's type with `ty.references_error()` will return
1a4d82fc
JJ
2809/// true. Likewise, if an expression is known to diverge, inspecting its
2810/// type with `ty::type_is_bot` will return true (n.b.: since Rust is
2811/// strict, _|_ can appear in the type of an expression that does not,
2812/// itself, diverge: for example, fn() -> _|_.)
2813/// Note that inspecting a type's structure *directly* may expose the fact
62682a34 2814/// that there are actually multiple representations for `TyError`, so avoid
1a4d82fc
JJ
2815/// that when err needs to be handled differently.
2816fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2817 expr: &'tcx hir::Expr,
1a4d82fc
JJ
2818 expected: Expectation<'tcx>,
2819 lvalue_pref: LvaluePreference,
2820 unifier: F) where
2821 F: FnOnce(),
2822{
62682a34
SL
2823 debug!(">> typechecking: expr={:?} expected={:?}",
2824 expr, expected);
1a4d82fc
JJ
2825
2826 // Checks a method call.
85aaf69f 2827 fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 2828 expr: &'tcx hir::Expr,
b039eaaf 2829 method_name: Spanned<ast::Name>,
e9174d1e
SL
2830 args: &'tcx [P<hir::Expr>],
2831 tps: &[P<hir::Ty>],
85aaf69f
SL
2832 expected: Expectation<'tcx>,
2833 lvalue_pref: LvaluePreference) {
1a4d82fc
JJ
2834 let rcvr = &*args[0];
2835 check_expr_with_lvalue_pref(fcx, &*rcvr, lvalue_pref);
2836
2837 // no need to check for bot/err -- callee does that
2838 let expr_t = structurally_resolved_type(fcx,
2839 expr.span,
2840 fcx.expr_ty(&*rcvr));
2841
2842 let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
2843 let fn_ty = match method::lookup(fcx,
2844 method_name.span,
b039eaaf 2845 method_name.node,
1a4d82fc
JJ
2846 expr_t,
2847 tps,
2848 expr,
2849 rcvr) {
2850 Ok(method) => {
2851 let method_ty = method.ty;
2852 let method_call = MethodCall::expr(expr.id);
c1a9b12d 2853 fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
1a4d82fc
JJ
2854 method_ty
2855 }
2856 Err(error) => {
85aaf69f 2857 method::report_error(fcx, method_name.span, expr_t,
b039eaaf 2858 method_name.node, Some(rcvr), error);
1a4d82fc
JJ
2859 fcx.write_error(expr.id);
2860 fcx.tcx().types.err
2861 }
2862 };
2863
2864 // Call the generic checker.
1a4d82fc
JJ
2865 let ret_ty = check_method_argument_types(fcx,
2866 method_name.span,
2867 fn_ty,
2868 expr,
85aaf69f 2869 &args[1..],
85aaf69f
SL
2870 DontTupleArguments,
2871 expected);
1a4d82fc
JJ
2872
2873 write_call(fcx, expr, ret_ty);
2874 }
2875
2876 // A generic function for checking the then and else in an if
2877 // or if-else.
2878 fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e
SL
2879 cond_expr: &'tcx hir::Expr,
2880 then_blk: &'tcx hir::Block,
2881 opt_else_expr: Option<&'tcx hir::Expr>,
1a4d82fc
JJ
2882 id: ast::NodeId,
2883 sp: Span,
2884 expected: Expectation<'tcx>) {
2885 check_expr_has_type(fcx, cond_expr, fcx.tcx().types.bool);
2886
2887 let expected = expected.adjust_for_branches(fcx);
2888 check_block_with_expected(fcx, then_blk, expected);
2889 let then_ty = fcx.node_ty(then_blk.id);
2890
2891 let branches_ty = match opt_else_expr {
2892 Some(ref else_expr) => {
2893 check_expr_with_expectation(fcx, &**else_expr, expected);
2894 let else_ty = fcx.expr_ty(&**else_expr);
2895 infer::common_supertype(fcx.infcx(),
2896 infer::IfExpression(sp),
2897 true,
2898 then_ty,
2899 else_ty)
2900 }
2901 None => {
2902 infer::common_supertype(fcx.infcx(),
2903 infer::IfExpressionWithNoElse(sp),
2904 false,
2905 then_ty,
c1a9b12d 2906 fcx.tcx().mk_nil())
1a4d82fc
JJ
2907 }
2908 };
2909
2910 let cond_ty = fcx.expr_ty(cond_expr);
c1a9b12d 2911 let if_ty = if cond_ty.references_error() {
1a4d82fc
JJ
2912 fcx.tcx().types.err
2913 } else {
2914 branches_ty
2915 };
2916
2917 fcx.write_ty(id, if_ty);
2918 }
2919
1a4d82fc 2920 // Check field access expressions
85aaf69f 2921 fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
e9174d1e 2922 expr: &'tcx hir::Expr,
85aaf69f 2923 lvalue_pref: LvaluePreference,
e9174d1e 2924 base: &'tcx hir::Expr,
b039eaaf 2925 field: &Spanned<ast::Name>) {
1a4d82fc
JJ
2926 let tcx = fcx.ccx.tcx;
2927 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
2928 let expr_t = structurally_resolved_type(fcx, expr.span,
2929 fcx.expr_ty(base));
2930 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
85aaf69f
SL
2931 let (_, autoderefs, field_ty) = autoderef(fcx,
2932 expr.span,
2933 expr_t,
2934 Some(base),
2935 UnresolvedTypeAction::Error,
2936 lvalue_pref,
2937 |base_t, _| {
1a4d82fc 2938 match base_t.sty {
e9174d1e 2939 ty::TyStruct(base_def, substs) => {
62682a34 2940 debug!("struct named {:?}", base_t);
e9174d1e 2941 base_def.struct_variant()
b039eaaf 2942 .find_field_named(field.node)
e9174d1e 2943 .map(|f| fcx.field_ty(expr.span, f, substs))
1a4d82fc
JJ
2944 }
2945 _ => None
2946 }
2947 });
2948 match field_ty {
2949 Some(field_ty) => {
2950 fcx.write_ty(expr.id, field_ty);
9346a6ac 2951 fcx.write_autoderef_adjustment(base.id, autoderefs);
1a4d82fc
JJ
2952 return;
2953 }
2954 None => {}
2955 }
2956
b039eaaf 2957 if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
1a4d82fc
JJ
2958 fcx.type_error_message(
2959 field.span,
2960 |actual| {
2961 format!("attempted to take value of method `{}` on type \
c1a9b12d 2962 `{}`", field.node, actual)
1a4d82fc
JJ
2963 },
2964 expr_t, None);
2965
c34b1796 2966 tcx.sess.fileline_help(field.span,
1a4d82fc
JJ
2967 "maybe a `()` to call it is missing? \
2968 If not, try an anonymous function");
2969 } else {
2970 fcx.type_error_message(
2971 expr.span,
2972 |actual| {
2973 format!("attempted access of field `{}` on \
2974 type `{}`, but no field with that \
2975 name was found",
c1a9b12d 2976 field.node,
1a4d82fc
JJ
2977 actual)
2978 },
2979 expr_t, None);
e9174d1e
SL
2980 if let ty::TyStruct(def, _) = expr_t.sty {
2981 suggest_field_names(def.struct_variant(), field, tcx, vec![]);
85aaf69f 2982 }
1a4d82fc
JJ
2983 }
2984
2985 fcx.write_error(expr.id);
2986 }
2987
85aaf69f 2988 // displays hints about the closest matches in field names
e9174d1e 2989 fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
b039eaaf 2990 field: &Spanned<ast::Name>,
e9174d1e 2991 tcx: &ty::ctxt<'tcx>,
c1a9b12d 2992 skip : Vec<InternedString>) {
b039eaaf 2993 let name = field.node.as_str();
85aaf69f
SL
2994 // only find fits with at least one matching letter
2995 let mut best_dist = name.len();
85aaf69f 2996 let mut best = None;
e9174d1e 2997 for elem in &variant.fields {
85aaf69f
SL
2998 let n = elem.name.as_str();
2999 // ignore already set fields
c1a9b12d 3000 if skip.iter().any(|x| *x == n) {
85aaf69f
SL
3001 continue;
3002 }
c34b1796 3003 // ignore private fields from non-local crates
e9174d1e 3004 if variant.did.krate != LOCAL_CRATE && elem.vis != Visibility::Public {
c34b1796
AL
3005 continue;
3006 }
c1a9b12d 3007 let dist = lev_distance(&n, &name);
85aaf69f
SL
3008 if dist < best_dist {
3009 best = Some(n);
3010 best_dist = dist;
3011 }
3012 }
3013 if let Some(n) = best {
3014 tcx.sess.span_help(field.span,
3015 &format!("did you mean `{}`?", n));
3016 }
3017 }
3018
1a4d82fc 3019 // Check tuple index expressions
85aaf69f 3020 fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
e9174d1e 3021 expr: &'tcx hir::Expr,
85aaf69f 3022 lvalue_pref: LvaluePreference,
e9174d1e 3023 base: &'tcx hir::Expr,
c34b1796 3024 idx: codemap::Spanned<usize>) {
1a4d82fc
JJ
3025 check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
3026 let expr_t = structurally_resolved_type(fcx, expr.span,
3027 fcx.expr_ty(base));
3028 let mut tuple_like = false;
3029 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
85aaf69f
SL
3030 let (_, autoderefs, field_ty) = autoderef(fcx,
3031 expr.span,
3032 expr_t,
3033 Some(base),
3034 UnresolvedTypeAction::Error,
3035 lvalue_pref,
3036 |base_t, _| {
1a4d82fc 3037 match base_t.sty {
e9174d1e
SL
3038 ty::TyStruct(base_def, substs) => {
3039 tuple_like = base_def.struct_variant().is_tuple_struct();
1a4d82fc 3040 if tuple_like {
62682a34 3041 debug!("tuple struct named {:?}", base_t);
e9174d1e
SL
3042 base_def.struct_variant()
3043 .fields
3044 .get(idx.node)
3045 .map(|f| fcx.field_ty(expr.span, f, substs))
1a4d82fc
JJ
3046 } else {
3047 None
3048 }
3049 }
62682a34 3050 ty::TyTuple(ref v) => {
1a4d82fc
JJ
3051 tuple_like = true;
3052 if idx.node < v.len() { Some(v[idx.node]) } else { None }
3053 }
3054 _ => None
3055 }
3056 });
3057 match field_ty {
3058 Some(field_ty) => {
3059 fcx.write_ty(expr.id, field_ty);
9346a6ac 3060 fcx.write_autoderef_adjustment(base.id, autoderefs);
1a4d82fc
JJ
3061 return;
3062 }
3063 None => {}
3064 }
3065 fcx.type_error_message(
3066 expr.span,
3067 |actual| {
3068 if tuple_like {
3069 format!("attempted out-of-bounds tuple index `{}` on \
3070 type `{}`",
3071 idx.node,
3072 actual)
3073 } else {
3074 format!("attempted tuple index `{}` on type `{}`, but the \
3075 type was not a tuple or tuple struct",
3076 idx.node,
3077 actual)
3078 }
3079 },
3080 expr_t, None);
3081
3082 fcx.write_error(expr.id);
3083 }
3084
e9174d1e
SL
3085 fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3086 ty: Ty<'tcx>,
3087 variant: ty::VariantDef<'tcx>,
3088 field: &hir::Field,
3089 skip_fields: &[hir::Field]) {
3090 fcx.type_error_message(
b039eaaf 3091 field.name.span,
e9174d1e
SL
3092 |actual| if let ty::TyEnum(..) = ty.sty {
3093 format!("struct variant `{}::{}` has no field named `{}`",
b039eaaf 3094 actual, variant.name.as_str(), field.name.node)
e9174d1e
SL
3095 } else {
3096 format!("structure `{}` has no field named `{}`",
b039eaaf 3097 actual, field.name.node)
e9174d1e
SL
3098 },
3099 ty,
3100 None);
3101 // prevent all specified fields from being suggested
b039eaaf
SL
3102 let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
3103 suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
e9174d1e
SL
3104 }
3105
e9174d1e
SL
3106 fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3107 adt_ty: Ty<'tcx>,
3108 span: Span,
3109 variant: ty::VariantDef<'tcx>,
3110 ast_fields: &'tcx [hir::Field],
3111 check_completeness: bool) {
1a4d82fc 3112 let tcx = fcx.ccx.tcx;
e9174d1e
SL
3113 let substs = match adt_ty.sty {
3114 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
3115 _ => tcx.sess.span_bug(span, "non-ADT passed to check_expr_struct_fields")
3116 };
1a4d82fc 3117
e9174d1e
SL
3118 let mut remaining_fields = FnvHashMap();
3119 for field in &variant.fields {
3120 remaining_fields.insert(field.name, field);
1a4d82fc
JJ
3121 }
3122
3123 let mut error_happened = false;
3124
3125 // Typecheck each field.
85aaf69f 3126 for field in ast_fields {
e9174d1e
SL
3127 let expected_field_type;
3128
b039eaaf 3129 if let Some(v_field) = remaining_fields.remove(&field.name.node) {
e9174d1e
SL
3130 expected_field_type = fcx.field_ty(field.span, v_field, substs);
3131 } else {
3132 error_happened = true;
3133 expected_field_type = tcx.types.err;
b039eaaf
SL
3134 if let Some(_) = variant.find_field_named(field.name.node) {
3135 span_err!(fcx.tcx().sess, field.name.span, E0062,
1a4d82fc 3136 "field `{}` specified more than once",
b039eaaf 3137 field.name.node);
e9174d1e
SL
3138 } else {
3139 report_unknown_field(fcx, adt_ty, variant, field, ast_fields);
1a4d82fc
JJ
3140 }
3141 }
3142
3143 // Make sure to give a type to the field even if there's
3144 // an error, so we can continue typechecking
3145 check_expr_coercable_to_type(fcx, &*field.expr, expected_field_type);
3146 }
3147
1a4d82fc 3148 // Make sure the programmer specified all the fields.
e9174d1e
SL
3149 if check_completeness &&
3150 !error_happened &&
3151 !remaining_fields.is_empty()
3152 {
3153 span_err!(tcx.sess, span, E0063,
3154 "missing field{}: {}",
3155 if remaining_fields.len() == 1 {""} else {"s"},
3156 remaining_fields.keys()
3157 .map(|n| format!("`{}`", n))
3158 .collect::<Vec<_>>()
3159 .join(", "));
1a4d82fc
JJ
3160 }
3161
1a4d82fc
JJ
3162 }
3163
85aaf69f
SL
3164 fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3165 id: ast::NodeId,
e9174d1e
SL
3166 fields: &'tcx [hir::Field],
3167 base_expr: &'tcx Option<P<hir::Expr>>) {
1a4d82fc
JJ
3168 // Make sure to still write the types
3169 // otherwise we might ICE
3170 fcx.write_error(id);
85aaf69f 3171 for field in fields {
1a4d82fc
JJ
3172 check_expr(fcx, &*field.expr);
3173 }
3174 match *base_expr {
3175 Some(ref base) => check_expr(fcx, &**base),
3176 None => {}
3177 }
3178 }
3179
e9174d1e
SL
3180 fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
3181 expr: &hir::Expr,
3182 path: &hir::Path,
3183 fields: &'tcx [hir::Field],
3184 base_expr: &'tcx Option<P<hir::Expr>>)
3185 {
3186 let tcx = fcx.tcx();
3187
3188 // Find the relevant variant
3189 let def = lookup_full_def(tcx, path.span, expr.id);
b039eaaf 3190 let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
e9174d1e
SL
3191 Some((adt, variant)) => (adt, variant),
3192 None => {
3193 span_err!(fcx.tcx().sess, path.span, E0071,
3194 "`{}` does not name a structure",
3195 pprust::path_to_string(path));
3196 check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
3197 return;
3198 }
3199 };
3200
3201 let expr_ty = fcx.instantiate_type(def.def_id(), path);
3202 fcx.write_ty(expr.id, expr_ty);
3203
3204 check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
3205 base_expr.is_none());
3206
3207 if let &Some(ref base_expr) = base_expr {
3208 check_expr_has_type(fcx, base_expr, expr_ty);
3209 if adt.adt_kind() == ty::AdtKind::Enum {
3210 span_err!(tcx.sess, base_expr.span, E0436,
3211 "functional record update syntax requires a struct");
3212 }
3213 }
3214 }
3215
3216 type ExprCheckerWithTy = fn(&FnCtxt, &hir::Expr, Ty);
1a4d82fc
JJ
3217
3218 let tcx = fcx.ccx.tcx;
3219 let id = expr.id;
3220 match expr.node {
b039eaaf
SL
3221 hir::ExprBox(ref subexpr) => {
3222 let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
3223 match ty.sty {
3224 ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
3225 _ => NoExpectation
3226 }
3227 });
3228 check_expr_with_expectation(fcx, subexpr, expected_inner);
3229 let referent_ty = fcx.expr_ty(&**subexpr);
3230 fcx.write_ty(id, tcx.mk_box(referent_ty));
1a4d82fc
JJ
3231 }
3232
e9174d1e 3233 hir::ExprLit(ref lit) => {
1a4d82fc
JJ
3234 let typ = check_lit(fcx, &**lit, expected);
3235 fcx.write_ty(id, typ);
3236 }
e9174d1e 3237 hir::ExprBinary(op, ref lhs, ref rhs) => {
c34b1796 3238 op::check_binop(fcx, expr, op, lhs, rhs);
1a4d82fc 3239 }
e9174d1e 3240 hir::ExprAssignOp(op, ref lhs, ref rhs) => {
c34b1796 3241 op::check_binop_assign(fcx, expr, op, lhs, rhs);
1a4d82fc 3242 }
e9174d1e 3243 hir::ExprUnary(unop, ref oprnd) => {
b039eaaf
SL
3244 let expected_inner = match unop {
3245 hir::UnNot | hir::UnNeg => {
3246 expected
1a4d82fc 3247 }
b039eaaf
SL
3248 hir::UnDeref => {
3249 NoExpectation
3250 }
3251 };
1a4d82fc 3252 let lvalue_pref = match unop {
e9174d1e 3253 hir::UnDeref => lvalue_pref,
1a4d82fc
JJ
3254 _ => NoPreference
3255 };
3256 check_expr_with_expectation_and_lvalue_pref(
3257 fcx, &**oprnd, expected_inner, lvalue_pref);
3258 let mut oprnd_t = fcx.expr_ty(&**oprnd);
3259
c1a9b12d 3260 if !oprnd_t.references_error() {
1a4d82fc 3261 match unop {
e9174d1e 3262 hir::UnDeref => {
1a4d82fc 3263 oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
e9174d1e 3264 oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
1a4d82fc
JJ
3265 Some(mt) => mt.ty,
3266 None => match try_overloaded_deref(fcx, expr.span,
3267 Some(MethodCall::expr(expr.id)),
3268 Some(&**oprnd), oprnd_t, lvalue_pref) {
3269 Some(mt) => mt.ty,
3270 None => {
62682a34
SL
3271 fcx.type_error_message(expr.span, |actual| {
3272 format!("type `{}` cannot be \
3273 dereferenced", actual)
3274 }, oprnd_t, None);
1a4d82fc
JJ
3275 tcx.types.err
3276 }
3277 }
3278 };
3279 }
e9174d1e 3280 hir::UnNot => {
1a4d82fc
JJ
3281 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3282 oprnd_t);
c1a9b12d 3283 if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) {
c34b1796
AL
3284 oprnd_t = op::check_user_unop(fcx, "!", "not",
3285 tcx.lang_items.not_trait(),
3286 expr, &**oprnd, oprnd_t, unop);
1a4d82fc
JJ
3287 }
3288 }
e9174d1e 3289 hir::UnNeg => {
1a4d82fc
JJ
3290 oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3291 oprnd_t);
c1a9b12d 3292 if !(oprnd_t.is_integral() || oprnd_t.is_fp()) {
c34b1796
AL
3293 oprnd_t = op::check_user_unop(fcx, "-", "neg",
3294 tcx.lang_items.neg_trait(),
3295 expr, &**oprnd, oprnd_t, unop);
3296 }
1a4d82fc
JJ
3297 }
3298 }
3299 }
3300 fcx.write_ty(id, oprnd_t);
3301 }
e9174d1e 3302 hir::ExprAddrOf(mutbl, ref oprnd) => {
85aaf69f 3303 let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
1a4d82fc 3304 match ty.sty {
62682a34 3305 ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
c1a9b12d 3306 if fcx.tcx().expr_is_lval(&**oprnd) {
1a4d82fc
JJ
3307 // Lvalues may legitimately have unsized types.
3308 // For example, dereferences of a fat pointer and
3309 // the last field of a struct can be unsized.
3310 ExpectHasType(mt.ty)
3311 } else {
c1a9b12d 3312 Expectation::rvalue_hint(tcx, mt.ty)
1a4d82fc
JJ
3313 }
3314 }
3315 _ => NoExpectation
3316 }
3317 });
62682a34 3318 let lvalue_pref = LvaluePreference::from_mutbl(mutbl);
1a4d82fc
JJ
3319 check_expr_with_expectation_and_lvalue_pref(fcx,
3320 &**oprnd,
3321 hint,
3322 lvalue_pref);
3323
c1a9b12d
SL
3324 let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
3325 let oprnd_t = if tm.ty.references_error() {
1a4d82fc
JJ
3326 tcx.types.err
3327 } else {
3328 // Note: at this point, we cannot say what the best lifetime
3329 // is to use for resulting pointer. We want to use the
3330 // shortest lifetime possible so as to avoid spurious borrowck
3331 // errors. Moreover, the longest lifetime will depend on the
3332 // precise details of the value whose address is being taken
3333 // (and how long it is valid), which we don't know yet until type
3334 // inference is complete.
3335 //
3336 // Therefore, here we simply generate a region variable. The
3337 // region inferencer will then select the ultimate value.
3338 // Finally, borrowck is charged with guaranteeing that the
3339 // value whose address was taken can actually be made to live
3340 // as long as it needs to live.
85aaf69f 3341 let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span));
c1a9b12d 3342 tcx.mk_ref(tcx.mk_region(region), tm)
1a4d82fc
JJ
3343 };
3344 fcx.write_ty(id, oprnd_t);
3345 }
e9174d1e 3346 hir::ExprPath(ref maybe_qself, ref path) => {
c34b1796
AL
3347 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
3348 fcx.to_ty(&qself.ty)
3349 });
85aaf69f 3350
c34b1796
AL
3351 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
3352 d
e9174d1e 3353 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
c34b1796
AL
3354 // Create some fake resolution that can't possibly be a type.
3355 def::PathResolution {
b039eaaf 3356 base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
c34b1796
AL
3357 last_private: LastMod(AllPublic),
3358 depth: path.segments.len()
3359 }
3360 } else {
3361 tcx.sess.span_bug(expr.span,
62682a34 3362 &format!("unbound path {:?}", expr))
c34b1796
AL
3363 };
3364
d9579d0f
AL
3365 if let Some((opt_ty, segments, def)) =
3366 resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
3367 expr.span, expr.id) {
9346a6ac
AL
3368 let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
3369 expr.span,
3370 def);
3371 instantiate_path(fcx,
d9579d0f 3372 segments,
9346a6ac
AL
3373 scheme,
3374 &predicates,
d9579d0f 3375 opt_ty,
9346a6ac
AL
3376 def,
3377 expr.span,
3378 id);
c34b1796 3379 }
1a4d82fc
JJ
3380
3381 // We always require that the type provided as the value for
3382 // a type parameter outlives the moment of instantiation.
e9174d1e
SL
3383 fcx.opt_node_ty_substs(expr.id, |item_substs| {
3384 fcx.add_wf_bounds(&item_substs.substs, expr);
3385 });
1a4d82fc 3386 }
e9174d1e 3387 hir::ExprInlineAsm(ref ia) => {
85aaf69f 3388 for &(_, ref input) in &ia.inputs {
1a4d82fc
JJ
3389 check_expr(fcx, &**input);
3390 }
85aaf69f 3391 for &(_, ref out, _) in &ia.outputs {
1a4d82fc
JJ
3392 check_expr(fcx, &**out);
3393 }
3394 fcx.write_nil(id);
3395 }
e9174d1e
SL
3396 hir::ExprBreak(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3397 hir::ExprAgain(_) => { fcx.write_ty(id, fcx.infcx().next_diverging_ty_var()); }
3398 hir::ExprRet(ref expr_opt) => {
1a4d82fc
JJ
3399 match fcx.ret_ty {
3400 ty::FnConverging(result_type) => {
3401 match *expr_opt {
3402 None =>
3403 if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span),
c1a9b12d 3404 result_type, fcx.tcx().mk_nil()) {
1a4d82fc 3405 span_err!(tcx.sess, expr.span, E0069,
d9579d0f
AL
3406 "`return;` in a function whose return type is \
3407 not `()`");
1a4d82fc
JJ
3408 },
3409 Some(ref e) => {
3410 check_expr_coercable_to_type(fcx, &**e, result_type);
3411 }
3412 }
3413 }
3414 ty::FnDiverging => {
3415 if let Some(ref e) = *expr_opt {
3416 check_expr(fcx, &**e);
3417 }
3418 span_err!(tcx.sess, expr.span, E0166,
3419 "`return` in a function declared as diverging");
3420 }
3421 }
3422 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3423 }
e9174d1e 3424 hir::ExprAssign(ref lhs, ref rhs) => {
1a4d82fc
JJ
3425 check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
3426
3427 let tcx = fcx.tcx();
c1a9b12d 3428 if !tcx.expr_is_lval(&**lhs) {
1a4d82fc 3429 span_err!(tcx.sess, expr.span, E0070,
c1a9b12d 3430 "invalid left-hand side expression");
1a4d82fc
JJ
3431 }
3432
3433 let lhs_ty = fcx.expr_ty(&**lhs);
3434 check_expr_coercable_to_type(fcx, &**rhs, lhs_ty);
3435 let rhs_ty = fcx.expr_ty(&**rhs);
3436
3437 fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
3438
c1a9b12d 3439 if lhs_ty.references_error() || rhs_ty.references_error() {
1a4d82fc
JJ
3440 fcx.write_error(id);
3441 } else {
3442 fcx.write_nil(id);
3443 }
3444 }
e9174d1e 3445 hir::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
1a4d82fc
JJ
3446 check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
3447 id, expr.span, expected);
3448 }
e9174d1e 3449 hir::ExprWhile(ref cond, ref body, _) => {
1a4d82fc
JJ
3450 check_expr_has_type(fcx, &**cond, tcx.types.bool);
3451 check_block_no_value(fcx, &**body);
3452 let cond_ty = fcx.expr_ty(&**cond);
3453 let body_ty = fcx.node_ty(body.id);
c1a9b12d 3454 if cond_ty.references_error() || body_ty.references_error() {
1a4d82fc
JJ
3455 fcx.write_error(id);
3456 }
3457 else {
3458 fcx.write_nil(id);
3459 }
3460 }
e9174d1e 3461 hir::ExprLoop(ref body, _) => {
1a4d82fc
JJ
3462 check_block_no_value(fcx, &**body);
3463 if !may_break(tcx, expr.id, &**body) {
3464 fcx.write_ty(id, fcx.infcx().next_diverging_ty_var());
3465 } else {
3466 fcx.write_nil(id);
3467 }
3468 }
e9174d1e 3469 hir::ExprMatch(ref discrim, ref arms, match_src) => {
85aaf69f 3470 _match::check_match(fcx, expr, &**discrim, arms, expected, match_src);
1a4d82fc 3471 }
e9174d1e 3472 hir::ExprClosure(capture, ref decl, ref body) => {
85aaf69f 3473 closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
1a4d82fc 3474 }
e9174d1e 3475 hir::ExprBlock(ref b) => {
1a4d82fc
JJ
3476 check_block_with_expected(fcx, &**b, expected);
3477 fcx.write_ty(id, fcx.node_ty(b.id));
3478 }
e9174d1e 3479 hir::ExprCall(ref callee, ref args) => {
85aaf69f 3480 callee::check_call(fcx, expr, &**callee, &args[..], expected);
e9174d1e
SL
3481
3482 // we must check that return type of called functions is WF:
3483 let ret_ty = fcx.expr_ty(expr);
3484 fcx.register_wf_obligation(ret_ty, expr.span, traits::MiscObligation);
1a4d82fc 3485 }
b039eaaf
SL
3486 hir::ExprMethodCall(name, ref tps, ref args) => {
3487 check_method_call(fcx, expr, name, &args[..], &tps[..], expected, lvalue_pref);
e9174d1e
SL
3488 let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
3489 let args_err = arg_tys.fold(false, |rest_err, a| rest_err || a.references_error());
3490 if args_err {
3491 fcx.write_error(id);
3492 }
1a4d82fc 3493 }
e9174d1e
SL
3494 hir::ExprCast(ref e, ref t) => {
3495 if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
c34b1796
AL
3496 check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
3497 }
3498
3499 // Find the type of `e`. Supply hints based on the type we are casting to,
3500 // if appropriate.
62682a34
SL
3501 let t_cast = fcx.to_ty(t);
3502 let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
3503 check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
3504 let t_expr = fcx.expr_ty(e);
c34b1796
AL
3505
3506 // Eagerly check for some obvious errors.
c1a9b12d 3507 if t_expr.references_error() {
c34b1796 3508 fcx.write_error(id);
62682a34
SL
3509 } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
3510 report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
c34b1796
AL
3511 } else {
3512 // Write a type for the whole expression, assuming everything is going
3513 // to work out Ok.
62682a34 3514 fcx.write_ty(id, t_cast);
c34b1796
AL
3515
3516 // Defer other checks until we're done type checking.
3517 let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
62682a34 3518 let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
9346a6ac 3519 deferred_cast_checks.push(cast_check);
1a4d82fc 3520 }
1a4d82fc 3521 }
e9174d1e 3522 hir::ExprVec(ref args) => {
85aaf69f 3523 let uty = expected.to_option(fcx).and_then(|uty| {
1a4d82fc 3524 match uty.sty {
62682a34 3525 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
1a4d82fc
JJ
3526 _ => None
3527 }
3528 });
3529
3530 let typ = match uty {
3531 Some(uty) => {
85aaf69f 3532 for e in args {
1a4d82fc
JJ
3533 check_expr_coercable_to_type(fcx, &**e, uty);
3534 }
3535 uty
3536 }
3537 None => {
3538 let t: Ty = fcx.infcx().next_ty_var();
85aaf69f 3539 for e in args {
1a4d82fc
JJ
3540 check_expr_has_type(fcx, &**e, t);
3541 }
3542 t
3543 }
3544 };
c1a9b12d 3545 let typ = tcx.mk_array(typ, args.len());
1a4d82fc
JJ
3546 fcx.write_ty(id, typ);
3547 }
e9174d1e 3548 hir::ExprRepeat(ref element, ref count_expr) => {
c34b1796 3549 check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
c1a9b12d 3550 let count = fcx.tcx().eval_repeat_count(&**count_expr);
1a4d82fc
JJ
3551
3552 let uty = match expected {
3553 ExpectHasType(uty) => {
3554 match uty.sty {
62682a34 3555 ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
1a4d82fc
JJ
3556 _ => None
3557 }
3558 }
3559 _ => None
3560 };
3561
3562 let (element_ty, t) = match uty {
3563 Some(uty) => {
3564 check_expr_coercable_to_type(fcx, &**element, uty);
3565 (uty, uty)
3566 }
3567 None => {
3568 let t: Ty = fcx.infcx().next_ty_var();
3569 check_expr_has_type(fcx, &**element, t);
3570 (fcx.expr_ty(&**element), t)
3571 }
3572 };
3573
3574 if count > 1 {
3575 // For [foo, ..n] where n > 1, `foo` must have
3576 // Copy type:
3577 fcx.require_type_meets(
3578 t,
3579 expr.span,
3580 traits::RepeatVec,
3581 ty::BoundCopy);
3582 }
3583
c1a9b12d 3584 if element_ty.references_error() {
1a4d82fc
JJ
3585 fcx.write_error(id);
3586 } else {
c1a9b12d 3587 let t = tcx.mk_array(t, count);
1a4d82fc
JJ
3588 fcx.write_ty(id, t);
3589 }
3590 }
e9174d1e 3591 hir::ExprTup(ref elts) => {
85aaf69f 3592 let flds = expected.only_has_type(fcx).and_then(|ty| {
1a4d82fc 3593 match ty.sty {
62682a34 3594 ty::TyTuple(ref flds) => Some(&flds[..]),
1a4d82fc
JJ
3595 _ => None
3596 }
3597 });
3598 let mut err_field = false;
3599
3600 let elt_ts = elts.iter().enumerate().map(|(i, e)| {
3601 let t = match flds {
3602 Some(ref fs) if i < fs.len() => {
3603 let ety = fs[i];
3604 check_expr_coercable_to_type(fcx, &**e, ety);
3605 ety
3606 }
3607 _ => {
3608 check_expr_with_expectation(fcx, &**e, NoExpectation);
3609 fcx.expr_ty(&**e)
3610 }
3611 };
c1a9b12d 3612 err_field = err_field || t.references_error();
1a4d82fc
JJ
3613 t
3614 }).collect();
3615 if err_field {
3616 fcx.write_error(id);
3617 } else {
c1a9b12d 3618 let typ = tcx.mk_tup(elt_ts);
1a4d82fc
JJ
3619 fcx.write_ty(id, typ);
3620 }
3621 }
e9174d1e
SL
3622 hir::ExprStruct(ref path, ref fields, ref base_expr) => {
3623 check_expr_struct(fcx, expr, path, fields, base_expr);
1a4d82fc
JJ
3624
3625 fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized);
3626 }
e9174d1e 3627 hir::ExprField(ref base, ref field) => {
1a4d82fc
JJ
3628 check_field(fcx, expr, lvalue_pref, &**base, field);
3629 }
e9174d1e 3630 hir::ExprTupField(ref base, idx) => {
1a4d82fc
JJ
3631 check_tup_field(fcx, expr, lvalue_pref, &**base, idx);
3632 }
e9174d1e 3633 hir::ExprIndex(ref base, ref idx) => {
1a4d82fc 3634 check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
d9579d0f
AL
3635 check_expr(fcx, &**idx);
3636
1a4d82fc 3637 let base_t = fcx.expr_ty(&**base);
d9579d0f
AL
3638 let idx_t = fcx.expr_ty(&**idx);
3639
c1a9b12d 3640 if base_t.references_error() {
1a4d82fc 3641 fcx.write_ty(id, base_t);
c1a9b12d 3642 } else if idx_t.references_error() {
d9579d0f 3643 fcx.write_ty(id, idx_t);
1a4d82fc 3644 } else {
d9579d0f
AL
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);
3651 }
3652 None => {
3653 check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
3654 fcx.type_error_message(
3655 expr.span,
3656 |actual| {
3657 format!("cannot index a value of type `{}`",
3658 actual)
3659 },
3660 base_t,
3661 None);
3662 fcx.write_ty(id, fcx.tcx().types.err);
1a4d82fc
JJ
3663 }
3664 }
3665 }
3666 }
e9174d1e 3667 hir::ExprRange(ref start, ref end) => {
1a4d82fc
JJ
3668 let t_start = start.as_ref().map(|e| {
3669 check_expr(fcx, &**e);
3670 fcx.expr_ty(&**e)
3671 });
3672 let t_end = end.as_ref().map(|e| {
3673 check_expr(fcx, &**e);
3674 fcx.expr_ty(&**e)
3675 });
3676
3677 let idx_type = match (t_start, t_end) {
3678 (Some(ty), None) | (None, Some(ty)) => {
3679 Some(ty)
3680 }
c1a9b12d
SL
3681 (Some(t_start), Some(t_end)) if (t_start.references_error() ||
3682 t_end.references_error()) => {
1a4d82fc
JJ
3683 Some(fcx.tcx().types.err)
3684 }
3685 (Some(t_start), Some(t_end)) => {
3686 Some(infer::common_supertype(fcx.infcx(),
3687 infer::RangeExpression(expr.span),
3688 true,
3689 t_start,
3690 t_end))
3691 }
3692 _ => None
3693 };
3694
3695 // Note that we don't check the type of start/end satisfy any
3696 // bounds because right now the range structs do not have any. If we add
3697 // some bounds, then we'll need to check `t_start` against them here.
3698
3699 let range_type = match idx_type {
c1a9b12d 3700 Some(idx_type) if idx_type.references_error() => {
1a4d82fc
JJ
3701 fcx.tcx().types.err
3702 }
3703 Some(idx_type) => {
3704 // Find the did from the appropriate lang item.
3705 let did = match (start, end) {
3706 (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
3707 (&Some(_), &None) => tcx.lang_items.range_from_struct(),
3708 (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
3709 (&None, &None) => {
3710 tcx.sess.span_bug(expr.span, "full range should be dealt with above")
3711 }
3712 };
3713
3714 if let Some(did) = did {
e9174d1e 3715 let def = tcx.lookup_adt_def(did);
c1a9b12d 3716 let predicates = tcx.lookup_predicates(did);
1a4d82fc 3717 let substs = Substs::new_type(vec![idx_type], vec![]);
85aaf69f 3718 let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
1a4d82fc
JJ
3719 fcx.add_obligations_for_parameters(
3720 traits::ObligationCause::new(expr.span,
3721 fcx.body_id,
3722 traits::ItemObligation(did)),
3723 &bounds);
3724
e9174d1e 3725 tcx.mk_struct(def, tcx.mk_substs(substs))
1a4d82fc 3726 } else {
85aaf69f 3727 span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
1a4d82fc
JJ
3728 fcx.tcx().types.err
3729 }
3730 }
3731 None => {
85aaf69f
SL
3732 // Neither start nor end => RangeFull
3733 if let Some(did) = tcx.lang_items.range_full_struct() {
e9174d1e
SL
3734 tcx.mk_struct(
3735 tcx.lookup_adt_def(did),
3736 tcx.mk_substs(Substs::empty())
3737 )
1a4d82fc 3738 } else {
85aaf69f 3739 span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
1a4d82fc
JJ
3740 fcx.tcx().types.err
3741 }
3742 }
3743 };
3744
3745 fcx.write_ty(id, range_type);
3746 }
3747
3748 }
3749
3750 debug!("type of expr({}) {} is...", expr.id,
e9174d1e 3751 pprust::expr_to_string(expr));
62682a34
SL
3752 debug!("... {:?}, expected is {:?}",
3753 fcx.expr_ty(expr),
3754 expected);
1a4d82fc
JJ
3755
3756 unifier();
3757}
3758
d9579d0f
AL
3759pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
3760 path_res: def::PathResolution,
3761 opt_self_ty: Option<Ty<'tcx>>,
e9174d1e 3762 path: &'a hir::Path,
d9579d0f
AL
3763 span: Span,
3764 node_id: ast::NodeId)
3765 -> Option<(Option<Ty<'tcx>>,
e9174d1e 3766 &'a [hir::PathSegment],
d9579d0f
AL
3767 def::Def)>
3768{
62682a34
SL
3769
3770 // Associated constants can't depend on generic types.
3771 fn have_disallowed_generic_consts<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3772 def: def::Def,
3773 ty: Ty<'tcx>,
3774 span: Span,
3775 node_id: ast::NodeId) -> bool {
3776 match def {
3777 def::DefAssociatedConst(..) => {
c1a9b12d 3778 if ty.has_param_types() || ty.has_self_ty() {
62682a34
SL
3779 span_err!(fcx.sess(), span, E0329,
3780 "Associated consts cannot depend \
3781 on type parameters or Self.");
3782 fcx.write_error(node_id);
3783 return true;
3784 }
3785 }
3786 _ => {}
3787 }
3788 false
3789 }
3790
d9579d0f
AL
3791 // If fully resolved already, we don't have to do anything.
3792 if path_res.depth == 0 {
62682a34
SL
3793 if let Some(ty) = opt_self_ty {
3794 if have_disallowed_generic_consts(fcx, path_res.full_def(), ty,
3795 span, node_id) {
3796 return None;
3797 }
3798 }
d9579d0f
AL
3799 Some((opt_self_ty, &path.segments, path_res.base_def))
3800 } else {
3801 let mut def = path_res.base_def;
c1a9b12d 3802 let ty_segments = path.segments.split_last().unwrap().1;
d9579d0f
AL
3803 let base_ty_end = path.segments.len() - path_res.depth;
3804 let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
3805 PathParamMode::Optional,
3806 &mut def,
3807 opt_self_ty,
3808 &ty_segments[..base_ty_end],
3809 &ty_segments[base_ty_end..]);
3810 let item_segment = path.segments.last().unwrap();
3811 let item_name = item_segment.identifier.name;
3812 match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3813 Ok((def, lp)) => {
62682a34
SL
3814 if have_disallowed_generic_consts(fcx, def, ty, span, node_id) {
3815 return None;
3816 }
d9579d0f
AL
3817 // Write back the new resolution.
3818 fcx.ccx.tcx.def_map.borrow_mut()
3819 .insert(node_id, def::PathResolution {
3820 base_def: def,
3821 last_private: path_res.last_private.or(lp),
3822 depth: 0
3823 });
3824 Some((Some(ty), slice::ref_slice(item_segment), def))
3825 }
3826 Err(error) => {
3827 method::report_error(fcx, span, ty,
3828 item_name, None, error);
3829 fcx.write_error(node_id);
3830 None
3831 }
3832 }
3833 }
3834}
3835
1a4d82fc
JJ
3836impl<'tcx> Expectation<'tcx> {
3837 /// Provide an expectation for an rvalue expression given an *optional*
3838 /// hint, which is not required for type safety (the resulting type might
3839 /// be checked higher up, as is the case with `&expr` and `box expr`), but
3840 /// is useful in determining the concrete type.
3841 ///
3842 /// The primary use case is where the expected type is a fat pointer,
c34b1796 3843 /// like `&[isize]`. For example, consider the following statement:
1a4d82fc 3844 ///
c34b1796 3845 /// let x: &[isize] = &[1, 2, 3];
1a4d82fc
JJ
3846 ///
3847 /// In this case, the expected type for the `&[1, 2, 3]` expression is
c34b1796
AL
3848 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
3849 /// expectation `ExpectHasType([isize])`, that would be too strong --
3850 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
1a4d82fc 3851 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
c34b1796 3852 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
1a4d82fc
JJ
3853 /// which still is useful, because it informs integer literals and the like.
3854 /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
3855 /// for examples of where this comes up,.
c1a9b12d
SL
3856 fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
3857 match tcx.struct_tail(ty).sty {
62682a34 3858 ty::TySlice(_) | ty::TyTrait(..) => {
1a4d82fc
JJ
3859 ExpectRvalueLikeUnsized(ty)
3860 }
3861 _ => ExpectHasType(ty)
3862 }
3863 }
3864
1a4d82fc
JJ
3865 // Resolves `expected` by a single level if it is a variable. If
3866 // there is no expected type or resolution is not possible (e.g.,
3867 // no constraints yet present), just returns `None`.
3868 fn resolve<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
3869 match self {
3870 NoExpectation => {
3871 NoExpectation
3872 }
3873 ExpectCastableToType(t) => {
3874 ExpectCastableToType(
3875 fcx.infcx().resolve_type_vars_if_possible(&t))
3876 }
3877 ExpectHasType(t) => {
3878 ExpectHasType(
3879 fcx.infcx().resolve_type_vars_if_possible(&t))
3880 }
3881 ExpectRvalueLikeUnsized(t) => {
3882 ExpectRvalueLikeUnsized(
3883 fcx.infcx().resolve_type_vars_if_possible(&t))
3884 }
3885 }
3886 }
3887
85aaf69f 3888 fn to_option<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
1a4d82fc 3889 match self.resolve(fcx) {
85aaf69f 3890 NoExpectation => None,
1a4d82fc
JJ
3891 ExpectCastableToType(ty) |
3892 ExpectHasType(ty) |
85aaf69f 3893 ExpectRvalueLikeUnsized(ty) => Some(ty),
1a4d82fc
JJ
3894 }
3895 }
3896
85aaf69f 3897 fn only_has_type<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
1a4d82fc 3898 match self.resolve(fcx) {
85aaf69f
SL
3899 ExpectHasType(ty) => Some(ty),
3900 _ => None
1a4d82fc
JJ
3901 }
3902 }
3903}
3904
85aaf69f 3905pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
e9174d1e
SL
3906 local: &'tcx hir::Local,
3907 init: &'tcx hir::Expr)
1a4d82fc 3908{
c34b1796
AL
3909 let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
3910
3911 let local_ty = fcx.local_ty(init.span, local.id);
62682a34 3912 if let Some(m) = ref_bindings {
c34b1796
AL
3913 // Somewhat subtle: if we have a `ref` binding in the pattern,
3914 // we want to avoid introducing coercions for the RHS. This is
3915 // both because it helps preserve sanity and, in the case of
3916 // ref mut, for soundness (issue #23116). In particular, in
3917 // the latter case, we need to be clear that the type of the
3918 // referent for the reference that results is *equal to* the
3919 // type of the lvalue it is referencing, and not some
3920 // supertype thereof.
62682a34 3921 check_expr_with_lvalue_pref(fcx, init, LvaluePreference::from_mutbl(m));
c34b1796
AL
3922 let init_ty = fcx.expr_ty(init);
3923 demand::eqtype(fcx, init.span, init_ty, local_ty);
62682a34
SL
3924 } else {
3925 check_expr_coercable_to_type(fcx, init, local_ty)
c34b1796 3926 };
1a4d82fc
JJ
3927}
3928
e9174d1e 3929pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx hir::Local) {
1a4d82fc
JJ
3930 let tcx = fcx.ccx.tcx;
3931
3932 let t = fcx.local_ty(local.span, local.id);
3933 fcx.write_ty(local.id, t);
3934
3935 if let Some(ref init) = local.init {
c34b1796 3936 check_decl_initializer(fcx, local, &**init);
1a4d82fc 3937 let init_ty = fcx.expr_ty(&**init);
c1a9b12d 3938 if init_ty.references_error() {
1a4d82fc
JJ
3939 fcx.write_ty(local.id, init_ty);
3940 }
3941 }
3942
3943 let pcx = pat_ctxt {
3944 fcx: fcx,
3945 map: pat_id_map(&tcx.def_map, &*local.pat),
3946 };
3947 _match::check_pat(&pcx, &*local.pat, t);
3948 let pat_ty = fcx.node_ty(local.pat.id);
c1a9b12d 3949 if pat_ty.references_error() {
1a4d82fc
JJ
3950 fcx.write_ty(local.id, pat_ty);
3951 }
3952}
3953
e9174d1e 3954pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx hir::Stmt) {
1a4d82fc
JJ
3955 let node_id;
3956 let mut saw_bot = false;
3957 let mut saw_err = false;
3958 match stmt.node {
e9174d1e 3959 hir::StmtDecl(ref decl, id) => {
1a4d82fc
JJ
3960 node_id = id;
3961 match decl.node {
e9174d1e 3962 hir::DeclLocal(ref l) => {
1a4d82fc
JJ
3963 check_decl_local(fcx, &**l);
3964 let l_t = fcx.node_ty(l.id);
3965 saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
c1a9b12d 3966 saw_err = saw_err || l_t.references_error();
1a4d82fc 3967 }
e9174d1e 3968 hir::DeclItem(_) => {/* ignore for now */ }
1a4d82fc
JJ
3969 }
3970 }
e9174d1e 3971 hir::StmtExpr(ref expr, id) => {
1a4d82fc
JJ
3972 node_id = id;
3973 // Check with expected type of ()
c1a9b12d 3974 check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil());
1a4d82fc
JJ
3975 let expr_ty = fcx.expr_ty(&**expr);
3976 saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
c1a9b12d 3977 saw_err = saw_err || expr_ty.references_error();
1a4d82fc 3978 }
e9174d1e 3979 hir::StmtSemi(ref expr, id) => {
1a4d82fc
JJ
3980 node_id = id;
3981 check_expr(fcx, &**expr);
3982 let expr_ty = fcx.expr_ty(&**expr);
3983 saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
c1a9b12d 3984 saw_err |= expr_ty.references_error();
1a4d82fc 3985 }
1a4d82fc
JJ
3986 }
3987 if saw_bot {
3988 fcx.write_ty(node_id, fcx.infcx().next_diverging_ty_var());
3989 }
3990 else if saw_err {
3991 fcx.write_error(node_id);
3992 }
3993 else {
3994 fcx.write_nil(node_id)
3995 }
3996}
3997
e9174d1e 3998pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx hir::Block) {
c1a9b12d 3999 check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil()));
1a4d82fc 4000 let blkty = fcx.node_ty(blk.id);
c1a9b12d 4001 if blkty.references_error() {
1a4d82fc
JJ
4002 fcx.write_error(blk.id);
4003 } else {
c1a9b12d 4004 let nilty = fcx.tcx().mk_nil();
1a4d82fc
JJ
4005 demand::suptype(fcx, blk.span, nilty, blkty);
4006 }
4007}
4008
4009fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 4010 blk: &'tcx hir::Block,
1a4d82fc
JJ
4011 expected: Expectation<'tcx>) {
4012 let prev = {
4013 let mut fcx_ps = fcx.ps.borrow_mut();
4014 let unsafety_state = fcx_ps.recurse(blk);
4015 replace(&mut *fcx_ps, unsafety_state)
4016 };
4017
4018 let mut warned = false;
4019 let mut any_diverges = false;
4020 let mut any_err = false;
85aaf69f 4021 for s in &blk.stmts {
1a4d82fc 4022 check_stmt(fcx, &**s);
e9174d1e 4023 let s_id = ::rustc_front::util::stmt_id(&**s);
1a4d82fc
JJ
4024 let s_ty = fcx.node_ty(s_id);
4025 if any_diverges && !warned && match s.node {
e9174d1e 4026 hir::StmtDecl(ref decl, _) => {
1a4d82fc 4027 match decl.node {
e9174d1e 4028 hir::DeclLocal(_) => true,
1a4d82fc
JJ
4029 _ => false,
4030 }
4031 }
e9174d1e 4032 hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
1a4d82fc
JJ
4033 } {
4034 fcx.ccx
4035 .tcx
4036 .sess
4037 .add_lint(lint::builtin::UNREACHABLE_CODE,
4038 s_id,
4039 s.span,
4040 "unreachable statement".to_string());
4041 warned = true;
4042 }
4043 any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
c1a9b12d 4044 any_err = any_err || s_ty.references_error();
1a4d82fc
JJ
4045 }
4046 match blk.expr {
4047 None => if any_err {
4048 fcx.write_error(blk.id);
4049 } else if any_diverges {
4050 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4051 } else {
4052 fcx.write_nil(blk.id);
4053 },
4054 Some(ref e) => {
4055 if any_diverges && !warned {
4056 fcx.ccx
4057 .tcx
4058 .sess
4059 .add_lint(lint::builtin::UNREACHABLE_CODE,
4060 e.id,
4061 e.span,
4062 "unreachable expression".to_string());
4063 }
4064 let ety = match expected {
4065 ExpectHasType(ety) => {
4066 check_expr_coercable_to_type(fcx, &**e, ety);
4067 ety
4068 }
4069 _ => {
4070 check_expr_with_expectation(fcx, &**e, expected);
4071 fcx.expr_ty(&**e)
4072 }
4073 };
4074
4075 if any_err {
4076 fcx.write_error(blk.id);
4077 } else if any_diverges {
4078 fcx.write_ty(blk.id, fcx.infcx().next_diverging_ty_var());
4079 } else {
4080 fcx.write_ty(blk.id, ety);
4081 }
4082 }
4083 };
4084
4085 *fcx.ps.borrow_mut() = prev;
4086}
4087
4088/// Checks a constant appearing in a type. At the moment this is just the
4089/// length expression in a fixed-length vector, but someday it might be
4090/// extended to type-level numeric literals.
4091fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
e9174d1e 4092 expr: &'tcx hir::Expr,
1a4d82fc 4093 expected_type: Ty<'tcx>) {
c1a9b12d
SL
4094 let tables = RefCell::new(ty::Tables::empty());
4095 let inh = static_inherited_fields(ccx, &tables);
1a4d82fc
JJ
4096 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
4097 check_const_with_ty(&fcx, expr.span, expr, expected_type);
4098}
4099
85aaf69f
SL
4100fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4101 sp: Span,
e9174d1e 4102 e: &'tcx hir::Expr,
85aaf69f 4103 id: ast::NodeId) {
c1a9b12d
SL
4104 let tables = RefCell::new(ty::Tables::empty());
4105 let inh = static_inherited_fields(ccx, &tables);
4106 let rty = ccx.tcx.node_id_to_type(id);
1a4d82fc 4107 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
b039eaaf 4108 let declty = fcx.ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty;
1a4d82fc
JJ
4109 check_const_with_ty(&fcx, sp, e, declty);
4110}
4111
4112fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4113 _: Span,
e9174d1e 4114 e: &'tcx hir::Expr,
1a4d82fc
JJ
4115 declty: Ty<'tcx>) {
4116 // Gather locals in statics (because of block expressions).
4117 // This is technically unnecessary because locals in static items are forbidden,
4118 // but prevents type checking from blowing up before const checking can properly
b039eaaf 4119 // emit an error.
1a4d82fc
JJ
4120 GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
4121
4122 check_expr_with_hint(fcx, e, declty);
4123 demand::coerce(fcx, e.span, declty, e);
e9174d1e
SL
4124
4125 fcx.select_all_obligations_and_apply_defaults();
4126 upvar::closure_analyze_const(&fcx, e);
4127 fcx.select_obligations_where_possible();
c34b1796 4128 fcx.check_casts();
e9174d1e
SL
4129 fcx.select_all_obligations_or_error();
4130
1a4d82fc
JJ
4131 regionck::regionck_expr(fcx, e);
4132 writeback::resolve_type_vars_in_expr(fcx, e);
4133}
4134
4135/// Checks whether a type can be represented in memory. In particular, it
4136/// identifies types that contain themselves without indirection through a
c1a9b12d 4137/// pointer, which would mean their size is unbounded.
1a4d82fc
JJ
4138pub fn check_representable(tcx: &ty::ctxt,
4139 sp: Span,
4140 item_id: ast::NodeId,
4141 designation: &str) -> bool {
c1a9b12d 4142 let rty = tcx.node_id_to_type(item_id);
1a4d82fc
JJ
4143
4144 // Check that it is possible to represent this type. This call identifies
4145 // (1) types that contain themselves and (2) types that contain a different
4146 // recursive type. It is only necessary to throw an error on those that
4147 // contain themselves. For case 2, there must be an inner type that will be
4148 // caught by case 1.
c1a9b12d 4149 match rty.is_representable(tcx, sp) {
e9174d1e
SL
4150 Representability::SelfRecursive => {
4151 span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
4152 tcx.sess.fileline_help(
4153 sp, "wrap the inner value in a box to make it representable");
4154 return false
4155 }
4156 Representability::Representable | Representability::ContainsRecursive => (),
1a4d82fc
JJ
4157 }
4158 return true
4159}
4160
1a4d82fc 4161pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
c1a9b12d 4162 let t = tcx.node_id_to_type(id);
1a4d82fc 4163 match t.sty {
e9174d1e
SL
4164 ty::TyStruct(def, substs) => {
4165 let fields = &def.struct_variant().fields;
1a4d82fc
JJ
4166 if fields.is_empty() {
4167 span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
4168 return;
4169 }
e9174d1e
SL
4170 let e = fields[0].ty(tcx, substs);
4171 if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1a4d82fc
JJ
4172 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
4173 return;
4174 }
e9174d1e
SL
4175 match e.sty {
4176 ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
4177 _ if e.is_machine() => { /* struct(u8, u8, u8, u8) is ok */ }
4178 _ => {
4179 span_err!(tcx.sess, sp, E0077,
4180 "SIMD vector element type should be machine type");
4181 return;
4182 }
1a4d82fc
JJ
4183 }
4184 }
4185 _ => ()
4186 }
4187}
4188
85aaf69f
SL
4189pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
4190 sp: Span,
e9174d1e 4191 vs: &'tcx [P<hir::Variant>],
85aaf69f 4192 id: ast::NodeId) {
1a4d82fc
JJ
4193
4194 fn disr_in_range(ccx: &CrateCtxt,
4195 ty: attr::IntType,
4196 disr: ty::Disr) -> bool {
b039eaaf 4197 fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool {
1a4d82fc 4198 match ty {
b039eaaf
SL
4199 ast::TyU8 => disr as u8 as Disr == disr,
4200 ast::TyU16 => disr as u16 as Disr == disr,
4201 ast::TyU32 => disr as u32 as Disr == disr,
4202 ast::TyU64 => disr as u64 as Disr == disr,
4203 ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
1a4d82fc
JJ
4204 }
4205 }
b039eaaf 4206 fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
1a4d82fc 4207 match ty {
b039eaaf
SL
4208 ast::TyI8 => disr as i8 as Disr == disr,
4209 ast::TyI16 => disr as i16 as Disr == disr,
4210 ast::TyI32 => disr as i32 as Disr == disr,
4211 ast::TyI64 => disr as i64 as Disr == disr,
4212 ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
1a4d82fc
JJ
4213 }
4214 }
4215 match ty {
4216 attr::UnsignedInt(ty) => uint_in_range(ccx, ty, disr),
4217 attr::SignedInt(ty) => int_in_range(ccx, ty, disr)
4218 }
4219 }
4220
4221 fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
e9174d1e 4222 vs: &'tcx [P<hir::Variant>],
1a4d82fc 4223 id: ast::NodeId,
c34b1796
AL
4224 hint: attr::ReprAttr) {
4225 #![allow(trivial_numeric_casts)]
1a4d82fc 4226
c1a9b12d 4227 let rty = ccx.tcx.node_id_to_type(id);
1a4d82fc 4228 let mut disr_vals: Vec<ty::Disr> = Vec::new();
1a4d82fc 4229
c1a9b12d
SL
4230 let tables = RefCell::new(ty::Tables::empty());
4231 let inh = static_inherited_fields(ccx, &tables);
c34b1796
AL
4232 let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
4233
c1a9b12d 4234 let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
85aaf69f 4235 for v in vs {
c34b1796
AL
4236 if let Some(ref e) = v.node.disr_expr {
4237 check_const_with_ty(&fcx, e.span, e, repr_type_ty);
4238 }
4239 }
1a4d82fc 4240
b039eaaf 4241 let def_id = ccx.tcx.map.local_def_id(id);
1a4d82fc 4242
e9174d1e 4243 let variants = &ccx.tcx.lookup_adt_def(def_id).variants;
c34b1796
AL
4244 for (v, variant) in vs.iter().zip(variants.iter()) {
4245 let current_disr_val = variant.disr_val;
1a4d82fc
JJ
4246
4247 // Check for duplicate discriminant values
4248 match disr_vals.iter().position(|&x| x == current_disr_val) {
4249 Some(i) => {
4250 span_err!(ccx.tcx.sess, v.span, E0081,
4251 "discriminant value `{}` already exists", disr_vals[i]);
b039eaaf
SL
4252 let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
4253 span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
1a4d82fc
JJ
4254 "conflicting discriminant here")
4255 }
4256 None => {}
4257 }
4258 // Check for unrepresentable discriminant values
4259 match hint {
4260 attr::ReprAny | attr::ReprExtern => (),
4261 attr::ReprInt(sp, ity) => {
4262 if !disr_in_range(ccx, ity, current_disr_val) {
4263 span_err!(ccx.tcx.sess, v.span, E0082,
4264 "discriminant value outside specified type");
4265 span_note!(ccx.tcx.sess, sp,
4266 "discriminant type specified here");
4267 }
4268 }
e9174d1e
SL
4269 attr::ReprSimd => {
4270 ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum");
4271 }
1a4d82fc
JJ
4272 attr::ReprPacked => {
4273 ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum");
4274 }
4275 }
4276 disr_vals.push(current_disr_val);
1a4d82fc 4277 }
1a4d82fc
JJ
4278 }
4279
b039eaaf
SL
4280 let def_id = ccx.tcx.map.local_def_id(id);
4281 let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
1a4d82fc
JJ
4282
4283 if hint != attr::ReprAny && vs.len() <= 1 {
4284 if vs.len() == 1 {
4285 span_err!(ccx.tcx.sess, sp, E0083,
4286 "unsupported representation for univariant enum");
4287 } else {
4288 span_err!(ccx.tcx.sess, sp, E0084,
4289 "unsupported representation for zero-variant enum");
4290 };
4291 }
4292
c34b1796 4293 do_check(ccx, vs, id, hint);
1a4d82fc
JJ
4294
4295 check_representable(ccx.tcx, sp, id, "enum");
1a4d82fc
JJ
4296}
4297
1a4d82fc 4298// Returns the type parameter count and the type for the given definition.
85aaf69f
SL
4299fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4300 sp: Span,
4301 defn: def::Def)
4302 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
1a4d82fc 4303 match defn {
b039eaaf 4304 def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
85aaf69f
SL
4305 let typ = fcx.local_ty(sp, nid);
4306 (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
4307 ty::GenericPredicates::empty())
4308 }
c1a9b12d 4309 def::DefFn(id, _) | def::DefMethod(id) |
85aaf69f 4310 def::DefStatic(id, _) | def::DefVariant(_, id, _) |
c1a9b12d
SL
4311 def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
4312 (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
85aaf69f
SL
4313 }
4314 def::DefTrait(_) |
4315 def::DefTy(..) |
4316 def::DefAssociatedTy(..) |
85aaf69f
SL
4317 def::DefPrimTy(_) |
4318 def::DefTyParam(..) |
4319 def::DefMod(..) |
4320 def::DefForeignMod(..) |
4321 def::DefUse(..) |
85aaf69f
SL
4322 def::DefLabel(..) |
4323 def::DefSelfTy(..) => {
4324 fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
4325 }
1a4d82fc
JJ
4326 }
4327}
4328
4329// Instantiates the given path, which must refer to an item with the given
4330// number of type parameters and type.
4331pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
e9174d1e 4332 segments: &[hir::PathSegment],
1a4d82fc 4333 type_scheme: TypeScheme<'tcx>,
85aaf69f
SL
4334 type_predicates: &ty::GenericPredicates<'tcx>,
4335 opt_self_ty: Option<Ty<'tcx>>,
1a4d82fc
JJ
4336 def: def::Def,
4337 span: Span,
4338 node_id: ast::NodeId) {
62682a34 4339 debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
c34b1796 4340 segments,
62682a34 4341 def,
1a4d82fc 4342 node_id,
62682a34 4343 type_scheme);
1a4d82fc
JJ
4344
4345 // We need to extract the type parameters supplied by the user in
4346 // the path `path`. Due to the current setup, this is a bit of a
4347 // tricky-process; the problem is that resolve only tells us the
4348 // end-point of the path resolution, and not the intermediate steps.
4349 // Luckily, we can (at least for now) deduce the intermediate steps
4350 // just from the end-point.
4351 //
d9579d0f 4352 // There are basically four cases to consider:
1a4d82fc
JJ
4353 //
4354 // 1. Reference to a *type*, such as a struct or enum:
4355 //
4356 // mod a { struct Foo<T> { ... } }
4357 //
4358 // Because we don't allow types to be declared within one
4359 // another, a path that leads to a type will always look like
4360 // `a::b::Foo<T>` where `a` and `b` are modules. This implies
4361 // that only the final segment can have type parameters, and
4362 // they are located in the TypeSpace.
4363 //
4364 // *Note:* Generally speaking, references to types don't
4365 // actually pass through this function, but rather the
4366 // `ast_ty_to_ty` function in `astconv`. However, in the case
4367 // of struct patterns (and maybe literals) we do invoke
4368 // `instantiate_path` to get the general type of an instance of
4369 // a struct. (In these cases, there are actually no type
4370 // parameters permitted at present, but perhaps we will allow
4371 // them in the future.)
4372 //
b039eaaf 4373 // 1b. Reference to an enum variant or tuple-like struct:
1a4d82fc
JJ
4374 //
4375 // struct foo<T>(...)
4376 // enum E<T> { foo(...) }
4377 //
4378 // In these cases, the parameters are declared in the type
4379 // space.
4380 //
4381 // 2. Reference to a *fn item*:
4382 //
4383 // fn foo<T>() { }
4384 //
4385 // In this case, the path will again always have the form
4386 // `a::b::foo::<T>` where only the final segment should have
4387 // type parameters. However, in this case, those parameters are
4388 // declared on a value, and hence are in the `FnSpace`.
4389 //
4390 // 3. Reference to a *method*:
4391 //
4392 // impl<A> SomeStruct<A> {
4393 // fn foo<B>(...)
4394 // }
4395 //
4396 // Here we can have a path like
4397 // `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
4398 // may appear in two places. The penultimate segment,
4399 // `SomeStruct::<A>`, contains parameters in TypeSpace, and the
4400 // final segment, `foo::<B>` contains parameters in fn space.
4401 //
d9579d0f
AL
4402 // 4. Reference to an *associated const*:
4403 //
4404 // impl<A> AnotherStruct<A> {
4405 // const FOO: B = BAR;
4406 // }
4407 //
4408 // The path in this case will look like
4409 // `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
4410 // only will have parameters in TypeSpace.
4411 //
1a4d82fc
JJ
4412 // The first step then is to categorize the segments appropriately.
4413
9346a6ac 4414 assert!(!segments.is_empty());
c34b1796 4415
c1a9b12d 4416 let mut ufcs_associated = None;
1a4d82fc
JJ
4417 let mut segment_spaces: Vec<_>;
4418 match def {
4419 // Case 1 and 1b. Reference to a *type* or *enum variant*.
4420 def::DefSelfTy(..) |
4421 def::DefStruct(..) |
4422 def::DefVariant(..) |
1a4d82fc
JJ
4423 def::DefTy(..) |
4424 def::DefAssociatedTy(..) |
1a4d82fc
JJ
4425 def::DefTrait(..) |
4426 def::DefPrimTy(..) |
4427 def::DefTyParam(..) => {
4428 // Everything but the final segment should have no
4429 // parameters at all.
c1a9b12d 4430 segment_spaces = vec![None; segments.len() - 1];
1a4d82fc
JJ
4431 segment_spaces.push(Some(subst::TypeSpace));
4432 }
4433
4434 // Case 2. Reference to a top-level value.
4435 def::DefFn(..) |
4436 def::DefConst(..) |
4437 def::DefStatic(..) => {
c1a9b12d 4438 segment_spaces = vec![None; segments.len() - 1];
1a4d82fc
JJ
4439 segment_spaces.push(Some(subst::FnSpace));
4440 }
4441
4442 // Case 3. Reference to a method.
c1a9b12d
SL
4443 def::DefMethod(def_id) => {
4444 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4445 match container {
4446 ty::TraitContainer(trait_did) => {
1a4d82fc
JJ
4447 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4448 }
c1a9b12d 4449 ty::ImplContainer(_) => {}
1a4d82fc
JJ
4450 }
4451
c34b1796 4452 if segments.len() >= 2 {
c1a9b12d 4453 segment_spaces = vec![None; segments.len() - 2];
c34b1796
AL
4454 segment_spaces.push(Some(subst::TypeSpace));
4455 segment_spaces.push(Some(subst::FnSpace));
4456 } else {
4457 // `<T>::method` will end up here, and so can `T::method`.
4458 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
4459 segment_spaces = vec![Some(subst::FnSpace)];
c1a9b12d 4460 ufcs_associated = Some((container, self_ty));
c34b1796 4461 }
1a4d82fc
JJ
4462 }
4463
c1a9b12d
SL
4464 def::DefAssociatedConst(def_id) => {
4465 let container = fcx.tcx().impl_or_trait_item(def_id).container();
4466 match container {
4467 ty::TraitContainer(trait_did) => {
d9579d0f
AL
4468 callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
4469 }
c1a9b12d 4470 ty::ImplContainer(_) => {}
d9579d0f
AL
4471 }
4472
4473 if segments.len() >= 2 {
c1a9b12d 4474 segment_spaces = vec![None; segments.len() - 2];
d9579d0f
AL
4475 segment_spaces.push(Some(subst::TypeSpace));
4476 segment_spaces.push(None);
4477 } else {
c1a9b12d
SL
4478 // `<T>::CONST` will end up here, and so can `T::CONST`.
4479 let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
d9579d0f 4480 segment_spaces = vec![None];
c1a9b12d 4481 ufcs_associated = Some((container, self_ty));
d9579d0f
AL
4482 }
4483 }
4484
1a4d82fc
JJ
4485 // Other cases. Various nonsense that really shouldn't show up
4486 // here. If they do, an error will have been reported
4487 // elsewhere. (I hope)
4488 def::DefMod(..) |
4489 def::DefForeignMod(..) |
4490 def::DefLocal(..) |
4491 def::DefUse(..) |
1a4d82fc
JJ
4492 def::DefLabel(..) |
4493 def::DefUpvar(..) => {
c1a9b12d 4494 segment_spaces = vec![None; segments.len()];
1a4d82fc
JJ
4495 }
4496 }
c34b1796
AL
4497 assert_eq!(segment_spaces.len(), segments.len());
4498
4499 // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
4500 // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
4501 // type parameters are not mandatory.
c1a9b12d 4502 let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
1a4d82fc
JJ
4503
4504 debug!("segment_spaces={:?}", segment_spaces);
4505
4506 // Next, examine the definition, and determine how many type
4507 // parameters we expect from each space.
4508 let type_defs = &type_scheme.generics.types;
4509 let region_defs = &type_scheme.generics.regions;
4510
4511 // Now that we have categorized what space the parameters for each
4512 // segment belong to, let's sort out the parameters that the user
4513 // provided (if any) into their appropriate spaces. We'll also report
4514 // errors if type parameters are provided in an inappropriate place.
4515 let mut substs = Substs::empty();
62682a34 4516 for (opt_space, segment) in segment_spaces.iter().zip(segments) {
1a4d82fc
JJ
4517 match *opt_space {
4518 None => {
e9174d1e 4519 prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
1a4d82fc
JJ
4520 }
4521
4522 Some(space) => {
4523 push_explicit_parameters_from_segment_to_substs(fcx,
4524 space,
c34b1796 4525 span,
1a4d82fc
JJ
4526 type_defs,
4527 region_defs,
4528 segment,
4529 &mut substs);
4530 }
4531 }
4532 }
85aaf69f 4533 if let Some(self_ty) = opt_self_ty {
c34b1796
AL
4534 if type_defs.len(subst::SelfSpace) == 1 {
4535 substs.types.push(subst::SelfSpace, self_ty);
4536 }
85aaf69f 4537 }
1a4d82fc
JJ
4538
4539 // Now we have to compare the types that the user *actually*
4540 // provided against the types that were *expected*. If the user
4541 // did not provide any types, then we want to substitute inference
4542 // variables. If the user provided some types, we may still need
4543 // to add defaults. If the user provided *too many* types, that's
4544 // a problem.
c1a9b12d 4545 for &space in &[subst::SelfSpace, subst::TypeSpace, subst::FnSpace] {
c34b1796
AL
4546 adjust_type_parameters(fcx, span, space, type_defs,
4547 require_type_space, &mut substs);
1a4d82fc
JJ
4548 assert_eq!(substs.types.len(space), type_defs.len(space));
4549
4550 adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
4551 assert_eq!(substs.regions().len(space), region_defs.len(space));
4552 }
4553
4554 // The things we are substituting into the type should not contain
4555 // escaping late-bound regions, and nor should the base type scheme.
4556 assert!(!substs.has_regions_escaping_depth(0));
4557 assert!(!type_scheme.has_escaping_regions());
4558
4559 // Add all the obligations that are required, substituting and
4560 // normalized appropriately.
85aaf69f 4561 let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
1a4d82fc
JJ
4562 fcx.add_obligations_for_parameters(
4563 traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
4564 &bounds);
4565
4566 // Substitute the values for the type parameters into the type of
4567 // the referenced item.
4568 let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
4569
1a4d82fc 4570
c1a9b12d 4571 if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
c34b1796
AL
4572 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
4573 // is inherent, there is no `Self` parameter, instead, the impl needs
4574 // type parameters, which we can infer by unifying the provided `Self`
4575 // with the substituted impl type.
c1a9b12d 4576 let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
c34b1796
AL
4577 assert_eq!(substs.types.len(subst::TypeSpace),
4578 impl_scheme.generics.types.len(subst::TypeSpace));
4579 assert_eq!(substs.regions().len(subst::TypeSpace),
4580 impl_scheme.generics.regions.len(subst::TypeSpace));
1a4d82fc 4581
c34b1796
AL
4582 let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
4583 if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
4584 fcx.tcx().sess.span_bug(span,
4585 &format!(
62682a34
SL
4586 "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
4587 self_ty,
4588 impl_ty));
1a4d82fc
JJ
4589 }
4590 }
4591
e9174d1e
SL
4592 debug!("instantiate_path: type of {:?} is {:?}",
4593 node_id,
4594 ty_substituted);
c34b1796
AL
4595 fcx.write_ty(node_id, ty_substituted);
4596 fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
4597 return;
4598
1a4d82fc
JJ
4599 /// Finds the parameters that the user provided and adds them to `substs`. If too many
4600 /// parameters are provided, then reports an error and clears the output vector.
4601 ///
4602 /// We clear the output vector because that will cause the `adjust_XXX_parameters()` later to
4603 /// use inference variables. This seems less likely to lead to derived errors.
4604 ///
4605 /// Note that we *do not* check for *too few* parameters here. Due to the presence of defaults
4606 /// etc that is more complicated. I wanted however to do the reporting of *too many* parameters
4607 /// here because we can easily use the precise span of the N+1'th parameter.
4608 fn push_explicit_parameters_from_segment_to_substs<'a, 'tcx>(
4609 fcx: &FnCtxt<'a, 'tcx>,
4610 space: subst::ParamSpace,
4611 span: Span,
4612 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4613 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
e9174d1e 4614 segment: &hir::PathSegment,
1a4d82fc
JJ
4615 substs: &mut Substs<'tcx>)
4616 {
4617 match segment.parameters {
e9174d1e 4618 hir::AngleBracketedParameters(ref data) => {
1a4d82fc
JJ
4619 push_explicit_angle_bracketed_parameters_from_segment_to_substs(
4620 fcx, space, type_defs, region_defs, data, substs);
4621 }
4622
e9174d1e 4623 hir::ParenthesizedParameters(ref data) => {
85aaf69f 4624 span_err!(fcx.tcx().sess, span, E0238,
1a4d82fc
JJ
4625 "parenthesized parameters may only be used with a trait");
4626 push_explicit_parenthesized_parameters_from_segment_to_substs(
4627 fcx, space, span, type_defs, data, substs);
4628 }
4629 }
4630 }
4631
4632 fn push_explicit_angle_bracketed_parameters_from_segment_to_substs<'a, 'tcx>(
4633 fcx: &FnCtxt<'a, 'tcx>,
4634 space: subst::ParamSpace,
4635 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
4636 region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
e9174d1e 4637 data: &hir::AngleBracketedParameterData,
1a4d82fc
JJ
4638 substs: &mut Substs<'tcx>)
4639 {
4640 {
4641 let type_count = type_defs.len(space);
4642 assert_eq!(substs.types.len(space), 0);
4643 for (i, typ) in data.types.iter().enumerate() {
4644 let t = fcx.to_ty(&**typ);
4645 if i < type_count {
4646 substs.types.push(space, t);
4647 } else if i == type_count {
4648 span_err!(fcx.tcx().sess, typ.span, E0087,
4649 "too many type parameters provided: \
62682a34
SL
4650 expected at most {} parameter{}, \
4651 found {} parameter{}",
4652 type_count,
4653 if type_count == 1 {""} else {"s"},
4654 data.types.len(),
4655 if data.types.len() == 1 {""} else {"s"});
1a4d82fc
JJ
4656 substs.types.truncate(space, 0);
4657 break;
4658 }
4659 }
4660 }
4661
9346a6ac 4662 if !data.bindings.is_empty() {
1a4d82fc
JJ
4663 span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
4664 "unexpected binding of associated item in expression path \
4665 (only allowed in type paths)");
4666 }
4667
4668 {
4669 let region_count = region_defs.len(space);
4670 assert_eq!(substs.regions().len(space), 0);
4671 for (i, lifetime) in data.lifetimes.iter().enumerate() {
4672 let r = ast_region_to_region(fcx.tcx(), lifetime);
4673 if i < region_count {
4674 substs.mut_regions().push(space, r);
4675 } else if i == region_count {
4676 span_err!(fcx.tcx().sess, lifetime.span, E0088,
4677 "too many lifetime parameters provided: \
62682a34 4678 expected {} parameter{}, found {} parameter{}",
1a4d82fc 4679 region_count,
62682a34
SL
4680 if region_count == 1 {""} else {"s"},
4681 data.lifetimes.len(),
4682 if data.lifetimes.len() == 1 {""} else {"s"});
1a4d82fc
JJ
4683 substs.mut_regions().truncate(space, 0);
4684 break;
4685 }
4686 }
4687 }
4688 }
4689
4690 /// As with
4691 /// `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
4692 /// but intended for `Foo(A,B) -> C` form. This expands to
4693 /// roughly the same thing as `Foo<(A,B),C>`. One important
4694 /// difference has to do with the treatment of anonymous
4695 /// regions, which are translated into bound regions (NYI).
4696 fn push_explicit_parenthesized_parameters_from_segment_to_substs<'a, 'tcx>(
4697 fcx: &FnCtxt<'a, 'tcx>,
4698 space: subst::ParamSpace,
4699 span: Span,
4700 type_defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
e9174d1e 4701 data: &hir::ParenthesizedParameterData,
1a4d82fc
JJ
4702 substs: &mut Substs<'tcx>)
4703 {
4704 let type_count = type_defs.len(space);
4705 if type_count < 2 {
4706 span_err!(fcx.tcx().sess, span, E0167,
4707 "parenthesized form always supplies 2 type parameters, \
4708 but only {} parameter(s) were expected",
4709 type_count);
4710 }
4711
4712 let input_tys: Vec<Ty> =
4713 data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
4714
c1a9b12d 4715 let tuple_ty = fcx.tcx().mk_tup(input_tys);
1a4d82fc
JJ
4716
4717 if type_count >= 1 {
4718 substs.types.push(space, tuple_ty);
4719 }
4720
4721 let output_ty: Option<Ty> =
4722 data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
4723
4724 let output_ty =
c1a9b12d 4725 output_ty.unwrap_or(fcx.tcx().mk_nil());
1a4d82fc
JJ
4726
4727 if type_count >= 2 {
4728 substs.types.push(space, output_ty);
4729 }
4730 }
4731
4732 fn adjust_type_parameters<'a, 'tcx>(
4733 fcx: &FnCtxt<'a, 'tcx>,
4734 span: Span,
4735 space: ParamSpace,
4736 defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
c34b1796 4737 require_type_space: bool,
1a4d82fc
JJ
4738 substs: &mut Substs<'tcx>)
4739 {
4740 let provided_len = substs.types.len(space);
4741 let desired = defs.get_slice(space);
4742 let required_len = desired.iter()
4743 .take_while(|d| d.default.is_none())
4744 .count();
4745
4746 debug!("adjust_type_parameters(space={:?}, \
4747 provided_len={}, \
4748 desired_len={}, \
4749 required_len={})",
4750 space,
4751 provided_len,
4752 desired.len(),
4753 required_len);
4754
4755 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4756 assert!(provided_len <= desired.len());
4757
4758 // Nothing specified at all: supply inference variables for
4759 // everything.
c34b1796 4760 if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
c1a9b12d
SL
4761 substs.types.replace(space, Vec::new());
4762 fcx.infcx().type_vars_for_defs(span, space, substs, &desired[..]);
1a4d82fc
JJ
4763 return;
4764 }
4765
4766 // Too few parameters specified: report an error and use Err
4767 // for everything.
4768 if provided_len < required_len {
4769 let qualifier =
4770 if desired.len() != required_len { "at least " } else { "" };
4771 span_err!(fcx.tcx().sess, span, E0089,
62682a34
SL
4772 "too few type parameters provided: expected {}{} parameter{}, \
4773 found {} parameter{}",
4774 qualifier, required_len,
4775 if required_len == 1 {""} else {"s"},
4776 provided_len,
4777 if provided_len == 1 {""} else {"s"});
c1a9b12d 4778 substs.types.replace(space, vec![fcx.tcx().types.err; desired.len()]);
1a4d82fc
JJ
4779 return;
4780 }
4781
4782 // Otherwise, add in any optional parameters that the user
4783 // omitted. The case of *too many* parameters is handled
4784 // already by
4785 // push_explicit_parameters_from_segment_to_substs(). Note
4786 // that the *default* type are expressed in terms of all prior
4787 // parameters, so we have to substitute as we go with the
4788 // partial substitution that we have built up.
85aaf69f 4789 for i in provided_len..desired.len() {
1a4d82fc
JJ
4790 let default = desired[i].default.unwrap();
4791 let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
4792 substs.types.push(space, default);
4793 }
4794 assert_eq!(substs.types.len(space), desired.len());
4795
62682a34 4796 debug!("Final substs: {:?}", substs);
1a4d82fc
JJ
4797 }
4798
4799 fn adjust_region_parameters(
4800 fcx: &FnCtxt,
4801 span: Span,
4802 space: ParamSpace,
4803 defs: &VecPerParamSpace<ty::RegionParameterDef>,
4804 substs: &mut Substs)
4805 {
4806 let provided_len = substs.mut_regions().len(space);
4807 let desired = defs.get_slice(space);
4808
4809 // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
4810 assert!(provided_len <= desired.len());
4811
4812 // If nothing was provided, just use inference variables.
4813 if provided_len == 0 {
4814 substs.mut_regions().replace(
4815 space,
4816 fcx.infcx().region_vars_for_defs(span, desired));
4817 return;
4818 }
4819
4820 // If just the right number were provided, everybody is happy.
4821 if provided_len == desired.len() {
4822 return;
4823 }
4824
4825 // Otherwise, too few were provided. Report an error and then
4826 // use inference variables.
4827 span_err!(fcx.tcx().sess, span, E0090,
62682a34
SL
4828 "too few lifetime parameters provided: expected {} parameter{}, \
4829 found {} parameter{}",
4830 desired.len(),
4831 if desired.len() == 1 {""} else {"s"},
4832 provided_len,
4833 if provided_len == 1 {""} else {"s"});
1a4d82fc
JJ
4834
4835 substs.mut_regions().replace(
4836 space,
4837 fcx.infcx().region_vars_for_defs(span, desired));
4838 }
4839}
4840
85aaf69f
SL
4841fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4842 sp: Span,
4843 ty: Ty<'tcx>,
4844 f: F) -> Ty<'tcx>
4845 where F: Fn() -> Ty<'tcx>
4846{
4847 let mut ty = fcx.resolve_type_vars_if_possible(ty);
1a4d82fc 4848
c1a9b12d 4849 if ty.is_ty_var() {
85aaf69f
SL
4850 let alternative = f();
4851
4852 // If not, error.
c1a9b12d 4853 if alternative.is_ty_var() || alternative.references_error() {
85aaf69f
SL
4854 fcx.type_error_message(sp, |_actual| {
4855 "the type of this value must be known in this context".to_string()
4856 }, ty, None);
4857 demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
4858 ty = fcx.tcx().types.err;
4859 } else {
4860 demand::suptype(fcx, sp, alternative, ty);
4861 ty = alternative;
4862 }
1a4d82fc
JJ
4863 }
4864
4865 ty
4866}
4867
85aaf69f
SL
4868// Resolves `typ` by a single level if `typ` is a type variable. If no
4869// resolution is possible, then an error is reported.
4870pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4871 sp: Span,
4872 ty: Ty<'tcx>)
4873 -> Ty<'tcx>
4874{
4875 structurally_resolve_type_or_else(fcx, sp, ty, || {
4876 fcx.tcx().types.err
4877 })
4878}
4879
1a4d82fc 4880// Returns true if b contains a break that can exit from b
e9174d1e 4881pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
1a4d82fc
JJ
4882 // First: is there an unlabeled break immediately
4883 // inside the loop?
4884 (loop_query(&*b, |e| {
4885 match *e {
e9174d1e 4886 hir::ExprBreak(None) => true,
1a4d82fc
JJ
4887 _ => false
4888 }
4889 })) ||
c34b1796
AL
4890 // Second: is there a labeled break with label
4891 // <id> nested anywhere inside the loop?
1a4d82fc 4892 (block_query(b, |e| {
e9174d1e 4893 if let hir::ExprBreak(Some(_)) = e.node {
c34b1796
AL
4894 lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
4895 } else {
4896 false
4897 }
4898 }))
1a4d82fc
JJ
4899}
4900
4901pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
4902 span: Span,
e9174d1e 4903 tps: &OwnedSlice<hir::TyParam>,
1a4d82fc 4904 ty: Ty<'tcx>) {
62682a34
SL
4905 debug!("check_bounds_are_used(n_tps={}, ty={:?})",
4906 tps.len(), ty);
1a4d82fc
JJ
4907
4908 // make a vector of booleans initially false, set to true when used
9346a6ac 4909 if tps.is_empty() { return; }
c1a9b12d 4910 let mut tps_used = vec![false; tps.len()];
1a4d82fc 4911
c1a9b12d
SL
4912 for leaf_ty in ty.walk() {
4913 if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
4914 debug!("Found use of ty param num {}", idx);
4915 tps_used[idx as usize] = true;
4916 }
4917 }
1a4d82fc
JJ
4918
4919 for (i, b) in tps_used.iter().enumerate() {
4920 if !*b {
4921 span_err!(ccx.tcx.sess, span, E0091,
4922 "type parameter `{}` is unused",
b039eaaf 4923 tps[i].name);
1a4d82fc
JJ
4924 }
4925 }
4926}