Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
98740a59
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,发现更多精彩内容 >>
提交
98740a59
编写于
5月 25, 2012
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
detect ambig. calls to iface bounds, use transactions
cc #2433
上级
93633ea7
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
96 addition
and
24 deletion
+96
-24
src/rustc/middle/typeck/check.rs
src/rustc/middle/typeck/check.rs
+4
-0
src/rustc/middle/typeck/check/method.rs
src/rustc/middle/typeck/check/method.rs
+39
-10
src/rustc/middle/typeck/infer.rs
src/rustc/middle/typeck/infer.rs
+27
-10
src/test/compile-fail/ambig_impl_1.rs
src/test/compile-fail/ambig_impl_1.rs
+2
-2
src/test/compile-fail/ambig_impl_2_exe.rs
src/test/compile-fail/ambig_impl_2_exe.rs
+2
-2
src/test/compile-fail/ambig_impl_bounds.rs
src/test/compile-fail/ambig_impl_bounds.rs
+10
-0
src/test/compile-fail/ambig_impl_unify.rs
src/test/compile-fail/ambig_impl_unify.rs
+12
-0
未找到文件。
src/rustc/middle/typeck/check.rs
浏览文件 @
98740a59
...
...
@@ -527,6 +527,10 @@ fn mk_subty(sub: ty::t, sup: ty::t) -> result<(), ty::type_err> {
infer
::
mk_subty
(
self
.infcx
,
sub
,
sup
)
}
fn
can_mk_subty
(
sub
:
ty
::
t
,
sup
:
ty
::
t
)
->
result
<
(),
ty
::
type_err
>
{
infer
::
can_mk_subty
(
self
.infcx
,
sub
,
sup
)
}
fn
mk_eqty
(
sub
:
ty
::
t
,
sup
:
ty
::
t
)
->
result
<
(),
ty
::
type_err
>
{
infer
::
mk_eqty
(
self
.infcx
,
sub
,
sup
)
}
...
...
src/rustc/middle/typeck/check/method.rs
浏览文件 @
98740a59
...
...
@@ -45,6 +45,7 @@ fn method_from_param(n: uint, did: ast::def_id) -> option<method_origin> {
let
tcx
=
self
.tcx
();
let
mut
iface_bnd_idx
=
0u
;
// count only iface bounds
let
bounds
=
tcx
.ty_param_bounds
.get
(
did
.node
);
let
mut
candidates
=
[];
for
vec
::
each
(
*
bounds
)
{|
bound
|
let
(
iid
,
bound_substs
)
=
alt
bound
{
ty
::
bound_copy
|
ty
::
bound_send
|
ty
::
bound_const
{
...
...
@@ -74,14 +75,33 @@ fn method_from_param(n: uint, did: ast::def_id) -> option<method_origin> {
// permitted).
let
substs
=
{
self_ty
:
some
(
self
.self_ty
)
with
bound_substs
};
ret
some
(
self
.write_mty_from_m
(
substs
,
ifce_methods
[
pos
],
method_param
(
iid
,
pos
,
n
,
iface_bnd_idx
)));
candidates
+=
[(
substs
,
ifce_methods
[
pos
],
iid
,
pos
,
n
,
iface_bnd_idx
)];
}
}
}
ret
none
;
if
candidates
.len
()
==
0u
{
ret
none
;
}
if
candidates
.len
()
>
1u
{
self
.tcx
()
.sess
.span_err
(
self
.expr.span
,
"multiple applicable methods in scope"
);
for
candidates
.eachi
{
|
i
,
candidate
|
let
(
_
,
_
,
iid
,
_
,
_
,
_
)
=
candidate
;
self
.tcx
()
.sess
.span_note
(
self
.expr.span
,
#
fmt
[
"candidate #%u derives from the bound `%s`"
,
(
i
+
1u
),
ty
::
item_path_str
(
self
.tcx
(),
iid
)]);
}
}
let
(
substs
,
mty
,
iid
,
pos
,
n
,
iface_bnd_idx
)
=
candidates
[
0u
];
ret
some
(
self
.write_mty_from_m
(
substs
,
mty
,
method_param
(
iid
,
pos
,
n
,
iface_bnd_idx
)));
}
fn
method_from_iface
(
...
...
@@ -197,10 +217,11 @@ fn method_from_scope() -> option<method_origin> {
// if we can assign the caller to the callee, that's a
// potential match. Collect those in the vector.
alt
self
.fcx
.mk_subty
(
ty
,
self_ty
)
{
alt
self
.fcx
.
can_
mk_subty
(
ty
,
self_ty
)
{
result
::
err
(
_
)
{
/* keep looking */
}
result
::
ok
(
_
)
{
results
+=
[(
self_substs
,
m
.n_tps
,
m
.did
)];
results
+=
[(
ty
,
self_ty
,
self_substs
,
m
.n_tps
,
m
.did
)];
}
}
}
...
...
@@ -216,7 +237,7 @@ fn method_from_scope() -> option<method_origin> {
// but I cannot for the life of me figure out how to
// annotate resolve to preserve this information.
for
results
.eachi
{
|
i
,
result
|
let
(
_
,
_
,
did
)
=
result
;
let
(
_
,
_
,
_
,
_
,
did
)
=
result
;
let
span
=
if
did
.crate
==
ast
::
local_crate
{
alt
check
self
.tcx
()
.items
.get
(
did
.node
)
{
ast_map
::
node_method
(
m
,
_
,
_
)
{
m
.span
}
...
...
@@ -226,13 +247,21 @@ fn method_from_scope() -> option<method_origin> {
};
self
.tcx
()
.sess
.span_note
(
span
,
#
fmt
[
"candidate #%u is
%s
"
,
#
fmt
[
"candidate #%u is
`%s`
"
,
(
i
+
1u
),
ty
::
item_path_str
(
self
.tcx
(),
did
)]);
}
}
let
(
self_substs
,
n_tps
,
did
)
=
results
[
0
];
let
(
ty
,
self_ty
,
self_substs
,
n_tps
,
did
)
=
results
[
0
];
alt
self
.fcx
.mk_subty
(
ty
,
self_ty
)
{
result
::
ok
(
_
)
{}
result
::
err
(
_
)
{
self
.tcx
()
.sess
.span_bug
(
self
.expr.span
,
"what was a subtype now is not?"
);
}
}
let
fty
=
self
.ty_from_did
(
did
);
ret
some
(
self
.write_mty_from_fty
(
self_substs
,
n_tps
,
fty
,
...
...
src/rustc/middle/typeck/infer.rs
浏览文件 @
98740a59
...
...
@@ -160,7 +160,7 @@ fn bar() {
export
infer_ctxt
;
export
new_infer_ctxt
;
export
mk_subty
;
export
mk_subty
,
can_mk_subty
;
export
mk_subr
;
export
mk_eqty
;
export
mk_assignty
;
...
...
@@ -235,6 +235,11 @@ fn mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
indent
{||
cx
.commit
{||
sub
(
cx
)
.tys
(
a
,
b
)
}
}
.to_ures
()
}
fn
can_mk_subty
(
cx
:
infer_ctxt
,
a
:
ty
::
t
,
b
:
ty
::
t
)
->
ures
{
#
debug
[
"can_mk_subty(%s <: %s)"
,
a
.to_str
(
cx
),
b
.to_str
(
cx
)];
indent
{||
cx
.probe
{||
sub
(
cx
)
.tys
(
a
,
b
)
}
}
.to_ures
()
}
fn
mk_subr
(
cx
:
infer_ctxt
,
a
:
ty
::
region
,
b
:
ty
::
region
)
->
ures
{
#
debug
[
"mk_subr(%s <: %s)"
,
a
.to_str
(
cx
),
b
.to_str
(
cx
)];
indent
{||
cx
.commit
{||
sub
(
cx
)
.regions
(
a
,
b
)
}
}
.to_ures
()
...
...
@@ -388,7 +393,17 @@ fn uok() -> ures {
ok
(())
}
fn
rollback_to
<
V
:
copy
vid
,
T
:
copy
>
(
vb
:
vals_and_bindings
<
V
,
T
>
,
len
:
uint
)
{
while
vb
.bindings
.len
()
!=
len
{
let
(
vid
,
old_v
)
=
vec
::
pop
(
vb
.bindings
);
vb
.vals
.insert
(
vid
.to_uint
(),
old_v
);
}
}
impl
transaction_methods
for
infer_ctxt
{
#[doc
=
"Execute `f` and commit the bindings if successful"
]
fn
commit
<
T
,
E
>
(
f
:
fn
()
->
result
<
T
,
E
>
)
->
result
<
T
,
E
>
{
assert
self
.vb.bindings
.len
()
==
0u
;
...
...
@@ -404,17 +419,9 @@ fn commit<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
ret
r
;
}
#[doc
=
"Execute `f`, unroll bindings on failure"
]
fn
try
<
T
,
E
>
(
f
:
fn
()
->
result
<
T
,
E
>
)
->
result
<
T
,
E
>
{
fn
rollback_to
<
V
:
copy
vid
,
T
:
copy
>
(
vb
:
vals_and_bindings
<
V
,
T
>
,
len
:
uint
)
{
while
vb
.bindings
.len
()
!=
len
{
let
(
vid
,
old_v
)
=
vec
::
pop
(
vb
.bindings
);
vb
.vals
.insert
(
vid
.to_uint
(),
old_v
);
}
}
let
vbl
=
self
.vb.bindings
.len
();
let
rbl
=
self
.rb.bindings
.len
();
#
debug
[
"try(vbl=%u, rbl=%u)"
,
vbl
,
rbl
];
...
...
@@ -429,6 +436,16 @@ fn rollback_to<V:copy vid, T:copy>(
}
ret
r
;
}
#[doc
=
"Execute `f` then unroll any bindings it creates"
]
fn
probe
<
T
,
E
>
(
f
:
fn
()
->
result
<
T
,
E
>
)
->
result
<
T
,
E
>
{
assert
self
.vb.bindings
.len
()
==
0u
;
assert
self
.rb.bindings
.len
()
==
0u
;
let
r
<-
f
();
rollback_to
(
self
.vb
,
0u
);
rollback_to
(
self
.rb
,
0u
);
ret
r
;
}
}
impl
methods
for
infer_ctxt
{
...
...
src/test/compile-fail/ambig_impl_1.rs
浏览文件 @
98740a59
impl
methods1
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #1 is
methods1::me
impl
methods2
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #2 is
methods2::me
impl
methods1
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #1 is
`methods1::me`
impl
methods2
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #2 is
`methods2::me`
fn
main
()
{
1u
.me
();
}
//! ERROR multiple applicable methods in scope
src/test/compile-fail/ambig_impl_2_exe.rs
浏览文件 @
98740a59
...
...
@@ -2,6 +2,6 @@
// aux-build:ambig_impl_2_lib.rs
use
ambig_impl_2_lib
;
import
ambig_impl_2_lib
::
methods1
;
impl
methods2
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #2 is
methods2::me
impl
methods2
for
uint
{
fn
me
()
->
uint
{
self
}
}
//! NOTE candidate #2 is
`methods2::me`
fn
main
()
{
1u
.me
();
}
//! ERROR multiple applicable methods in scope
//!^ NOTE candidate #1 is
ambig_impl_2_lib::methods1::me
//!^ NOTE candidate #1 is
`ambig_impl_2_lib::methods1::me`
src/test/compile-fail/ambig_impl_bounds.rs
0 → 100644
浏览文件 @
98740a59
iface
A
{
fn
foo
();
}
iface
B
{
fn
foo
();
}
fn
foo
<
T
:
A
B
>
(
t
:
T
)
{
t
.foo
();
//! ERROR multiple applicable methods in scope
//!^ NOTE candidate #1 derives from the bound `A`
//!^^ NOTE candidate #2 derives from the bound `B`
}
fn
main
()
{}
\ No newline at end of file
src/test/compile-fail/ambig_impl_unify.rs
0 → 100644
浏览文件 @
98740a59
impl
methods
for
[
uint
]
{
fn
foo
()
->
int
{
1
}
//! NOTE candidate #1 is `methods::foo`
}
impl
methods
for
[
int
]
{
fn
foo
()
->
int
{
2
}
//! NOTE candidate #2 is `methods::foo`
}
fn
main
()
{
let
x
=
[];
x
.foo
();
//! ERROR multiple applicable methods in scope
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录