Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d36d351a
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,发现更多精彩内容 >>
提交
d36d351a
编写于
6月 23, 2020
作者:
N
Nathan Corbyn
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement intrinsic
上级
1557fb03
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
107 addition
and
5 deletion
+107
-5
src/libcore/intrinsics.rs
src/libcore/intrinsics.rs
+15
-0
src/libcore/lib.rs
src/libcore/lib.rs
+1
-0
src/libcore/mem/mod.rs
src/libcore/mem/mod.rs
+27
-0
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/intrinsic.rs
+1
-1
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/interpret/intrinsics.rs
+12
-2
src/librustc_span/symbol.rs
src/librustc_span/symbol.rs
+1
-0
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/intrinsic.rs
+4
-2
src/test/ui/consts/const-variant-count.rs
src/test/ui/consts/const-variant-count.rs
+46
-0
未找到文件。
src/libcore/intrinsics.rs
浏览文件 @
d36d351a
...
@@ -1917,6 +1917,15 @@
...
@@ -1917,6 +1917,15 @@
#[rustc_const_unstable(feature
=
"const_discriminant"
,
issue
=
"69821"
)]
#[rustc_const_unstable(feature
=
"const_discriminant"
,
issue
=
"69821"
)]
pub
fn
discriminant_value
<
T
>
(
v
:
&
T
)
->
<
T
as
DiscriminantKind
>
::
Discriminant
;
pub
fn
discriminant_value
<
T
>
(
v
:
&
T
)
->
<
T
as
DiscriminantKind
>
::
Discriminant
;
/// Returns the number of variants of the type `T` cast to a `usize`;
/// if `T` has no variants, returns 0. Uninhabited variants will be counted.
///
/// The to-be-stabilized version of this intrinsic is
/// [`std::mem::variant_count`](../../std/mem/fn.variant_count.html)
#[rustc_const_unstable(feature
=
"variant_count"
,
issue
=
"73662"
)]
#[cfg(not(bootstrap))]
pub
fn
variant_count
<
T
>
()
->
usize
;
/// Rust's "try catch" construct which invokes the function pointer `try_fn`
/// Rust's "try catch" construct which invokes the function pointer `try_fn`
/// with the data pointer `data`.
/// with the data pointer `data`.
///
///
...
@@ -1960,6 +1969,12 @@
...
@@ -1960,6 +1969,12 @@
pub
fn
ptr_guaranteed_ne
<
T
>
(
ptr
:
*
const
T
,
other
:
*
const
T
)
->
bool
;
pub
fn
ptr_guaranteed_ne
<
T
>
(
ptr
:
*
const
T
,
other
:
*
const
T
)
->
bool
;
}
}
#[rustc_const_unstable(feature
=
"variant_count"
,
issue
=
"73662"
)]
#[cfg(bootstrap)]
pub
const
fn
variant_count
<
T
>
()
->
usize
{
0
}
// Some functions are defined here because they accidentally got made
// Some functions are defined here because they accidentally got made
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
// (`transmute` also falls into this category, but it cannot be wrapped due to the
// (`transmute` also falls into this category, but it cannot be wrapped due to the
...
...
src/libcore/lib.rs
浏览文件 @
d36d351a
...
@@ -124,6 +124,7 @@
...
@@ -124,6 +124,7 @@
#![feature(unsized_locals)]
#![feature(unsized_locals)]
#![feature(untagged_unions)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(unwind_attributes)]
#![feature(variant_count)]
#![feature(doc_alias)]
#![feature(doc_alias)]
#![feature(mmx_target_feature)]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(tbm_target_feature)]
...
...
src/libcore/mem/mod.rs
浏览文件 @
d36d351a
...
@@ -999,3 +999,30 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
...
@@ -999,3 +999,30 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
pub
const
fn
discriminant
<
T
>
(
v
:
&
T
)
->
Discriminant
<
T
>
{
pub
const
fn
discriminant
<
T
>
(
v
:
&
T
)
->
Discriminant
<
T
>
{
Discriminant
(
intrinsics
::
discriminant_value
(
v
))
Discriminant
(
intrinsics
::
discriminant_value
(
v
))
}
}
/// Returns the number of variants in the enum type `T`.
///
/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
/// return value is unspecified. Equally, if `T` is an enum with more variants than `usize::MAX`
/// the return value is unspecified. Uninhabited variants will be counted.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// enum Void {}
/// enum Foo { A(&'static str), B(i32), C(i32) }
///
/// assert_eq!(mem::variant_count::<Void>(), 0);
/// assert_eq!(mem::variant_count::<Foo>(), 3);
///
/// assert_eq!(mem::variant_count::<Option<!>>(), 2);
/// assert_eq!(mem::variant_count::<Result<!, !>>(), 2);
/// ```
#[inline(always)]
#[unstable(feature
=
"variant_count"
,
issue
=
"73662"
)]
#[rustc_const_unstable(feature
=
"variant_count"
,
issue
=
"73662"
)]
pub
const
fn
variant_count
<
T
>
()
->
usize
{
intrinsics
::
variant_count
::
<
T
>
()
}
src/librustc_codegen_llvm/intrinsic.rs
浏览文件 @
d36d351a
...
@@ -213,7 +213,7 @@ fn codegen_intrinsic_call(
...
@@ -213,7 +213,7 @@ fn codegen_intrinsic_call(
}
}
}
}
"size_of"
|
"pref_align_of"
|
"min_align_of"
|
"needs_drop"
|
"type_id"
"size_of"
|
"pref_align_of"
|
"min_align_of"
|
"needs_drop"
|
"type_id"
|
"type_name"
=>
{
|
"type_name"
|
"variant_count"
=>
{
let
value
=
self
let
value
=
self
.tcx
.tcx
.const_eval_instance
(
ty
::
ParamEnv
::
reveal_all
(),
instance
,
None
)
.const_eval_instance
(
ty
::
ParamEnv
::
reveal_all
(),
instance
,
None
)
...
...
src/librustc_mir/interpret/intrinsics.rs
浏览文件 @
d36d351a
...
@@ -69,6 +69,13 @@ fn numeric_intrinsic<'tcx, Tag>(
...
@@ -69,6 +69,13 @@ fn numeric_intrinsic<'tcx, Tag>(
ConstValue
::
from_machine_usize
(
n
,
&
tcx
)
ConstValue
::
from_machine_usize
(
n
,
&
tcx
)
}
}
sym
::
type_id
=>
ConstValue
::
from_u64
(
tcx
.type_id_hash
(
tp_ty
)),
sym
::
type_id
=>
ConstValue
::
from_u64
(
tcx
.type_id_hash
(
tp_ty
)),
sym
::
variant_count
=>
{
if
let
ty
::
Adt
(
ref
adt
,
_
)
=
tp_ty
.kind
{
ConstValue
::
from_machine_usize
(
adt
.variants
.len
()
as
u64
,
&
tcx
)
}
else
{
ConstValue
::
from_machine_usize
(
0u64
,
&
tcx
)
}
}
other
=>
bug!
(
"`{}` is not a zero arg intrinsic"
,
other
),
other
=>
bug!
(
"`{}` is not a zero arg intrinsic"
,
other
),
})
})
}
}
...
@@ -109,10 +116,13 @@ pub fn emulate_intrinsic(
...
@@ -109,10 +116,13 @@ pub fn emulate_intrinsic(
|
sym
::
needs_drop
|
sym
::
needs_drop
|
sym
::
size_of
|
sym
::
size_of
|
sym
::
type_id
|
sym
::
type_id
|
sym
::
type_name
=>
{
|
sym
::
type_name
|
sym
::
variant_count
=>
{
let
gid
=
GlobalId
{
instance
,
promoted
:
None
};
let
gid
=
GlobalId
{
instance
,
promoted
:
None
};
let
ty
=
match
intrinsic_name
{
let
ty
=
match
intrinsic_name
{
sym
::
min_align_of
|
sym
::
pref_align_of
|
sym
::
size_of
=>
self
.tcx.types.usize
,
sym
::
min_align_of
|
sym
::
pref_align_of
|
sym
::
size_of
|
sym
::
variant_count
=>
{
self
.tcx.types.usize
}
sym
::
needs_drop
=>
self
.tcx.types.bool
,
sym
::
needs_drop
=>
self
.tcx.types.bool
,
sym
::
type_id
=>
self
.tcx.types.u64
,
sym
::
type_id
=>
self
.tcx.types.u64
,
sym
::
type_name
=>
self
.tcx
.mk_static_str
(),
sym
::
type_name
=>
self
.tcx
.mk_static_str
(),
...
...
src/librustc_span/symbol.rs
浏览文件 @
d36d351a
...
@@ -830,6 +830,7 @@
...
@@ -830,6 +830,7 @@
v1
,
v1
,
val
,
val
,
var
,
var
,
variant_count
,
vec
,
vec
,
Vec
,
Vec
,
version
,
version
,
...
...
src/librustc_typeck/check/intrinsic.rs
浏览文件 @
d36d351a
...
@@ -75,7 +75,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
...
@@ -75,7 +75,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
|
"saturating_sub"
|
"rotate_left"
|
"rotate_right"
|
"ctpop"
|
"ctlz"
|
"cttz"
|
"saturating_sub"
|
"rotate_left"
|
"rotate_right"
|
"ctpop"
|
"ctlz"
|
"cttz"
|
"bswap"
|
"bitreverse"
|
"discriminant_value"
|
"type_id"
|
"likely"
|
"unlikely"
|
"bswap"
|
"bitreverse"
|
"discriminant_value"
|
"type_id"
|
"likely"
|
"unlikely"
|
"ptr_guaranteed_eq"
|
"ptr_guaranteed_ne"
|
"minnumf32"
|
"minnumf64"
|
"maxnumf32"
|
"ptr_guaranteed_eq"
|
"ptr_guaranteed_ne"
|
"minnumf32"
|
"minnumf64"
|
"maxnumf32"
|
"maxnumf64"
|
"type_name"
=>
hir
::
Unsafety
::
Normal
,
|
"maxnumf64"
|
"type_name"
|
"variant_count"
=>
hir
::
Unsafety
::
Normal
,
_
=>
hir
::
Unsafety
::
Unsafe
,
_
=>
hir
::
Unsafety
::
Unsafe
,
}
}
}
}
...
@@ -137,7 +137,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
...
@@ -137,7 +137,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let
unsafety
=
intrinsic_operation_unsafety
(
&
name
[
..
]);
let
unsafety
=
intrinsic_operation_unsafety
(
&
name
[
..
]);
let
(
n_tps
,
inputs
,
output
)
=
match
&
name
[
..
]
{
let
(
n_tps
,
inputs
,
output
)
=
match
&
name
[
..
]
{
"breakpoint"
=>
(
0
,
Vec
::
new
(),
tcx
.mk_unit
()),
"breakpoint"
=>
(
0
,
Vec
::
new
(),
tcx
.mk_unit
()),
"size_of"
|
"pref_align_of"
|
"min_align_of"
=>
(
1
,
Vec
::
new
(),
tcx
.types.usize
),
"size_of"
|
"pref_align_of"
|
"min_align_of"
|
"variant_count"
=>
{
(
1
,
Vec
::
new
(),
tcx
.types.usize
)
}
"size_of_val"
|
"min_align_of_val"
=>
{
"size_of_val"
|
"min_align_of_val"
=>
{
(
1
,
vec!
[
tcx
.mk_imm_ptr
(
param
(
0
))],
tcx
.types.usize
)
(
1
,
vec!
[
tcx
.mk_imm_ptr
(
param
(
0
))],
tcx
.types.usize
)
}
}
...
...
src/test/ui/consts/const-variant-count.rs
0 → 100644
浏览文件 @
d36d351a
// run-pass
#![allow(dead_code)]
#![feature(variant_count)]
use
std
::
mem
::
variant_count
;
enum
Void
{}
enum
Foo
{
A
,
B
,
C
,
}
enum
Bar
{
A
,
B
,
C
,
D
(
usize
),
E
{
field_1
:
usize
,
field_2
:
Foo
},
}
struct
Baz
{
a
:
u32
,
b
:
*
const
u8
,
}
const
TEST_VOID
:
usize
=
variant_count
::
<
Void
>
();
const
TEST_FOO
:
usize
=
variant_count
::
<
Foo
>
();
const
TEST_BAR
:
usize
=
variant_count
::
<
Bar
>
();
const
NO_ICE_STRUCT
:
usize
=
variant_count
::
<
Baz
>
();
const
NO_ICE_BOOL
:
usize
=
variant_count
::
<
bool
>
();
const
NO_ICE_PRIM
:
usize
=
variant_count
::
<*
const
u8
>
();
fn
main
()
{
assert_eq!
(
TEST_VOID
,
0
);
assert_eq!
(
TEST_FOO
,
3
);
assert_eq!
(
TEST_BAR
,
5
);
assert_eq!
(
variant_count
::
<
Void
>
(),
0
);
assert_eq!
(
variant_count
::
<
Foo
>
(),
3
);
assert_eq!
(
variant_count
::
<
Bar
>
(),
5
);
assert_eq!
(
variant_count
::
<
Option
<
char
>>
(),
2
);
assert_eq!
(
variant_count
::
<
Option
<!>>
(),
2
);
assert_eq!
(
variant_count
::
<
Result
<!
,
!>>
(),
2
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录