Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
019d4291
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,发现更多精彩内容 >>
提交
019d4291
编写于
7月 10, 2012
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Introduce a coherence checker, behind a compile switch for now
上级
e430a699
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
237 addition
and
3 deletion
+237
-3
src/rustc/driver/session.rs
src/rustc/driver/session.rs
+3
-3
src/rustc/middle/typeck.rs
src/rustc/middle/typeck.rs
+5
-0
src/rustc/middle/typeck/coherence.rs
src/rustc/middle/typeck/coherence.rs
+228
-0
src/rustc/rustc.rc
src/rustc/rustc.rc
+1
-0
未找到文件。
src/rustc/driver/session.rs
浏览文件 @
019d4291
...
...
@@ -35,7 +35,7 @@ enum crate_type { bin_crate, lib_crate, unknown_crate, }
// FIXME (#2377): This exists to transition to a Rust crate runtime
// It should be removed
const
no_rt
:
uint
=
256u
;
const
fast_resolv
e
:
uint
=
512u
;
const
coherenc
e
:
uint
=
512u
;
fn
debugging_opts_map
()
->
~
[(
str
,
str
,
uint
)]
{
~
[(
"ppregions"
,
"prettyprint regions with
\
...
...
@@ -49,7 +49,7 @@ fn debugging_opts_map() -> ~[(str, str, uint)] {
(
"no-verify"
,
"skip LLVM verification"
,
no_verify
),
(
"trace"
,
"emit trace logs"
,
trace
),
(
"no-rt"
,
"do not link to the runtime"
,
no_rt
),
(
"
fast-resolve"
,
"use fast name resolution"
,
fast_resolv
e
)
(
"
coherence"
,
"perform coherence checking"
,
coherenc
e
)
]
}
...
...
@@ -164,7 +164,7 @@ fn stats() -> bool { self.debugging_opt(stats) }
fn
no_asm_comments
()
->
bool
{
self
.debugging_opt
(
no_asm_comments
)
}
fn
no_verify
()
->
bool
{
self
.debugging_opt
(
no_verify
)
}
fn
trace
()
->
bool
{
self
.debugging_opt
(
trace
)
}
fn
fast_resolve
()
->
bool
{
self
.debugging_opt
(
fast_resolv
e
)
}
fn
coherence
()
->
bool
{
self
.debugging_opt
(
coherenc
e
)
}
}
/// Some reasonable defaults
...
...
src/rustc/middle/typeck.rs
浏览文件 @
019d4291
...
...
@@ -291,6 +291,11 @@ fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
vtable_map
:
std
::
map
::
int_hash
(),
tcx
:
tcx
};
collect
::
collect_item_types
(
ccx
,
crate
);
if
tcx
.sess
.coherence
()
{
coherence
::
check_coherence
(
ccx
,
crate
);
}
check
::
check_item_types
(
ccx
,
crate
);
check_for_main_fn
(
ccx
);
tcx
.sess
.abort_if_errors
();
...
...
src/rustc/middle/typeck/coherence.rs
0 → 100644
浏览文件 @
019d4291
// Coherence phase
//
// The job of the coherence phase of typechecking is to ensure that each trait
// has at most one implementation for each type. Then we build a mapping from
// each trait in the system to its implementations.
import
middle
::
ty
::{
get
,
t
,
ty_box
,
ty_uniq
,
ty_ptr
,
ty_rptr
,
ty_enum
};
import
middle
::
ty
::{
ty_class
,
ty_nil
,
ty_bot
,
ty_bool
,
ty_int
,
ty_uint
};
import
middle
::
ty
::{
ty_float
,
ty_str
,
ty_estr
,
ty_vec
,
ty_evec
,
ty_rec
};
import
middle
::
ty
::{
ty_fn
,
ty_trait
,
ty_tup
,
ty_var
,
ty_var_integral
};
import
middle
::
ty
::{
ty_param
,
ty_self
,
ty_constr
,
ty_type
,
ty_opaque_box
};
import
middle
::
ty
::{
ty_opaque_closure_ptr
,
ty_unboxed_vec
,
new_ty_hash
};
import
middle
::
ty
::{
subst
};
import
middle
::
typeck
::
infer
::{
infer_ctxt
,
mk_eqty
,
new_infer_ctxt
};
import
syntax
::
ast
::{
crate
,
def_id
,
item
,
item_impl
,
method
,
region_param
};
import
syntax
::
ast
::{
trait_ref
};
import
syntax
::
ast_util
::{
def_id_of_def
,
new_def_hash
};
import
syntax
::
visit
::{
default_simple_visitor
,
mk_simple_visitor
};
import
syntax
::
visit
::{
visit_crate
};
import
dvec
::{
dvec
,
extensions
};
import
result
::{
extensions
};
import
std
::
map
::
hashmap
;
import
uint
::
range
;
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
<
t
,
@
dvec
<@
item
>>
;
// Contains implementations of methods associated with a trait. For these,
// the associated trait must be imported at the call site.
let
extension_methods
:
hashmap
<
def_id
,
@
dvec
<@
item
>>
;
new
()
{
self
.inherent_methods
=
new_ty_hash
();
self
.extension_methods
=
new_def_hash
();
}
}
class
CoherenceChecker
{
let
crate_context
:
@
crate_ctxt
;
let
inference_context
:
infer_ctxt
;
let
info
:
@
CoherenceInfo
;
new
(
crate_context
:
@
crate_ctxt
)
{
self
.crate_context
=
crate_context
;
self
.inference_context
=
new_infer_ctxt
(
crate_context
.tcx
);
self
.info
=
@
CoherenceInfo
();
}
fn
check_coherence
(
crate
:
@
crate
)
{
// Check implementations. This populates the tables containing the
// inherent methods and extension methods.
visit_crate
(
*
crate
,
(),
mk_simple_visitor
(
@
{
visit_item
:
|
item
|
{
alt
item
.node
{
item_impl
(
_
,
_
,
associated_trait
,
self_type
,
_
)
{
self
.check_implementation
(
item
,
associated_trait
);
}
_
{
// Nothing to do.
}
};
}
with
*
default_simple_visitor
()
}));
// Check trait coherence.
for
self
.info.extension_methods.each
|
def_id
,
items
|
{
self
.check_implementation_coherence
(
def_id
,
items
);
}
}
fn
check_implementation
(
item
:
@
item
,
optional_associated_trait
:
option
<@
trait_ref
>
)
{
let
self_type
=
self
.crate_context.tcx.tcache
.get
(
local_def
(
item
.id
));
alt
optional_associated_trait
{
none
{
alt
self
.get_base_type
(
self_type
.ty
)
{
none
{
let
session
=
self
.crate_context.tcx.sess
;
session
.span_warn
(
item
.span
,
"no base type found for inherent
\
implementation; implement a trait
\
instead"
);
}
some
(
base_type
)
{
let
implementation_list
;
alt
self
.info.inherent_methods
.find
(
base_type
)
{
none
{
implementation_list
=
@
dvec
();
}
some
(
existing_implementation_list
)
{
implementation_list
=
existing_implementation_list
;
}
}
implementation_list
.push
(
item
);
}
}
}
some
(
associated_trait
)
{
let
def
=
self
.crate_context.tcx.def_map
.get
(
associated_trait
.id
);
let
def_id
=
def_id_of_def
(
def
);
let
implementation_list
;
alt
self
.info.extension_methods
.find
(
def_id
)
{
none
{
implementation_list
=
@
dvec
();
}
some
(
existing_implementation_list
)
{
implementation_list
=
existing_implementation_list
;
}
}
implementation_list
.push
(
item
);
}
}
}
fn
get_base_type
(
original_type
:
t
)
->
option
<
t
>
{
alt
get
(
original_type
)
.struct
{
ty_box
(
base_mutability_and_type
)
|
ty_uniq
(
base_mutability_and_type
)
|
ty_ptr
(
base_mutability_and_type
)
|
ty_rptr
(
_
,
base_mutability_and_type
)
{
self
.get_base_type
(
base_mutability_and_type
.ty
)
}
ty_enum
(
*
)
|
ty_class
(
*
)
{
some
(
original_type
)
}
ty_nil
|
ty_bot
|
ty_bool
|
ty_int
(
*
)
|
ty_uint
(
*
)
|
ty_float
(
*
)
|
ty_str
|
ty_estr
(
*
)
|
ty_vec
(
*
)
|
ty_evec
(
*
)
|
ty_rec
(
*
)
|
ty_fn
(
*
)
|
ty_trait
(
*
)
|
ty_tup
(
*
)
|
ty_var
(
*
)
|
ty_var_integral
(
*
)
|
ty_param
(
*
)
|
ty_self
|
ty_constr
(
*
)
|
ty_type
|
ty_opaque_box
|
ty_opaque_closure_ptr
(
*
)
|
ty_unboxed_vec
(
*
)
{
none
}
}
}
fn
check_implementation_coherence
(
_
trait_def_id
:
def_id
,
implementations
:
@
dvec
<@
item
>
)
{
// Unify pairs of polytypes.
for
implementations
.eachi
|
i
,
implementation_a
|
{
let
polytype_a
=
self
.get_self_type_for_implementation
(
implementation_a
);
for
range
(
i
+
1
,
implementations
.len
())
|
j
|
{
let
implementation_b
=
implementations
.get_elt
(
j
);
let
polytype_b
=
self
.get_self_type_for_implementation
(
implementation_b
);
if
self
.polytypes_unify
(
polytype_a
,
polytype_b
)
{
let
session
=
self
.crate_context.tcx.sess
;
session
.span_err
(
implementation_b
.span
,
"conflicting implementations for a
\
trait"
);
session
.span_note
(
implementation_a
.span
,
"note conflicting implementation here"
);
}
}
}
}
fn
polytypes_unify
(
polytype_a
:
ty_param_bounds_and_ty
,
polytype_b
:
ty_param_bounds_and_ty
)
->
bool
{
let
monotype_a
=
self
.universally_quantify_polytype
(
polytype_a
);
let
monotype_b
=
self
.universally_quantify_polytype
(
polytype_b
);
ret
mk_eqty
(
self
.inference_context
,
monotype_a
,
monotype_b
)
.is_ok
();
}
// 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
;
alt
polytype
.rp
{
ast
::
rp_none
{
self_region
=
none
;
}
ast
::
rp_self
{
self_region
=
some
(
self
.inference_context
.next_region_var
())
}
};
let
bounds_count
=
polytype
.bounds
.len
();
let
type_parameters
=
self
.inference_context
.next_ty_vars
(
bounds_count
);
let
substitutions
=
{
self_r
:
self_region
,
self_ty
:
none
,
tps
:
type_parameters
};
ret
subst
(
self
.crate_context.tcx
,
substitutions
,
polytype
.ty
);
}
fn
get_self_type_for_implementation
(
implementation
:
@
item
)
->
ty_param_bounds_and_ty
{
alt
implementation
.node
{
item_impl
(
*
)
{
let
def
=
local_def
(
implementation
.id
);
ret
self
.crate_context.tcx.tcache
.get
(
def
);
}
_
{
self
.crate_context.tcx.sess
.span_bug
(
implementation
.span
,
"not an implementation"
);
}
}
}
}
fn
check_coherence
(
crate_context
:
@
crate_ctxt
,
crate
:
@
crate
)
{
CoherenceChecker
(
crate_context
)
.check_coherence
(
crate
);
}
src/rustc/rustc.rc
浏览文件 @
019d4291
...
...
@@ -67,6 +67,7 @@ mod middle {
mod
astconv
;
mod
infer
;
mod
collect
;
mod
coherence
;
}
mod
check_loop
;
mod
check_alt
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录