Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
635a9593
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,发现更多精彩内容 >>
提交
635a9593
编写于
7月 18, 2012
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Make coherence aware of multiple-traits-per-impl
上级
5506bf14
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
80 addition
and
97 deletion
+80
-97
src/rustc/middle/typeck/coherence.rs
src/rustc/middle/typeck/coherence.rs
+80
-97
未找到文件。
src/rustc/middle/typeck/coherence.rs
浏览文件 @
635a9593
...
...
@@ -111,6 +111,7 @@ fn get_base_type_def_id(inference_context: infer_ctxt,
class
CoherenceInfo
{
// Contains implementations of methods that are inherent to a type.
// Methods in these implementations don't need to be exported.
let
inherent_methods
:
hashmap
<
def_id
,
@
dvec
<@
Impl
>>
;
// Contains implementations of methods associated with a trait. For these,
...
...
@@ -129,14 +130,17 @@ fn get_base_type_def_id(inference_context: infer_ctxt,
// A mapping from implementations to the corresponding base type
// definition ID.
let
base_type_def_ids
:
hashmap
<
def_id
,
def_id
>
;
// A set of implementations in privileged scopes; i.e. those
// implementations that are defined in the same scope as their base types.
let
privileged_implementations
:
hashmap
<
node_id
,()
>
;
// The set of types that we are currently in the privileged scope of. This
// is used while we traverse the AST while checking privileged scopes.
let
privileged_types
:
hashmap
<
def_id
,()
>
;
new
(
crate_context
:
@
crate_ctxt
)
{
...
...
@@ -158,17 +162,7 @@ fn check_coherence(crate: @crate) {
alt
item
.node
{
item_impl
(
_
,
associated_traits
,
self_type
,
_
)
{
// XXX: Accept an array of traits.
let
optional_associated_trait
;
if
associated_traits
.len
()
==
0
{
optional_associated_trait
=
none
;
}
else
{
optional_associated_trait
=
some
(
associated_traits
[
0
]);
}
self
.check_implementation
(
item
,
optional_associated_trait
);
self
.check_implementation
(
item
,
associated_traits
);
}
_
{
// Nothing to do.
...
...
@@ -195,47 +189,49 @@ fn check_coherence(crate: @crate) {
self
.add_external_crates
();
}
fn
check_implementation
(
item
:
@
item
,
optional_associated_trait
:
option
<@
trait_ref
>
)
{
fn
check_implementation
(
item
:
@
item
,
associated_traits
:
~
[
@
trait_ref
])
{
let
self_type
=
self
.crate_context.tcx.tcache
.get
(
local_def
(
item
.id
));
alt
optional_associated_trait
{
none
{
#
debug
(
"(checking implementation) no associated trait for
\
item '%s'"
,
*
item
.ident
);
alt
get_base_type_def_id
(
self
.inference_context
,
item
.span
,
self_type
.ty
)
{
none
{
let
session
=
self
.crate_context.tcx.sess
;
session
.span_err
(
item
.span
,
~
"no base type found for inherent
\
implementation; implement a
\
trait instead"
);
}
some
(
_
)
{
// Nothing to do.
}
// If there are no traits, then this implementation must have a
// base type.
if
associated_traits
.len
()
==
0
{
#
debug
(
"(checking implementation) no associated traits for item
\
'%s'"
,
*
item
.ident
);
alt
get_base_type_def_id
(
self
.inference_context
,
item
.span
,
self_type
.ty
)
{
none
{
let
session
=
self
.crate_context.tcx.sess
;
session
.span_err
(
item
.span
,
~
"no base type found for inherent
\
implementation; implement a
\
trait instead"
);
}
some
(
_
)
{
// Nothing to do.
}
}
some
(
associated_trait
)
{
let
def
=
self
.crate_context.tcx.def_map
.get
(
associated_trait
.ref_id
);
#
debug
(
"(checking implementation) adding impl for trait
\
'%s', item '%s'"
,
ast_map
::
node_id_to_str
(
self
.crate_context.tcx.items
,
associated_trait
.ref_id
),
*
item
.ident
);
}
let
implementation
=
self
.create_impl_from_item
(
item
);
self
.add_trait_method
(
def_id_of_def
(
def
),
implementation
);
}
for
associated_traits
.each
|
associated_trait
|
{
let
def
=
self
.crate_context.tcx.def_map
.get
(
associated_trait
.ref_id
);
#
debug
(
"(checking implementation) adding impl for trait
\
'%s', item '%s'"
,
ast_map
::
node_id_to_str
(
self
.crate_context.tcx.items
,
associated_trait
.ref_id
),
*
item
.ident
);
let
implementation
=
self
.create_impl_from_item
(
item
);
self
.add_trait_method
(
def_id_of_def
(
def
),
implementation
);
}
// Add the implementation to the mapping from implementation to base
// type def ID, if there is a base type for this implementation.
alt
get_base_type_def_id
(
self
.inference_context
,
item
.span
,
self_type
.ty
)
{
...
...
@@ -326,6 +322,7 @@ fn polytypes_unify(polytype_a: ty_param_bounds_and_ty,
// Converts a polytype to a monotype by replacing all parameters with
// type variables.
fn
universally_quantify_polytype
(
polytype
:
ty_param_bounds_and_ty
)
->
t
{
let
self_region
=
if
!
polytype
.rp
{
none
}
...
...
@@ -385,14 +382,6 @@ fn check_privileged_scopes(crate: @crate) {
}
}
item_impl
(
_
,
associated_traits
,
_
,
_
)
{
// XXX: Accept an array of traits.
let
optional_trait_ref
;
if
associated_traits
.len
()
==
0
{
optional_trait_ref
=
none
;
}
else
{
optional_trait_ref
=
some
(
associated_traits
[
0
]);
}
alt
self
.base_type_def_ids
.find
(
local_def
(
item
.id
))
{
none
{
// Nothing to do.
...
...
@@ -411,56 +400,50 @@ fn check_privileged_scopes(crate: @crate) {
}
else
{
// This implementation is not in scope of
// its base type. This still might be OK
// if the trait
is
defined in the same
// if the trait
s are
defined in the same
// crate.
alt
optional_trait_ref
{
none
{
// There is no trait to implement,
// so this is an error.
if
associated_traits
.len
()
==
0
{
// There is no trait to implement, so
// this is an error.
let
session
=
self
.crate_context.tcx.sess
;
session
.span_err
(
item
.span
,
~
"cannot implement
\
inherent methods
\
for a type outside
\
the scope the type
\
was defined in;
\
define and
\
implement a trait
\
instead"
);
}
let
session
=
self
.crate_context.tcx.sess
;
for
associated_traits
.each
|
trait_ref
|
{
// This is OK if and only if the
// trait was defined in this
// crate.
let
def_map
=
self
.crate_context.tcx
.def_map
;
let
trait_def
=
def_map
.get
(
trait_ref
.ref_id
);
let
trait_id
=
def_id_of_def
(
trait_def
);
if
trait_id
.crate
!=
local_crate
{
let
session
=
self
.crate_context
.tcx.sess
;
session
.span_err
(
item
.span
,
~
"cannot
\
implement
\
inherent
\
methods for a
\
type outside
\
the scope the
\
type was
\
defined in;
\
define and
\
implement a
\
trait instead"
);
}
some
(
trait_ref
)
{
// This is OK if and only if the
// trait was defined in this
// crate.
let
def_map
=
self
.crate_context
.tcx.def_map
;
let
trait_def
=
def_map
.get
(
trait_ref
.ref_id
);
let
trait_id
=
def_id_of_def
(
trait_def
);
if
trait_id
.crate
!=
local_crate
{
let
session
=
self
.crate_context.tcx.sess
;
session
.span_err
(
item
.span
,
~
"cannot
\
provide
\
an
\
extension
\
implementa
\
tion
\
for a
\
trait not
\
defined
\
in this
\
crate"
);
}
provide an
\
extension
\
implementa
\
tion
\
for a trait
\
not defined
\
in this
\
crate"
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录