Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
98728c2b
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,发现更多精彩内容 >>
提交
98728c2b
编写于
5月 10, 2021
作者:
F
Fabian Wolff
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement changes suggested by tmiasko and davidtwco
上级
ee882b3a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
42 addition
and
43 deletion
+42
-43
compiler/rustc_ty_utils/src/representability.rs
compiler/rustc_ty_utils/src/representability.rs
+42
-43
src/test/ui/structs-enums/struct-rec/issue-74224.rs
src/test/ui/structs-enums/struct-rec/issue-74224.rs
+0
-0
src/test/ui/structs-enums/struct-rec/issue-74224.stderr
src/test/ui/structs-enums/struct-rec/issue-74224.stderr
+0
-0
src/test/ui/structs-enums/struct-rec/issue-84611.rs
src/test/ui/structs-enums/struct-rec/issue-84611.rs
+0
-0
src/test/ui/structs-enums/struct-rec/issue-84611.stderr
src/test/ui/structs-enums/struct-rec/issue-84611.stderr
+0
-0
src/test/ui/structs-enums/struct-rec/mutual-struct-recursion.rs
...st/ui/structs-enums/struct-rec/mutual-struct-recursion.rs
+0
-0
src/test/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr
...i/structs-enums/struct-rec/mutual-struct-recursion.stderr
+0
-0
未找到文件。
compiler/rustc_ty_utils/src/representability.rs
浏览文件 @
98728c2b
...
...
@@ -25,12 +25,17 @@ pub enum Representability {
pub
fn
ty_is_representable
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
sp
:
Span
)
->
Representability
{
debug!
(
"is_type_representable: {:?}"
,
ty
);
// To avoid a stack overflow when checking an enum variant or struct that
// contains a different, structurally recursive type, maintain a stack
// of seen types and check recursion for each of them (issues #3008, #3779).
// contains a different, structurally recursive type, maintain a stack of
// seen types and check recursion for each of them (issues #3008, #3779,
// #74224, #84611). `shadow_seen` contains the full stack and `seen` only
// the one for the current type (e.g. if we have structs A and B, B contains
// a field of type A, and we're currently looking at B, then `seen` will be
// cleared when recursing to check A, but `shadow_seen` won't, so that we
// can catch cases of mutual recursion where A also contains B).
let
mut
seen
:
Vec
<
Ty
<
'_
>>
=
Vec
::
new
();
let
mut
shadow_seen
:
Vec
<
Ty
<
'_
>
>
=
Vec
::
new
();
let
mut
shadow_seen
:
Vec
<
&
'tcx
ty
::
AdtDef
>
=
Vec
::
new
();
let
mut
representable_cache
=
FxHashMap
::
default
();
let
mut
f
_res
=
false
;
let
mut
f
orce_result
=
false
;
let
r
=
is_type_structurally_recursive
(
tcx
,
sp
,
...
...
@@ -38,7 +43,7 @@ pub fn ty_is_representable<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, sp: Span) -> R
&
mut
shadow_seen
,
&
mut
representable_cache
,
ty
,
&
mut
f
_res
,
&
mut
f
orce_result
,
);
debug!
(
"is_type_representable: {:?} is {:?}"
,
ty
,
r
);
r
...
...
@@ -58,10 +63,10 @@ fn are_inner_types_recursive<'tcx>(
tcx
:
TyCtxt
<
'tcx
>
,
sp
:
Span
,
seen
:
&
mut
Vec
<
Ty
<
'tcx
>>
,
shadow_seen
:
&
mut
Vec
<
Ty
<
'tcx
>
>
,
shadow_seen
:
&
mut
Vec
<
&
'tcx
ty
::
AdtDef
>
,
representable_cache
:
&
mut
FxHashMap
<
Ty
<
'tcx
>
,
Representability
>
,
ty
:
Ty
<
'tcx
>
,
f
_res
:
&
mut
bool
,
f
orce_result
:
&
mut
bool
,
)
->
Representability
{
debug!
(
"are_inner_types_recursive({:?}, {:?}, {:?})"
,
ty
,
seen
,
shadow_seen
);
match
ty
.kind
()
{
...
...
@@ -75,7 +80,7 @@ fn are_inner_types_recursive<'tcx>(
shadow_seen
,
representable_cache
,
ty
,
f
_res
,
f
orce_result
,
)
}))
}
...
...
@@ -88,7 +93,7 @@ fn are_inner_types_recursive<'tcx>(
shadow_seen
,
representable_cache
,
ty
,
f
_res
,
f
orce_result
,
),
ty
::
Adt
(
def
,
substs
)
=>
{
// Find non representable fields with their spans
...
...
@@ -125,22 +130,12 @@ fn are_inner_types_recursive<'tcx>(
// case (shadow_seen.first() is the type we are originally
// interested in, and if we ever encounter the same AdtDef again,
// we know that it must be SelfRecursive) and "forcibly" returning
// SelfRecursive (by setting f
_res
, which tells the calling
// SelfRecursive (by setting f
orce_result
, which tells the calling
// invocations of are_inner_types_representable to forward the
// result without adjusting).
if
shadow_seen
.len
()
>
1
&&
shadow_seen
.len
()
>
seen
.len
()
{
match
shadow_seen
.first
()
.map
(|
ty
|
ty
.kind
())
{
Some
(
ty
::
Adt
(
f_def
,
_
))
=>
{
if
f_def
==
def
{
*
f_res
=
true
;
result
=
Some
(
Representability
::
SelfRecursive
(
vec!
[
span
]));
}
}
Some
(
_
)
=>
{
bug!
(
"shadow_seen stack contains non-ADT type: {:?}"
,
ty
);
}
None
=>
unreachable!
(),
}
if
shadow_seen
.len
()
>
seen
.len
()
&&
shadow_seen
.first
()
==
Some
(
def
)
{
*
force_result
=
true
;
result
=
Some
(
Representability
::
SelfRecursive
(
vec!
[
span
]));
}
if
result
==
None
{
...
...
@@ -154,15 +149,11 @@ fn are_inner_types_recursive<'tcx>(
// If we have encountered an ADT definition that we have not seen
// before (no need to check them twice), recurse to see whether that
// definition is SelfRecursive. If so, we must be ContainsRecursive.
if
shadow_seen
.iter
()
.len
()
>
1
&&
!
shadow_seen
.iter
()
.take
(
shadow_seen
.iter
()
.len
()
-
1
)
.any
(|
seen_ty
|
{
match
seen_ty
.kind
()
{
ty
::
Adt
(
seen_def
,
_
)
=>
seen_def
==
def
,
_
=>
{
bug!
(
"seen stack contains non-ADT type: {:?}"
,
seen_ty
);
}
}
})
if
shadow_seen
.len
()
>
1
&&
!
shadow_seen
.iter
()
.take
(
shadow_seen
.len
()
-
1
)
.any
(|
seen_def
|
seen_def
==
def
)
{
let
adt_def_id
=
def
.did
;
let
raw_adt_ty
=
tcx
.type_of
(
adt_def_id
);
...
...
@@ -180,10 +171,10 @@ fn are_inner_types_recursive<'tcx>(
shadow_seen
,
representable_cache
,
raw_adt_ty
,
f
_res
,
f
orce_result
,
)
{
Representability
::
SelfRecursive
(
_
)
=>
{
if
*
f
_res
{
if
*
f
orce_result
{
Representability
::
SelfRecursive
(
vec!
[
span
])
}
else
{
Representability
::
ContainsRecursive
...
...
@@ -227,7 +218,7 @@ fn are_inner_types_recursive<'tcx>(
shadow_seen
,
representable_cache
,
ty
,
f
_res
,
f
orce_result
,
)
{
Representability
::
SelfRecursive
(
_
)
=>
{
Representability
::
SelfRecursive
(
vec!
[
span
])
...
...
@@ -263,10 +254,10 @@ fn is_type_structurally_recursive<'tcx>(
tcx
:
TyCtxt
<
'tcx
>
,
sp
:
Span
,
seen
:
&
mut
Vec
<
Ty
<
'tcx
>>
,
shadow_seen
:
&
mut
Vec
<
Ty
<
'tcx
>
>
,
shadow_seen
:
&
mut
Vec
<
&
'tcx
ty
::
AdtDef
>
,
representable_cache
:
&
mut
FxHashMap
<
Ty
<
'tcx
>
,
Representability
>
,
ty
:
Ty
<
'tcx
>
,
f
_res
:
&
mut
bool
,
f
orce_result
:
&
mut
bool
,
)
->
Representability
{
debug!
(
"is_type_structurally_recursive: {:?} {:?}"
,
ty
,
sp
);
if
let
Some
(
representability
)
=
representable_cache
.get
(
ty
)
{
...
...
@@ -284,7 +275,7 @@ fn is_type_structurally_recursive<'tcx>(
shadow_seen
,
representable_cache
,
ty
,
f
_res
,
f
orce_result
,
);
representable_cache
.insert
(
ty
,
representability
.clone
());
...
...
@@ -295,10 +286,10 @@ fn is_type_structurally_recursive_inner<'tcx>(
tcx
:
TyCtxt
<
'tcx
>
,
sp
:
Span
,
seen
:
&
mut
Vec
<
Ty
<
'tcx
>>
,
shadow_seen
:
&
mut
Vec
<
Ty
<
'tcx
>
>
,
shadow_seen
:
&
mut
Vec
<
&
'tcx
ty
::
AdtDef
>
,
representable_cache
:
&
mut
FxHashMap
<
Ty
<
'tcx
>
,
Representability
>
,
ty
:
Ty
<
'tcx
>
,
f
_res
:
&
mut
bool
,
f
orce_result
:
&
mut
bool
,
)
->
Representability
{
match
ty
.kind
()
{
ty
::
Adt
(
def
,
_
)
=>
{
...
...
@@ -346,7 +337,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
// For structs and enums, track all previously seen types by pushing them
// onto the 'seen' stack.
seen
.push
(
ty
);
shadow_seen
.push
(
ty
);
shadow_seen
.push
(
def
);
let
out
=
are_inner_types_recursive
(
tcx
,
sp
,
...
...
@@ -354,7 +345,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
shadow_seen
,
representable_cache
,
ty
,
f
_res
,
f
orce_result
,
);
shadow_seen
.pop
();
seen
.pop
();
...
...
@@ -362,7 +353,15 @@ fn is_type_structurally_recursive_inner<'tcx>(
}
_
=>
{
// No need to push in other cases.
are_inner_types_recursive
(
tcx
,
sp
,
seen
,
shadow_seen
,
representable_cache
,
ty
,
f_res
)
are_inner_types_recursive
(
tcx
,
sp
,
seen
,
shadow_seen
,
representable_cache
,
ty
,
force_result
,
)
}
}
}
src/test/ui/
issues
/issue-74224.rs
→
src/test/ui/
structs-enums/struct-rec
/issue-74224.rs
浏览文件 @
98728c2b
文件已移动
src/test/ui/
issues
/issue-74224.stderr
→
src/test/ui/
structs-enums/struct-rec
/issue-74224.stderr
浏览文件 @
98728c2b
文件已移动
src/test/ui/
issues
/issue-84611.rs
→
src/test/ui/
structs-enums/struct-rec
/issue-84611.rs
浏览文件 @
98728c2b
文件已移动
src/test/ui/
issues
/issue-84611.stderr
→
src/test/ui/
structs-enums/struct-rec
/issue-84611.stderr
浏览文件 @
98728c2b
文件已移动
src/test/ui/mutual-struct-recursion.rs
→
src/test/ui/
structs-enums/struct-rec/
mutual-struct-recursion.rs
浏览文件 @
98728c2b
文件已移动
src/test/ui/mutual-struct-recursion.stderr
→
src/test/ui/
structs-enums/struct-rec/
mutual-struct-recursion.stderr
浏览文件 @
98728c2b
文件已移动
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录