Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
9b291381
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
9b291381
编写于
9月 06, 2021
作者:
E
Ellen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
as casts and block exprs
上级
2987f4ba
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
57 addition
and
35 deletion
+57
-35
compiler/rustc_middle/src/mir/abstract_const.rs
compiler/rustc_middle/src/mir/abstract_const.rs
+2
-2
compiler/rustc_privacy/src/lib.rs
compiler/rustc_privacy/src/lib.rs
+1
-1
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
...ler/rustc_trait_selection/src/traits/const_evaluatable.rs
+53
-31
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
+1
-1
未找到文件。
compiler/rustc_middle/src/mir/abstract_const.rs
浏览文件 @
9b291381
//! A subset of a mir body used for const evaluatability checking.
use
crate
::
mir
::{
self
,
CastKind
}
;
use
crate
::
mir
;
use
crate
::
ty
::{
self
,
Ty
};
rustc_index
::
newtype_index!
{
...
...
@@ -18,7 +18,7 @@ pub enum Node<'tcx> {
UnaryOp
(
mir
::
UnOp
,
NodeId
),
FunctionCall
(
NodeId
,
&
'tcx
[
NodeId
]),
Block
(
&
'tcx
[
NodeId
],
Option
<
NodeId
>
),
Cast
(
CastKind
,
NodeId
,
Ty
<
'tcx
>
),
Cast
(
NodeId
,
Ty
<
'tcx
>
),
}
#[derive(Debug,
Copy,
Clone,
PartialEq,
Eq,
HashStable,
TyEncodable,
TyDecodable)]
...
...
compiler/rustc_privacy/src/lib.rs
浏览文件 @
9b291381
...
...
@@ -158,7 +158,7 @@ fn visit_abstract_const_expr(
let
leaf
=
leaf
.subst
(
tcx
,
ct
.substs
);
self
.visit_const
(
leaf
)
}
ACNode
::
Cast
(
_
,
_
,
ty
)
=>
self
.visit_ty
(
ty
),
ACNode
::
Cast
(
_
,
ty
)
=>
self
.visit_ty
(
ty
),
ACNode
::
Block
(
_
,
_
)
|
ACNode
::
Binop
(
..
)
|
ACNode
::
UnaryOp
(
..
)
...
...
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
浏览文件 @
9b291381
...
...
@@ -92,7 +92,7 @@ enum FailureKind {
ControlFlow
::
CONTINUE
}
Node
::
Cast
(
_
,
_
,
ty
)
=>
{
Node
::
Cast
(
_
,
ty
)
=>
{
let
ty
=
ty
.subst
(
tcx
,
ct
.substs
);
if
ty
.has_infer_types_or_consts
()
{
failure_kind
=
FailureKind
::
MentionsInfer
;
...
...
@@ -292,7 +292,7 @@ fn add_node(&mut self, node: Node<'tcx>, span: Span) -> NodeId {
stmts
.iter
()
.for_each
(|
&
id
|
self
.nodes
[
id
]
.used
=
true
);
opt_expr
.map
(|
e
|
self
.nodes
[
e
]
.used
=
true
);
}
Node
::
Cast
(
_
,
operand
,
_
)
=>
{
Node
::
Cast
(
operand
,
_
)
=>
{
self
.nodes
[
operand
]
.used
=
true
;
}
}
...
...
@@ -335,6 +335,7 @@ fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorReported> {
}
}
// FIXME I dont even think we can get unused nodes anymore with thir abstract const
if
let
Some
(
&
unused
)
=
self
.nodes
.iter
()
.find
(|
n
|
!
n
.used
)
{
self
.error
(
Some
(
unused
.span
),
"dead code"
)
?
;
}
...
...
@@ -352,6 +353,8 @@ fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported>
&
ExprKind
::
PlaceTypeAscription
{
source
,
..
}
|
&
ExprKind
::
ValueTypeAscription
{
source
,
..
}
=>
self
.recurse_build
(
source
)
?
,
// subtle: associated consts are literals this arm handles
// `<T as Trait>::ASSOC` as well as `12`
&
ExprKind
::
Literal
{
literal
,
..
}
|
&
ExprKind
::
StaticRef
{
literal
,
..
}
=>
self
.add_node
(
Node
::
Leaf
(
literal
),
node
.span
),
...
...
@@ -375,14 +378,6 @@ fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported>
let
arg
=
self
.recurse_build
(
arg
)
?
;
self
.add_node
(
Node
::
UnaryOp
(
op
,
arg
),
node
.span
)
},
// HACK: without this arm the following doesn't compile:
// ```
// fn foo<const N: usize>(_: [(); N + 1]) {
// bar::<{ N + 1}>();
// }
// ```
// we ought to properly handle this in `try_unify`
ExprKind
::
Block
{
body
:
thir
::
Block
{
stmts
:
box
[],
expr
:
Some
(
e
),
..
}}
=>
self
.recurse_build
(
*
e
)
?
,
ExprKind
::
Block
{
body
}
=>
{
let
mut
stmts
=
Vec
::
with_capacity
(
body
.stmts
.len
());
for
&
id
in
body
.stmts
.iter
()
{
...
...
@@ -398,26 +393,34 @@ fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported>
let
opt_expr
=
body
.expr
.map
(|
e
|
self
.recurse_build
(
e
))
.transpose
()
?
;
self
.add_node
(
Node
::
Block
(
stmts
,
opt_expr
),
node
.span
)
}
&
ExprKind
::
Cast
{
source
}
=>
todo!
(),
// ExprKind::Use happens when a `hir::ExprKind::Cast` is a
// "coercion cast" i.e. using a coercion or is a no-op.
// this is important so that `N as usize as usize` doesnt unify with `N as usize`
&
ExprKind
::
Use
{
source
}
|
&
ExprKind
::
Cast
{
source
}
=>
{
let
arg
=
self
.recurse_build
(
source
)
?
;
self
.add_node
(
Node
::
Cast
(
arg
,
node
.ty
),
node
.span
)
},
// never can arise even without panic/fail to terminate
&
ExprKind
::
NeverToAny
{
source
}
=>
todo!
(),
// i think this is a dummy usage of the expr to allow coercions
&
ExprKind
::
Use
{
source
}
=>
todo!
(),
ExprKind
::
Return
{
..
}
|
ExprKind
::
Box
{
..
}
// allocations not allowed in constants
|
ExprKind
::
AssignOp
{
..
}
|
ExprKind
::
AddressOf
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Borrow
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Deref
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Repeat
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Array
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Tuple
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Index
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Field
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
ConstBlock
{
..
}
// FIXME(generic_const_exprs)
|
ExprKind
::
Adt
(
_
)
// FIXME(generic_const_exprs) we *should* permit this but dont currently
|
ExprKind
::
Match
{
..
}
// FIXME(generic_const_exprs) we want to support these
ExprKind
::
AddressOf
{
..
}
|
ExprKind
::
Borrow
{
..
}
|
ExprKind
::
Deref
{
..
}
|
ExprKind
::
Repeat
{
..
}
|
ExprKind
::
Array
{
..
}
|
ExprKind
::
Tuple
{
..
}
|
ExprKind
::
Index
{
..
}
|
ExprKind
::
Field
{
..
}
|
ExprKind
::
ConstBlock
{
..
}
|
ExprKind
::
Adt
(
_
)
=>
return
self
.error
(
Some
(
node
.span
),
"unsupported operation in generic constant, this may be supported in the future"
,
)
.map
(|
never
|
never
),
ExprKind
::
Match
{
..
}
|
ExprKind
::
VarRef
{
..
}
//
|
ExprKind
::
UpvarRef
{
..
}
// we dont permit let stmts so...
|
ExprKind
::
Closure
{
..
}
...
...
@@ -433,6 +436,9 @@ fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported>
|
ExprKind
::
Pointer
{
..
}
// dont know if this is correct
|
ExprKind
::
ThreadLocalRef
(
_
)
|
ExprKind
::
LlvmInlineAsm
{
..
}
|
ExprKind
::
Return
{
..
}
|
ExprKind
::
Box
{
..
}
// allocations not allowed in constants
|
ExprKind
::
AssignOp
{
..
}
|
ExprKind
::
InlineAsm
{
..
}
|
ExprKind
::
Yield
{
..
}
=>
return
self
.error
(
Some
(
node
.span
),
"unsupported operation in generic constant"
)
.map
(|
never
|
never
),
})
...
...
@@ -521,7 +527,7 @@ fn recurse<'tcx, R>(
}
ControlFlow
::
CONTINUE
}
Node
::
Cast
(
_
,
operand
,
_
)
=>
recurse
(
tcx
,
ct
.subtree
(
operand
),
f
),
Node
::
Cast
(
operand
,
_
)
=>
recurse
(
tcx
,
ct
.subtree
(
operand
),
f
),
}
}
...
...
@@ -604,11 +610,27 @@ pub(super) fn try_unify<'tcx>(
&&
iter
::
zip
(
a_args
,
b_args
)
.all
(|(
&
an
,
&
bn
)|
try_unify
(
tcx
,
a
.subtree
(
an
),
b
.subtree
(
bn
)))
}
(
Node
::
Cast
(
a_
cast_kind
,
a_operand
,
a_ty
),
Node
::
Cast
(
b_cast_kind
,
b_operand
,
b_ty
))
if
(
a_ty
==
b_ty
)
&&
(
a_cast_kind
==
b_cast_kind
)
=>
(
Node
::
Cast
(
a_
operand
,
a_ty
),
Node
::
Cast
(
b_operand
,
b_ty
))
if
(
a_ty
==
b_ty
)
=>
{
try_unify
(
tcx
,
a
.subtree
(
a_operand
),
b
.subtree
(
b_operand
))
}
_
=>
false
,
(
Node
::
Block
(
a_stmts
,
a_opt_expr
),
Node
::
Block
(
b_stmts
,
b_opt_expr
))
if
a_stmts
.len
()
==
b_stmts
.len
()
=>
{
a_stmts
.iter
()
.zip
(
b_stmts
.iter
())
.all
(|(
&
a_stmt
,
&
b_stmt
)|
{
try_unify
(
tcx
,
a
.subtree
(
a_stmt
),
b
.subtree
(
b_stmt
))
})
&&
match
(
a_opt_expr
,
b_opt_expr
)
{
(
Some
(
a_expr
),
Some
(
b_expr
))
=>
try_unify
(
tcx
,
a
.subtree
(
a_expr
),
b
.subtree
(
b_expr
)),
(
None
,
None
)
=>
true
,
_
=>
false
,
}
}
// use this over `_ => false` to make adding variants to `Node` less error prone
(
Node
::
Block
(
..
),
_
)
|
(
Node
::
Cast
(
..
),
_
)
|
(
Node
::
FunctionCall
(
..
),
_
)
|
(
Node
::
UnaryOp
(
..
),
_
)
|
(
Node
::
Binop
(
..
),
_
)
|
(
Node
::
Leaf
(
..
),
_
)
=>
false
,
}
}
compiler/rustc_trait_selection/src/traits/object_safety.rs
浏览文件 @
9b291381
...
...
@@ -843,7 +843,7 @@ fn visit_unevaluated_const(
let
leaf
=
leaf
.subst
(
self
.tcx
,
ct
.substs
);
self
.visit_const
(
leaf
)
}
Node
::
Cast
(
_
,
_
,
ty
)
=>
self
.visit_ty
(
ty
),
Node
::
Cast
(
_
,
ty
)
=>
self
.visit_ty
(
ty
),
Node
::
Block
(
_
,
_
)
|
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录