Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ae076e1e
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,发现更多精彩内容 >>
提交
ae076e1e
编写于
1月 29, 2015
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement deref coercions (rust-lang/rfcs#241).
上级
b48c4c8c
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
261 addition
and
60 deletion
+261
-60
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/callee.rs
+2
-0
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+60
-20
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+27
-13
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/probe.rs
+14
-11
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+49
-11
src/test/compile-fail/coerce-overloaded-autoderef.rs
src/test/compile-fail/coerce-overloaded-autoderef.rs
+40
-0
src/test/compile-fail/method-self-arg-1.rs
src/test/compile-fail/method-self-arg-1.rs
+0
-5
src/test/run-pass/coerce-overloaded-autoderef.rs
src/test/run-pass/coerce-overloaded-autoderef.rs
+69
-0
未找到文件。
src/librustc_typeck/check/callee.rs
浏览文件 @
ae076e1e
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
use
super
::
method
;
use
super
::
method
;
use
super
::
structurally_resolved_type
;
use
super
::
structurally_resolved_type
;
use
super
::
TupleArgumentsFlag
;
use
super
::
TupleArgumentsFlag
;
use
super
::
UnresolvedTypeAction
;
use
super
::
write_call
;
use
super
::
write_call
;
use
middle
::
infer
;
use
middle
::
infer
;
...
@@ -77,6 +78,7 @@ pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -77,6 +78,7 @@ pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
callee_expr
.span
,
callee_expr
.span
,
original_callee_ty
,
original_callee_ty
,
Some
(
callee_expr
),
Some
(
callee_expr
),
UnresolvedTypeAction
::
Error
,
LvaluePreference
::
NoPreference
,
LvaluePreference
::
NoPreference
,
|
adj_ty
,
idx
|
{
|
adj_ty
,
idx
|
{
let
autoderefref
=
ty
::
AutoDerefRef
{
autoderefs
:
idx
,
autoref
:
None
};
let
autoderefref
=
ty
::
AutoDerefRef
{
autoderefs
:
idx
,
autoref
:
None
};
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
ae076e1e
...
@@ -60,7 +60,7 @@
...
@@ -60,7 +60,7 @@
//! sort of a minor point so I've opted to leave it for later---after all
//! sort of a minor point so I've opted to leave it for later---after all
//! we may want to adjust precisely when coercions occur.
//! we may want to adjust precisely when coercions occur.
use
check
::
FnCtxt
;
use
check
::
{
autoderef
,
FnCtxt
,
NoPreference
,
PreferMutLvalue
,
UnresolvedTypeAction
}
;
use
middle
::
infer
::{
self
,
cres
,
Coercion
,
TypeTrace
};
use
middle
::
infer
::{
self
,
cres
,
Coercion
,
TypeTrace
};
use
middle
::
infer
::
combine
::
Combine
;
use
middle
::
infer
::
combine
::
Combine
;
...
@@ -98,7 +98,11 @@ fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
...
@@ -98,7 +98,11 @@ fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
f
(
self
.fcx
.infcx
()
.shallow_resolve
(
a
))
f
(
self
.fcx
.infcx
()
.shallow_resolve
(
a
))
}
}
fn
coerce
(
&
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CoerceResult
<
'tcx
>
{
fn
coerce
(
&
self
,
expr_a
:
&
ast
::
Expr
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CoerceResult
<
'tcx
>
{
debug!
(
"Coerce.tys({} => {})"
,
debug!
(
"Coerce.tys({} => {})"
,
a
.repr
(
self
.tcx
()),
a
.repr
(
self
.tcx
()),
b
.repr
(
self
.tcx
()));
b
.repr
(
self
.tcx
()));
...
@@ -124,7 +128,7 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
...
@@ -124,7 +128,7 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
ty
::
ty_rptr
(
_
,
mt_b
)
=>
{
ty
::
ty_rptr
(
_
,
mt_b
)
=>
{
return
self
.unpack_actual_value
(
a
,
|
a
|
{
return
self
.unpack_actual_value
(
a
,
|
a
|
{
self
.coerce_borrowed_pointer
(
a
,
b
,
mt_b
.mutbl
)
self
.coerce_borrowed_pointer
(
expr_a
,
a
,
b
,
mt_b
.mutbl
)
});
});
}
}
...
@@ -147,8 +151,11 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
...
@@ -147,8 +151,11 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
})
})
}
}
// ~T -> &T or &mut T -> &T (including where T = [U] or str)
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
/// To match `A` with `B`, autoderef will be performed,
/// calling `deref`/`deref_mut` where necessary.
fn
coerce_borrowed_pointer
(
&
self
,
fn
coerce_borrowed_pointer
(
&
self
,
expr_a
:
&
ast
::
Expr
,
a
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
mutbl_b
:
ast
::
Mutability
)
mutbl_b
:
ast
::
Mutability
)
...
@@ -163,29 +170,62 @@ fn coerce_borrowed_pointer(&self,
...
@@ -163,29 +170,62 @@ fn coerce_borrowed_pointer(&self,
// to type check, we will construct the type that `&M*expr` would
// to type check, we will construct the type that `&M*expr` would
// yield.
// yield.
let
coercion
=
Coercion
(
self
.trace
.clone
());
match
a
.sty
{
let
r_borrow
=
self
.fcx
.infcx
()
.next_region_var
(
coercion
);
let
inner_ty
=
match
a
.sty
{
ty
::
ty_rptr
(
_
,
mt_a
)
=>
{
ty
::
ty_rptr
(
_
,
mt_a
)
=>
{
if
!
can_coerce_mutbls
(
mt_a
.mutbl
,
mutbl_b
)
{
if
!
can_coerce_mutbls
(
mt_a
.mutbl
,
mutbl_b
)
{
return
Err
(
ty
::
terr_mutability
);
return
Err
(
ty
::
terr_mutability
);
}
}
mt_a
.ty
}
}
_
=>
return
self
.subtype
(
a
,
b
)
_
=>
return
self
.subtype
(
a
,
b
)
}
;
}
let
a_borrowed
=
ty
::
mk_rptr
(
self
.tcx
(),
let
coercion
=
Coercion
(
self
.trace
.clone
());
self
.tcx
()
.mk_region
(
r_borrow
),
let
r_borrow
=
self
.fcx
.infcx
()
.next_region_var
(
coercion
);
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl_b
});
let
autoref
=
Some
(
AutoPtr
(
r_borrow
,
mutbl_b
,
None
));
try!
(
self
.subtype
(
a_borrowed
,
b
));
if
let
Err
(
original_err
)
=
self
.subtype
(
a_borrowed
,
b
)
{
Ok
(
Some
(
AdjustDerefRef
(
AutoDerefRef
{
let
r_borrow
=
self
.tcx
()
.mk_region
(
r_borrow
);
autoderefs
:
1
,
let
lvalue_pref
=
match
mutbl_b
{
autoref
:
Some
(
AutoPtr
(
r_borrow
,
mutbl_b
,
None
))
ast
::
MutMutable
=>
PreferMutLvalue
,
})))
ast
::
MutImmutable
=>
NoPreference
};
let
mut
first_error
=
None
;
let
(
_
,
autoderefs
,
success
)
=
autoderef
(
self
.fcx
,
expr_a
.span
,
a
,
Some
(
expr_a
),
UnresolvedTypeAction
::
Ignore
,
lvalue_pref
,
|
inner_ty
,
autoderef
|
{
if
autoderef
==
0
{
// Don't let this pass, otherwise it would cause
// &T to autoref to &&T.
return
None
;
}
let
ty
=
ty
::
mk_rptr
(
self
.tcx
(),
r_borrow
,
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl_b
});
if
let
Err
(
err
)
=
self
.fcx
.infcx
()
.try
(|
_
|
self
.subtype
(
ty
,
b
))
{
if
first_error
.is_none
()
{
first_error
=
Some
(
err
);
}
None
}
else
{
Some
(())
}
});
match
success
{
Some
(
_
)
=>
{
Ok
(
Some
(
AdjustDerefRef
(
AutoDerefRef
{
autoderefs
:
autoderefs
,
autoref
:
autoref
})))
}
None
=>
{
// Return original error as if overloaded deref was never
// attempted, to avoid irrelevant/confusing error messages.
Err
(
first_error
.expect
(
"coerce_borrowed_pointer failed with no error?"
))
}
}
}
}
...
@@ -426,7 +466,7 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -426,7 +466,7 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
Coerce
{
Coerce
{
fcx
:
fcx
,
fcx
:
fcx
,
trace
:
infer
::
TypeTrace
::
types
(
origin
,
false
,
a
,
b
)
trace
:
infer
::
TypeTrace
::
types
(
origin
,
false
,
a
,
b
)
}
.coerce
(
a
,
b
)
}
.coerce
(
expr
,
a
,
b
)
})
})
}));
}));
if
let
Some
(
adjustment
)
=
adjustment
{
if
let
Some
(
adjustment
)
=
adjustment
{
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
ae076e1e
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
use
super
::
probe
;
use
super
::
probe
;
use
check
::{
self
,
FnCtxt
,
NoPreference
,
PreferMutLvalue
,
callee
,
demand
};
use
check
::{
self
,
FnCtxt
,
NoPreference
,
PreferMutLvalue
,
callee
,
demand
};
use
check
::
UnresolvedTypeAction
;
use
middle
::
mem_categorization
::
Typer
;
use
middle
::
mem_categorization
::
Typer
;
use
middle
::
subst
::{
self
};
use
middle
::
subst
::{
self
};
use
middle
::
traits
;
use
middle
::
traits
;
...
@@ -141,10 +142,19 @@ fn adjust_self_ty(&mut self,
...
@@ -141,10 +142,19 @@ fn adjust_self_ty(&mut self,
// Commit the autoderefs by calling `autoderef again, but this
// Commit the autoderefs by calling `autoderef again, but this
// time writing the results into the various tables.
// time writing the results into the various tables.
let
(
autoderefd_ty
,
n
,
result
)
=
let
(
autoderefd_ty
,
n
,
result
)
=
check
::
autoderef
(
self
.fcx
,
check
::
autoderef
(
self
.span
,
self
.fcx
,
self
.span
,
unadjusted_self_ty
,
Some
(
self
.self_expr
),
NoPreference
,
unadjusted_self_ty
,
|
_
,
n
|
if
n
==
auto_deref_ref
.autoderefs
{
Some
(())
}
else
{
None
});
Some
(
self
.self_expr
),
UnresolvedTypeAction
::
Error
,
NoPreference
,
|
_
,
n
|
{
if
n
==
auto_deref_ref
.autoderefs
{
Some
(())
}
else
{
None
}
});
assert_eq!
(
n
,
auto_deref_ref
.autoderefs
);
assert_eq!
(
n
,
auto_deref_ref
.autoderefs
);
assert_eq!
(
result
,
Some
(()));
assert_eq!
(
result
,
Some
(()));
...
@@ -302,15 +312,18 @@ fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R wh
...
@@ -302,15 +312,18 @@ fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R wh
// yield an object-type (e.g., `&Object` or `Box<Object>`
// yield an object-type (e.g., `&Object` or `Box<Object>`
// etc).
// etc).
let
(
_
,
_
,
result
)
=
let
(
_
,
_
,
result
)
=
check
::
autoderef
(
self
.fcx
,
check
::
autoderef
(
self
.span
,
self
.fcx
,
self
.span
,
self_ty
,
None
,
NoPreference
,
self_ty
,
|
ty
,
_
|
{
None
,
match
ty
.sty
{
UnresolvedTypeAction
::
Error
,
ty
::
ty_trait
(
ref
data
)
=>
Some
(
closure
(
self
,
ty
,
&**
data
)),
NoPreference
,
_
=>
None
,
|
ty
,
_
|
{
}
match
ty
.sty
{
});
ty
::
ty_trait
(
ref
data
)
=>
Some
(
closure
(
self
,
ty
,
&**
data
)),
_
=>
None
,
}
});
match
result
{
match
result
{
Some
(
r
)
=>
r
,
Some
(
r
)
=>
r
,
...
@@ -517,6 +530,7 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
...
@@ -517,6 +530,7 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
expr
.span
,
expr
.span
,
self
.fcx
.expr_ty
(
expr
),
self
.fcx
.expr_ty
(
expr
),
Some
(
expr
),
Some
(
expr
),
UnresolvedTypeAction
::
Error
,
PreferMutLvalue
,
PreferMutLvalue
,
|
_
,
autoderefs
|
{
|
_
,
autoderefs
|
{
if
autoderefs
==
autoderef_count
+
1
{
if
autoderefs
==
autoderef_count
+
1
{
...
...
src/librustc_typeck/check/method/probe.rs
浏览文件 @
ae076e1e
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
use
super
::
suggest
;
use
super
::
suggest
;
use
check
;
use
check
;
use
check
::{
FnCtxt
,
NoPreference
};
use
check
::{
FnCtxt
,
NoPreference
,
UnresolvedTypeAction
};
use
middle
::
fast_reject
;
use
middle
::
fast_reject
;
use
middle
::
subst
;
use
middle
::
subst
;
use
middle
::
subst
::
Subst
;
use
middle
::
subst
::
Subst
;
...
@@ -169,16 +169,19 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -169,16 +169,19 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
->
Option
<
Vec
<
CandidateStep
<
'tcx
>>>
{
->
Option
<
Vec
<
CandidateStep
<
'tcx
>>>
{
let
mut
steps
=
Vec
::
new
();
let
mut
steps
=
Vec
::
new
();
let
(
fully_dereferenced_ty
,
dereferences
,
_
)
=
let
(
final_ty
,
dereferences
,
_
)
=
check
::
autoderef
(
fcx
,
check
::
autoderef
(
span
,
fcx
,
span
,
self_ty
,
None
,
NoPreference
,
self_ty
,
|
t
,
d
|
{
None
,
let
adjustment
=
AutoDeref
(
d
);
UnresolvedTypeAction
::
Error
,
steps
.push
(
CandidateStep
{
self_ty
:
t
,
adjustment
:
adjustment
});
NoPreference
,
None
::
<
()
>
// keep iterating until we can't anymore
|
t
,
d
|
{
});
let
adjustment
=
AutoDeref
(
d
);
steps
.push
(
CandidateStep
{
self_ty
:
t
,
adjustment
:
adjustment
});
match
fully_dereferenced_ty
.sty
{
None
::
<
()
>
// keep iterating until we can't anymore
});
match
final_ty
.sty
{
ty
::
ty_vec
(
elem_ty
,
Some
(
len
))
=>
{
ty
::
ty_vec
(
elem_ty
,
Some
(
len
))
=>
{
steps
.push
(
CandidateStep
{
steps
.push
(
CandidateStep
{
self_ty
:
ty
::
mk_vec
(
fcx
.tcx
(),
elem_ty
,
None
),
self_ty
:
ty
::
mk_vec
(
fcx
.tcx
(),
elem_ty
,
None
),
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
ae076e1e
...
@@ -1865,6 +1865,17 @@ pub enum LvaluePreference {
...
@@ -1865,6 +1865,17 @@ pub enum LvaluePreference {
NoPreference
NoPreference
}
}
/// Whether `autoderef` requires types to resolve.
#[derive(Copy,
Show,
PartialEq,
Eq)]
pub
enum
UnresolvedTypeAction
{
/// Produce an error and return `ty_err` whenever a type cannot
/// be resolved (i.e. it is `ty_infer`).
Error
,
/// Go on without emitting any errors, and return the unresolved
/// type. Useful for probing, e.g. in coercions.
Ignore
}
/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
///
///
...
@@ -1874,6 +1885,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -1874,6 +1885,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
sp
:
Span
,
sp
:
Span
,
base_ty
:
Ty
<
'tcx
>
,
base_ty
:
Ty
<
'tcx
>
,
opt_expr
:
Option
<&
ast
::
Expr
>
,
opt_expr
:
Option
<&
ast
::
Expr
>
,
unresolved_type_action
:
UnresolvedTypeAction
,
mut
lvalue_pref
:
LvaluePreference
,
mut
lvalue_pref
:
LvaluePreference
,
mut
should_stop
:
F
)
mut
should_stop
:
F
)
->
(
Ty
<
'tcx
>
,
uint
,
Option
<
T
>
)
->
(
Ty
<
'tcx
>
,
uint
,
Option
<
T
>
)
...
@@ -1886,11 +1898,22 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -1886,11 +1898,22 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
let
mut
t
=
base_ty
;
let
mut
t
=
base_ty
;
for
autoderefs
in
0
..
fcx
.tcx
()
.sess.recursion_limit
.get
()
{
for
autoderefs
in
0
..
fcx
.tcx
()
.sess.recursion_limit
.get
()
{
let
resolved_t
=
structurally_resolved_type
(
fcx
,
sp
,
t
);
let
resolved_t
=
match
unresolved_type_action
{
UnresolvedTypeAction
::
Error
=>
{
if
ty
::
type_is_error
(
resolved_t
)
{
let
resolved_t
=
structurally_resolved_type
(
fcx
,
sp
,
t
);
return
(
resolved_t
,
autoderefs
,
None
);
if
ty
::
type_is_error
(
resolved_t
)
{
}
return
(
resolved_t
,
autoderefs
,
None
);
}
resolved_t
}
UnresolvedTypeAction
::
Ignore
=>
{
// We can continue even when the type cannot be resolved
// (i.e. it is an inference variable) because `ty::deref`
// and `try_overloaded_deref` both simply return `None`
// in such a case without producing spurious errors.
fcx
.resolve_type_vars_if_possible
(
t
)
}
};
match
should_stop
(
resolved_t
,
autoderefs
)
{
match
should_stop
(
resolved_t
,
autoderefs
)
{
Some
(
x
)
=>
return
(
resolved_t
,
autoderefs
,
Some
(
x
)),
Some
(
x
)
=>
return
(
resolved_t
,
autoderefs
,
Some
(
x
)),
...
@@ -2011,8 +2034,13 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
...
@@ -2011,8 +2034,13 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
// autoderef that normal method probing does. They could likely be
// autoderef that normal method probing does. They could likely be
// consolidated.
// consolidated.
let
(
ty
,
autoderefs
,
final_mt
)
=
let
(
ty
,
autoderefs
,
final_mt
)
=
autoderef
(
fcx
,
autoderef
(
fcx
,
base_expr
.span
,
base_ty
,
Some
(
base_expr
),
lvalue_pref
,
|
adj_ty
,
idx
|
{
base_expr
.span
,
base_ty
,
Some
(
base_expr
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
adj_ty
,
idx
|
{
let
autoderefref
=
ty
::
AutoDerefRef
{
autoderefs
:
idx
,
autoref
:
None
};
let
autoderefref
=
ty
::
AutoDerefRef
{
autoderefs
:
idx
,
autoref
:
None
};
step
(
adj_ty
,
autoderefref
)
step
(
adj_ty
,
autoderefref
)
});
});
...
@@ -3053,8 +3081,13 @@ fn check_field(fcx: &FnCtxt,
...
@@ -3053,8 +3081,13 @@ fn check_field(fcx: &FnCtxt,
let
expr_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
let
expr_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
fcx
.expr_ty
(
base
));
fcx
.expr_ty
(
base
));
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
let
(
_
,
autoderefs
,
field_ty
)
=
let
(
_
,
autoderefs
,
field_ty
)
=
autoderef
(
fcx
,
autoderef
(
fcx
,
expr
.span
,
expr_t
,
Some
(
base
),
lvalue_pref
,
|
base_t
,
_
|
{
expr
.span
,
expr_t
,
Some
(
base
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
base_t
,
_
|
{
match
base_t
.sty
{
match
base_t
.sty
{
ty
::
ty_struct
(
base_id
,
substs
)
=>
{
ty
::
ty_struct
(
base_id
,
substs
)
=>
{
debug!
(
"struct named {}"
,
ppaux
::
ty_to_string
(
tcx
,
base_t
));
debug!
(
"struct named {}"
,
ppaux
::
ty_to_string
(
tcx
,
base_t
));
...
@@ -3146,8 +3179,13 @@ fn check_tup_field(fcx: &FnCtxt,
...
@@ -3146,8 +3179,13 @@ fn check_tup_field(fcx: &FnCtxt,
fcx
.expr_ty
(
base
));
fcx
.expr_ty
(
base
));
let
mut
tuple_like
=
false
;
let
mut
tuple_like
=
false
;
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
// FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
let
(
_
,
autoderefs
,
field_ty
)
=
let
(
_
,
autoderefs
,
field_ty
)
=
autoderef
(
fcx
,
autoderef
(
fcx
,
expr
.span
,
expr_t
,
Some
(
base
),
lvalue_pref
,
|
base_t
,
_
|
{
expr
.span
,
expr_t
,
Some
(
base
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
base_t
,
_
|
{
match
base_t
.sty
{
match
base_t
.sty
{
ty
::
ty_struct
(
base_id
,
substs
)
=>
{
ty
::
ty_struct
(
base_id
,
substs
)
=>
{
tuple_like
=
ty
::
is_tuple_struct
(
tcx
,
base_id
);
tuple_like
=
ty
::
is_tuple_struct
(
tcx
,
base_id
);
...
...
src/test/compile-fail/coerce-overloaded-autoderef.rs
0 → 100644
浏览文件 @
ae076e1e
// Copyright 2014 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.
fn
borrow_mut
<
T
>
(
x
:
&
mut
T
)
->
&
mut
T
{
x
}
fn
borrow
<
T
>
(
x
:
&
T
)
->
&
T
{
x
}
fn
borrow_mut2
<
T
>
(
_
:
&
mut
T
,
_
:
&
mut
T
)
{}
fn
borrow2
<
T
>
(
_
:
&
mut
T
,
_
:
&
T
)
{}
fn
double_mut_borrow
<
T
>
(
x
:
&
mut
Box
<
T
>
)
{
let
y
=
borrow_mut
(
x
);
let
z
=
borrow_mut
(
x
);
//~^ ERROR cannot borrow `*x` as mutable more than once at a time
}
fn
double_imm_borrow
(
x
:
&
mut
Box
<
i32
>
)
{
let
y
=
borrow
(
x
);
let
z
=
borrow
(
x
);
**
x
+=
1
;
//~^ ERROR cannot assign to `**x` because it is borrowed
}
fn
double_mut_borrow2
<
T
>
(
x
:
&
mut
Box
<
T
>
)
{
borrow_mut2
(
x
,
x
);
//~^ ERROR cannot borrow `*x` as mutable more than once at a time
}
fn
double_borrow2
<
T
>
(
x
:
&
mut
Box
<
T
>
)
{
borrow2
(
x
,
x
);
//~^ ERROR cannot borrow `*x` as immutable because it is also borrowed as mutable
}
pub
fn
main
()
{}
src/test/compile-fail/method-self-arg-1.rs
浏览文件 @
ae076e1e
...
@@ -23,11 +23,6 @@ fn main() {
...
@@ -23,11 +23,6 @@ fn main() {
//~| found `Foo`
//~| found `Foo`
//~| expected &-ptr
//~| expected &-ptr
//~| found struct `Foo`
//~| found struct `Foo`
Foo
::
bar
(
&&
x
);
//~ ERROR mismatched types
//~| expected `&Foo`
//~| found `&&Foo`
//~| expected struct `Foo`
//~| found &-ptr
Foo
::
bar
(
&
42
is
);
//~ ERROR mismatched types
Foo
::
bar
(
&
42
is
);
//~ ERROR mismatched types
//~| expected `&Foo`
//~| expected `&Foo`
//~| found `&isize`
//~| found `&isize`
...
...
src/test/run-pass/coerce-overloaded-autoderef.rs
0 → 100644
浏览文件 @
ae076e1e
// Copyright 2014 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
::
rc
::
Rc
;
// Examples from the "deref coercions" RFC, at rust-lang/rfcs#241.
fn
use_ref
<
T
>
(
_
:
&
T
)
{}
fn
use_mut
<
T
>
(
_
:
&
mut
T
)
{}
fn
use_rc
<
T
>
(
t
:
Rc
<
T
>
)
{
use_ref
(
&*
t
);
// what you have to write today
use_ref
(
&
t
);
// what you'd be able to write
use_ref
(
&&&&&&
t
);
use_ref
(
&
mut
&&&&&
t
);
use_ref
(
&&&
mut
&&&
t
);
}
fn
use_mut_box
<
T
>
(
mut
t
:
&
mut
Box
<
T
>
)
{
use_mut
(
&
mut
*
t
);
// what you have to write today
use_mut
(
t
);
// what you'd be able to write
use_mut
(
&
mut
&
mut
&
mut
t
);
use_ref
(
&*
t
);
// what you have to write today
use_ref
(
t
);
// what you'd be able to write
use_ref
(
&&&&&&
t
);
use_ref
(
&
mut
&&&&&
t
);
use_ref
(
&&&
mut
&&&
t
);
}
fn
use_nested
<
T
>
(
t
:
&
Box
<
T
>
)
{
use_ref
(
&**
t
);
// what you have to write today
use_ref
(
t
);
// what you'd be able to write (note: recursive deref)
use_ref
(
&&&&&&
t
);
use_ref
(
&
mut
&&&&&
t
);
use_ref
(
&&&
mut
&&&
t
);
}
fn
use_slice
(
_
:
&
[
u8
])
{}
fn
use_slice_mut
(
_
:
&
mut
[
u8
])
{}
fn
use_vec
(
mut
v
:
Vec
<
u8
>
)
{
use_slice_mut
(
&
mut
v
[]);
// what you have to write today
use_slice_mut
(
&
mut
v
);
// what you'd be able to write
use_slice_mut
(
&
mut
&
mut
&
mut
v
);
use_slice
(
&
v
[]);
// what you have to write today
use_slice
(
&
v
);
// what you'd be able to write
use_slice
(
&&&&&&
v
);
use_slice
(
&
mut
&&&&&
v
);
use_slice
(
&&&
mut
&&&
v
);
}
fn
use_vec_ref
(
v
:
&
Vec
<
u8
>
)
{
use_slice
(
&
v
[]);
// what you have to write today
use_slice
(
v
);
// what you'd be able to write
use_slice
(
&&&&&&
v
);
use_slice
(
&
mut
&&&&&
v
);
use_slice
(
&&&
mut
&&&
v
);
}
pub
fn
main
()
{}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录