Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
99a48660
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,发现更多精彩内容 >>
提交
99a48660
编写于
2月 21, 2012
作者:
B
Brian Anderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Allow any integral types on rhs of shift ops
上级
e9c7f0c2
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
156 addition
and
8 deletion
+156
-8
src/comp/middle/trans/base.rs
src/comp/middle/trans/base.rs
+43
-0
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+18
-8
src/comp/syntax/ast_util.rs
src/comp/syntax/ast_util.rs
+9
-0
src/test/run-pass/shift.rs
src/test/run-pass/shift.rs
+86
-0
未找到文件。
src/comp/middle/trans/base.rs
浏览文件 @
99a48660
...
...
@@ -1641,6 +1641,44 @@ fn trans_compare(cx: block, op: ast::binop, lhs: ValueRef,
}
}
fn
cast_shift_expr_rhs
(
cx
:
block
,
op
:
ast
::
binop
,
lhs
:
ValueRef
,
rhs
:
ValueRef
)
->
ValueRef
{
cast_shift_rhs
(
op
,
lhs
,
rhs
,
bind
Trunc
(
cx
,
_
,
_
),
bind
ZExt
(
cx
,
_
,
_
))
}
fn
cast_shift_const_rhs
(
op
:
ast
::
binop
,
lhs
:
ValueRef
,
rhs
:
ValueRef
)
->
ValueRef
{
cast_shift_rhs
(
op
,
lhs
,
rhs
,
llvm
::
LLVMConstTrunc
,
llvm
::
LLVMConstZExt
)
}
fn
cast_shift_rhs
(
op
:
ast
::
binop
,
lhs
:
ValueRef
,
rhs
:
ValueRef
,
trunc
:
fn
(
ValueRef
,
TypeRef
)
->
ValueRef
,
zext
:
fn
(
ValueRef
,
TypeRef
)
->
ValueRef
)
->
ValueRef
{
// Shifts may have any size int on the rhs
if
ast_util
::
is_shift_binop
(
op
)
{
let
rhs_llty
=
val_ty
(
rhs
);
let
lhs_llty
=
val_ty
(
lhs
);
let
rhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
rhs_llty
);
let
lhs_sz
=
llvm
::
LLVMGetIntTypeWidth
(
lhs_llty
);
if
lhs_sz
<
rhs_sz
{
trunc
(
rhs
,
lhs_llty
)
}
else
if
lhs_sz
>
rhs_sz
{
// FIXME: If shifting by negative values becomes not undefined
// then this is wrong.
zext
(
rhs
,
lhs_llty
)
}
else
{
rhs
}
}
else
{
rhs
}
}
// Important to get types for both lhs and rhs, because one might be _|_
// and the other not.
fn
trans_eager_binop
(
cx
:
block
,
op
:
ast
::
binop
,
lhs
:
ValueRef
,
...
...
@@ -1651,6 +1689,8 @@ fn trans_eager_binop(cx: block, op: ast::binop, lhs: ValueRef,
if
ty
::
type_is_bot
(
intype
)
{
intype
=
rhs_t
;
}
let
is_float
=
ty
::
type_is_fp
(
intype
);
let
rhs
=
cast_shift_expr_rhs
(
cx
,
op
,
lhs
,
rhs
);
if
op
==
ast
::
add
&&
ty
::
type_is_sequence
(
intype
)
{
ret
tvec
::
trans_add
(
cx
,
intype
,
lhs
,
rhs
,
dest
);
}
...
...
@@ -4059,6 +4099,9 @@ fn trans_const_expr(cx: crate_ctxt, e: @ast::expr) -> ValueRef {
ast
::
expr_binary
(
b
,
e1
,
e2
)
{
let
te1
=
trans_const_expr
(
cx
,
e1
);
let
te2
=
trans_const_expr
(
cx
,
e2
);
let
te2
=
cast_shift_const_rhs
(
b
,
te1
,
te2
);
/* Neither type is bottom, and we expect them to be unified already,
* so the following is safe. */
let
ty
=
ty
::
expr_ty
(
cx
.tcx
,
e1
);
...
...
src/comp/middle/typeck.rs
浏览文件 @
99a48660
...
...
@@ -2117,8 +2117,17 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
let
lhs_t
=
next_ty_var
(
fcx
);
bot
=
check_expr_with
(
fcx
,
lhs
,
lhs_t
);
let
rhs_bot
=
check_expr_with
(
fcx
,
rhs
,
lhs_t
);
let
rhs_bot
=
if
!
ast_util
::
is_shift_binop
(
binop
)
{
check_expr_with
(
fcx
,
rhs
,
lhs_t
)
}
else
{
let
rhs_bot
=
check_expr
(
fcx
,
rhs
);
let
rhs_t
=
expr_ty
(
tcx
,
rhs
);
require_integral
(
fcx
,
rhs
.span
,
rhs_t
);
rhs_bot
};
if
!
ast_util
::
lazy_binop
(
binop
)
{
bot
|
=
rhs_bot
;
}
let
result
=
check_binop
(
fcx
,
expr
,
lhs_t
,
binop
,
rhs
);
write_ty
(
tcx
,
id
,
result
);
}
...
...
@@ -2572,13 +2581,6 @@ fn get_node(f: spanned<field>) -> field { f.node }
let
base_t
=
do_autoderef
(
fcx
,
expr
.span
,
raw_base_t
);
bot
|
=
check_expr
(
fcx
,
idx
);
let
idx_t
=
expr_ty
(
tcx
,
idx
);
fn
require_integral
(
fcx
:
@
fn_ctxt
,
sp
:
span
,
t
:
ty
::
t
)
{
if
!
type_is_integral
(
fcx
,
sp
,
t
)
{
fcx
.ccx.tcx.sess
.span_err
(
sp
,
"mismatched types: expected
\
`integer` but found `"
+
ty_to_str
(
fcx
.ccx.tcx
,
t
)
+
"`"
);
}
}
alt
structure_of
(
fcx
,
expr
.span
,
base_t
)
{
ty
::
ty_vec
(
mt
)
{
require_integral
(
fcx
,
idx
.span
,
idx_t
);
...
...
@@ -2612,6 +2614,14 @@ fn require_integral(fcx: @fn_ctxt, sp: span, t: ty::t) {
ret
bot
;
}
fn
require_integral
(
fcx
:
@
fn_ctxt
,
sp
:
span
,
t
:
ty
::
t
)
{
if
!
type_is_integral
(
fcx
,
sp
,
t
)
{
fcx
.ccx.tcx.sess
.span_err
(
sp
,
"mismatched types: expected
\
`integer` but found `"
+
ty_to_str
(
fcx
.ccx.tcx
,
t
)
+
"`"
);
}
}
fn
next_ty_var_id
(
fcx
:
@
fn_ctxt
)
->
int
{
let
id
=
*
fcx
.next_var_id
;
*
fcx
.next_var_id
+=
1
;
...
...
src/comp/syntax/ast_util.rs
浏览文件 @
99a48660
...
...
@@ -64,6 +64,15 @@ fn binop_to_str(op: binop) -> str {
alt
b
{
and
{
true
}
or
{
true
}
_
{
false
}
}
}
pure
fn
is_shift_binop
(
b
:
binop
)
->
bool
{
alt
b
{
lsl
{
true
}
lsr
{
true
}
asr
{
true
}
_
{
false
}
}
}
fn
unop_to_str
(
op
:
unop
)
->
str
{
alt
op
{
box
(
mt
)
{
if
mt
==
m_mutbl
{
ret
"@mut "
;
}
ret
"@"
;
}
...
...
src/test/run-pass/shift.rs
0 → 100644
浏览文件 @
99a48660
// Testing shifts for various combinations of integers
// Issue #1570
fn
main
()
{
test_misc
();
test_expr
();
test_const
();
}
fn
test_misc
()
{
assert
1
<<
1i8
<<
1u8
<<
1i16
<<
1
as
char
<<
1u64
==
32
;
}
fn
test_expr
()
{
let
v10
=
10
as
uint
;
let
v4
=
4
as
u8
;
let
v2
=
2
as
u8
;
assert
(
v10
>>
v2
==
v2
as
uint
);
assert
(
v10
>>>
v2
==
v2
as
uint
);
assert
(
v10
<<
v4
==
160
as
uint
);
let
v10
=
10
as
u8
;
let
v4
=
4
as
uint
;
let
v2
=
2
as
uint
;
assert
(
v10
>>
v2
==
v2
as
u8
);
assert
(
v10
>>>
v2
==
v2
as
u8
);
assert
(
v10
<<
v4
==
160
as
u8
);
let
v10
=
10
as
int
;
let
v4
=
4
as
i8
;
let
v2
=
2
as
i8
;
assert
(
v10
>>
v2
==
v2
as
int
);
assert
(
v10
>>>
v2
==
v2
as
int
);
assert
(
v10
<<
v4
==
160
as
int
);
let
v10
=
10
as
i8
;
let
v4
=
4
as
int
;
let
v2
=
2
as
int
;
assert
(
v10
>>
v2
==
v2
as
i8
);
assert
(
v10
>>>
v2
==
v2
as
i8
);
assert
(
v10
<<
v4
==
160
as
i8
);
let
v10
=
10
as
uint
;
let
v4
=
4
as
int
;
let
v2
=
2
as
int
;
assert
(
v10
>>
v2
==
v2
as
uint
);
assert
(
v10
>>>
v2
==
v2
as
uint
);
assert
(
v10
<<
v4
==
160
as
uint
);
}
fn
test_const
()
{
const
r1_1
:
uint
=
10u
>>
2u8
;
const
r2_1
:
uint
=
10u
>>>
2u8
;
const
r3_1
:
uint
=
10u
<<
4u8
;
assert
r1_1
==
2
as
uint
;
assert
r2_1
==
2
as
uint
;
assert
r3_1
==
160
as
uint
;
const
r1_2
:
u8
=
10u8
>>
2u
;
const
r2_2
:
u8
=
10u8
>>>
2u
;
const
r3_2
:
u8
=
10u8
<<
4u
;
assert
r1_2
==
2
as
u8
;
assert
r2_2
==
2
as
u8
;
assert
r3_2
==
160
as
u8
;
const
r1_3
:
int
=
10
>>
2i8
;
const
r2_3
:
int
=
10
>>>
2i8
;
const
r3_3
:
int
=
10
<<
4i8
;
assert
r1_3
==
2
as
int
;
assert
r2_3
==
2
as
int
;
assert
r3_3
==
160
as
int
;
const
r1_4
:
i8
=
10i8
>>
2
;
const
r2_4
:
i8
=
10i8
>>>
2
;
const
r3_4
:
i8
=
10i8
<<
4
;
assert
r1_4
==
2
as
i8
;
assert
r2_4
==
2
as
i8
;
assert
r3_4
==
160
as
i8
;
const
r1_5
:
uint
=
10u
>>
2i8
;
const
r2_5
:
uint
=
10u
>>>
2i8
;
const
r3_5
:
uint
=
10u
<<
4i8
;
assert
r1_5
==
2
as
uint
;
assert
r2_5
==
2
as
uint
;
assert
r3_5
==
160
as
uint
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录