Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6383de15
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6383de15
编写于
4月 12, 2017
作者:
C
Cengiz Can
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fixes #40013
上级
c398efc5
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
272 addition
and
287 deletion
+272
-287
src/librustc/diagnostics.rs
src/librustc/diagnostics.rs
+52
-0
src/librustc/traits/error_reporting.rs
src/librustc/traits/error_reporting.rs
+84
-41
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/check/writeback.rs
+85
-166
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/diagnostics.rs
+1
-47
src/test/compile-fail/issue-22897.rs
src/test/compile-fail/issue-22897.rs
+0
-19
src/test/ui/type-check/cannot_infer_local_or_array.rs
src/test/ui/type-check/cannot_infer_local_or_array.rs
+1
-1
src/test/ui/type-check/cannot_infer_local_or_array.stderr
src/test/ui/type-check/cannot_infer_local_or_array.stderr
+10
-0
src/test/ui/type-check/cannot_infer_local_or_vec.rs
src/test/ui/type-check/cannot_infer_local_or_vec.rs
+0
-0
src/test/ui/type-check/cannot_infer_local_or_vec.stderr
src/test/ui/type-check/cannot_infer_local_or_vec.stderr
+1
-1
src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs
...test/ui/type-check/cannot_infer_local_or_vec_in_tuples.rs
+2
-4
src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
.../ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
+3
-3
src/test/ui/type-check/issue-22897.rs
src/test/ui/type-check/issue-22897.rs
+15
-0
src/test/ui/type-check/issue-22897.stderr
src/test/ui/type-check/issue-22897.stderr
+8
-0
src/test/ui/type-check/unknown_type_for_closure.rs
src/test/ui/type-check/unknown_type_for_closure.rs
+2
-5
src/test/ui/type-check/unknown_type_for_closure.stderr
src/test/ui/type-check/unknown_type_for_closure.stderr
+8
-0
未找到文件。
src/librustc/diagnostics.rs
浏览文件 @
6383de15
...
...
@@ -1807,6 +1807,58 @@ extern "C" fn foo(userdata: Box<i32>) {
[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
"##
,
/*
E0101: r##"
#### Note: this error code is no longer emitted by the compiler.
You hit this error because the compiler lacks the information to
determine a type for this expression. Erroneous code example:
```ignore
let x = |_| {}; // error: cannot determine a type for this expression
```
You have two possibilities to solve this situation:
* Give an explicit definition of the expression
* Infer the expression
Examples:
```
let x = |_ : u32| {}; // ok!
// or:
let x = |_| {};
x(0u32);
```
"##,
E0102: r##"
#### Note: this error code is no longer emitted by the compiler.
You hit this error because the compiler lacks the information to
determine the type of this variable. Erroneous code example:
```ignore
// could be an array of anything
let x = []; // error: cannot determine a type for this local variable
```
To solve this situation, constrain the type of the variable.
Examples:
```
#![allow(unused_variables)]
fn main() {
let x: [u8; 0] = [];
}
```
"##,
*/
}
...
...
src/librustc/traits/error_reporting.rs
浏览文件 @
6383de15
...
...
@@ -25,7 +25,7 @@
use
errors
::
DiagnosticBuilder
;
use
fmt_macros
::{
Parser
,
Piece
,
Position
};
use
hir
::{
intravisit
,
Local
,
Pat
};
use
hir
::{
self
,
intravisit
,
Local
,
Pat
,
Body
};
use
hir
::
intravisit
::{
Visitor
,
NestedVisitorMap
};
use
hir
::
map
::
NodeExpr
;
use
hir
::
def_id
::
DefId
;
...
...
@@ -33,8 +33,8 @@
use
infer
::
type_variable
::
TypeVariableOrigin
;
use
rustc
::
lint
::
builtin
::
EXTRA_REQUIREMENT_IN_IMPL
;
use
std
::
fmt
;
use
syntax
::
ast
;
use
ty
::{
self
,
AdtKind
,
ToPredicate
,
ToPolyTraitRef
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
syntax
::
ast
::{
self
,
NodeId
}
;
use
ty
::{
self
,
AdtKind
,
ToPredicate
,
ToPolyTraitRef
,
Ty
,
TyCtxt
,
TypeFoldable
,
TyInfer
,
TyVar
};
use
ty
::
error
::
ExpectedFound
;
use
ty
::
fast_reject
;
use
ty
::
fold
::
TypeFolder
;
...
...
@@ -66,37 +66,52 @@ fn from_error(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
struct
FindLocalByTypeVisitor
<
'a
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
>
{
infcx
:
&
'a
InferCtxt
<
'a
,
'gcx
,
'tcx
>
,
target_ty
:
&
'a
Ty
<
'tcx
>
,
found_pattern
:
Option
<&
'a
Pat
>
,
hir_map
:
&
'a
hir
::
map
::
Map
<
'gcx
>
,
found_local_pattern
:
Option
<&
'gcx
Pat
>
,
found_arg_pattern
:
Option
<&
'gcx
Pat
>
,
}
impl
<
'a
,
'gcx
,
'tcx
>
FindLocalByTypeVisitor
<
'a
,
'gcx
,
'tcx
>
{
fn
is_match
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
ty
==
*
self
.target_ty
||
match
(
&
ty
.sty
,
&
self
.target_ty.sty
)
{
(
&
ty
::
TyInfer
(
ty
::
TyVar
(
a_vid
)),
&
ty
::
TyInfer
(
ty
::
TyVar
(
b_vid
)))
=>
self
.infcx.type_variables
.borrow_mut
()
.sub_unified
(
a_vid
,
b_vid
),
fn
node_matches_type
(
&
mut
self
,
node_id
:
&
'gcx
NodeId
)
->
bool
{
match
self
.infcx.tables
.borrow
()
.node_types
.get
(
node_id
)
{
Some
(
&
ty
)
=>
{
let
ty
=
self
.infcx
.resolve_type_vars_if_possible
(
&
ty
);
ty
.walk
()
.any
(|
inner_ty
|
{
inner_ty
==
*
self
.target_ty
||
match
(
&
inner_ty
.sty
,
&
self
.target_ty.sty
)
{
(
&
TyInfer
(
TyVar
(
a_vid
)),
&
TyInfer
(
TyVar
(
b_vid
)))
=>
{
self
.infcx
.type_variables
.borrow_mut
()
.sub_unified
(
a_vid
,
b_vid
)
}
_
=>
false
,
}
})
}
_
=>
false
,
}
}
}
impl
<
'a
,
'gcx
,
'tcx
>
Visitor
<
'
a
>
for
FindLocalByTypeVisitor
<
'a
,
'gcx
,
'tcx
>
{
fn
nested_visit_map
<
'this
>
(
&
'this
mut
self
)
->
NestedVisitorMap
<
'this
,
'
a
>
{
NestedVisitorMap
::
None
impl
<
'a
,
'gcx
,
'tcx
>
Visitor
<
'
gcx
>
for
FindLocalByTypeVisitor
<
'a
,
'gcx
,
'tcx
>
{
fn
nested_visit_map
<
'this
>
(
&
'this
mut
self
)
->
NestedVisitorMap
<
'this
,
'
gcx
>
{
NestedVisitorMap
::
OnlyBodies
(
&
self
.hir_map
)
}
fn
visit_local
(
&
mut
self
,
local
:
&
'a
Local
)
{
if
let
Some
(
&
ty
)
=
self
.infcx.tables
.borrow
()
.node_types
.get
(
&
local
.id
)
{
let
ty
=
self
.infcx
.resolve_type_vars_if_possible
(
&
ty
);
let
is_match
=
ty
.walk
()
.any
(|
t
|
self
.is_match
(
t
));
fn
visit_local
(
&
mut
self
,
local
:
&
'gcx
Local
)
{
if
self
.found_local_pattern
.is_none
()
&&
self
.node_matches_type
(
&
local
.id
)
{
self
.found_local_pattern
=
Some
(
&*
local
.pat
);
}
intravisit
::
walk_local
(
self
,
local
);
}
if
is_match
&&
self
.found_pattern
.is_none
()
{
self
.found_pattern
=
Some
(
&*
local
.pat
);
fn
visit_body
(
&
mut
self
,
body
:
&
'gcx
Body
)
{
for
argument
in
&
body
.arguments
{
if
self
.found_arg_pattern
.is_none
()
&&
self
.node_matches_type
(
&
argument
.id
)
{
self
.found_arg_pattern
=
Some
(
&*
argument
.pat
);
}
}
intravisit
::
walk_
local
(
self
,
local
);
intravisit
::
walk_
body
(
self
,
body
);
}
}
...
...
@@ -721,6 +736,8 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
// coherence violation, so we don't report it here.
let
predicate
=
self
.resolve_type_vars_if_possible
(
&
obligation
.predicate
);
let
body_id
=
hir
::
BodyId
{
node_id
:
obligation
.cause.body_id
};
let
span
=
obligation
.cause.span
;
debug!
(
"maybe_report_ambiguity(predicate={:?}, obligation={:?})"
,
predicate
,
...
...
@@ -768,10 +785,10 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
self
.tcx.lang_items
.sized_trait
()
.map_or
(
false
,
|
sized_id
|
sized_id
==
trait_ref
.def_id
())
{
self
.need_type_info
(
obligatio
n
,
self_ty
);
self
.need_type_info
(
body_id
,
spa
n
,
self_ty
);
}
else
{
let
mut
err
=
struct_span_err!
(
self
.tcx.sess
,
obligation
.cause.
span
,
E0283
,
span
,
E0283
,
"type annotations required:
\
cannot resolve `{}`"
,
predicate
);
...
...
@@ -785,7 +802,7 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
// Same hacky approach as above to avoid deluging user
// with error messages.
if
!
ty
.references_error
()
&&
!
self
.tcx.sess
.has_errors
()
{
self
.need_type_info
(
obligatio
n
,
ty
);
self
.need_type_info
(
body_id
,
spa
n
,
ty
);
}
}
...
...
@@ -796,7 +813,9 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
let
&
SubtypePredicate
{
a_is_expected
:
_
,
a
,
b
}
=
data
.skip_binder
();
// both must be type variables, or the other would've been instantiated
assert
!
(
a
.is_ty_var
()
&&
b
.is_ty_var
());
self
.need_type_info
(
obligation
,
a
);
self
.need_type_info
(
hir
::
BodyId
{
node_id
:
obligation
.cause.body_id
},
obligation
.cause.span
,
a
);
}
}
...
...
@@ -874,42 +893,66 @@ fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
}
}
fn
need_type_info
(
&
self
,
obligation
:
&
PredicateObligation
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
{
pub
fn
need_type_info
(
&
self
,
body_id
:
hir
::
BodyId
,
span
:
Span
,
ty
:
Ty
<
'tcx
>
)
{
let
ty
=
self
.resolve_type_vars_if_possible
(
&
ty
);
let
name
=
self
.extract_type_name
(
&
ty
);
let
ref
cause
=
obligation
.cause
;
let
mut
err
=
struct_span_err!
(
self
.tcx.sess
,
cause
.span
,
E0282
,
"type annotations needed"
);
err
.span_label
(
cause
.span
,
&
format!
(
"cannot infer type for `{}`"
,
name
));
let
mut
err_span
=
span
;
let
mut
labels
=
vec!
[(
span
,
format!
(
"cannot infer type for `{}`"
,
name
))];
let
mut
local_visitor
=
FindLocalByTypeVisitor
{
infcx
:
&
self
,
target_ty
:
&
ty
,
found_pattern
:
None
,
hir_map
:
&
self
.tcx.hir
,
found_local_pattern
:
None
,
found_arg_pattern
:
None
,
};
// #40294: cause.body_id can also be a fn declaration.
// Currently, if it's anything other than NodeExpr, we just ignore it
match
self
.tcx.hir
.find
(
cause
.body
_id
)
{
match
self
.tcx.hir
.find
(
body_id
.node
_id
)
{
Some
(
NodeExpr
(
expr
))
=>
local_visitor
.visit_expr
(
expr
),
_
=>
()
}
if
let
Some
(
pattern
)
=
local_visitor
.found_pattern
{
let
pattern_span
=
pattern
.span
;
if
let
Some
(
pattern
)
=
local_visitor
.found_arg_pattern
{
err_span
=
pattern
.span
;
// We don't want to show the default label for closures.
//
// So, before clearing, the output would look something like this:
// ```
// let x = |_| { };
// - ^^^^ cannot infer type for `[_; 0]`
// |
// consider giving this closure parameter a type
// ```
//
// After clearing, it looks something like this:
// ```
// let x = |_| { };
// ^ consider giving this closure parameter a type
// ```
labels
.clear
();
labels
.push
((
pattern
.span
,
format!
(
"consider giving this closure parameter a type"
)));
}
if
let
Some
(
pattern
)
=
local_visitor
.found_local_pattern
{
if
let
Some
(
simple_name
)
=
pattern
.simple_name
()
{
err
.span_label
(
pattern_span
,
&
format!
(
"consider giving `{}` a type"
,
simple_name
));
labels
.push
((
pattern
.span
,
format!
(
"consider giving `{}` a type"
,
simple_name
)));
}
else
{
err
.span_label
(
pattern_span
,
&
format!
(
"consider giving a type to pattern"
));
labels
.push
((
pattern
.span
,
format!
(
"consider giving a type to pattern"
)
));
}
}
let
mut
err
=
struct_span_err!
(
self
.tcx.sess
,
err_span
,
E0282
,
"type annotations needed"
);
for
(
target_span
,
label_message
)
in
labels
{
err
.span_label
(
target_span
,
&
label_message
);
}
err
.emit
();
}
...
...
src/librustc_typeck/check/writeback.rs
浏览文件 @
6383de15
...
...
@@ -11,22 +11,18 @@
// Type resolution: the phase that finds all the types in the AST with
// unresolved type variables and replaces "ty_var" types with their
// substitutions.
use
self
::
ResolveReason
::
*
;
use
check
::
FnCtxt
;
use
rustc
::
hir
;
use
rustc
::
hir
::
intravisit
::{
self
,
Visitor
,
NestedVisitorMap
};
use
rustc
::
infer
::{
InferCtxt
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
,
MethodCall
,
MethodCallee
};
use
rustc
::
ty
::
adjustment
;
use
rustc
::
ty
::
fold
::{
TypeFolder
,
TypeFoldable
};
use
rustc
::
infer
::{
InferCtxt
,
FixupError
};
use
rustc
::
util
::
nodemap
::{
DefIdMap
,
DefIdSet
};
use
std
::
mem
;
use
syntax
::
ast
;
use
syntax_pos
::
Span
;
use
rustc
::
hir
::
intravisit
::{
self
,
Visitor
,
NestedVisitorMap
};
use
rustc
::
hir
;
use
std
::
mem
;
///////////////////////////////////////////////////////////////////////////
// Entry point
...
...
@@ -37,9 +33,9 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body)
let
item_id
=
self
.tcx.hir
.body_owner
(
body
.id
());
let
item_def_id
=
self
.tcx.hir
.local_def_id
(
item_id
);
let
mut
wbcx
=
WritebackCx
::
new
(
self
);
let
mut
wbcx
=
WritebackCx
::
new
(
self
,
body
);
for
arg
in
&
body
.arguments
{
wbcx
.visit_node_id
(
ResolvingPattern
(
arg
.pat.span
)
,
arg
.id
);
wbcx
.visit_node_id
(
arg
.pat.span
,
arg
.id
);
}
wbcx
.visit_body
(
body
);
wbcx
.visit_upvar_borrow_map
();
...
...
@@ -80,15 +76,19 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
// early-bound versions of them, visible from the
// outside of the function. This is needed by, and
// only populated if there are any `impl Trait`.
free_to_bound_regions
:
DefIdMap
<&
'gcx
ty
::
Region
>
free_to_bound_regions
:
DefIdMap
<&
'gcx
ty
::
Region
>
,
body
:
&
'gcx
hir
::
Body
,
}
impl
<
'cx
,
'gcx
,
'tcx
>
WritebackCx
<
'cx
,
'gcx
,
'tcx
>
{
fn
new
(
fcx
:
&
'cx
FnCtxt
<
'cx
,
'gcx
,
'tcx
>
)
->
WritebackCx
<
'cx
,
'gcx
,
'tcx
>
{
fn
new
(
fcx
:
&
'cx
FnCtxt
<
'cx
,
'gcx
,
'tcx
>
,
body
:
&
'gcx
hir
::
Body
)
->
WritebackCx
<
'cx
,
'gcx
,
'tcx
>
{
let
mut
wbcx
=
WritebackCx
{
fcx
:
fcx
,
tables
:
ty
::
TypeckTables
::
empty
(),
free_to_bound_regions
:
DefIdMap
()
free_to_bound_regions
:
DefIdMap
(),
body
:
body
};
// Only build the reverse mapping if `impl Trait` is used.
...
...
@@ -195,21 +195,20 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
}
fn
visit_stmt
(
&
mut
self
,
s
:
&
'gcx
hir
::
Stmt
)
{
self
.visit_node_id
(
ResolvingExpr
(
s
.span
)
,
s
.node
.id
());
self
.visit_node_id
(
s
.span
,
s
.node
.id
());
intravisit
::
walk_stmt
(
self
,
s
);
}
fn
visit_expr
(
&
mut
self
,
e
:
&
'gcx
hir
::
Expr
)
{
self
.fix_scalar_builtin_expr
(
e
);
self
.visit_node_id
(
ResolvingExpr
(
e
.span
),
e
.id
);
self
.visit_method_map_entry
(
ResolvingExpr
(
e
.span
),
MethodCall
::
expr
(
e
.id
));
self
.visit_node_id
(
e
.span
,
e
.id
);
self
.visit_method_map_entry
(
e
.span
,
MethodCall
::
expr
(
e
.id
));
if
let
hir
::
ExprClosure
(
_
,
_
,
body
,
_
)
=
e
.node
{
let
body
=
self
.fcx.tcx.hir
.body
(
body
);
for
arg
in
&
body
.arguments
{
self
.visit_node_id
(
ResolvingExpr
(
e
.span
)
,
arg
.id
);
self
.visit_node_id
(
e
.span
,
arg
.id
);
}
self
.visit_body
(
body
);
...
...
@@ -219,20 +218,20 @@ fn visit_expr(&mut self, e: &'gcx hir::Expr) {
}
fn
visit_block
(
&
mut
self
,
b
:
&
'gcx
hir
::
Block
)
{
self
.visit_node_id
(
ResolvingExpr
(
b
.span
)
,
b
.id
);
self
.visit_node_id
(
b
.span
,
b
.id
);
intravisit
::
walk_block
(
self
,
b
);
}
fn
visit_pat
(
&
mut
self
,
p
:
&
'gcx
hir
::
Pat
)
{
self
.visit_node_id
(
ResolvingPattern
(
p
.span
)
,
p
.id
);
self
.visit_node_id
(
p
.span
,
p
.id
);
intravisit
::
walk_pat
(
self
,
p
);
}
fn
visit_local
(
&
mut
self
,
l
:
&
'gcx
hir
::
Local
)
{
intravisit
::
walk_local
(
self
,
l
);
let
var_ty
=
self
.fcx
.local_ty
(
l
.span
,
l
.id
);
let
var_ty
=
self
.resolve
(
&
var_ty
,
ResolvingLocal
(
l
.span
)
);
let
var_ty
=
self
.resolve
(
&
var_ty
,
&
l
.span
);
self
.write_ty_to_tables
(
l
.id
,
var_ty
);
intravisit
::
walk_local
(
self
,
l
);
}
}
...
...
@@ -243,7 +242,7 @@ fn visit_upvar_borrow_map(&mut self) {
ty
::
UpvarCapture
::
ByValue
=>
ty
::
UpvarCapture
::
ByValue
,
ty
::
UpvarCapture
::
ByRef
(
ref
upvar_borrow
)
=>
{
let
r
=
upvar_borrow
.region
;
let
r
=
self
.resolve
(
&
r
,
ResolvingUpvar
(
*
upvar_id
)
);
let
r
=
self
.resolve
(
&
r
,
&
upvar_id
.var_id
);
ty
::
UpvarCapture
::
ByRef
(
ty
::
UpvarBorrow
{
kind
:
upvar_borrow
.kind
,
region
:
r
})
}
...
...
@@ -257,7 +256,7 @@ fn visit_upvar_borrow_map(&mut self) {
fn
visit_closures
(
&
mut
self
)
{
for
(
&
id
,
closure_ty
)
in
self
.fcx.tables
.borrow
()
.closure_tys
.iter
()
{
let
closure_ty
=
self
.resolve
(
closure_ty
,
ResolvingClosure
(
id
)
);
let
closure_ty
=
self
.resolve
(
closure_ty
,
&
id
);
self
.tables.closure_tys
.insert
(
id
,
closure_ty
);
}
...
...
@@ -282,8 +281,7 @@ fn visit_free_region_map(&mut self) {
fn
visit_anon_types
(
&
mut
self
)
{
let
gcx
=
self
.tcx
()
.global_tcx
();
for
(
&
node_id
,
&
concrete_ty
)
in
self
.fcx.anon_types
.borrow
()
.iter
()
{
let
reason
=
ResolvingAnonTy
(
node_id
);
let
inside_ty
=
self
.resolve
(
&
concrete_ty
,
reason
);
let
inside_ty
=
self
.resolve
(
&
concrete_ty
,
&
node_id
);
// Convert the type from the function into a type valid outside
// the function, by replacing free regions with early-bound ones.
...
...
@@ -305,7 +303,7 @@ fn visit_anon_types(&mut self) {
ty
::
ReLateBound
(
..
)
|
ty
::
ReScope
(
_
)
|
ty
::
ReSkolemized
(
..
)
=>
{
let
span
=
reason
.span
(
self
.tcx
()
);
let
span
=
node_id
.to_span
(
&
self
.fcx.tcx
);
span_err!
(
self
.tcx
()
.sess
,
span
,
E0564
,
"only named lifetimes are allowed in `impl Trait`,
\
but `{}` was found in the type `{}`"
,
r
,
inside_ty
);
...
...
@@ -314,7 +312,7 @@ fn visit_anon_types(&mut self) {
ty
::
ReVar
(
_
)
|
ty
::
ReErased
=>
{
let
span
=
reason
.span
(
self
.tcx
()
);
let
span
=
node_id
.to_span
(
&
self
.fcx.tcx
);
span_bug!
(
span
,
"invalid region in impl Trait: {:?}"
,
r
);
}
}
...
...
@@ -324,37 +322,37 @@ fn visit_anon_types(&mut self) {
}
}
fn
visit_node_id
(
&
mut
self
,
reason
:
ResolveReason
,
id
:
ast
::
NodeId
)
{
fn
visit_node_id
(
&
mut
self
,
span
:
Span
,
node_
id
:
ast
::
NodeId
)
{
// Export associated path extensions.
if
let
Some
(
def
)
=
self
.fcx.tables
.borrow_mut
()
.type_relative_path_defs
.remove
(
&
id
)
{
self
.tables.type_relative_path_defs
.insert
(
id
,
def
);
if
let
Some
(
def
)
=
self
.fcx.tables
.borrow_mut
()
.type_relative_path_defs
.remove
(
&
node_
id
)
{
self
.tables.type_relative_path_defs
.insert
(
node_
id
,
def
);
}
// Resolve any borrowings for the node with id `id`
self
.visit_adjustments
(
reason
,
id
);
// Resolve any borrowings for the node with id `
node_
id`
self
.visit_adjustments
(
span
,
node_
id
);
// Resolve the type of the node with id `id`
let
n_ty
=
self
.fcx
.node_ty
(
id
);
let
n_ty
=
self
.resolve
(
&
n_ty
,
reaso
n
);
self
.write_ty_to_tables
(
id
,
n_ty
);
debug!
(
"Node {} has type {:?}"
,
id
,
n_ty
);
// Resolve the type of the node with id `
node_
id`
let
n_ty
=
self
.fcx
.node_ty
(
node_
id
);
let
n_ty
=
self
.resolve
(
&
n_ty
,
&
spa
n
);
self
.write_ty_to_tables
(
node_
id
,
n_ty
);
debug!
(
"Node {} has type {:?}"
,
node_
id
,
n_ty
);
// Resolve any substitutions
self
.fcx
.opt_node_ty_substs
(
id
,
|
item_substs
|
{
let
item_substs
=
self
.resolve
(
item_substs
,
reaso
n
);
self
.fcx
.opt_node_ty_substs
(
node_
id
,
|
item_substs
|
{
let
item_substs
=
self
.resolve
(
item_substs
,
&
spa
n
);
if
!
item_substs
.is_noop
()
{
debug!
(
"write_substs_to_tcx({}, {:?})"
,
id
,
item_substs
);
debug!
(
"write_substs_to_tcx({}, {:?})"
,
node_
id
,
item_substs
);
assert
!
(
!
item_substs
.substs
.needs_infer
());
self
.tables.item_substs
.insert
(
id
,
item_substs
);
self
.tables.item_substs
.insert
(
node_
id
,
item_substs
);
}
});
}
fn
visit_adjustments
(
&
mut
self
,
reason
:
ResolveReason
,
id
:
ast
::
NodeId
)
{
let
adjustments
=
self
.fcx.tables
.borrow_mut
()
.adjustments
.remove
(
&
id
);
fn
visit_adjustments
(
&
mut
self
,
span
:
Span
,
node_
id
:
ast
::
NodeId
)
{
let
adjustments
=
self
.fcx.tables
.borrow_mut
()
.adjustments
.remove
(
&
node_
id
);
match
adjustments
{
None
=>
{
debug!
(
"No adjustments for node {}"
,
id
);
debug!
(
"No adjustments for node {}"
,
node_
id
);
}
Some
(
adjustment
)
=>
{
...
...
@@ -381,29 +379,29 @@ fn visit_adjustments(&mut self, reason: ResolveReason, id: ast::NodeId) {
adjustment
::
Adjust
::
DerefRef
{
autoderefs
,
autoref
,
unsize
}
=>
{
for
autoderef
in
0
..
autoderefs
{
let
method_call
=
MethodCall
::
autoderef
(
id
,
autoderef
as
u32
);
self
.visit_method_map_entry
(
reaso
n
,
method_call
);
let
method_call
=
MethodCall
::
autoderef
(
node_
id
,
autoderef
as
u32
);
self
.visit_method_map_entry
(
spa
n
,
method_call
);
}
adjustment
::
Adjust
::
DerefRef
{
autoderefs
:
autoderefs
,
autoref
:
self
.resolve
(
&
autoref
,
reaso
n
),
autoref
:
self
.resolve
(
&
autoref
,
&
spa
n
),
unsize
:
unsize
,
}
}
};
let
resolved_adjustment
=
adjustment
::
Adjustment
{
kind
:
resolved_adjustment
,
target
:
self
.resolve
(
&
adjustment
.target
,
reaso
n
)
target
:
self
.resolve
(
&
adjustment
.target
,
&
spa
n
)
};
debug!
(
"Adjustments for node {}: {:?}"
,
id
,
resolved_adjustment
);
self
.tables.adjustments
.insert
(
id
,
resolved_adjustment
);
debug!
(
"Adjustments for node {}: {:?}"
,
node_
id
,
resolved_adjustment
);
self
.tables.adjustments
.insert
(
node_
id
,
resolved_adjustment
);
}
}
}
fn
visit_method_map_entry
(
&
mut
self
,
reason
:
ResolveReaso
n
,
method_span
:
Spa
n
,
method_call
:
MethodCall
)
{
// Resolve any method map entry
let
new_method
=
match
self
.fcx.tables
.borrow_mut
()
.method_map
.remove
(
&
method_call
)
{
...
...
@@ -413,8 +411,8 @@ fn visit_method_map_entry(&mut self,
method
);
let
new_method
=
MethodCallee
{
def_id
:
method
.def_id
,
ty
:
self
.resolve
(
&
method
.ty
,
reaso
n
),
substs
:
self
.resolve
(
&
method
.substs
,
reaso
n
),
ty
:
self
.resolve
(
&
method
.ty
,
&
method_spa
n
),
substs
:
self
.resolve
(
&
method
.substs
,
&
method_spa
n
),
};
Some
(
new_method
)
...
...
@@ -430,72 +428,49 @@ fn visit_method_map_entry(&mut self,
fn
visit_liberated_fn_sigs
(
&
mut
self
)
{
for
(
&
node_id
,
fn_sig
)
in
self
.fcx.tables
.borrow
()
.liberated_fn_sigs
.iter
()
{
let
fn_sig
=
self
.resolve
(
fn_sig
,
ResolvingFnSig
(
node_id
)
);
let
fn_sig
=
self
.resolve
(
fn_sig
,
&
node_id
);
self
.tables.liberated_fn_sigs
.insert
(
node_id
,
fn_sig
.clone
());
}
}
fn
visit_fru_field_types
(
&
mut
self
)
{
for
(
&
node_id
,
ftys
)
in
self
.fcx.tables
.borrow
()
.fru_field_types
.iter
()
{
let
ftys
=
self
.resolve
(
ftys
,
ResolvingFieldTypes
(
node_id
)
);
let
ftys
=
self
.resolve
(
ftys
,
&
node_id
);
self
.tables.fru_field_types
.insert
(
node_id
,
ftys
);
}
}
fn
visit_type_nodes
(
&
self
)
{
for
(
&
id
,
ty
)
in
self
.fcx.ast_ty_to_ty_cache
.borrow
()
.iter
()
{
let
ty
=
self
.resolve
(
ty
,
ResolvingTyNode
(
id
)
);
let
ty
=
self
.resolve
(
ty
,
&
id
);
self
.fcx.tcx.ast_ty_to_ty_cache
.borrow_mut
()
.insert
(
id
,
ty
);
}
}
fn
resolve
<
T
>
(
&
self
,
x
:
&
T
,
reason
:
ResolveReason
)
->
T
::
Lifted
fn
resolve
<
T
>
(
&
self
,
x
:
&
T
,
span
:
&
Locatable
)
->
T
::
Lifted
where
T
:
TypeFoldable
<
'tcx
>
+
ty
::
Lift
<
'gcx
>
{
let
x
=
x
.fold_with
(
&
mut
Resolver
::
new
(
self
.fcx
,
reason
));
let
x
=
x
.fold_with
(
&
mut
Resolver
::
new
(
self
.fcx
,
span
,
self
.body
));
if
let
Some
(
lifted
)
=
self
.tcx
()
.lift_to_global
(
&
x
)
{
lifted
}
else
{
span_bug!
(
reason
.span
(
self
.tcx
()),
"writeback: `{:?}` missing from the global type context"
,
x
);
span_bug!
(
span
.to_span
(
&
self
.fcx.tcx
),
"writeback: `{:?}` missing from the global type context"
,
x
);
}
}
}
///////////////////////////////////////////////////////////////////////////
// Resolution reason.
#[derive(Copy,
Clone,
Debug)]
enum
ResolveReason
{
ResolvingExpr
(
Span
),
ResolvingLocal
(
Span
),
ResolvingPattern
(
Span
),
ResolvingUpvar
(
ty
::
UpvarId
),
ResolvingClosure
(
ast
::
NodeId
),
ResolvingFnSig
(
ast
::
NodeId
),
ResolvingFieldTypes
(
ast
::
NodeId
),
ResolvingAnonTy
(
ast
::
NodeId
),
ResolvingTyNode
(
ast
::
NodeId
),
trait
Locatable
{
fn
to_span
(
&
self
,
tcx
:
&
TyCtxt
)
->
Span
;
}
impl
<
'a
,
'gcx
,
'tcx
>
ResolveReason
{
fn
span
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
)
->
Span
{
match
*
self
{
ResolvingExpr
(
s
)
=>
s
,
ResolvingLocal
(
s
)
=>
s
,
ResolvingPattern
(
s
)
=>
s
,
ResolvingUpvar
(
upvar_id
)
=>
{
tcx
.expr_span
(
upvar_id
.closure_expr_id
)
}
ResolvingClosure
(
id
)
|
ResolvingFnSig
(
id
)
|
ResolvingFieldTypes
(
id
)
|
ResolvingTyNode
(
id
)
|
ResolvingAnonTy
(
id
)
=>
{
tcx
.hir
.span
(
id
)
}
}
}
impl
Locatable
for
Span
{
fn
to_span
(
&
self
,
_
:
&
TyCtxt
)
->
Span
{
*
self
}
}
impl
Locatable
for
ast
::
NodeId
{
fn
to_span
(
&
self
,
tcx
:
&
TyCtxt
)
->
Span
{
tcx
.hir
.span
(
*
self
)
}
}
///////////////////////////////////////////////////////////////////////////
...
...
@@ -505,82 +480,25 @@ fn span(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Span {
struct
Resolver
<
'cx
,
'gcx
:
'cx
+
'tcx
,
'tcx
:
'cx
>
{
tcx
:
TyCtxt
<
'cx
,
'gcx
,
'tcx
>
,
infcx
:
&
'cx
InferCtxt
<
'cx
,
'gcx
,
'tcx
>
,
reason
:
ResolveReason
,
span
:
&
'cx
Locatable
,
body
:
&
'gcx
hir
::
Body
,
}
impl
<
'cx
,
'gcx
,
'tcx
>
Resolver
<
'cx
,
'gcx
,
'tcx
>
{
fn
new
(
fcx
:
&
'cx
FnCtxt
<
'cx
,
'gcx
,
'tcx
>
,
reason
:
ResolveReason
)
->
Resolver
<
'cx
,
'gcx
,
'tcx
>
fn
new
(
fcx
:
&
'cx
FnCtxt
<
'cx
,
'gcx
,
'tcx
>
,
span
:
&
'cx
Locatable
,
body
:
&
'gcx
hir
::
Body
)
->
Resolver
<
'cx
,
'gcx
,
'tcx
>
{
Resolver
::
from_infcx
(
fcx
,
reason
)
}
fn
from_infcx
(
infcx
:
&
'cx
InferCtxt
<
'cx
,
'gcx
,
'tcx
>
,
reason
:
ResolveReason
)
->
Resolver
<
'cx
,
'gcx
,
'tcx
>
{
Resolver
{
infcx
:
infcx
,
tcx
:
infcx
.tcx
,
reason
:
reason
}
Resolver
{
tcx
:
fcx
.tcx
,
infcx
:
fcx
,
span
:
span
,
body
:
body
,
}
}
fn
report_error
(
&
self
,
e
:
FixupError
)
{
fn
report_error
(
&
self
,
t
:
Ty
<
'tcx
>
)
{
if
!
self
.tcx.sess
.has_errors
()
{
match
self
.reason
{
ResolvingExpr
(
span
)
=>
{
struct_span_err!
(
self
.tcx.sess
,
span
,
E0101
,
"cannot determine a type for this expression: {}"
,
e
)
.span_label
(
span
,
&
format!
(
"cannot resolve type of expression"
))
.emit
();
}
ResolvingLocal
(
span
)
=>
{
struct_span_err!
(
self
.tcx.sess
,
span
,
E0102
,
"cannot determine a type for this local variable: {}"
,
e
)
.span_label
(
span
,
&
format!
(
"cannot resolve type of variable"
))
.emit
();
}
ResolvingPattern
(
span
)
=>
{
span_err!
(
self
.tcx.sess
,
span
,
E0103
,
"cannot determine a type for this pattern binding: {}"
,
e
);
}
ResolvingUpvar
(
upvar_id
)
=>
{
let
span
=
self
.reason
.span
(
self
.tcx
);
span_err!
(
self
.tcx.sess
,
span
,
E0104
,
"cannot resolve lifetime for captured variable `{}`: {}"
,
self
.tcx
.local_var_name_str
(
upvar_id
.var_id
),
e
);
}
ResolvingClosure
(
_
)
=>
{
let
span
=
self
.reason
.span
(
self
.tcx
);
span_err!
(
self
.tcx.sess
,
span
,
E0196
,
"cannot determine a type for this closure"
)
}
ResolvingFnSig
(
_
)
|
ResolvingFieldTypes
(
_
)
|
ResolvingTyNode
(
_
)
=>
{
// any failures here should also fail when
// resolving the patterns, closure types, or
// something else.
let
span
=
self
.reason
.span
(
self
.tcx
);
self
.tcx.sess
.delay_span_bug
(
span
,
&
format!
(
"cannot resolve some aspect of data for {:?}: {}"
,
self
.reason
,
e
));
}
ResolvingAnonTy
(
_
)
=>
{
let
span
=
self
.reason
.span
(
self
.tcx
);
span_err!
(
self
.tcx.sess
,
span
,
E0563
,
"cannot determine a type for this `impl Trait`: {}"
,
e
)
}
}
self
.infcx
.need_type_info
(
self
.body
.id
(),
self
.span
.to_span
(
&
self
.tcx
),
t
);
}
}
}
...
...
@@ -593,20 +511,21 @@ fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
self
.infcx
.fully_resolve
(
&
t
)
{
Ok
(
t
)
=>
t
,
Err
(
e
)
=>
{
Err
(
_
)
=>
{
debug!
(
"Resolver::fold_ty: input type `{:?}` not fully resolvable"
,
t
);
self
.report_error
(
e
);
self
.report_error
(
t
);
self
.tcx
()
.types.err
}
}
}
// FIXME This should be carefully checked
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
fn
fold_region
(
&
mut
self
,
r
:
&
'tcx
ty
::
Region
)
->
&
'tcx
ty
::
Region
{
match
self
.infcx
.fully_resolve
(
&
r
)
{
Ok
(
r
)
=>
r
,
Err
(
e
)
=>
{
self
.report_error
(
e
);
Err
(
_
)
=>
{
self
.tcx
.mk_region
(
ty
::
ReStatic
)
}
}
...
...
src/librustc_typeck/diagnostics.rs
浏览文件 @
6383de15
...
...
@@ -1351,50 +1351,6 @@ fn main() {
```
"##
,
E0101
:
r##"
You hit this error because the compiler lacks the information to
determine a type for this expression. Erroneous code example:
```compile_fail,E0101
let x = |_| {}; // error: cannot determine a type for this expression
```
You have two possibilities to solve this situation:
* Give an explicit definition of the expression
* Infer the expression
Examples:
```
let x = |_ : u32| {}; // ok!
// or:
let x = |_| {};
x(0u32);
```
"##
,
E0102
:
r##"
You hit this error because the compiler lacks the information to
determine the type of this variable. Erroneous code example:
```compile_fail,E0282
// could be an array of anything
let x = []; // error: cannot determine a type for this local variable
```
To solve this situation, constrain the type of the variable.
Examples:
```
#![allow(unused_variables)]
fn main() {
let x: [u8; 0] = [];
}
```
"##
,
E0107
:
r##"
This error means that an incorrect number of lifetime parameters were provided
for a type (like a struct or enum) or trait:
...
...
@@ -4146,8 +4102,6 @@ fn main() { }
// E0068,
// E0085,
// E0086,
E0103
,
// @GuillaumeGomez: I was unable to get this error, try your best!
E0104
,
// E0123,
// E0127,
// E0129,
...
...
@@ -4164,7 +4118,7 @@ fn main() { }
// E0188, // can not cast an immutable reference to a mutable pointer
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
// E0190, // deprecated: can only cast a &-pointer to an &-object
E0196
,
// cannot determine a type for this closure
E0196
,
// cannot determine a type for this closure
// @cengizIO: this is no longer thrown. should I DELETE THIS?
E0203
,
// type parameter has more than one relaxed default bound,
// and only one is supported
E0208
,
...
...
src/test/compile-fail/issue-22897.rs
已删除
100644 → 0
浏览文件 @
c398efc5
// Copyright 2015 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.
fn
main
()
{
}
// Before these errors would ICE as "cat_expr Errd" because the errors
// were unknown when the bug was triggered.
fn
unconstrained_type
()
{
[];
//~^ ERROR cannot determine a type for this expression: unconstrained type
}
src/test/ui/type-check/
issue-38812-2
.rs
→
src/test/ui/type-check/
cannot_infer_local_or_array
.rs
浏览文件 @
6383de15
...
...
@@ -9,5 +9,5 @@
// except according to those terms.
fn
main
()
{
let
(
x
,)
=
(
vec!
[],)
;
let
x
=
[]
;
}
src/test/ui/type-check/cannot_infer_local_or_array.stderr
0 → 100644
浏览文件 @
6383de15
error[E0282]: type annotations needed
--> $DIR/cannot_infer_local_or_array.rs:12:13
|
12 | let x = [];
| - ^^ cannot infer type for `_`
| |
| consider giving `x` a type
error: aborting due to previous error
src/test/ui/type-check/
issue-38812
.rs
→
src/test/ui/type-check/
cannot_infer_local_or_vec
.rs
浏览文件 @
6383de15
文件已移动
src/test/ui/type-check/
issue-38812
.stderr
→
src/test/ui/type-check/
cannot_infer_local_or_vec
.stderr
浏览文件 @
6383de15
error[E0282]: type annotations needed
--> $DIR/
issue-38812
.rs:12:13
--> $DIR/
cannot_infer_local_or_vec
.rs:12:13
|
12 | let x = vec![];
| - ^^^^^^ cannot infer type for `T`
...
...
src/test/
compile-fail/E0101
.rs
→
src/test/
ui/type-check/cannot_infer_local_or_vec_in_tuples
.rs
浏览文件 @
6383de15
// Copyright 201
6
The Rust Project Developers. See the COPYRIGHT
// Copyright 201
7
The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
...
...
@@ -9,7 +9,5 @@
// except according to those terms.
fn
main
()
{
let
x
=
|
_
|
{};
//~^ ERROR E0101
//~| NOTE cannot resolve type of expression
let
(
x
,
)
=
(
vec!
[],
);
}
src/test/ui/type-check/
issue-38812-2
.stderr
→
src/test/ui/type-check/
cannot_infer_local_or_vec_in_tuples
.stderr
浏览文件 @
6383de15
error[E0282]: type annotations needed
--> $DIR/
issue-38812-2.rs:12:17
--> $DIR/
cannot_infer_local_or_vec_in_tuples.rs:12:18
|
12 | let (x,
) = (vec![],
);
| ---- ^^^^^^ cannot infer type for `T`
12 | let (x,
) = (vec![],
);
| ----
-
^^^^^^ cannot infer type for `T`
| |
| consider giving a type to pattern
|
...
...
src/test/ui/type-check/issue-22897.rs
0 → 100644
浏览文件 @
6383de15
// 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.
fn
main
()
{
}
fn
unconstrained_type
()
{
[];
}
src/test/ui/type-check/issue-22897.stderr
0 → 100644
浏览文件 @
6383de15
error[E0282]: type annotations needed
--> $DIR/issue-22897.rs:14:5
|
14 | [];
| ^^ cannot infer type for `[_; 0]`
error: aborting due to previous error
src/test/
compile-fail/E0102
.rs
→
src/test/
ui/type-check/unknown_type_for_closure
.rs
浏览文件 @
6383de15
// Copyright 201
6
The Rust Project Developers. See the COPYRIGHT
// Copyright 201
7
The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
...
...
@@ -9,8 +9,5 @@
// except according to those terms.
fn
main
()
{
let
x
=
[];
//~^ ERROR type annotations needed
//~| NOTE consider giving `x` a type
//~| NOTE cannot infer type for `_`
let
x
=
|
_
|
{
};
}
src/test/ui/type-check/unknown_type_for_closure.stderr
0 → 100644
浏览文件 @
6383de15
error[E0282]: type annotations needed
--> $DIR/unknown_type_for_closure.rs:12:14
|
12 | let x = |_| { };
| ^ consider giving this closure parameter a type
error: aborting due to previous error
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录