]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/writeback.rs
Unignore u128 test for stage 0,1
[rust.git] / src / librustc_typeck / check / writeback.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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 // Type resolution: the phase that finds all the types in the AST with
12 // unresolved type variables and replaces "ty_var" types with their
13 // substitutions.
14 use self::ResolveReason::*;
15
16 use check::FnCtxt;
17 use hir::def_id::DefId;
18 use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
19 use rustc::ty::adjustment;
20 use rustc::ty::fold::{TypeFolder,TypeFoldable};
21 use rustc::infer::{InferCtxt, FixupError};
22 use rustc::util::nodemap::{DefIdMap, DefIdSet};
23
24 use std::cell::Cell;
25 use std::mem;
26
27 use syntax::ast;
28 use syntax_pos::Span;
29
30 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
31 use rustc::hir;
32
33 ///////////////////////////////////////////////////////////////////////////
34 // Entry point
35
36 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37     pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) {
38         assert_eq!(self.writeback_errors.get(), false);
39
40         let item_id = self.tcx.hir.body_owner(body.id());
41         let item_def_id = self.tcx.hir.local_def_id(item_id);
42
43         let mut wbcx = WritebackCx::new(self);
44         for arg in &body.arguments {
45             wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.id);
46         }
47         wbcx.visit_body(body);
48         wbcx.visit_upvar_borrow_map();
49         wbcx.visit_closures();
50         wbcx.visit_liberated_fn_sigs();
51         wbcx.visit_fru_field_types();
52         wbcx.visit_anon_types();
53         wbcx.visit_deferred_obligations(item_id);
54         wbcx.visit_type_nodes();
55         wbcx.visit_cast_types();
56         wbcx.visit_lints();
57
58         let tables = self.tcx.alloc_tables(wbcx.tables);
59         self.tcx.tables.borrow_mut().insert(item_def_id, tables);
60
61         let used_trait_imports = mem::replace(&mut *self.used_trait_imports.borrow_mut(),
62                                               DefIdSet());
63         debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
64         self.tcx.used_trait_imports.borrow_mut().insert(item_def_id, used_trait_imports);
65     }
66 }
67
68 ///////////////////////////////////////////////////////////////////////////
69 // The Writerback context. This visitor walks the AST, checking the
70 // fn-specific tables to find references to types or regions. It
71 // resolves those regions to remove inference variables and writes the
72 // final result back into the master tables in the tcx. Here and
73 // there, it applies a few ad-hoc checks that were not convenient to
74 // do elsewhere.
75
76 struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
77     fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>,
78
79     tables: ty::TypeckTables<'gcx>,
80
81     // Mapping from free regions of the function to the
82     // early-bound versions of them, visible from the
83     // outside of the function. This is needed by, and
84     // only populated if there are any `impl Trait`.
85     free_to_bound_regions: DefIdMap<&'gcx ty::Region>
86 }
87
88 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
89     fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>) -> WritebackCx<'cx, 'gcx, 'tcx> {
90         let mut wbcx = WritebackCx {
91             fcx: fcx,
92             tables: ty::TypeckTables::empty(),
93             free_to_bound_regions: DefIdMap()
94         };
95
96         // Only build the reverse mapping if `impl Trait` is used.
97         if fcx.anon_types.borrow().is_empty() {
98             return wbcx;
99         }
100
101         let gcx = fcx.tcx.global_tcx();
102         let free_substs = fcx.parameter_environment.free_substs;
103         for (i, k) in free_substs.params().iter().enumerate() {
104             let r = if let Some(r) = k.as_region() {
105                 r
106             } else {
107                 continue;
108             };
109             match *r {
110                 ty::ReFree(ty::FreeRegion {
111                     bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
112                 }) => {
113                     let bound_region = gcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
114                         index: i as u32,
115                         name: name,
116                     }));
117                     wbcx.free_to_bound_regions.insert(def_id, bound_region);
118                 }
119                 _ => {
120                     bug!("{:?} is not a free region for an early-bound lifetime", r);
121                 }
122             }
123         }
124
125         wbcx
126     }
127
128     fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
129         self.fcx.tcx
130     }
131
132     fn write_ty_to_tables(&mut self, node_id: ast::NodeId, ty: Ty<'gcx>) {
133         debug!("write_ty_to_tables({}, {:?})", node_id,  ty);
134         assert!(!ty.needs_infer());
135         self.tables.node_types.insert(node_id, ty);
136     }
137
138     // Hacky hack: During type-checking, we treat *all* operators
139     // as potentially overloaded. But then, during writeback, if
140     // we observe that something like `a+b` is (known to be)
141     // operating on scalars, we clear the overload.
142     fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
143         match e.node {
144             hir::ExprUnary(hir::UnNeg, ref inner) |
145             hir::ExprUnary(hir::UnNot, ref inner)  => {
146                 let inner_ty = self.fcx.node_ty(inner.id);
147                 let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
148
149                 if inner_ty.is_scalar() {
150                     self.fcx.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
151                 }
152             }
153             hir::ExprBinary(ref op, ref lhs, ref rhs) |
154             hir::ExprAssignOp(ref op, ref lhs, ref rhs) => {
155                 let lhs_ty = self.fcx.node_ty(lhs.id);
156                 let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty);
157
158                 let rhs_ty = self.fcx.node_ty(rhs.id);
159                 let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
160
161                 if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
162                     self.fcx.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
163
164                     // weird but true: the by-ref binops put an
165                     // adjustment on the lhs but not the rhs; the
166                     // adjustment for rhs is kind of baked into the
167                     // system.
168                     match e.node {
169                         hir::ExprBinary(..) => {
170                             if !op.node.is_by_value() {
171                                 self.fcx.tables.borrow_mut().adjustments.remove(&lhs.id);
172                             }
173                         },
174                         hir::ExprAssignOp(..) => {
175                             self.fcx.tables.borrow_mut().adjustments.remove(&lhs.id);
176                         },
177                         _ => {},
178                     }
179                 }
180             }
181             _ => {},
182         }
183     }
184 }
185
186 ///////////////////////////////////////////////////////////////////////////
187 // Impl of Visitor for Resolver
188 //
189 // This is the master code which walks the AST. It delegates most of
190 // the heavy lifting to the generic visit and resolve functions
191 // below. In general, a function is made into a `visitor` if it must
192 // traffic in node-ids or update tables in the type context etc.
193
194 impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
195     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
196         NestedVisitorMap::None
197     }
198
199     fn visit_stmt(&mut self, s: &'gcx hir::Stmt) {
200         if self.fcx.writeback_errors.get() {
201             return;
202         }
203
204         self.visit_node_id(ResolvingExpr(s.span), s.node.id());
205         intravisit::walk_stmt(self, s);
206     }
207
208     fn visit_expr(&mut self, e: &'gcx hir::Expr) {
209         if self.fcx.writeback_errors.get() {
210             return;
211         }
212
213         self.fix_scalar_builtin_expr(e);
214
215         self.visit_node_id(ResolvingExpr(e.span), e.id);
216         self.visit_method_map_entry(ResolvingExpr(e.span),
217                                     MethodCall::expr(e.id));
218
219         if let hir::ExprClosure(_, _, body, _) = e.node {
220             let body = self.fcx.tcx.hir.body(body);
221             for arg in &body.arguments {
222                 self.visit_node_id(ResolvingExpr(e.span), arg.id);
223             }
224
225             self.visit_body(body);
226         }
227
228         intravisit::walk_expr(self, e);
229     }
230
231     fn visit_block(&mut self, b: &'gcx hir::Block) {
232         if self.fcx.writeback_errors.get() {
233             return;
234         }
235
236         self.visit_node_id(ResolvingExpr(b.span), b.id);
237         intravisit::walk_block(self, b);
238     }
239
240     fn visit_pat(&mut self, p: &'gcx hir::Pat) {
241         if self.fcx.writeback_errors.get() {
242             return;
243         }
244
245         self.visit_node_id(ResolvingPattern(p.span), p.id);
246
247         intravisit::walk_pat(self, p);
248     }
249
250     fn visit_local(&mut self, l: &'gcx hir::Local) {
251         if self.fcx.writeback_errors.get() {
252             return;
253         }
254
255         let var_ty = self.fcx.local_ty(l.span, l.id);
256         let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span));
257         self.write_ty_to_tables(l.id, var_ty);
258         intravisit::walk_local(self, l);
259     }
260 }
261
262 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
263     fn visit_upvar_borrow_map(&mut self) {
264         if self.fcx.writeback_errors.get() {
265             return;
266         }
267
268         for (upvar_id, upvar_capture) in self.fcx.tables.borrow().upvar_capture_map.iter() {
269             let new_upvar_capture = match *upvar_capture {
270                 ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
271                 ty::UpvarCapture::ByRef(ref upvar_borrow) => {
272                     let r = upvar_borrow.region;
273                     let r = self.resolve(&r, ResolvingUpvar(*upvar_id));
274                     ty::UpvarCapture::ByRef(
275                         ty::UpvarBorrow { kind: upvar_borrow.kind, region: r })
276                 }
277             };
278             debug!("Upvar capture for {:?} resolved to {:?}",
279                    upvar_id,
280                    new_upvar_capture);
281             self.tables.upvar_capture_map.insert(*upvar_id, new_upvar_capture);
282         }
283     }
284
285     fn visit_closures(&self) {
286         if self.fcx.writeback_errors.get() {
287             return
288         }
289
290         for (&id, closure_ty) in self.fcx.tables.borrow().closure_tys.iter() {
291             let closure_ty = self.resolve(closure_ty, ResolvingClosure(id));
292             let def_id = self.tcx().hir.local_def_id(id);
293             self.tcx().closure_tys.borrow_mut().insert(def_id, closure_ty);
294         }
295
296         for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() {
297             let def_id = self.tcx().hir.local_def_id(id);
298             self.tcx().closure_kinds.borrow_mut().insert(def_id, closure_kind);
299         }
300     }
301
302     fn visit_cast_types(&mut self) {
303         if self.fcx.writeback_errors.get() {
304             return
305         }
306
307         self.tables.cast_kinds.extend(
308             self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
309     }
310
311     fn visit_lints(&mut self) {
312         if self.fcx.writeback_errors.get() {
313             return
314         }
315
316         self.fcx.tables.borrow_mut().lints.transfer(&mut self.tables.lints);
317     }
318
319     fn visit_anon_types(&self) {
320         if self.fcx.writeback_errors.get() {
321             return
322         }
323
324         let gcx = self.tcx().global_tcx();
325         for (&def_id, &concrete_ty) in self.fcx.anon_types.borrow().iter() {
326             let reason = ResolvingAnonTy(def_id);
327             let inside_ty = self.resolve(&concrete_ty, reason);
328
329             // Convert the type from the function into a type valid outside
330             // the function, by replacing free regions with early-bound ones.
331             let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| {
332                 match *r {
333                     // 'static is valid everywhere.
334                     ty::ReStatic |
335                     ty::ReEmpty => gcx.mk_region(*r),
336
337                     // Free regions that come from early-bound regions are valid.
338                     ty::ReFree(ty::FreeRegion {
339                         bound_region: ty::BoundRegion::BrNamed(def_id, ..), ..
340                     }) if self.free_to_bound_regions.contains_key(&def_id) => {
341                         self.free_to_bound_regions[&def_id]
342                     }
343
344                     ty::ReFree(_) |
345                     ty::ReEarlyBound(_) |
346                     ty::ReLateBound(..) |
347                     ty::ReScope(_) |
348                     ty::ReSkolemized(..) => {
349                         let span = reason.span(self.tcx());
350                         span_err!(self.tcx().sess, span, E0564,
351                                   "only named lifetimes are allowed in `impl Trait`, \
352                                    but `{}` was found in the type `{}`", r, inside_ty);
353                         gcx.mk_region(ty::ReStatic)
354                     }
355
356                     ty::ReVar(_) |
357                     ty::ReErased => {
358                         let span = reason.span(self.tcx());
359                         span_bug!(span, "invalid region in impl Trait: {:?}", r);
360                     }
361                 }
362             });
363
364             gcx.item_types.borrow_mut().insert(def_id, outside_ty);
365         }
366     }
367
368     fn visit_node_id(&mut self, reason: ResolveReason, id: ast::NodeId) {
369         // Export associated path extensions.
370         if let Some(def) = self.fcx.tables.borrow_mut().type_relative_path_defs.remove(&id) {
371             self.tables.type_relative_path_defs.insert(id, def);
372         }
373
374         // Resolve any borrowings for the node with id `id`
375         self.visit_adjustments(reason, id);
376
377         // Resolve the type of the node with id `id`
378         let n_ty = self.fcx.node_ty(id);
379         let n_ty = self.resolve(&n_ty, reason);
380         self.write_ty_to_tables(id, n_ty);
381         debug!("Node {} has type {:?}", id, n_ty);
382
383         // Resolve any substitutions
384         self.fcx.opt_node_ty_substs(id, |item_substs| {
385             let item_substs = self.resolve(item_substs, reason);
386             if !item_substs.is_noop() {
387                 debug!("write_substs_to_tcx({}, {:?})", id, item_substs);
388                 assert!(!item_substs.substs.needs_infer());
389                 self.tables.item_substs.insert(id, item_substs);
390             }
391         });
392     }
393
394     fn visit_adjustments(&mut self, reason: ResolveReason, id: ast::NodeId) {
395         let adjustments = self.fcx.tables.borrow_mut().adjustments.remove(&id);
396         match adjustments {
397             None => {
398                 debug!("No adjustments for node {}", id);
399             }
400
401             Some(adjustment) => {
402                 let resolved_adjustment = match adjustment.kind {
403                     adjustment::Adjust::NeverToAny => {
404                         adjustment::Adjust::NeverToAny
405                     }
406
407                     adjustment::Adjust::ReifyFnPointer => {
408                         adjustment::Adjust::ReifyFnPointer
409                     }
410
411                     adjustment::Adjust::MutToConstPointer => {
412                         adjustment::Adjust::MutToConstPointer
413                     }
414
415                     adjustment::Adjust::UnsafeFnPointer => {
416                         adjustment::Adjust::UnsafeFnPointer
417                     }
418
419                     adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => {
420                         for autoderef in 0..autoderefs {
421                             let method_call = MethodCall::autoderef(id, autoderef as u32);
422                             self.visit_method_map_entry(reason, method_call);
423                         }
424
425                         adjustment::Adjust::DerefRef {
426                             autoderefs: autoderefs,
427                             autoref: self.resolve(&autoref, reason),
428                             unsize: unsize,
429                         }
430                     }
431                 };
432                 let resolved_adjustment = adjustment::Adjustment {
433                     kind: resolved_adjustment,
434                     target: self.resolve(&adjustment.target, reason)
435                 };
436                 debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
437                 self.tables.adjustments.insert(id, resolved_adjustment);
438             }
439         }
440     }
441
442     fn visit_method_map_entry(&mut self,
443                               reason: ResolveReason,
444                               method_call: MethodCall) {
445         // Resolve any method map entry
446         let new_method = match self.fcx.tables.borrow_mut().method_map.remove(&method_call) {
447             Some(method) => {
448                 debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
449                        method_call,
450                        method);
451                 let new_method = MethodCallee {
452                     def_id: method.def_id,
453                     ty: self.resolve(&method.ty, reason),
454                     substs: self.resolve(&method.substs, reason),
455                 };
456
457                 Some(new_method)
458             }
459             None => None
460         };
461
462         //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE
463         if let Some(method) = new_method {
464             self.tables.method_map.insert(method_call, method);
465         }
466     }
467
468     fn visit_liberated_fn_sigs(&mut self) {
469         for (&node_id, fn_sig) in self.fcx.tables.borrow().liberated_fn_sigs.iter() {
470             let fn_sig = self.resolve(fn_sig, ResolvingFnSig(node_id));
471             self.tables.liberated_fn_sigs.insert(node_id, fn_sig.clone());
472         }
473     }
474
475     fn visit_fru_field_types(&mut self) {
476         for (&node_id, ftys) in self.fcx.tables.borrow().fru_field_types.iter() {
477             let ftys = self.resolve(ftys, ResolvingFieldTypes(node_id));
478             self.tables.fru_field_types.insert(node_id, ftys);
479         }
480     }
481
482     fn visit_deferred_obligations(&mut self, item_id: ast::NodeId) {
483         let deferred_obligations = self.fcx.deferred_obligations.borrow();
484         let obligations: Vec<_> = deferred_obligations.iter().map(|obligation| {
485             let reason = ResolvingDeferredObligation(obligation.cause.span);
486             self.resolve(obligation, reason)
487         }).collect();
488
489         if !obligations.is_empty() {
490             assert!(self.fcx.ccx.deferred_obligations.borrow_mut()
491                                 .insert(item_id, obligations).is_none());
492         }
493     }
494
495     fn visit_type_nodes(&self) {
496         for (&id, ty) in self.fcx.ast_ty_to_ty_cache.borrow().iter() {
497             let ty = self.resolve(ty, ResolvingTyNode(id));
498             self.fcx.ccx.ast_ty_to_ty_cache.borrow_mut().insert(id, ty);
499         }
500     }
501
502     fn resolve<T>(&self, x: &T, reason: ResolveReason) -> T::Lifted
503         where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
504     {
505         let x = x.fold_with(&mut Resolver::new(self.fcx, reason));
506         if let Some(lifted) = self.tcx().lift_to_global(&x) {
507             lifted
508         } else {
509             span_bug!(reason.span(self.tcx()),
510                       "writeback: `{:?}` missing from the global type context", x);
511         }
512     }
513 }
514
515 ///////////////////////////////////////////////////////////////////////////
516 // Resolution reason.
517
518 #[derive(Copy, Clone, Debug)]
519 enum ResolveReason {
520     ResolvingExpr(Span),
521     ResolvingLocal(Span),
522     ResolvingPattern(Span),
523     ResolvingUpvar(ty::UpvarId),
524     ResolvingClosure(ast::NodeId),
525     ResolvingFnSig(ast::NodeId),
526     ResolvingFieldTypes(ast::NodeId),
527     ResolvingAnonTy(DefId),
528     ResolvingDeferredObligation(Span),
529     ResolvingTyNode(ast::NodeId),
530 }
531
532 impl<'a, 'gcx, 'tcx> ResolveReason {
533     fn span(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Span {
534         match *self {
535             ResolvingExpr(s) => s,
536             ResolvingLocal(s) => s,
537             ResolvingPattern(s) => s,
538             ResolvingUpvar(upvar_id) => {
539                 tcx.expr_span(upvar_id.closure_expr_id)
540             }
541             ResolvingClosure(id) |
542             ResolvingFnSig(id) |
543             ResolvingFieldTypes(id) |
544             ResolvingTyNode(id) => {
545                 tcx.hir.span(id)
546             }
547             ResolvingAnonTy(did) => {
548                 tcx.def_span(did)
549             }
550             ResolvingDeferredObligation(span) => span
551         }
552     }
553 }
554
555 ///////////////////////////////////////////////////////////////////////////
556 // The Resolver. This is the type folding engine that detects
557 // unresolved types and so forth.
558
559 struct Resolver<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
560     tcx: TyCtxt<'cx, 'gcx, 'tcx>,
561     infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
562     writeback_errors: &'cx Cell<bool>,
563     reason: ResolveReason,
564 }
565
566 impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
567     fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>,
568            reason: ResolveReason)
569            -> Resolver<'cx, 'gcx, 'tcx>
570     {
571         Resolver::from_infcx(fcx, &fcx.writeback_errors, reason)
572     }
573
574     fn from_infcx(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
575                   writeback_errors: &'cx Cell<bool>,
576                   reason: ResolveReason)
577                   -> Resolver<'cx, 'gcx, 'tcx>
578     {
579         Resolver { infcx: infcx,
580                    tcx: infcx.tcx,
581                    writeback_errors: writeback_errors,
582                    reason: reason }
583     }
584
585     fn report_error(&self, e: FixupError) {
586         self.writeback_errors.set(true);
587         if !self.tcx.sess.has_errors() {
588             match self.reason {
589                 ResolvingExpr(span) => {
590                     struct_span_err!(
591                         self.tcx.sess, span, E0101,
592                         "cannot determine a type for this expression: {}", e)
593                         .span_label(span, &format!("cannot resolve type of expression"))
594                         .emit();
595                 }
596
597                 ResolvingLocal(span) => {
598                     struct_span_err!(
599                         self.tcx.sess, span, E0102,
600                         "cannot determine a type for this local variable: {}", e)
601                         .span_label(span, &format!("cannot resolve type of variable"))
602                         .emit();
603                 }
604
605                 ResolvingPattern(span) => {
606                     span_err!(self.tcx.sess, span, E0103,
607                         "cannot determine a type for this pattern binding: {}", e);
608                 }
609
610                 ResolvingUpvar(upvar_id) => {
611                     let span = self.reason.span(self.tcx);
612                     span_err!(self.tcx.sess, span, E0104,
613                         "cannot resolve lifetime for captured variable `{}`: {}",
614                         self.tcx.local_var_name_str(upvar_id.var_id), e);
615                 }
616
617                 ResolvingClosure(_) => {
618                     let span = self.reason.span(self.tcx);
619                     span_err!(self.tcx.sess, span, E0196,
620                               "cannot determine a type for this closure")
621                 }
622
623                 ResolvingFnSig(_) |
624                 ResolvingFieldTypes(_) |
625                 ResolvingDeferredObligation(_) |
626                 ResolvingTyNode(_) => {
627                     // any failures here should also fail when
628                     // resolving the patterns, closure types, or
629                     // something else.
630                     let span = self.reason.span(self.tcx);
631                     self.tcx.sess.delay_span_bug(
632                         span,
633                         &format!("cannot resolve some aspect of data for {:?}: {}",
634                                  self.reason, e));
635                 }
636
637                 ResolvingAnonTy(_) => {
638                     let span = self.reason.span(self.tcx);
639                     span_err!(self.tcx.sess, span, E0563,
640                               "cannot determine a type for this `impl Trait`: {}", e)
641                 }
642             }
643         }
644     }
645 }
646
647 impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
648     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
649         self.tcx
650     }
651
652     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
653         match self.infcx.fully_resolve(&t) {
654             Ok(t) => t,
655             Err(e) => {
656                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable",
657                        t);
658                 self.report_error(e);
659                 self.tcx().types.err
660             }
661         }
662     }
663
664     fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
665         match self.infcx.fully_resolve(&r) {
666             Ok(r) => r,
667             Err(e) => {
668                 self.report_error(e);
669                 self.tcx.mk_region(ty::ReStatic)
670             }
671         }
672     }
673 }
674
675 ///////////////////////////////////////////////////////////////////////////
676 // During type check, we store promises with the result of trait
677 // lookup rather than the actual results (because the results are not
678 // necessarily available immediately). These routines unwind the
679 // promises. It is expected that we will have already reported any
680 // errors that may be encountered, so if the promises store an error,
681 // a dummy result is returned.