Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7c64f036
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,发现更多精彩内容 >>
提交
7c64f036
编写于
5月 02, 2014
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc: Implement the `Box<T>` type syntax. RFC #14. Issue #13885.
上级
b5d6b073
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
211 addition
and
81 deletion
+211
-81
src/librustc/middle/lang_items.rs
src/librustc/middle/lang_items.rs
+1
-0
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/astconv.rs
+161
-81
src/libstd/owned.rs
src/libstd/owned.rs
+8
-0
src/test/run-pass/new-box.rs
src/test/run-pass/new-box.rs
+41
-0
未找到文件。
src/librustc/middle/lang_items.rs
浏览文件 @
7c64f036
...
...
@@ -262,6 +262,7 @@ pub fn collect_language_items(krate: &ast::Crate,
ManagedHeapLangItem
,
"managed_heap"
,
managed_heap
;
ExchangeHeapLangItem
,
"exchange_heap"
,
exchange_heap
;
GcLangItem
,
"gc"
,
gc
;
OwnedBoxLangItem
,
"owned_box"
,
owned_box
;
CovariantTypeItem
,
"covariant_type"
,
covariant_type
;
ContravariantTypeItem
,
"contravariant_type"
,
contravariant_type
;
...
...
src/librustc/middle/typeck/astconv.rs
浏览文件 @
7c64f036
...
...
@@ -317,7 +317,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
match
ast_ty
.node
{
ast
::
TyPath
(
ref
path
,
_
,
id
)
=>
{
let
a_def
=
match
tcx
.def_map
.borrow
()
.find
(
&
id
)
{
None
=>
tcx
.sess
.span_
fatal
(
None
=>
tcx
.sess
.span_
bug
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
))),
Some
(
&
d
)
=>
d
};
...
...
@@ -366,95 +366,173 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
}
}
// Parses the programmer's textual representation of a type into our
// internal notion of a type.
pub
fn
ast_ty_to_ty
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ast_ty
:
&
ast
::
Ty
)
->
ty
::
t
{
enum
PointerTy
{
Box
,
RPtr
(
ty
::
Region
),
Uniq
/// Converts the given AST type to a built-in type. A "built-in type" is, at
/// present, either a core numeric type, a string, or `Box`.
pub
fn
ast_ty_to_builtin_ty
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ast_ty
:
&
ast
::
Ty
)
->
Option
<
ty
::
t
>
{
match
ast_ty_to_prim_ty
(
this
.tcx
(),
ast_ty
)
{
Some
(
typ
)
=>
return
Some
(
typ
),
None
=>
{}
}
fn
ast_ty_to_mt
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ty
:
&
ast
::
Ty
)
->
ty
::
mt
{
ty
::
mt
{
ty
:
ast_ty_to_ty
(
this
,
rscope
,
ty
),
mutbl
:
ast
::
MutImmutable
}
}
match
ast_ty
.node
{
ast
::
TyPath
(
ref
path
,
_
,
id
)
=>
{
let
a_def
=
match
this
.tcx
()
.def_map
.borrow
()
.find
(
&
id
)
{
None
=>
this
.tcx
()
.sess
.span_bug
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
))),
Some
(
&
d
)
=>
d
};
// Handle ~, and & being able to mean strs and vecs.
// If a_seq_ty is a str or a vec, make it a str/vec.
// Also handle first-class trait types.
fn
mk_pointer
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
a_seq_ty
:
&
ast
::
MutTy
,
ptr_ty
:
PointerTy
,
constr
:
|
ty
::
t
|
->
ty
::
t
)
->
ty
::
t
{
let
tcx
=
this
.tcx
();
debug!
(
"mk_pointer(ptr_ty={:?})"
,
ptr_ty
);
match
a_seq_ty
.ty.node
{
ast
::
TyVec
(
ty
)
=>
{
let
mut
mt
=
ast_ty_to_mt
(
this
,
rscope
,
ty
);
if
a_seq_ty
.mutbl
==
ast
::
MutMutable
{
mt
.mutbl
=
ast
::
MutMutable
;
}
return
constr
(
ty
::
mk_vec
(
tcx
,
mt
,
None
));
}
ast
::
TyPath
(
ref
path
,
ref
bounds
,
id
)
=>
{
// Note that the "bounds must be empty if path is not a trait"
// restriction is enforced in the below case for ty_path, which
// will run after this as long as the path isn't a trait.
match
tcx
.def_map
.borrow
()
.find
(
&
id
)
{
Some
(
&
ast
::
DefPrimTy
(
ast
::
TyStr
))
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
match
ptr_ty
{
Uniq
=>
{
return
ty
::
mk_uniq
(
tcx
,
ty
::
mk_str
(
tcx
));
}
RPtr
(
r
)
=>
{
return
ty
::
mk_str_slice
(
tcx
,
r
,
ast
::
MutImmutable
);
}
_
=>
tcx
.sess
.span_err
(
path
.span
,
format!
(
"managed strings are not supported"
)),
}
// FIXME(#12938): This is a hack until we have full support for
// DST.
match
a_def
{
ast
::
DefTy
(
did
)
|
ast
::
DefStruct
(
did
)
if
Some
(
did
)
==
this
.tcx
()
.lang_items
.owned_box
()
=>
{
if
path
.segments
.iter
()
.flat_map
(|
s
|
s
.types
.iter
())
.len
()
>
1
{
this
.tcx
()
.sess
.span_err
(
path
.span
,
"`Box` has only one type parameter"
)
}
Some
(
&
ast
::
DefTrait
(
trait_def_id
))
=>
{
let
result
=
ast_path_to_trait_ref
(
this
,
rscope
,
trait_def_id
,
None
,
path
);
let
trait_store
=
match
ptr_ty
{
Uniq
=>
ty
::
UniqTraitStore
,
RPtr
(
r
)
=>
{
ty
::
RegionTraitStore
(
r
,
a_seq_ty
.mutbl
)
}
_
=>
{
tcx
.sess
.span_err
(
path
.span
,
"~trait or &trait are the only supported
\
forms of casting-to-trait"
);
return
ty
::
mk_err
();
}
for
inner_ast_type
in
path
.segments
.iter
()
.flat_map
(|
s
|
s
.types
.iter
())
{
let
mt
=
ast
::
MutTy
{
ty
:
*
inner_ast_type
,
mutbl
:
ast
::
MutImmutable
,
};
let
bounds
=
conv_builtin_bounds
(
this
.tcx
(),
bounds
,
trait_store
);
return
ty
::
mk_trait
(
tcx
,
result
.def_id
,
result
.substs
.clone
(),
trait_store
,
bounds
);
return
Some
(
mk_pointer
(
this
,
rscope
,
&
mt
,
Uniq
,
|
typ
|
{
match
ty
::
get
(
typ
)
.sty
{
ty
::
ty_str
=>
{
this
.tcx
()
.sess
.span_err
(
path
.span
,
"`Box<str>` is not a type"
);
ty
::
mk_err
()
}
ty
::
ty_vec
(
_
,
None
)
=>
{
this
.tcx
()
.sess
.span_err
(
path
.span
,
"`Box<[T]>` is not a type"
);
ty
::
mk_err
()
}
_
=>
ty
::
mk_uniq
(
this
.tcx
(),
typ
),
}
}))
}
_
=>
{}
this
.tcx
()
.sess
.span_bug
(
path
.span
,
"not enough type parameters
\
supplied to `Box<T>`"
)
}
_
=>
None
}
_
=>
{}
}
_
=>
None
}
}
enum
PointerTy
{
Box
,
RPtr
(
ty
::
Region
),
Uniq
}
fn
ast_ty_to_mt
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ty
:
&
ast
::
Ty
)
->
ty
::
mt
{
ty
::
mt
{
ty
:
ast_ty_to_ty
(
this
,
rscope
,
ty
),
mutbl
:
ast
::
MutImmutable
}
}
// Handle `~`, `Box`, and `&` being able to mean strs and vecs.
// If a_seq_ty is a str or a vec, make it a str/vec.
// Also handle first-class trait types.
fn
mk_pointer
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
a_seq_ty
:
&
ast
::
MutTy
,
ptr_ty
:
PointerTy
,
constr
:
|
ty
::
t
|
->
ty
::
t
)
->
ty
::
t
{
let
tcx
=
this
.tcx
();
debug!
(
"mk_pointer(ptr_ty={:?})"
,
ptr_ty
);
constr
(
ast_ty_to_ty
(
this
,
rscope
,
a_seq_ty
.ty
))
match
a_seq_ty
.ty.node
{
ast
::
TyVec
(
ty
)
=>
{
let
mut
mt
=
ast_ty_to_mt
(
this
,
rscope
,
ty
);
if
a_seq_ty
.mutbl
==
ast
::
MutMutable
{
mt
.mutbl
=
ast
::
MutMutable
;
}
return
constr
(
ty
::
mk_vec
(
tcx
,
mt
,
None
));
}
ast
::
TyPath
(
ref
path
,
ref
bounds
,
id
)
=>
{
// Note that the "bounds must be empty if path is not a trait"
// restriction is enforced in the below case for ty_path, which
// will run after this as long as the path isn't a trait.
match
tcx
.def_map
.borrow
()
.find
(
&
id
)
{
Some
(
&
ast
::
DefPrimTy
(
ast
::
TyStr
))
=>
{
check_path_args
(
tcx
,
path
,
NO_TPS
|
NO_REGIONS
);
match
ptr_ty
{
Uniq
=>
{
return
constr
(
ty
::
mk_str
(
tcx
));
}
RPtr
(
r
)
=>
{
return
ty
::
mk_str_slice
(
tcx
,
r
,
ast
::
MutImmutable
);
}
_
=>
tcx
.sess
.span_err
(
path
.span
,
format!
(
"managed strings are not supported"
)),
}
}
Some
(
&
ast
::
DefTrait
(
trait_def_id
))
=>
{
let
result
=
ast_path_to_trait_ref
(
this
,
rscope
,
trait_def_id
,
None
,
path
);
let
trait_store
=
match
ptr_ty
{
Uniq
=>
ty
::
UniqTraitStore
,
RPtr
(
r
)
=>
{
ty
::
RegionTraitStore
(
r
,
a_seq_ty
.mutbl
)
}
_
=>
{
tcx
.sess
.span_err
(
path
.span
,
"~trait or &trait are the only supported
\
forms of casting-to-trait"
);
return
ty
::
mk_err
();
}
};
let
bounds
=
conv_builtin_bounds
(
this
.tcx
(),
bounds
,
trait_store
);
return
ty
::
mk_trait
(
tcx
,
result
.def_id
,
result
.substs
.clone
(),
trait_store
,
bounds
);
}
_
=>
{}
}
}
_
=>
{}
}
constr
(
ast_ty_to_ty
(
this
,
rscope
,
a_seq_ty
.ty
))
}
// Parses the programmer's textual representation of a type into our
// internal notion of a type.
pub
fn
ast_ty_to_ty
<
AC
:
AstConv
,
RS
:
RegionScope
>
(
this
:
&
AC
,
rscope
:
&
RS
,
ast_ty
:
&
ast
::
Ty
)
->
ty
::
t
{
let
tcx
=
this
.tcx
();
let
mut
ast_ty_to_ty_cache
=
tcx
.ast_ty_to_ty_cache
.borrow_mut
();
...
...
@@ -471,7 +549,8 @@ fn mk_pointer<AC:AstConv,
ast_ty_to_ty_cache
.insert
(
ast_ty
.id
,
ty
::
atttce_unresolved
);
drop
(
ast_ty_to_ty_cache
);
let
typ
=
ast_ty_to_prim_ty
(
tcx
,
ast_ty
)
.unwrap_or_else
(||
match
ast_ty
.node
{
let
typ
=
ast_ty_to_builtin_ty
(
this
,
rscope
,
ast_ty
)
.unwrap_or_else
(||
{
match
ast_ty
.node
{
ast
::
TyNil
=>
ty
::
mk_nil
(),
ast
::
TyBot
=>
ty
::
mk_bot
(),
ast
::
TyBox
(
ty
)
=>
{
...
...
@@ -555,7 +634,7 @@ fn mk_pointer<AC:AstConv,
}
ast
::
TyPath
(
ref
path
,
ref
bounds
,
id
)
=>
{
let
a_def
=
match
tcx
.def_map
.borrow
()
.find
(
&
id
)
{
None
=>
tcx
.sess
.span_
fatal
(
None
=>
tcx
.sess
.span_
bug
(
ast_ty
.span
,
format!
(
"unbound path {}"
,
path_to_str
(
path
))),
Some
(
&
d
)
=>
d
};
...
...
@@ -639,7 +718,8 @@ fn mk_pointer<AC:AstConv,
// and will not descend into this routine.
this
.ty_infer
(
ast_ty
.span
)
}
});
}
});
tcx
.ast_ty_to_ty_cache
.borrow_mut
()
.insert
(
ast_ty
.id
,
ty
::
atttce_resolved
(
typ
));
return
typ
;
...
...
src/libstd/owned.rs
浏览文件 @
7c64f036
...
...
@@ -26,6 +26,14 @@
#[cfg(test)]
pub
static
HEAP
:
()
=
();
/// A type that represents a uniquely-owned value.
#[lang=
"owned_box"
]
#[cfg(not(test))]
pub
struct
Box
<
T
>
(
*
T
);
#[cfg(test)]
pub
struct
Box
<
T
>
(
*
T
);
#[cfg(not(test))]
impl
<
T
:
Eq
>
Eq
for
~
T
{
#[inline]
...
...
src/test/run-pass/new-box.rs
0 → 100644
浏览文件 @
7c64f036
// Copyright 2012 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
::
owned
::
Box
;
fn
f
(
x
:
Box
<
int
>
)
{
let
y
:
&
int
=
x
;
println!
(
"{}"
,
*
x
);
println!
(
"{}"
,
*
y
);
}
trait
Trait
{
fn
printme
(
&
self
);
}
struct
Struct
;
impl
Trait
for
Struct
{
fn
printme
(
&
self
)
{
println!
(
"hello world!"
);
}
}
fn
g
(
x
:
Box
<
Trait
>
)
{
x
.printme
();
let
y
:
&
Trait
=
x
;
y
.printme
();
}
fn
main
()
{
f
(
box
1234
);
g
(
box
Struct
as
Box
<
Trait
>
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录