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