Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4c0ff95e
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,发现更多精彩内容 >>
提交
4c0ff95e
编写于
12月 21, 2017
作者:
L
leonardo.yvens
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Be more explicit about how and why we need fallback in targets of casts
上级
02084f33
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
34 addition
and
21 deletion
+34
-21
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+8
-2
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+10
-19
src/test/run-pass/cast-does-fallback.rs
src/test/run-pass/cast-does-fallback.rs
+16
-0
未找到文件。
src/librustc_typeck/check/cast.rs
浏览文件 @
4c0ff95e
...
...
@@ -38,7 +38,7 @@
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
//! `U1` coerces to `U2`).
use
super
::{
Diverges
,
FnCtxt
};
use
super
::{
Diverges
,
F
allback
,
F
nCtxt
};
use
errors
::
DiagnosticBuilder
;
use
hir
::
def_id
::
DefId
;
...
...
@@ -392,7 +392,13 @@ fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
}
pub
fn
check
(
mut
self
,
fcx
:
&
FnCtxt
<
'a
,
'gcx
,
'tcx
>
)
{
self
.expr_ty
=
fcx
.resolved_type
(
self
.span
,
self
.expr_ty
);
self
.expr_ty
=
fcx
.structurally_resolved_type
(
self
.span
,
self
.expr_ty
);
// For backwards compatibility we apply numeric fallback here. This means that in:
// `let x = 100; x as u8;`, we infer `x` to `i32` rather than `u8`.
if
self
.expr_ty
.is_ty_infer
()
{
fcx
.apply_fallback_if_possible
(
self
.expr_ty
,
Fallback
::
Numeric
);
self
.expr_ty
=
fcx
.structurally_resolved_type
(
self
.span
,
self
.expr_ty
);
}
self
.cast_ty
=
fcx
.structurally_resolved_type
(
self
.span
,
self
.cast_ty
);
debug!
(
"check_cast({}, {:?} as {:?})"
,
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
4c0ff95e
...
...
@@ -1724,6 +1724,12 @@ enum TupleArgumentsFlag {
TupleArguments
,
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
Eq)]
pub
enum
Fallback
{
Full
,
Numeric
}
impl
<
'a
,
'gcx
,
'tcx
>
FnCtxt
<
'a
,
'gcx
,
'tcx
>
{
pub
fn
new
(
inh
:
&
'a
Inherited
<
'a
,
'gcx
,
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
...
...
@@ -2133,7 +2139,7 @@ fn resolve_generator_interiors(&self, def_id: DefId) {
// unconstrained floats with f64.
// Defaulting inference variables becomes very dubious if we have
// encountered type-checking errors. In that case, fallback to TyError.
fn
apply_fallback_if_possible
(
&
self
,
ty
:
Ty
<
'tcx
>
)
{
fn
apply_fallback_if_possible
(
&
self
,
ty
:
Ty
<
'tcx
>
,
fallback
:
Fallback
)
{
use
rustc
::
ty
::
error
::
UnconstrainedNumeric
::
Neither
;
use
rustc
::
ty
::
error
::
UnconstrainedNumeric
::{
UnconstrainedInt
,
UnconstrainedFloat
};
...
...
@@ -2142,7 +2148,8 @@ fn apply_fallback_if_possible(&self, ty: Ty<'tcx>) {
_
if
self
.is_tainted_by_errors
()
=>
self
.tcx
()
.types.err
,
UnconstrainedInt
=>
self
.tcx.types.i32
,
UnconstrainedFloat
=>
self
.tcx.types.f64
,
Neither
if
self
.type_var_diverges
(
ty
)
=>
self
.tcx
.mk_diverging_default
(),
Neither
if
self
.type_var_diverges
(
ty
)
&&
fallback
==
Fallback
::
Full
=>
self
.tcx
.mk_diverging_default
(),
Neither
=>
return
};
debug!
(
"default_type_parameters: defaulting `{:?}` to `{:?}`"
,
ty
,
fallback
);
...
...
@@ -2159,7 +2166,7 @@ fn select_all_obligations_or_error(&self) {
self
.select_obligations_where_possible
();
for
ty
in
&
self
.unsolved_variables
()
{
self
.apply_fallback_if_possible
(
ty
);
self
.apply_fallback_if_possible
(
ty
,
Fallback
::
Full
);
}
let
mut
fulfillment_cx
=
self
.fulfillment_cx
.borrow_mut
();
...
...
@@ -4937,22 +4944,6 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
}
}
// Same as `structurally_resolved_type` but also resolves numeric vars, with fallback.
pub
fn
resolved_type
(
&
self
,
sp
:
Span
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
let
mut
ty
=
self
.resolve_type_vars_with_obligations
(
ty
);
if
!
ty
.is_ty_infer
()
{
return
ty
;
}
else
{
self
.apply_fallback_if_possible
(
ty
);
ty
=
self
.resolve_type_vars_with_obligations
(
ty
);
if
!
ty
.is_ty_infer
()
{
ty
}
else
{
// Fallback failed, error.
self
.must_be_known_in_context
(
sp
,
ty
)
}
}
}
fn
must_be_known_in_context
(
&
self
,
sp
:
Span
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
!
self
.is_tainted_by_errors
()
{
type_error_struct!
(
self
.tcx.sess
,
sp
,
ty
,
E0619
,
...
...
src/test/run-pass/cast-does-fallback.rs
0 → 100644
浏览文件 @
4c0ff95e
// 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.
pub
fn
main
()
{
let
cap
=
512
*
512
;
cap
as
u8
;
// Assert `cap` did not get inferred to `u8` and overflowed.
assert_ne!
(
cap
,
0
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录