Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ad91f199
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,发现更多精彩内容 >>
提交
ad91f199
编写于
2月 22, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
typeck: Support multiple expressions getting coerced at the same type.
上级
3ff4c347
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
225 addition
and
216 deletion
+225
-216
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/callee.rs
+1
-1
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+66
-49
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+83
-81
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/probe.rs
+1
-1
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/method/suggest.rs
+1
-1
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+73
-83
未找到文件。
src/librustc_typeck/check/callee.rs
浏览文件 @
ad91f199
...
...
@@ -82,7 +82,7 @@ pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
autoderef
(
fcx
,
callee_expr
.span
,
original_callee_ty
,
Some
(
callee_expr
),
||
Some
(
callee_expr
),
UnresolvedTypeAction
::
Error
,
LvaluePreference
::
NoPreference
,
|
adj_ty
,
idx
|
{
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
ad91f199
...
...
@@ -87,6 +87,14 @@ struct Coerce<'a, 'tcx: 'a> {
type
CoerceResult
<
'tcx
>
=
RelateResult
<
'tcx
,
Option
<
AutoAdjustment
<
'tcx
>>>
;
impl
<
'f
,
'tcx
>
Coerce
<
'f
,
'tcx
>
{
fn
new
(
fcx
:
&
'a
FnCtxt
<
'a
,
'tcx
>
,
origin
:
TypeOrigin
)
->
Self
{
Coerce
{
fcx
:
fcx
,
origin
:
origin
,
unsizing_obligations
:
RefCell
::
new
(
vec!
[])
}
}
fn
tcx
(
&
self
)
->
&
TyCtxt
<
'tcx
>
{
self
.fcx
.tcx
()
}
...
...
@@ -96,16 +104,17 @@ fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
Ok
(
None
)
// No coercion required.
}
fn
coerce
(
&
self
,
expr_a
:
&
hir
::
Expr
,
fn
coerce
<
'a
,
E
,
I
>
(
&
self
,
exprs
:
&
E
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
CoerceResult
<
'tcx
>
{
debug!
(
"Coerce.tys({:?} => {:?})"
,
a
,
b
);
->
CoerceResult
<
'tcx
>
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
where
E
:
Fn
()
->
I
,
I
:
IntoIterator
<
Item
=&
'a
hir
::
Expr
>
{
let
a
=
self
.fcx
.infcx
()
.shallow_resolve
(
a
);
debug!
(
"Coerce.tys({:?} => {:?})"
,
a
,
b
);
// Just ignore error types.
if
a
.references_error
()
||
b
.references_error
()
{
...
...
@@ -156,15 +165,18 @@ fn coerce(&self,
/// 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
,
expr_a
:
&
hir
::
Expr
,
fn
coerce_borrowed_pointer
<
'a
,
E
,
I
>
(
&
self
,
span
:
Span
,
exprs
:
&
E
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
mutbl_b
:
hir
::
Mutability
)
->
CoerceResult
<
'tcx
>
{
debug!
(
"coerce_borrowed_pointer(a={:?}, b={:?})"
,
a
,
b
);
->
CoerceResult
<
'tcx
>
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
where
E
:
Fn
()
->
I
,
I
:
IntoIterator
<
Item
=&
'a
hir
::
Expr
>
{
debug!
(
"coerce_borrowed_pointer(a={:?}, b={:?})"
,
a
,
b
);
// If we have a parameter of type `&M T_a` and the value
// provided is `expr`, we will be adding an implicit borrow,
...
...
@@ -179,17 +191,15 @@ fn coerce_borrowed_pointer(&self,
_
=>
return
self
.subtype
(
a
,
b
)
}
let
coercion
=
Coercion
(
self
.origin
.span
());
let
span
=
self
.origin
.span
();
let
coercion
=
Coercion
(
span
);
let
r_borrow
=
self
.fcx
.infcx
()
.next_region_var
(
coercion
);
let
r_borrow
=
self
.tcx
()
.mk_region
(
r_borrow
);
let
autoref
=
Some
(
AutoPtr
(
r_borrow
,
mutbl_b
));
let
lvalue_pref
=
LvaluePreference
::
from_mutbl
(
mutbl_b
);
let
mut
first_error
=
None
;
let
(
_
,
autoderefs
,
success
)
=
autoderef
(
self
.fcx
,
expr_a
.span
,
a
,
Some
(
expr_a
),
let
(
_
,
autoderefs
,
success
)
=
autoderef
(
self
.fcx
,
span
,
a
,
exprs
,
UnresolvedTypeAction
::
Ignore
,
lvalue_pref
,
|
inner_ty
,
autoderef
|
{
...
...
@@ -323,9 +333,7 @@ fn coerce_unsized(&self,
}
}
let
mut
obligations
=
self
.unsizing_obligations
.borrow_mut
();
assert
!
(
obligations
.is_empty
());
*
obligations
=
leftover_predicates
;
*
self
.unsizing_obligations
.borrow_mut
()
=
leftover_predicates
;
let
adjustment
=
AutoDerefRef
{
autoderefs
:
if
reborrow
.is_some
()
{
1
}
else
{
0
},
...
...
@@ -425,39 +433,48 @@ fn coerce_unsafe_ptr(&self,
}
}
pub
fn
try
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
expr
:
&
hir
::
Expr
,
fn
apply
<
'a
,
'b
,
'tcx
,
E
,
I
>
(
coerce
:
&
mut
Coerce
<
'a
,
'tcx
>
,
exprs
:
&
E
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
()
>
{
debug!
(
"coercion::try({:?} -> {:?})"
,
a
,
b
);
let
mut
unsizing_obligations
=
vec!
[];
let
adjustment
=
try!
(
indent
(||
{
fcx
.infcx
()
.commit_if_ok
(|
_
|
{
let
coerce
=
Coerce
{
fcx
:
fcx
,
origin
:
TypeOrigin
::
ExprAssignable
(
expr
.span
),
unsizing_obligations
:
RefCell
::
new
(
vec!
[])
};
let
adjustment
=
try!
(
coerce
.coerce
(
expr
,
a
,
b
));
unsizing_obligations
=
coerce
.unsizing_obligations
.into_inner
();
Ok
(
adjustment
)
})
}));
->
RelateResult
<
'tcx
,
Ty
<
'tcx
>>
where
E
:
Fn
()
->
I
,
I
:
IntoIterator
<
Item
=&
'b
hir
::
Expr
>
{
let
(
ty
,
adjustment
)
=
try!
(
indent
(||
coerce
.coerce
(
exprs
,
a
,
b
)));
if
let
Some
(
AdjustDerefRef
(
auto
))
=
adjustment
{
let
fcx
=
coerce
.fcx
;
if
let
AdjustDerefRef
(
auto
)
=
adjustment
{
if
auto
.unsize
.is_some
()
{
for
obligation
in
unsizing_obligations
{
for
obligation
in
coerce
.unsizing_obligations
.borrow_mut
()
.drain
()
{
fcx
.register_predicate
(
obligation
);
}
}
}
if
let
Some
(
adjustment
)
=
adjustment
{
if
!
adjustment
.is_identity
()
{
debug!
(
"Success, coerced with {:?}"
,
adjustment
);
for
expr
in
exprs
()
{
assert
!
(
!
fcx
.inh.tables
.borrow
()
.adjustments
.contains
(
&
expr
.id
));
fcx
.write_adjustment
(
expr
.id
,
adjustment
);
}
Ok
(())
}
Ok
(
ty
)
}
/// Attempt to coerce an expression from a type (a) to another type (b).
/// Adjustments are only recorded if the coercion was successful.
/// The expressions *must not* have any pre-existing adjustments.
pub
fn
try
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
expr
:
&
hir
::
Expr
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
)
->
RelateResult
<
'tcx
,
()
>
{
debug!
(
"coercion::try({:?} -> {:?})"
,
a
,
b
);
let
mut
coerce
=
Coerce
::
new
(
fcx
,
TypeOrigin
::
ExprAssignable
(
expr
.span
));
fcx
.infcx
()
.commit_if_ok
(|
_
|
{
apply
(
&
mut
coerce
,
&
||
Some
(
expr
),
a
,
b
)
})
.map
(|
_
|
())
}
fn
coerce_mutbls
<
'tcx
>
(
from_mutbl
:
hir
::
Mutability
,
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
ad91f199
...
...
@@ -158,7 +158,7 @@ fn adjust_self_ty(&mut self,
let
(
autoderefd_ty
,
n
,
result
)
=
check
::
autoderef
(
self
.fcx
,
self
.span
,
unadjusted_self_ty
,
Some
(
self
.self_expr
),
||
Some
(
self
.self_expr
),
UnresolvedTypeAction
::
Error
,
NoPreference
,
|
_
,
n
|
{
...
...
@@ -287,7 +287,7 @@ fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R wh
let
(
_
,
_
,
result
)
=
check
::
autoderef
(
self
.fcx
,
self
.span
,
self_ty
,
None
,
||
None
,
UnresolvedTypeAction
::
Error
,
NoPreference
,
|
ty
,
_
|
{
...
...
@@ -509,7 +509,7 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
check
::
autoderef
(
self
.fcx
,
expr
.span
,
self
.fcx
.expr_ty
(
expr
),
Some
(
expr
),
||
Some
(
expr
),
UnresolvedTypeAction
::
Error
,
PreferMutLvalue
,
|
_
,
autoderefs
|
{
...
...
@@ -522,7 +522,9 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
}
// Don't retry the first one or we might infinite loop!
if
i
!=
0
{
if
i
==
0
{
continue
;
}
match
expr
.node
{
hir
::
ExprIndex
(
ref
base_expr
,
ref
index_expr
)
=>
{
// If this is an overloaded index, the
...
...
@@ -597,20 +599,20 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
// a preference for mut
let
method_call
=
ty
::
MethodCall
::
expr
(
expr
.id
);
if
self
.fcx.inh.tables
.borrow
()
.method_map
.contains_key
(
&
method_call
)
{
check
::
try_overloaded_deref
(
let
method
=
check
::
try_overloaded_deref
(
self
.fcx
,
expr
.span
,
Some
(
method_call
),
Some
(
&
base_expr
),
self
.fcx
.expr_ty
(
&
base_expr
),
PreferMutLvalue
);
let
method
=
method
.expect
(
"re-trying deref failed"
);
self
.fcx.inh.tables
.borrow_mut
()
.method_map
.insert
(
method_call
,
method
);
}
}
_
=>
{}
}
}
}
}
///////////////////////////////////////////////////////////////////////////
// MISCELLANY
...
...
src/librustc_typeck/check/method/probe.rs
浏览文件 @
ad91f199
...
...
@@ -200,7 +200,7 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let
(
final_ty
,
dereferences
,
_
)
=
check
::
autoderef
(
fcx
,
span
,
self_ty
,
None
,
||
None
,
UnresolvedTypeAction
::
Error
,
NoPreference
,
|
t
,
d
|
{
...
...
src/librustc_typeck/check/method/suggest.rs
浏览文件 @
ad91f199
...
...
@@ -351,7 +351,7 @@ fn is_local(ty: Ty) -> bool {
return
is_local
(
fcx
.resolve_type_vars_if_possible
(
rcvr_ty
));
}
check
::
autoderef
(
fcx
,
span
,
rcvr_ty
,
None
,
check
::
autoderef
(
fcx
,
span
,
rcvr_ty
,
||
None
,
check
::
UnresolvedTypeAction
::
Ignore
,
ty
::
NoPreference
,
|
ty
,
_
|
{
if
is_local
(
ty
)
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
ad91f199
...
...
@@ -2053,20 +2053,21 @@ pub enum UnresolvedTypeAction {
///
/// Note: this method does not modify the adjustments table. The caller is responsible for
/// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
pub
fn
autoderef
<
'a
,
'
tcx
,
T
,
F
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
pub
fn
autoderef
<
'a
,
'
b
,
'tcx
,
E
,
I
,
T
,
F
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
sp
:
Span
,
base_ty
:
Ty
<
'tcx
>
,
opt_expr
:
Option
<&
hir
::
Expr
>
,
maybe_exprs
:
E
,
unresolved_type_action
:
UnresolvedTypeAction
,
mut
lvalue_pref
:
LvaluePreference
,
mut
should_stop
:
F
)
->
(
Ty
<
'tcx
>
,
usize
,
Option
<
T
>
)
where
F
:
FnMut
(
Ty
<
'tcx
>
,
usize
)
->
Option
<
T
>
,
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
where
E
:
Fn
()
->
I
,
I
:
IntoIterator
<
Item
=&
'b
hir
::
Expr
>
,
F
:
FnMut
(
Ty
<
'tcx
>
,
usize
)
->
Option
<
T
>
,
{
debug!
(
"autoderef(base_ty={:?}, opt_expr={:?}, lvalue_pref={:?})"
,
base_ty
,
opt_expr
,
lvalue_pref
);
debug!
(
"autoderef(base_ty={:?}, lvalue_pref={:?})"
,
base_ty
,
lvalue_pref
);
let
mut
t
=
base_ty
;
for
autoderefs
in
0
..
fcx
.tcx
()
.sess.recursion_limit
.get
()
{
...
...
@@ -2092,11 +2093,6 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
}
// Otherwise, deref if type is derefable:
let
mt
=
match
resolved_t
.builtin_deref
(
false
,
lvalue_pref
)
{
Some
(
mt
)
=>
Some
(
mt
),
None
=>
{
let
method_call
=
opt_expr
.map
(|
expr
|
MethodCall
::
autoderef
(
expr
.id
,
autoderefs
as
u32
));
// Super subtle: it might seem as though we should
// pass `opt_expr` to `try_overloaded_deref`, so that
...
...
@@ -2109,19 +2105,24 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
// when they encounter an overloaded autoderef, have
// to do some reconstructive surgery. This is a pretty
// complex mess that is begging for a proper MIR.
try_overloaded_deref
(
fcx
,
sp
,
method_call
,
None
,
resolved_t
,
lvalue_pref
)
let
mt
=
if
let
Some
(
mt
)
=
resolved_t
.builtin_deref
(
false
,
lvalue_pref
)
{
mt
}
else
if
let
Some
(
method
)
=
try_overloaded_deref
(
fcx
,
sp
,
None
,
resolved_t
,
lvalue_pref
)
{
for
expr
in
maybe_exprs
()
{
let
method_call
=
MethodCall
::
autoderef
(
expr
.id
,
autoderefs
as
u32
);
fcx
.inh.tables
.borrow_mut
()
.method_map
.insert
(
method_call
,
method
);
}
make_overloaded_lvalue_return_type
(
fcx
.tcx
(),
method
)
}
else
{
return
(
resolved_t
,
autoderefs
,
None
);
};
match
mt
{
Some
(
mt
)
=>
{
t
=
mt
.ty
;
if
mt
.mutbl
==
hir
::
MutImmutable
{
lvalue_pref
=
NoPreference
;
}
}
None
=>
return
(
resolved_t
,
autoderefs
,
None
)
}
}
// We've reached the recursion limit, error gracefully.
span_err!
(
fcx
.tcx
()
.sess
,
sp
,
E0055
,
...
...
@@ -2132,11 +2133,10 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
fn
try_overloaded_deref
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
span
:
Span
,
method_call
:
Option
<
MethodCall
>
,
base_expr
:
Option
<&
hir
::
Expr
>
,
base_ty
:
Ty
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
->
Option
<
ty
::
TypeAndMut
<
'tcx
>>
->
Option
<
MethodCallee
<
'tcx
>>
{
// Try DerefMut first, if preferred.
let
method
=
match
(
lvalue_pref
,
fcx
.tcx
()
.lang_items
.deref_mut_trait
())
{
...
...
@@ -2158,33 +2158,23 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
(
method
,
_
)
=>
method
};
m
ake_overloaded_lvalue_return_type
(
fcx
,
method_call
,
method
)
m
ethod
}
/// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
/// actual type we assign to the *expression* is `T`. So this function just peels off the return
/// type by one layer to yield `T`. It also inserts the `method-callee` into the method map.
fn
make_overloaded_lvalue_return_type
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
method_call
:
Option
<
MethodCall
>
,
method
:
Option
<
MethodCallee
<
'tcx
>>
)
->
Option
<
ty
::
TypeAndMut
<
'tcx
>>
/// type by one layer to yield `T`.
fn
make_overloaded_lvalue_return_type
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
method
:
MethodCallee
<
'tcx
>
)
->
ty
::
TypeAndMut
<
'tcx
>
{
match
method
{
Some
(
method
)
=>
{
// extract method return type, which will be &T;
// all LB regions should have been instantiated during method lookup
let
ret_ty
=
method
.ty
.fn_ret
();
let
ret_ty
=
fcx
.tcx
()
.no_late_bound_regions
(
&
ret_ty
)
.unwrap
()
.unwrap
();
if
let
Some
(
method_call
)
=
method_call
{
fcx
.inh.tables
.borrow_mut
()
.method_map
.insert
(
method_call
,
method
);
}
let
ret_ty
=
tcx
.no_late_bound_regions
(
&
ret_ty
)
.unwrap
()
.unwrap
();
// method returns &T, but the type as visible to user is T, so deref
ret_ty
.builtin_deref
(
true
,
NoPreference
)
}
None
=>
None
,
}
ret_ty
.builtin_deref
(
true
,
NoPreference
)
.unwrap
()
}
fn
lookup_indexing
<
'a
,
'tcx
>
(
fcx
:
&
FnCtxt
<
'a
,
'tcx
>
,
...
...
@@ -2202,7 +2192,7 @@ fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let
(
ty
,
autoderefs
,
final_mt
)
=
autoderef
(
fcx
,
base_expr
.span
,
base_ty
,
Some
(
base_expr
),
||
Some
(
base_expr
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
adj_ty
,
idx
|
{
...
...
@@ -2299,10 +2289,10 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// If some lookup succeeds, write callee into table and extract index/element
// type from the method signature.
// If some lookup succeeded, install method in table
method
.
and_then
(|
method
|
{
method
.
map
(|
method
|
{
debug!
(
"try_index_step: success, using overloaded indexing"
);
make_overloaded_lvalue_return_type
(
fcx
,
Some
(
method_call
),
Some
(
method
))
.
map
(|
ret
|
(
input_ty
,
ret
.ty
)
)
fcx
.inh.tables
.borrow_mut
()
.method_map
.insert
(
method_call
,
method
);
(
input_ty
,
make_overloaded_lvalue_return_type
(
fcx
.tcx
(),
method
)
.ty
)
})
}
...
...
@@ -2907,7 +2897,7 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
let
(
_
,
autoderefs
,
field_ty
)
=
autoderef
(
fcx
,
expr
.span
,
expr_t
,
Some
(
base
),
||
Some
(
base
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
base_t
,
_
|
{
...
...
@@ -3005,7 +2995,7 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
let
(
_
,
autoderefs
,
field_ty
)
=
autoderef
(
fcx
,
expr
.span
,
expr_t
,
Some
(
base
),
||
Some
(
base
),
UnresolvedTypeAction
::
Error
,
lvalue_pref
,
|
base_t
,
_
|
{
...
...
@@ -3253,22 +3243,22 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
match
unop
{
hir
::
UnDeref
=>
{
oprnd_t
=
structurally_resolved_type
(
fcx
,
expr
.span
,
oprnd_t
);
oprnd_t
=
match
oprnd_t
.builtin_deref
(
true
,
NoPreference
)
{
Some
(
mt
)
=>
mt
.ty
,
None
=>
match
try_overloaded_deref
(
fcx
,
expr
.span
,
Some
(
MethodCall
::
expr
(
expr
.id
)),
Some
(
&
oprnd
),
oprnd_t
,
lvalue_pref
)
{
Some
(
mt
)
=>
mt
.ty
,
None
=>
{
if
let
Some
(
mt
)
=
oprnd_t
.builtin_deref
(
true
,
NoPreference
)
{
oprnd_t
=
mt
.ty
;
}
else
if
let
Some
(
method
)
=
try_overloaded_deref
(
fcx
,
expr
.span
,
Some
(
&
oprnd
),
oprnd_t
,
lvalue_pref
)
{
oprnd_t
=
make_overloaded_lvalue_return_type
(
tcx
,
method
)
.ty
;
fcx
.inh.tables
.borrow_mut
()
.method_map
.insert
(
MethodCall
::
expr
(
expr
.id
),
method
);
}
else
{
fcx
.type_error_message
(
expr
.span
,
|
actual
|
{
format!
(
"type `{}` cannot be
\
dereferenced"
,
actual
)
},
oprnd_t
,
None
);
tcx
.types.err
oprnd_t
=
tcx
.types.err
;
}
}
};
}
hir
::
UnNot
=>
{
oprnd_t
=
structurally_resolved_type
(
fcx
,
oprnd
.span
,
oprnd_t
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录