Skip to content

Commit 505ff71

Browse files
committed
Record semantic types for all syntactic types in bodies
1 parent 5b9b50e commit 505ff71

File tree

5 files changed

+62
-14
lines changed

5 files changed

+62
-14
lines changed

src/librustc_typeck/astconv.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub trait AstConv<'gcx, 'tcx> {
7676
/// used to help suppress derived errors typeck might otherwise
7777
/// report.
7878
fn set_tainted_by_errors(&self);
79+
80+
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
7981
}
8082

8183
struct ConvertedBinding<'tcx> {
@@ -975,6 +977,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
975977
}
976978
}
977979
Def::Err => {
980+
for segment in &path.segments {
981+
for ty in &segment.parameters.types {
982+
self.ast_ty_to_ty(ty);
983+
}
984+
for binding in &segment.parameters.bindings {
985+
self.ast_ty_to_ty(&binding.ty);
986+
}
987+
}
978988
self.set_tainted_by_errors();
979989
return self.tcx().types.err;
980990
}
@@ -1115,6 +1125,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
11151125
}
11161126
};
11171127

1128+
self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
11181129
result_ty
11191130
}
11201131

@@ -1124,8 +1135,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
11241135
-> Ty<'tcx>
11251136
{
11261137
match ty.node {
1127-
hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
1128-
hir::TyInfer => self.ty_infer(ty.span),
1138+
hir::TyInfer if expected_ty.is_some() => {
1139+
self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
1140+
expected_ty.unwrap()
1141+
}
11291142
_ => self.ast_ty_to_ty(ty),
11301143
}
11311144
}
@@ -1214,19 +1227,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
12141227

12151228
let expected_ret_ty = expected_sig.as_ref().map(|e| e.output());
12161229

1217-
let is_infer = match decl.output {
1218-
hir::Return(ref output) if output.node == hir::TyInfer => true,
1219-
hir::DefaultReturn(..) => true,
1220-
_ => false
1221-
};
1222-
12231230
let output_ty = match decl.output {
1224-
_ if is_infer && expected_ret_ty.is_some() =>
1225-
expected_ret_ty.unwrap(),
1226-
_ if is_infer => self.ty_infer(decl.output.span()),
1227-
hir::Return(ref output) =>
1228-
self.ast_ty_to_ty(&output),
1229-
hir::DefaultReturn(..) => bug!(),
1231+
hir::Return(ref output) => {
1232+
if let (&hir::TyInfer, Some(expected_ret_ty)) = (&output.node, expected_ret_ty) {
1233+
self.record_ty(output.hir_id, expected_ret_ty, output.span);
1234+
expected_ret_ty
1235+
} else {
1236+
self.ast_ty_to_ty(&output)
1237+
}
1238+
}
1239+
hir::DefaultReturn(span) => {
1240+
if let Some(expected_ret_ty) = expected_ret_ty {
1241+
expected_ret_ty
1242+
} else {
1243+
self.ty_infer(span)
1244+
}
1245+
}
12301246
};
12311247

12321248
debug!("ty_of_closure: output_ty={:?}", output_ty);

src/librustc_typeck/check/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,10 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
16651665
fn set_tainted_by_errors(&self) {
16661666
self.infcx.set_tainted_by_errors()
16671667
}
1668+
1669+
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
1670+
self.write_ty(hir_id, ty)
1671+
}
16681672
}
16691673

16701674
/// Controls whether the arguments are tupled. This is used for the call

src/librustc_typeck/check/writeback.rs

+7
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
207207
let var_ty = self.resolve(&var_ty, &l.span);
208208
self.write_ty_to_tables(l.hir_id, var_ty);
209209
}
210+
211+
fn visit_ty(&mut self, hir_ty: &'gcx hir::Ty) {
212+
intravisit::walk_ty(self, hir_ty);
213+
let ty = self.fcx.node_ty(hir_ty.hir_id);
214+
let ty = self.resolve(&ty, &hir_ty.span);
215+
self.write_ty_to_tables(hir_ty.hir_id, ty);
216+
}
210217
}
211218

212219
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {

src/librustc_typeck/collect.rs

+4
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
221221
fn set_tainted_by_errors(&self) {
222222
// no obvious place to track this, just let it go
223223
}
224+
225+
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
226+
// no place to record types from signatures?
227+
}
224228
}
225229

226230
fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 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 arguments of unresolved types should have their types recorded
12+
13+
fn main() {
14+
let _: Nonexistent<u8, Assoc = u16>; //~ ERROR cannot find type `Nonexistent` in this scope
15+
16+
let _ = |a, b: _| -> _ { 0 };
17+
}

0 commit comments

Comments
 (0)