Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
11e265c2
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,发现更多精彩内容 >>
提交
11e265c2
编写于
1月 07, 2015
作者:
A
Alex Crichton
浏览文件
操作
浏览文件
下载
差异文件
rollup merge of #20707: nikomatsakis/issue-20582
上级
373cbab5
a70428aa
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
86 addition
and
30 deletion
+86
-30
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/higher_ranked/mod.rs
+1
-1
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/mod.rs
+1
-1
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+19
-8
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_fold.rs
+4
-1
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+2
-2
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+11
-2
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+1
-1
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/closure.rs
+1
-1
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/common.rs
+14
-10
src/librustc_trans/trans/monomorphize.rs
src/librustc_trans/trans/monomorphize.rs
+4
-2
src/librustc_trans/trans/type_of.rs
src/librustc_trans/trans/type_of.rs
+1
-1
src/test/run-pass/associated-types-region-erasure-issue-20582.rs
...t/run-pass/associated-types-region-erasure-issue-20582.rs
+27
-0
未找到文件。
src/librustc/middle/infer/higher_ranked/mod.rs
浏览文件 @
11e265c2
...
...
@@ -468,7 +468,7 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
* when higher-ranked things are involved. See `doc.rs` for more details.
*/
let
(
result
,
map
)
=
ty
::
replace_late_bound_regions
(
infcx
.tcx
,
binder
,
|
br
,
_
|
{
let
(
result
,
map
)
=
ty
::
replace_late_bound_regions
(
infcx
.tcx
,
binder
,
|
br
|
{
infcx
.region_vars
.new_skolemized
(
br
,
&
snapshot
.region_vars_snapshot
)
});
...
...
src/librustc/middle/infer/mod.rs
浏览文件 @
11e265c2
...
...
@@ -1048,7 +1048,7 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
ty
::
replace_late_bound_regions
(
self
.tcx
,
value
,
|
br
,
_
|
self
.next_region_var
(
LateBoundRegion
(
span
,
br
,
lbrct
)))
|
br
|
self
.next_region_var
(
LateBoundRegion
(
span
,
br
,
lbrct
)))
}
/// See `verify_generic_bound` method in `region_inference`
...
...
src/librustc/middle/ty.rs
浏览文件 @
11e265c2
...
...
@@ -6686,7 +6686,7 @@ pub fn liberate_late_bound_regions<'tcx, T>(
{
replace_late_bound_regions
(
tcx
,
value
,
|
br
,
_
|
ty
::
ReFree
(
ty
::
FreeRegion
{
scope
:
scope
,
bound_region
:
br
}))
.0
|
br
|
ty
::
ReFree
(
ty
::
FreeRegion
{
scope
:
scope
,
bound_region
:
br
}))
.0
}
pub
fn
count_late_bound_regions
<
'tcx
,
T
>
(
...
...
@@ -6695,7 +6695,7 @@ pub fn count_late_bound_regions<'tcx, T>(
->
uint
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
{
let
(
_
,
skol_map
)
=
replace_late_bound_regions
(
tcx
,
value
,
|
_
,
_
|
ty
::
ReStatic
);
let
(
_
,
skol_map
)
=
replace_late_bound_regions
(
tcx
,
value
,
|
_
|
ty
::
ReStatic
);
skol_map
.len
()
}
...
...
@@ -6726,7 +6726,7 @@ pub fn erase_late_bound_regions<'tcx, T>(
->
T
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
{
replace_late_bound_regions
(
tcx
,
value
,
|
_
,
_
|
ty
::
ReStatic
)
.0
replace_late_bound_regions
(
tcx
,
value
,
|
_
|
ty
::
ReStatic
)
.0
}
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
...
...
@@ -6744,9 +6744,9 @@ pub fn anonymize_late_bound_regions<'tcx, T>(
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
,
{
let
mut
counter
=
0
;
ty
::
Binder
(
replace_late_bound_regions
(
tcx
,
sig
,
|
_
,
db
|
{
ty
::
Binder
(
replace_late_bound_regions
(
tcx
,
sig
,
|
_
|
{
counter
+=
1
;
ReLateBound
(
db
,
BrAnon
(
counter
))
ReLateBound
(
ty
::
DebruijnIndex
::
new
(
1
)
,
BrAnon
(
counter
))
})
.0
)
}
...
...
@@ -6757,7 +6757,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
mut
mapf
:
F
)
->
(
T
,
FnvHashMap
<
ty
::
BoundRegion
,
ty
::
Region
>
)
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
,
F
:
FnMut
(
BoundRegion
,
DebruijnIndex
)
->
ty
::
Region
,
F
:
FnMut
(
BoundRegion
)
->
ty
::
Region
,
{
debug!
(
"replace_late_bound_regions({})"
,
binder
.repr
(
tcx
));
...
...
@@ -6769,8 +6769,19 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
debug!
(
"region={}"
,
region
.repr
(
tcx
));
match
region
{
ty
::
ReLateBound
(
debruijn
,
br
)
if
debruijn
.depth
==
current_depth
=>
{
*
map
.entry
(
br
)
.get
()
.unwrap_or_else
(
|
vacant_entry
|
vacant_entry
.insert
(
mapf
(
br
,
debruijn
)))
let
region
=
*
map
.entry
(
br
)
.get
()
.unwrap_or_else
(
|
vacant_entry
|
vacant_entry
.insert
(
mapf
(
br
)));
if
let
ty
::
ReLateBound
(
debruijn1
,
br
)
=
region
{
// If the callback returns a late-bound region,
// that region should always use depth 1. Then we
// adjust it to the correct depth.
assert_eq!
(
debruijn1
.depth
,
1
);
ty
::
ReLateBound
(
debruijn
,
br
)
}
else
{
region
}
}
_
=>
{
region
...
...
src/librustc/middle/ty_fold.rs
浏览文件 @
11e265c2
...
...
@@ -862,7 +862,10 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
///////////////////////////////////////////////////////////////////////////
// Region eraser
//
// Replaces all free regions with 'static. Useful in trans.
// Replaces all free regions with 'static. Useful in contexts, such as
// method probing, where precise region relationships are not
// important. Note that in trans you should use
// `common::erase_regions` instead.
pub
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
...
...
src/librustc/util/ppaux.rs
浏览文件 @
11e265c2
...
...
@@ -1183,8 +1183,8 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
// the output. We'll probably want to tweak this over time to
// decide just how much information to give.
let
mut
names
=
Vec
::
new
();
let
(
unbound_value
,
_
)
=
ty
::
replace_late_bound_regions
(
tcx
,
self
,
|
br
,
debruijn
|
{
ty
::
ReLateBound
(
debruijn
,
match
br
{
let
(
unbound_value
,
_
)
=
ty
::
replace_late_bound_regions
(
tcx
,
self
,
|
br
|
{
ty
::
ReLateBound
(
ty
::
DebruijnIndex
::
new
(
1
)
,
match
br
{
ty
::
BrNamed
(
_
,
name
)
=>
{
names
.push
(
token
::
get_name
(
name
));
br
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
11e265c2
...
...
@@ -281,8 +281,15 @@ pub fn kind_for_unboxed_closure(ccx: &CrateContext, closure_id: ast::DefId)
pub
fn
decl_rust_fn
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
fn_ty
:
Ty
<
'tcx
>
,
name
:
&
str
)
->
ValueRef
{
debug!
(
"decl_rust_fn(fn_ty={}, name={:?})"
,
fn_ty
.repr
(
ccx
.tcx
()),
name
);
let
fn_ty
=
monomorphize
::
normalize_associated_type
(
ccx
.tcx
(),
&
fn_ty
);
debug!
(
"decl_rust_fn: fn_ty={} (after normalized associated types)"
,
fn_ty
.repr
(
ccx
.tcx
()));
let
function_type
;
// placeholder so that the memory ownership works out ok
let
(
sig
,
abi
,
env
)
=
match
fn_ty
.sty
{
...
...
@@ -305,10 +312,12 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
sig
=
ty
::
erase_late_bound_regions
(
ccx
.tcx
(),
sig
);
let
sig
=
ty
::
Binder
(
sig
);
debug!
(
"decl_rust_fn: sig={} (after erasing regions)"
,
sig
.repr
(
ccx
.tcx
()));
let
llfty
=
type_of_rust_fn
(
ccx
,
env
,
&
sig
,
abi
);
debug!
(
"decl_rust_fn(sig={}, type={})"
,
sig
.repr
(
ccx
.tcx
()),
debug!
(
"decl_rust_fn: llfty={}"
,
ccx
.tn
()
.type_to_string
(
llfty
));
let
llfn
=
decl_fn
(
ccx
,
name
,
llvm
::
CCallConv
,
llfty
,
sig
.0
.output
/* (1) */
);
...
...
src/librustc_trans/trans/callee.rs
浏览文件 @
11e265c2
...
...
@@ -265,7 +265,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let
_
icx
=
push_ctxt
(
"trans_fn_pointer_shim"
);
let
tcx
=
ccx
.tcx
();
let
bare_fn_ty
=
normalize_ty
(
tcx
,
bare_fn_ty
);
let
bare_fn_ty
=
erase_regions
(
tcx
,
&
bare_fn_ty
);
match
ccx
.fn_pointer_shims
()
.borrow
()
.get
(
&
bare_fn_ty
)
{
Some
(
&
llval
)
=>
{
return
llval
;
}
None
=>
{
}
...
...
src/librustc_trans/trans/closure.rs
浏览文件 @
11e265c2
...
...
@@ -466,7 +466,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
// Normalize type so differences in regions and typedefs don't cause
// duplicate declarations
let
function_type
=
normalize_ty
(
ccx
.tcx
(),
function_type
);
let
function_type
=
erase_regions
(
ccx
.tcx
(),
&
function_type
);
let
params
=
match
function_type
.sty
{
ty
::
ty_unboxed_closure
(
_
,
_
,
ref
substs
)
=>
substs
.types
.clone
(),
_
=>
unreachable!
()
...
...
src/librustc_trans/trans/common.rs
浏览文件 @
11e265c2
...
...
@@ -58,16 +58,21 @@
pub
use
trans
::
context
::
CrateContext
;
/// Returns an equivalent type with all the typedefs and self regions removed.
pub
fn
normalize_ty
<
'tcx
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
let
u
=
TypeNormalizer
(
cx
)
.fold_ty
(
ty
);
debug!
(
"normalize_ty({}) = {}"
,
ty
.repr
(
cx
),
u
.repr
(
cx
));
return
u
;
/// Returns an equivalent value with all free regions removed (note
/// that late-bound regions remain, because they are important for
/// subtyping, but they are anonymized and normalized as well). This
/// is a stronger, caching version of `ty_fold::erase_regions`.
pub
fn
erase_regions
<
'tcx
,
T
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
{
let
value1
=
value
.fold_with
(
&
mut
RegionEraser
(
cx
));
debug!
(
"erase_regions({}) = {}"
,
value
.repr
(
cx
),
value1
.repr
(
cx
));
return
value1
;
struct
TypeNormaliz
er
<
'a
,
'tcx
:
'a
>
(
&
'a
ty
::
ctxt
<
'tcx
>
);
struct
RegionEras
er
<
'a
,
'tcx
:
'a
>
(
&
'a
ty
::
ctxt
<
'tcx
>
);
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
TypeNormaliz
er
<
'a
,
'tcx
>
{
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEras
er
<
'a
,
'tcx
>
{
fn
tcx
(
&
self
)
->
&
ty
::
ctxt
<
'tcx
>
{
self
.0
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
...
...
@@ -84,7 +89,6 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
fn
fold_binder
<
T
>
(
&
mut
self
,
t
:
&
ty
::
Binder
<
T
>
)
->
ty
::
Binder
<
T
>
where
T
:
TypeFoldable
<
'tcx
>
+
Repr
<
'tcx
>
{
// FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`.
let
u
=
ty
::
anonymize_late_bound_regions
(
self
.tcx
(),
t
);
ty_fold
::
super_fold_binder
(
self
,
&
u
)
}
...
...
@@ -989,7 +993,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
tcx
=
ccx
.tcx
();
// Remove any references to regions; this helps improve caching.
let
trait_ref
=
ty_fold
::
erase_regions
(
tcx
,
trait_ref
);
let
trait_ref
=
erase_regions
(
tcx
,
&
trait_ref
);
// First check the cache.
match
ccx
.trait_cache
()
.borrow
()
.get
(
&
trait_ref
)
{
...
...
src/librustc_trans/trans/monomorphize.rs
浏览文件 @
11e265c2
...
...
@@ -313,8 +313,10 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
{
debug!
(
"normalize_associated_type(t={})"
,
value
.repr
(
tcx
));
let
value
=
erase_regions
(
tcx
,
value
);
if
!
value
.has_projection_types
()
{
return
value
.clone
()
;
return
value
;
}
// FIXME(#20304) -- cache
...
...
@@ -324,7 +326,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
let
mut
selcx
=
traits
::
SelectionContext
::
new
(
&
infcx
,
&
typer
);
let
cause
=
traits
::
ObligationCause
::
dummy
();
let
traits
::
Normalized
{
value
:
result
,
obligations
}
=
traits
::
normalize
(
&
mut
selcx
,
cause
,
value
);
traits
::
normalize
(
&
mut
selcx
,
cause
,
&
value
);
debug!
(
"normalize_associated_type: result={} obligations={}"
,
result
.repr
(
tcx
),
...
...
src/librustc_trans/trans/type_of.rs
浏览文件 @
11e265c2
...
...
@@ -285,7 +285,7 @@ fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Ty
// Rust types are defined as the same LLVM types. If we don't do
// this then, e.g. `Option<{myfield: bool}>` would be a different
// type than `Option<myrec>`.
let
t_norm
=
normalize_ty
(
cx
.tcx
(),
t
);
let
t_norm
=
erase_regions
(
cx
.tcx
(),
&
t
);
if
t
!=
t_norm
{
let
llty
=
type_of
(
cx
,
t_norm
);
...
...
src/test/run-pass/associated-types-region-erasure-issue-20582.rs
0 → 100644
浏览文件 @
11e265c2
// 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.
// Regression test for #20582. This test caused an ICE related to
// inconsistent region erasure in trans.
struct
Foo
<
'a
>
{
buf
:
&
'a
[
u8
]
}
impl
<
'a
>
Iterator
for
Foo
<
'a
>
{
type
Item
=
&
'a
[
u8
];
fn
next
(
&
mut
self
)
->
Option
<<
Self
as
Iterator
>
::
Item
>
{
Some
(
self
.buf
)
}
}
fn
main
()
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录