Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
80e191fb
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
80e191fb
编写于
12月 06, 2015
作者:
A
Ariel Ben-Yehuda
提交者:
Ariel Ben-Yehuda
12月 07, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
introduce a region unification table and use it in dropck
Fixes #29844
上级
4dbdfb49
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
123 addition
and
11 deletion
+123
-11
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/mod.rs
+7
-0
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
+25
-2
src/librustc/middle/infer/resolve.rs
src/librustc/middle/infer/resolve.rs
+35
-0
src/librustc/middle/infer/unify_key.rs
src/librustc/middle/infer/unify_key.rs
+7
-0
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/dropck.rs
+16
-9
src/test/run-pass/issue-29844.rs
src/test/run-pass/issue-29844.rs
+33
-0
未找到文件。
src/librustc/middle/infer/mod.rs
浏览文件 @
80e191fb
...
...
@@ -1225,6 +1225,13 @@ pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
value
.fold_with
(
&
mut
r
)
}
pub
fn
resolve_type_and_region_vars_if_possible
<
T
>
(
&
self
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
let
mut
r
=
resolve
::
OpportunisticTypeAndRegionResolver
::
new
(
self
);
value
.fold_with
(
&
mut
r
)
}
/// Resolves all type variables in `t` and then, if any were left
/// unresolved, substitutes an error type. This is used after the
/// main checking when doing a second pass before writeback. The
...
...
src/librustc/middle/infer/region_inference/mod.rs
浏览文件 @
80e191fb
...
...
@@ -20,6 +20,7 @@
use
super
::{
RegionVariableOrigin
,
SubregionOrigin
,
TypeTrace
,
MiscVariable
};
use
rustc_data_structures
::
graph
::{
self
,
Direction
,
NodeIndex
};
use
rustc_data_structures
::
unify
::{
self
,
UnificationTable
};
use
middle
::
free_region
::
FreeRegionMap
;
use
middle
::
ty
::{
self
,
Ty
};
use
middle
::
ty
::{
BoundRegion
,
FreeRegion
,
Region
,
RegionVid
};
...
...
@@ -234,15 +235,16 @@ pub struct RegionVarBindings<'a, 'tcx: 'a> {
// bound on a variable and so forth, which can never be rolled
// back.
undo_log
:
RefCell
<
Vec
<
UndoLogEntry
>>
,
unification_table
:
RefCell
<
UnificationTable
<
ty
::
RegionVid
>>
,
// This contains the results of inference. It begins as an empty
// option and only acquires a value after inference is complete.
values
:
RefCell
<
Option
<
Vec
<
VarValue
>>>
,
}
#[derive(Debug)]
pub
struct
RegionSnapshot
{
length
:
usize
,
region_snapshot
:
unify
::
Snapshot
<
ty
::
RegionVid
>
,
skolemization_count
:
u32
,
}
...
...
@@ -260,6 +262,7 @@ pub fn new(tcx: &'a ty::ctxt<'tcx>) -> RegionVarBindings<'a, 'tcx> {
skolemization_count
:
Cell
::
new
(
0
),
bound_count
:
Cell
::
new
(
0
),
undo_log
:
RefCell
::
new
(
Vec
::
new
()),
unification_table
:
RefCell
::
new
(
UnificationTable
::
new
()),
}
}
...
...
@@ -273,6 +276,7 @@ pub fn start_snapshot(&self) -> RegionSnapshot {
self
.undo_log
.borrow_mut
()
.push
(
OpenSnapshot
);
RegionSnapshot
{
length
:
length
,
region_snapshot
:
self
.unification_table
.borrow_mut
()
.snapshot
(),
skolemization_count
:
self
.skolemization_count
.get
(),
}
}
...
...
@@ -289,6 +293,7 @@ pub fn commit(&self, snapshot: RegionSnapshot) {
(
*
undo_log
)[
snapshot
.length
]
=
CommitedSnapshot
;
}
self
.skolemization_count
.set
(
snapshot
.skolemization_count
);
self
.unification_table
.borrow_mut
()
.commit
(
snapshot
.region_snapshot
);
}
pub
fn
rollback_to
(
&
self
,
snapshot
:
RegionSnapshot
)
{
...
...
@@ -328,6 +333,8 @@ pub fn rollback_to(&self, snapshot: RegionSnapshot) {
let
c
=
undo_log
.pop
()
.unwrap
();
assert
!
(
c
==
OpenSnapshot
);
self
.skolemization_count
.set
(
snapshot
.skolemization_count
);
self
.unification_table
.borrow_mut
()
.rollback_to
(
snapshot
.region_snapshot
);
}
pub
fn
num_vars
(
&
self
)
->
u32
{
...
...
@@ -340,7 +347,8 @@ pub fn num_vars(&self) -> u32 {
pub
fn
new_region_var
(
&
self
,
origin
:
RegionVariableOrigin
)
->
RegionVid
{
let
id
=
self
.num_vars
();
self
.var_origins
.borrow_mut
()
.push
(
origin
.clone
());
let
vid
=
RegionVid
{
index
:
id
};
let
vid
=
self
.unification_table
.borrow_mut
()
.new_key
(());
assert_eq!
(
vid
.index
,
id
);
if
self
.in_snapshot
()
{
self
.undo_log
.borrow_mut
()
.push
(
AddVar
(
vid
));
}
...
...
@@ -460,6 +468,10 @@ pub fn make_eqregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Reg
// equating regions.
self
.make_subregion
(
origin
.clone
(),
sub
,
sup
);
self
.make_subregion
(
origin
,
sup
,
sub
);
if
let
(
ty
::
ReVar
(
sub
),
ty
::
ReVar
(
sup
))
=
(
sub
,
sup
)
{
self
.unification_table
.borrow_mut
()
.union
(
sub
,
sup
);
}
}
}
...
...
@@ -568,6 +580,10 @@ pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
}
}
pub
fn
opportunistic_resolve_var
(
&
self
,
rid
:
RegionVid
)
->
ty
::
Region
{
ty
::
ReVar
(
self
.unification_table
.borrow_mut
()
.find
(
rid
))
}
fn
combine_map
(
&
self
,
t
:
CombineMapType
)
->
&
RefCell
<
CombineMap
>
{
match
t
{
Glb
=>
&
self
.glbs
,
...
...
@@ -1312,6 +1328,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
fmt
::
Debug
for
RegionSnapshot
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
write!
(
f
,
"RegionSnapshot(length={},skolemization={})"
,
self
.length
,
self
.skolemization_count
)
}
}
impl
<
'tcx
>
fmt
::
Debug
for
GenericKind
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
match
*
self
{
...
...
src/librustc/middle/infer/resolve.rs
浏览文件 @
80e191fb
...
...
@@ -45,6 +45,41 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
}
}
/// The opportunistic type and region resolver is similar to the
/// opportunistic type resolver, but also opportunistly resolves
/// regions. It is useful for canonicalization.
pub
struct
OpportunisticTypeAndRegionResolver
<
'a
,
'tcx
:
'a
>
{
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
,
}
impl
<
'a
,
'tcx
>
OpportunisticTypeAndRegionResolver
<
'a
,
'tcx
>
{
pub
fn
new
(
infcx
:
&
'a
InferCtxt
<
'a
,
'tcx
>
)
->
Self
{
OpportunisticTypeAndRegionResolver
{
infcx
:
infcx
}
}
}
impl
<
'a
,
'tcx
>
ty
::
fold
::
TypeFolder
<
'tcx
>
for
OpportunisticTypeAndRegionResolver
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.infcx.tcx
}
fn
fold_ty
(
&
mut
self
,
t
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
!
t
.needs_infer
()
{
t
// micro-optimize -- if there is nothing in this type that this fold affects...
}
else
{
let
t0
=
self
.infcx
.shallow_resolve
(
t
);
ty
::
fold
::
super_fold_ty
(
self
,
t0
)
}
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
match
r
{
ty
::
ReVar
(
rid
)
=>
self
.infcx.region_vars
.opportunistic_resolve_var
(
rid
),
_
=>
r
,
}
}
}
///////////////////////////////////////////////////////////////////////////
// FULL TYPE RESOLUTION
...
...
src/librustc/middle/infer/unify_key.rs
浏览文件 @
80e191fb
...
...
@@ -23,6 +23,13 @@ fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } }
fn
tag
(
_
:
Option
<
ty
::
IntVid
>
)
->
&
'static
str
{
"IntVid"
}
}
impl
UnifyKey
for
ty
::
RegionVid
{
type
Value
=
();
fn
index
(
&
self
)
->
u32
{
self
.index
}
fn
from_index
(
i
:
u32
)
->
ty
::
RegionVid
{
ty
::
RegionVid
{
index
:
i
}
}
fn
tag
(
_
:
Option
<
ty
::
RegionVid
>
)
->
&
'static
str
{
"RegionVid"
}
}
impl
<
'tcx
>
ToType
<
'tcx
>
for
IntVarValue
{
fn
to_type
(
&
self
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
*
self
{
...
...
src/librustc_typeck/check/dropck.rs
浏览文件 @
80e191fb
...
...
@@ -17,7 +17,6 @@
use
middle
::
subst
::{
self
,
Subst
};
use
middle
::
traits
;
use
middle
::
ty
::{
self
,
Ty
};
use
util
::
nodemap
::
FnvHashSet
;
use
syntax
::
ast
;
use
syntax
::
codemap
::{
self
,
Span
};
...
...
@@ -280,7 +279,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
rcx
:
rcx
,
span
:
span
,
parent_scope
:
parent_scope
,
breadcrumbs
:
FnvHashSet
()
breadcrumbs
:
Vec
::
new
(),
},
TypeContext
::
Root
,
typ
,
...
...
@@ -341,7 +340,7 @@ enum TypeContext {
struct
DropckContext
<
'a
,
'b
:
'a
,
'tcx
:
'b
>
{
rcx
:
&
'a
mut
Rcx
<
'b
,
'tcx
>
,
/// types that have already been traversed
breadcrumbs
:
FnvHashSet
<
Ty
<
'tcx
>>
,
breadcrumbs
:
Vec
<
Ty
<
'tcx
>>
,
/// span for error reporting
span
:
Span
,
/// the scope reachable dtorck types must outlive
...
...
@@ -356,6 +355,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
depth
:
usize
)
->
Result
<
(),
Error
<
'tcx
>>
{
let
tcx
=
cx
.rcx
.tcx
();
let
ty
=
cx
.rcx
.infcx
()
.resolve_type_and_region_vars_if_possible
(
&
ty
);
// Issue #22443: Watch out for overflow. While we are careful to
// handle regular types properly, non-regular ones cause problems.
let
recursion_limit
=
tcx
.sess.recursion_limit
.get
();
...
...
@@ -366,13 +367,19 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
return
Err
(
Error
::
Overflow
(
context
,
ty
))
}
if
!
cx
.breadcrumbs
.insert
(
ty
)
{
debug!
(
"iterate_over_potentially_unsafe_regions_in_type
\
{}ty: {} scope: {:?} - cached"
,
(
0
..
depth
)
.map
(|
_
|
' '
)
.collect
::
<
String
>
(),
ty
,
cx
.parent_scope
);
return
Ok
(());
// we already visited this type
for
breadcrumb
in
&
mut
cx
.breadcrumbs
{
*
breadcrumb
=
cx
.rcx
.infcx
()
.resolve_type_and_region_vars_if_possible
(
breadcrumb
);
if
*
breadcrumb
==
ty
{
debug!
(
"iterate_over_potentially_unsafe_regions_in_type
\
{}ty: {} scope: {:?} - cached"
,
(
0
..
depth
)
.map
(|
_
|
' '
)
.collect
::
<
String
>
(),
ty
,
cx
.parent_scope
);
return
Ok
(());
// we already visited this type
}
}
cx
.breadcrumbs
.push
(
ty
);
debug!
(
"iterate_over_potentially_unsafe_regions_in_type
\
{}ty: {} scope: {:?}"
,
(
0
..
depth
)
.map
(|
_
|
' '
)
.collect
::
<
String
>
(),
...
...
src/test/run-pass/issue-29844.rs
0 → 100644
浏览文件 @
80e191fb
// Copyright 2015 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.
use
std
::
sync
::
Arc
;
pub
struct
DescriptorSet
<
'a
>
{
pub
slots
:
Vec
<
AttachInfo
<
'a
,
Resources
>>
}
pub
trait
ResourcesTrait
<
'r
>
:
Sized
{
type
DescriptorSet
:
'r
;
}
pub
struct
Resources
;
impl
<
'a
>
ResourcesTrait
<
'a
>
for
Resources
{
type
DescriptorSet
=
DescriptorSet
<
'a
>
;
}
pub
enum
AttachInfo
<
'a
,
R
:
ResourcesTrait
<
'a
>>
{
NextDescriptorSet
(
Arc
<
R
::
DescriptorSet
>
)
}
fn
main
()
{
let
_
x
=
DescriptorSet
{
slots
:
Vec
::
new
()};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录