Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
361b3db8
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,发现更多精彩内容 >>
提交
361b3db8
编写于
11月 09, 2017
作者:
M
Michael Hewson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement raw-pointer `self`. Works for traits, including trait objects, but not structs
上级
53a6d14e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
130 addition
and
18 deletion
+130
-18
src/librustc/traits/object_safety.rs
src/librustc/traits/object_safety.rs
+1
-3
src/librustc/ty/util.rs
src/librustc/ty/util.rs
+8
-2
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/autoderef.rs
+18
-6
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/wfcheck.rs
+20
-7
src/test/run-pass/arbitrary_self_types_raw_pointer_struct.rs
src/test/run-pass/arbitrary_self_types_raw_pointer_struct.rs
+24
-0
src/test/run-pass/arbitrary_self_types_raw_pointer_trait.rs
src/test/run-pass/arbitrary_self_types_raw_pointer_trait.rs
+59
-0
未找到文件。
src/librustc/traits/object_safety.rs
浏览文件 @
361b3db8
...
...
@@ -59,9 +59,7 @@ pub fn error_msg(&self) -> Cow<'static, str> {
ObjectSafetyViolation
::
Method
(
name
,
MethodViolationCode
::
Generic
)
=>
format!
(
"method `{}` has generic type parameters"
,
name
)
.into
(),
ObjectSafetyViolation
::
Method
(
name
,
MethodViolationCode
::
NonStandardSelfType
)
=>
format!
(
"method `{}` has a non-standard `self` type. Only `&self`,
\
`&mut self`, and `Box<Self>` are currently supported
\
for trait objects"
,
name
)
.into
(),
format!
(
"method `{}` has a non-standard `self` type"
,
name
)
.into
(),
ObjectSafetyViolation
::
AssociatedConst
(
name
)
=>
format!
(
"the trait cannot contain associated consts like `{}`"
,
name
)
.into
(),
}
...
...
src/librustc/ty/util.rs
浏览文件 @
361b3db8
...
...
@@ -1191,6 +1191,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub
enum
ExplicitSelf
<
'tcx
>
{
ByValue
,
ByReference
(
ty
::
Region
<
'tcx
>
,
hir
::
Mutability
),
ByRawPointer
(
hir
::
Mutability
),
ByBox
,
Other
}
...
...
@@ -1231,10 +1232,15 @@ pub fn determine<P>(
match
self_arg_ty
.sty
{
_
if
is_self_ty
(
self_arg_ty
)
=>
ByValue
,
ty
::
TyRef
(
region
,
ty
::
TypeAndMut
{
ty
,
mutbl
})
if
is_self_ty
(
ty
)
=>
{
ty
::
TyRef
(
region
,
ty
::
TypeAndMut
{
ty
,
mutbl
})
if
is_self_ty
(
ty
)
=>
{
ByReference
(
region
,
mutbl
)
}
ty
::
TyAdt
(
def
,
_
)
if
def
.is_box
()
&&
is_self_ty
(
self_arg_ty
.boxed_ty
())
=>
ByBox
,
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
mutbl
})
if
is_self_ty
(
ty
)
=>
{
ByRawPointer
(
mutbl
)
}
ty
::
TyAdt
(
def
,
_
)
if
def
.is_box
()
&&
is_self_ty
(
self_arg_ty
.boxed_ty
())
=>
{
ByBox
}
_
=>
Other
}
}
...
...
src/librustc_typeck/check/autoderef.rs
浏览文件 @
361b3db8
...
...
@@ -37,6 +37,7 @@ pub struct Autoderef<'a, 'gcx: 'tcx, 'tcx: 'a> {
cur_ty
:
Ty
<
'tcx
>
,
obligations
:
Vec
<
traits
::
PredicateObligation
<
'tcx
>>
,
at_start
:
bool
,
include_raw_pointers
:
bool
,
span
:
Span
,
}
...
...
@@ -76,12 +77,13 @@ fn next(&mut self) -> Option<Self::Item> {
}
// Otherwise, deref if type is derefable:
let
(
kind
,
new_ty
)
=
if
let
Some
(
mt
)
=
self
.cur_ty
.builtin_deref
(
false
,
NoPreference
)
{
(
AutoderefKind
::
Builtin
,
mt
.ty
)
}
else
{
let
ty
=
self
.overloaded_deref_ty
(
self
.cur_ty
)
?
;
(
AutoderefKind
::
Overloaded
,
ty
)
};
let
(
kind
,
new_ty
)
=
if
let
Some
(
mt
)
=
self
.cur_ty
.builtin_deref
(
self
.include_raw_pointers
,
NoPreference
)
{
(
AutoderefKind
::
Builtin
,
mt
.ty
)
}
else
{
let
ty
=
self
.overloaded_deref_ty
(
self
.cur_ty
)
?
;
(
AutoderefKind
::
Overloaded
,
ty
)
};
if
new_ty
.references_error
()
{
return
None
;
...
...
@@ -194,6 +196,15 @@ pub fn adjust_steps_as_infer_ok(&self, pref: LvaluePreference)
}
}
/// also dereference through raw pointer types
/// e.g. assuming ptr_to_Foo is the type `*const Foo`
/// fcx.autoderef(span, ptr_to_Foo) => [*const Foo]
/// fcx.autoderef(span, ptr_to_Foo).include_raw_ptrs() => [*const Foo, Foo]
pub
fn
include_raw_pointers
(
mut
self
)
->
Self
{
self
.include_raw_pointers
=
true
;
self
}
pub
fn
finalize
(
self
)
{
let
fcx
=
self
.fcx
;
fcx
.register_predicates
(
self
.into_obligations
());
...
...
@@ -212,6 +223,7 @@ pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'gcx,
cur_ty
:
self
.resolve_type_vars_if_possible
(
&
base_ty
),
obligations
:
vec!
[],
at_start
:
true
,
include_raw_pointers
:
false
,
span
,
}
}
...
...
src/librustc_typeck/check/wfcheck.rs
浏览文件 @
361b3db8
...
...
@@ -503,7 +503,7 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self,
&
ty
::
Binder
(
self_arg_ty
)
);
let
mut
autoderef
=
fcx
.autoderef
(
span
,
self_arg_ty
);
let
mut
autoderef
=
fcx
.autoderef
(
span
,
self_arg_ty
)
.include_raw_pointers
()
;
loop
{
if
let
Some
((
potential_self_ty
,
_
))
=
autoderef
.next
()
{
...
...
@@ -532,12 +532,25 @@ fn check_method_receiver<'fcx, 'tcx>(&mut self,
let
is_self_ty
=
|
ty
|
fcx
.infcx
.can_eq
(
fcx
.param_env
,
self_ty
,
ty
)
.is_ok
();
let
self_kind
=
ExplicitSelf
::
determine
(
self_arg_ty
,
is_self_ty
);
if
let
ExplicitSelf
::
Other
=
self_kind
{
if
!
fcx
.tcx.sess.features
.borrow
()
.arbitrary_self_types
{
feature_gate
::
feature_err
(
&
fcx
.tcx.sess.parse_sess
,
"arbitrary_self_types"
,
span
,
GateIssue
::
Language
,
"arbitrary `self` types are unstable"
)
.help
(
"consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`"
)
.emit
();
if
!
fcx
.tcx.sess.features
.borrow
()
.arbitrary_self_types
{
match
self_kind
{
ExplicitSelf
::
ByValue
|
ExplicitSelf
::
ByReference
(
_
,
_
)
|
ExplicitSelf
::
ByBox
=>
(),
ExplicitSelf
::
ByRawPointer
(
_
)
=>
{
feature_gate
::
feature_err
(
&
fcx
.tcx.sess.parse_sess
,
"arbitrary_self_types"
,
span
,
GateIssue
::
Language
,
"raw pointer `self` is unstable"
)
.help
(
"consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`"
)
.emit
();
}
ExplicitSelf
::
Other
=>
{
feature_gate
::
feature_err
(
&
fcx
.tcx.sess.parse_sess
,
"arbitrary_self_types"
,
span
,
GateIssue
::
Language
,
"arbitrary `self` types are unstable"
)
.help
(
"consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`"
)
.emit
();
}
}
}
}
...
...
src/test/run-pass/arbitrary_self_types_raw_pointer_struct.rs
0 → 100644
浏览文件 @
361b3db8
// 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.
#![feature(arbitrary_self_types)]
struct
Foo
(
String
);
impl
Foo
{
unsafe
fn
foo
(
self
:
*
const
Self
)
->
*
const
str
{
(
*
self
)
.0
.as_ref
()
}
}
fn
main
()
{
let
foo
=
Foo
(
"abc123"
.into
());
assert_eq!
(
"abc123"
,
unsafe
{
&*
(
&
foo
as
*
const
Foo
)
.foo
()
});
}
src/test/run-pass/arbitrary_self_types_raw_pointer_trait.rs
0 → 100644
浏览文件 @
361b3db8
// 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.
#![feature(arbitrary_self_types)]
use
std
::
ptr
;
trait
Foo
{
fn
foo
(
self
:
*
const
Self
)
->
&
'static
str
;
unsafe
fn
bar
(
self
:
*
const
Self
)
->
i64
;
}
impl
Foo
for
i32
{
fn
foo
(
self
:
*
const
Self
)
->
&
'static
str
{
"I'm an i32!"
}
unsafe
fn
bar
(
self
:
*
const
Self
)
->
i64
{
*
self
as
i64
}
}
impl
Foo
for
u32
{
fn
foo
(
self
:
*
const
Self
)
->
&
'static
str
{
"I'm a u32!"
}
unsafe
fn
bar
(
self
:
*
const
Self
)
->
i64
{
*
self
as
i64
}
}
fn
main
()
{
let
foo_i32
=
ptr
::
null
::
<
i32
>
()
as
*
const
Foo
;
let
foo_u32
=
ptr
::
null
::
<
u32
>
()
as
*
const
Foo
;
assert_eq!
(
"I'm an i32!"
,
foo_i32
.foo
());
assert_eq!
(
"I'm a u32!"
,
foo_u32
.foo
());
let
bar_i32
=
5i32
;
let
bar_i32_thin
=
&
bar_i32
as
*
const
i32
;
assert_eq!
(
5
,
unsafe
{
bar_i32_thin
.bar
()
});
let
bar_i32_fat
=
bar_i32_thin
as
*
const
Foo
;
assert_eq!
(
5
,
unsafe
{
bar_i32_fat
.bar
()
});
let
bar_u32
=
18u32
;
let
bar_u32_thin
=
&
bar_u32
as
*
const
u32
;
assert_eq!
(
18
,
unsafe
{
bar_u32_thin
.bar
()
});
let
bar_u32_fat
=
bar_u32_thin
as
*
const
Foo
;
assert_eq!
(
18
,
unsafe
{
bar_u32_fat
.bar
()
});
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录