Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
180534f3
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,发现更多精彩内容 >>
提交
180534f3
编写于
8月 28, 2016
作者:
A
Andrew Cann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove use of expr_ty from coercions code
上级
bd661481
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
37 addition
and
26 deletion
+37
-26
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+7
-3
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+2
-2
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+13
-9
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/demand.rs
+3
-3
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+12
-9
未找到文件。
src/librustc_typeck/check/_match.rs
浏览文件 @
180534f3
...
...
@@ -419,11 +419,14 @@ pub fn check_match(&self,
}
_
=>
result_ty
};
let
mut
arm_tys
=
Vec
::
new
();
for
(
i
,
arm
)
in
arms
.iter
()
.enumerate
()
{
if
let
Some
(
ref
e
)
=
arm
.guard
{
self
.check_expr_has_type
(
e
,
tcx
.types.bool
);
}
let
arm_ty
=
self
.check_expr_with_expectation
(
&
arm
.body
,
expected
);
arm_tys
.push
(
arm_ty
);
if
result_ty
.references_error
()
||
arm_ty
.references_error
()
{
result_ty
=
tcx
.types.err
;
...
...
@@ -453,10 +456,11 @@ pub fn check_match(&self,
})
}
else
if
i
==
0
{
// Special-case the first arm, as it has no "previous expressions".
self
.try_coerce
(
&
arm
.body
,
coerce_first
)
self
.try_coerce
(
&
arm
.body
,
arm_ty
,
coerce_first
)
}
else
{
let
prev_arms
=
||
arms
[
..
i
]
.iter
()
.map
(|
arm
|
&*
arm
.body
);
self
.try_find_coercion_lub
(
origin
,
prev_arms
,
result_ty
,
&
arm
.body
)
let
prev_arms
=
||
arms
[
..
i
]
.iter
()
.map
(|
arm
|
&*
arm
.body
)
.zip
(
arm_tys
.iter
()
.cloned
());
self
.try_find_coercion_lub
(
origin
,
prev_arms
,
result_ty
,
&
arm
.body
,
arm_ty
)
};
result_ty
=
match
result
{
...
...
src/librustc_typeck/check/cast.rs
浏览文件 @
180534f3
...
...
@@ -321,7 +321,7 @@ fn do_check(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Result<CastKind, CastError>
(
None
,
Some
(
t_cast
))
=>
{
if
let
ty
::
TyFnDef
(
..
,
f
)
=
self
.expr_ty.sty
{
// Attempt a coercion to a fn pointer type.
let
res
=
fcx
.try_coerce
(
self
.expr
,
fcx
.tcx
.mk_fn_ptr
(
f
));
let
res
=
fcx
.try_coerce
(
self
.expr
,
self
.expr_ty
,
fcx
.tcx
.mk_fn_ptr
(
f
));
if
!
res
.is_ok
()
{
return
Err
(
CastError
::
NonScalar
);
}
...
...
@@ -471,7 +471,7 @@ fn check_addr_ptr_cast(&self,
}
fn
try_coercion_cast
(
&
self
,
fcx
:
&
FnCtxt
<
'a
,
'gcx
,
'tcx
>
)
->
bool
{
fcx
.try_coerce
(
self
.expr
,
self
.cast_ty
)
.is_ok
()
fcx
.try_coerce
(
self
.expr
,
self
.
expr_ty
,
self
.
cast_ty
)
.is_ok
()
}
}
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
180534f3
...
...
@@ -630,9 +630,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// The expressions *must not* have any pre-existing adjustments.
pub
fn
try_coerce
(
&
self
,
expr
:
&
hir
::
Expr
,
expr_ty
:
Ty
<
'tcx
>
,
target
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
{
let
source
=
self
.resolve_type_vars_with_obligations
(
self
.expr_ty
(
expr
)
);
let
source
=
self
.resolve_type_vars_with_obligations
(
expr_ty
);
debug!
(
"coercion::try({:?}: {:?} -> {:?})"
,
expr
,
source
,
target
);
let
mut
coerce
=
Coerce
::
new
(
self
,
TypeOrigin
::
ExprAssignable
(
expr
.span
));
...
...
@@ -658,14 +659,15 @@ pub fn try_find_coercion_lub<'b, E, I>(&self,
origin
:
TypeOrigin
,
exprs
:
E
,
prev_ty
:
Ty
<
'tcx
>
,
new
:
&
'b
hir
::
Expr
)
new
:
&
'b
hir
::
Expr
,
new_ty
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
where
E
:
Fn
()
->
I
,
I
:
IntoIterator
<
Item
=
&
'b
hir
::
Expr
>
{
I
:
IntoIterator
<
Item
=
(
&
'b
hir
::
Expr
,
Ty
<
'tcx
>
)
>
{
let
prev_ty
=
self
.resolve_type_vars_with_obligations
(
prev_ty
);
let
new_ty
=
self
.resolve_type_vars_with_obligations
(
self
.expr_ty
(
new
)
);
let
new_ty
=
self
.resolve_type_vars_with_obligations
(
new_ty
);
debug!
(
"coercion::try_find_lub({:?}, {:?})"
,
prev_ty
,
new_ty
);
let
trace
=
TypeTrace
::
types
(
origin
,
true
,
prev_ty
,
new_ty
);
...
...
@@ -701,7 +703,7 @@ pub fn try_find_coercion_lub<'b, E, I>(&self,
}
// Reify both sides and return the reified fn pointer type.
for
expr
in
exprs
()
.into_iter
()
.chain
(
Some
(
new
))
{
for
(
expr
,
_
)
in
exprs
()
.into_iter
()
.chain
(
Some
((
new
,
new_ty
)
))
{
// No adjustments can produce a fn item, so this should never trip.
assert
!
(
!
self
.tables
.borrow
()
.adjustments
.contains_key
(
&
expr
.id
));
self
.write_adjustment
(
expr
.id
,
AdjustReifyFnPointer
);
...
...
@@ -735,13 +737,13 @@ pub fn try_find_coercion_lub<'b, E, I>(&self,
// Then try to coerce the previous expressions to the type of the new one.
// This requires ensuring there are no coercions applied to *any* of the
// previous expressions, other than noop reborrows (ignoring lifetimes).
for
expr
in
exprs
()
{
for
(
expr
,
expr_ty
)
in
exprs
()
{
let
noop
=
match
self
.tables
.borrow
()
.adjustments
.get
(
&
expr
.id
)
{
Some
(
&
AdjustDerefRef
(
AutoDerefRef
{
autoderefs
:
1
,
autoref
:
Some
(
AutoPtr
(
_
,
mutbl_adj
)),
unsize
:
None
}))
=>
match
self
.expr_ty
(
expr
)
.sty
{
}))
=>
match
expr_ty
.sty
{
ty
::
TyRef
(
_
,
mt_orig
)
=>
{
// Reborrow that we can safely ignore.
mutbl_adj
==
mt_orig
.mutbl
...
...
@@ -765,7 +767,9 @@ pub fn try_find_coercion_lub<'b, E, I>(&self,
}
}
match
self
.commit_if_ok
(|
_
|
apply
(
&
mut
coerce
,
&
exprs
,
prev_ty
,
new_ty
))
{
match
self
.commit_if_ok
(|
_
|
apply
(
&
mut
coerce
,
&
||
exprs
()
.into_iter
()
.map
(|(
e
,
_
)|
e
),
prev_ty
,
new_ty
))
{
Err
(
_
)
=>
{
// Avoid giving strange errors on failed attempts.
if
let
Some
(
e
)
=
first_error
{
...
...
@@ -783,7 +787,7 @@ pub fn try_find_coercion_lub<'b, E, I>(&self,
}
Ok
((
ty
,
adjustment
))
=>
{
if
!
adjustment
.is_identity
()
{
for
expr
in
exprs
()
{
for
(
expr
,
_
)
in
exprs
()
{
let
previous
=
self
.tables
.borrow
()
.adjustments
.get
(
&
expr
.id
)
.cloned
();
if
let
Some
(
AdjustNeverToAny
(
_
))
=
previous
{
self
.write_adjustment
(
expr
.id
,
AdjustNeverToAny
(
ty
));
...
...
src/librustc_typeck/check/demand.rs
浏览文件 @
180534f3
...
...
@@ -53,11 +53,11 @@ pub fn demand_eqtype_with_origin(&self,
}
// Checks that the type of `expr` can be coerced to `expected`.
pub
fn
demand_coerce
(
&
self
,
expr
:
&
hir
::
Expr
,
expected
:
Ty
<
'tcx
>
)
{
pub
fn
demand_coerce
(
&
self
,
expr
:
&
hir
::
Expr
,
checked_ty
:
Ty
<
'tcx
>
,
expected
:
Ty
<
'tcx
>
)
{
let
expected
=
self
.resolve_type_vars_with_obligations
(
expected
);
if
let
Err
(
e
)
=
self
.try_coerce
(
expr
,
expected
)
{
if
let
Err
(
e
)
=
self
.try_coerce
(
expr
,
checked_ty
,
expected
)
{
let
origin
=
TypeOrigin
::
Misc
(
expr
.span
);
let
expr_ty
=
self
.resolve_type_vars_with_obligations
(
self
.expr_ty
(
expr
)
);
let
expr_ty
=
self
.resolve_type_vars_with_obligations
(
checked_ty
);
self
.report_mismatched_types
(
origin
,
expected
,
expr_ty
,
e
);
}
}
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
180534f3
...
...
@@ -2567,13 +2567,13 @@ fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
Expectation
::
rvalue_hint
(
self
,
ty
)
});
self
.check_expr_with_expectation
(
&
arg
,
expected
.unwrap_or
(
ExpectHasType
(
formal_ty
)));
let
checked_ty
=
self
.check_expr_with_expectation
(
&
arg
,
expected
.unwrap_or
(
ExpectHasType
(
formal_ty
)));
// 2. Coerce to the most detailed type that could be coerced
// to, which is `expected_ty` if `rvalue_hint` returns an
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
let
coerce_ty
=
expected
.and_then
(|
e
|
e
.only_has_type
(
self
));
self
.demand_coerce
(
&
arg
,
coerce_ty
.unwrap_or
(
formal_ty
));
self
.demand_coerce
(
&
arg
,
c
hecked_ty
,
c
oerce_ty
.unwrap_or
(
formal_ty
));
// 3. Relate the expected type and the formal one,
// if the expected type was used for the coercion.
...
...
@@ -2715,7 +2715,7 @@ fn check_expr_coercable_to_type(&self,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
let
ty
=
self
.check_expr_with_hint
(
expr
,
expected
);
self
.demand_coerce
(
expr
,
expected
);
self
.demand_coerce
(
expr
,
ty
,
expected
);
ty
}
...
...
@@ -2861,8 +2861,8 @@ fn check_then_else(&self,
// Only try to coerce-unify if we have a then expression
// to assign coercions to, otherwise it's () or diverging.
let
result
=
if
let
Some
(
ref
then
)
=
then_blk
.expr
{
let
res
=
self
.try_find_coercion_lub
(
origin
,
||
Some
(
&**
then
),
then_ty
,
else_expr
);
let
res
=
self
.try_find_coercion_lub
(
origin
,
||
Some
(
(
&**
then
,
then_ty
)
),
then_ty
,
else_expr
,
else_ty
);
// In case we did perform an adjustment, we have to update
// the type of the block, because old trans still uses it.
...
...
@@ -3594,16 +3594,19 @@ fn check_expr_kind(&self,
let
mut
unified
=
self
.next_ty_var
();
let
coerce_to
=
uty
.unwrap_or
(
unified
);
let
mut
arg_tys
=
Vec
::
new
();
for
(
i
,
e
)
in
args
.iter
()
.enumerate
()
{
let
e_ty
=
self
.check_expr_with_hint
(
e
,
coerce_to
);
arg_tys
.push
(
e_ty
);
let
origin
=
TypeOrigin
::
Misc
(
e
.span
);
// Special-case the first element, as it has no "previous expressions".
let
result
=
if
i
==
0
{
self
.try_coerce
(
e
,
coerce_to
)
self
.try_coerce
(
e
,
e_ty
,
coerce_to
)
}
else
{
let
prev_elems
=
||
args
[
..
i
]
.iter
()
.map
(|
e
|
&**
e
);
self
.try_find_coercion_lub
(
origin
,
prev_elems
,
unified
,
e
)
let
prev_elems
=
||
args
[
..
i
]
.iter
()
.map
(|
e
|
&**
e
)
.zip
(
arg_tys
.iter
()
.cloned
());
self
.try_find_coercion_lub
(
origin
,
prev_elems
,
unified
,
e
,
e_ty
)
};
match
result
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录