Record semantic types for all syntactic types in bodies
This commit is contained in:
parent
5b9b50e712
commit
505ff71ac1
5 changed files with 62 additions and 14 deletions
|
@ -76,6 +76,8 @@ pub trait AstConv<'gcx, 'tcx> {
|
||||||
/// used to help suppress derived errors typeck might otherwise
|
/// used to help suppress derived errors typeck might otherwise
|
||||||
/// report.
|
/// report.
|
||||||
fn set_tainted_by_errors(&self);
|
fn set_tainted_by_errors(&self);
|
||||||
|
|
||||||
|
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConvertedBinding<'tcx> {
|
struct ConvertedBinding<'tcx> {
|
||||||
|
@ -975,6 +977,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Def::Err => {
|
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();
|
self.set_tainted_by_errors();
|
||||||
return self.tcx().types.err;
|
return self.tcx().types.err;
|
||||||
}
|
}
|
||||||
|
@ -1115,6 +1125,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
|
||||||
result_ty
|
result_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,8 +1135,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
-> Ty<'tcx>
|
-> Ty<'tcx>
|
||||||
{
|
{
|
||||||
match ty.node {
|
match ty.node {
|
||||||
hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
|
hir::TyInfer if expected_ty.is_some() => {
|
||||||
hir::TyInfer => self.ty_infer(ty.span),
|
self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
|
||||||
|
expected_ty.unwrap()
|
||||||
|
}
|
||||||
_ => self.ast_ty_to_ty(ty),
|
_ => self.ast_ty_to_ty(ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1214,19 +1227,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
|
|
||||||
let expected_ret_ty = expected_sig.as_ref().map(|e| e.output());
|
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 {
|
let output_ty = match decl.output {
|
||||||
_ if is_infer && expected_ret_ty.is_some() =>
|
hir::Return(ref output) => {
|
||||||
expected_ret_ty.unwrap(),
|
if let (&hir::TyInfer, Some(expected_ret_ty)) = (&output.node, expected_ret_ty) {
|
||||||
_ if is_infer => self.ty_infer(decl.output.span()),
|
self.record_ty(output.hir_id, expected_ret_ty, output.span);
|
||||||
hir::Return(ref output) =>
|
expected_ret_ty
|
||||||
self.ast_ty_to_ty(&output),
|
} else {
|
||||||
hir::DefaultReturn(..) => bug!(),
|
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);
|
debug!("ty_of_closure: output_ty={:?}", output_ty);
|
||||||
|
|
|
@ -1665,6 +1665,10 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
fn set_tainted_by_errors(&self) {
|
fn set_tainted_by_errors(&self) {
|
||||||
self.infcx.set_tainted_by_errors()
|
self.infcx.set_tainted_by_errors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
|
||||||
|
self.write_ty(hir_id, ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Controls whether the arguments are tupled. This is used for the call
|
/// Controls whether the arguments are tupled. This is used for the call
|
||||||
|
|
|
@ -207,6 +207,13 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||||
let var_ty = self.resolve(&var_ty, &l.span);
|
let var_ty = self.resolve(&var_ty, &l.span);
|
||||||
self.write_ty_to_tables(l.hir_id, var_ty);
|
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> {
|
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||||
|
|
|
@ -221,6 +221,10 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
|
||||||
fn set_tainted_by_errors(&self) {
|
fn set_tainted_by_errors(&self) {
|
||||||
// no obvious place to track this, just let it go
|
// 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>,
|
fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
|
17
src/test/compile-fail/type-path-err-node-types.rs
Normal file
17
src/test/compile-fail/type-path-err-node-types.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// 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 };
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue