Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
706e52e2
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,发现更多精彩内容 >>
提交
706e52e2
编写于
10月 02, 2017
作者:
A
Ariel Ben-Yehuda
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix handling of `Self`
上级
ad998660
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
79 addition
and
26 deletion
+79
-26
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/error_reporting/mod.rs
+2
-1
src/librustc/ty/mod.rs
src/librustc/ty/mod.rs
+30
-7
src/librustc/ty/util.rs
src/librustc/ty/util.rs
+1
-3
src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs
src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs
+5
-1
src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
...test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
+41
-14
未找到文件。
src/librustc/infer/error_reporting/mod.rs
浏览文件 @
706e52e2
...
...
@@ -794,7 +794,8 @@ fn report_generic_bound_failure(&self,
let
generics
=
self
.tcx
.generics_of
(
did
);
// Account for the case where `did` corresponds to `Self`, which doesn't have
// the expected type argument.
if
let
Some
(
type_param
)
=
generics
.type_param
(
param
,
self
.tcx
)
{
if
!
param
.is_self
()
{
let
type_param
=
generics
.type_param
(
param
,
self
.tcx
);
let
hir
=
&
self
.tcx.hir
;
hir
.as_local_node_id
(
type_param
.def_id
)
.map
(|
id
|
{
// Get the `hir::TyParam` to verify wether it already has any bounds.
...
...
src/librustc/ty/mod.rs
浏览文件 @
706e52e2
...
...
@@ -713,6 +713,13 @@ pub fn to_bound_region(&self) -> ty::BoundRegion {
/// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to hir::Generics.
///
/// Note that in the presence of a `Self` parameter, the ordering here
/// is different from the ordering in a Substs. Substs are ordered as
/// Self, *Regions, *Other Type Params, (...child generics)
/// while this struct is ordered as
/// regions = Regions
/// types = [Self, *Other Type Params]
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
Generics
{
pub
parent
:
Option
<
DefId
>
,
...
...
@@ -755,18 +762,34 @@ pub fn region_param(&'tcx self,
}
}
/// Returns the `TypeParameterDef` associated with this `ParamTy`, or `None`
/// if `param` is `self`.
/// Returns the `TypeParameterDef` associated with this `ParamTy`.
pub
fn
type_param
(
&
'tcx
self
,
param
:
&
ParamTy
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
)
->
Option
<&
TypeParameterDef
>
{
->
&
TypeParameterDef
{
if
let
Some
(
idx
)
=
param
.idx
.checked_sub
(
self
.parent_count
()
as
u32
)
{
let
type_param_start
=
(
self
.has_self
as
usize
)
+
self
.regions
.len
();
if
let
Some
(
idx
)
=
(
idx
as
usize
)
.checked_sub
(
type_param_start
)
{
Some
(
&
self
.types
[
idx
])
// non-Self type parameters are always offset by exactly
// `self.regions.len()`. In the absence of a Self, this is obvious,
// but even in the absence of a `Self` we just have to "compensate"
// for the regions:
//
// For example, for `trait Foo<'a, 'b, T1, T2>`, the
// situation is:
// Substs:
// 0 1 2 3 4
// Self 'a 'b T1 T2
// generics.types:
// 0 1 2
// Self T1 T2
// And it can be seen that to move from a substs offset to a
// generics offset you just have to offset by the number of regions.
let
type_param_offset
=
self
.regions
.len
();
if
let
Some
(
idx
)
=
(
idx
as
usize
)
.checked_sub
(
type_param_offset
)
{
assert
!
(
!
(
self
.has_self
&&
idx
==
0
));
&
self
.types
[
idx
]
}
else
{
None
assert
!
(
self
.has_self
&&
idx
==
0
);
&
self
.types
[
0
]
}
}
else
{
tcx
.generics_of
(
self
.parent
.expect
(
"parent_count>0 but no parent?"
))
...
...
src/librustc/ty/util.rs
浏览文件 @
706e52e2
...
...
@@ -519,9 +519,7 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef)
}
else
if
let
Some
(
&
ty
::
TyS
{
sty
:
ty
::
TypeVariants
::
TyParam
(
ref
pt
),
..
})
=
k
.as_type
()
{
!
impl_generics
.type_param
(
pt
,
self
)
.expect
(
"drop impl param doesn't have a ParameterDef?"
)
.pure_wrt_drop
!
impl_generics
.type_param
(
pt
,
self
)
.pure_wrt_drop
}
else
{
// not a type or region param - this should be reported
// as an error.
...
...
src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.rs
浏览文件 @
706e52e2
...
...
@@ -28,7 +28,11 @@ struct Foo<T> {
foo
:
&
'static
T
}
trait
X
<
T
>
{}
trait
X
<
K
>
:
Sized
{
fn
foo
<
'a
,
L
:
X
<&
'a
Nested
<
K
>>>
();
// check that we give a sane error for `Self`
fn
bar
<
'a
,
L
:
X
<&
'a
Nested
<
Self
>>>
();
}
struct
Nested
<
K
>
(
K
);
impl
<
K
>
Nested
<
K
>
{
...
...
src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
浏览文件 @
706e52e2
...
...
@@ -27,37 +27,64 @@ note: ...so that the reference type `&'static T` does not outlive the data it po
| ^^^^^^^^^^^^^^^
error[E0309]: the parameter type `K` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:3
5
:5
--> $DIR/lifetime-doesnt-live-long-enough.rs:3
2
:5
|
34 | impl<K> Nested<K> {
31 | trait X<K>: Sized {
| - help: consider adding an explicit lifetime bound `K: 'a`...
32 | fn foo<'a, L: X<&'a Nested<K>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:32:5
|
32 | fn foo<'a, L: X<&'a Nested<K>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0309]: the parameter type `Self` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:34:5
|
34 | fn bar<'a, L: X<&'a Nested<Self>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `Self: 'a`...
note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:34:5
|
34 | fn bar<'a, L: X<&'a Nested<Self>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0309]: the parameter type `K` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:39:5
|
38 | impl<K> Nested<K> {
| - help: consider adding an explicit lifetime bound `K: 'a`...
3
5
| / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
36
| | }
3
9
| / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
40
| | }
| |_____^
|
note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:3
5
:5
--> $DIR/lifetime-doesnt-live-long-enough.rs:3
9
:5
|
3
5
| / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
36
| | }
3
9
| / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
40
| | }
| |_____^
error[E0309]: the parameter type `M` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:
37
:5
--> $DIR/lifetime-doesnt-live-long-enough.rs:
41
:5
|
37
| fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
41
| fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
| ^ -- help: consider adding an explicit lifetime bound `M: 'a`...
| _____|
| |
38
| | }
42
| | }
| |_____^
|
note: ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:
37
:5
--> $DIR/lifetime-doesnt-live-long-enough.rs:
41
:5
|
37
| / fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
38
| | }
41
| / fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
42
| | }
| |_____^
error: aborting due to
4
previous errors
error: aborting due to
6
previous errors
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录