/// used to help suppress derived errors typeck might otherwise
/// report.
fn set_tainted_by_errors(&self);
+
+ fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
}
struct ConvertedBinding<'tcx> {
}
}
Def::Err => {
+ for segment in &path.segments {
+ for ty in &segment.parameters.types {
+ self.ast_ty_to_ty(ty);
+ }
+ for binding in &segment.parameters.bindings {
+ self.ast_ty_to_ty(&binding.ty);
+ }
+ }
self.set_tainted_by_errors();
return self.tcx().types.err;
}
}
};
+ self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
result_ty
}
-> Ty<'tcx>
{
match ty.node {
- hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
- hir::TyInfer => self.ty_infer(ty.span),
+ hir::TyInfer if expected_ty.is_some() => {
+ self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
+ expected_ty.unwrap()
+ }
_ => self.ast_ty_to_ty(ty),
}
}
let expected_ret_ty = expected_sig.as_ref().map(|e| e.output());
- let is_infer = match decl.output {
- hir::Return(ref output) if output.node == hir::TyInfer => true,
- hir::DefaultReturn(..) => true,
- _ => false
- };
-
let output_ty = match decl.output {
- _ if is_infer && expected_ret_ty.is_some() =>
- expected_ret_ty.unwrap(),
- _ if is_infer => self.ty_infer(decl.output.span()),
- hir::Return(ref output) =>
- self.ast_ty_to_ty(&output),
- hir::DefaultReturn(..) => bug!(),
+ hir::Return(ref output) => {
+ if let (&hir::TyInfer, Some(expected_ret_ty)) = (&output.node, expected_ret_ty) {
+ self.record_ty(output.hir_id, expected_ret_ty, output.span);
+ expected_ret_ty
+ } else {
+ self.ast_ty_to_ty(&output)
+ }
+ }
+ hir::DefaultReturn(span) => {
+ if let Some(expected_ret_ty) = expected_ret_ty {
+ expected_ret_ty
+ } else {
+ self.ty_infer(span)
+ }
+ }
};
debug!("ty_of_closure: output_ty={:?}", output_ty);
let var_ty = self.resolve(&var_ty, &l.span);
self.write_ty_to_tables(l.hir_id, var_ty);
}
+
+ fn visit_ty(&mut self, hir_ty: &'gcx hir::Ty) {
+ intravisit::walk_ty(self, hir_ty);
+ let ty = self.fcx.node_ty(hir_ty.hir_id);
+ let ty = self.resolve(&ty, &hir_ty.span);
+ self.write_ty_to_tables(hir_ty.hir_id, ty);
+ }
}
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
fn set_tainted_by_errors(&self) {
// no obvious place to track this, just let it go
}
+
+ fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
+ // no place to record types from signatures?
+ }
}
fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Type arguments of unresolved types should have their types recorded
+
+fn main() {
+ let _: Nonexistent<u8, Assoc = u16>; //~ ERROR cannot find type `Nonexistent` in this scope
+
+ let _ = |a, b: _| -> _ { 0 };
+}