Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
2c4a75bf
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
2c4a75bf
编写于
1月 29, 2018
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_typeck: rename `LvaluePreference::PreferMutLvalue` to `Needs::MutPlace`.
上级
800166cf
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
80 addition
and
82 deletion
+80
-82
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+2
-2
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/autoderef.rs
+5
-5
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/callee.rs
+4
-4
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+3
-3
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/confirm.rs
+5
-5
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+55
-57
src/librustc_typeck/check/op.rs
src/librustc_typeck/check/op.rs
+6
-6
未找到文件。
src/librustc_typeck/check/_match.rs
浏览文件 @
2c4a75bf
...
...
@@ -15,7 +15,7 @@
use
rustc
::
infer
::
type_variable
::
TypeVariableOrigin
;
use
rustc
::
traits
::
ObligationCauseCode
;
use
rustc
::
ty
::{
self
,
Ty
,
TypeFoldable
};
use
check
::{
FnCtxt
,
Expectation
,
Diverges
,
LvaluePreference
};
use
check
::{
FnCtxt
,
Expectation
,
Diverges
,
Needs
};
use
check
::
coercion
::
CoerceMany
;
use
util
::
nodemap
::
FxHashMap
;
...
...
@@ -584,7 +584,7 @@ pub fn check_match(&self,
});
let
discrim_ty
;
if
let
Some
(
m
)
=
contains_ref_bindings
{
discrim_ty
=
self
.check_expr_with_
lvalue_pref
(
discrim
,
LvaluePreference
::
from_mutbl
(
m
));
discrim_ty
=
self
.check_expr_with_
needs
(
discrim
,
Needs
::
maybe_mut_place
(
m
));
}
else
{
// ...but otherwise we want to use any supertype of the
// discriminant. This is sort of a workaround, see note (*) in
...
...
src/librustc_typeck/check/autoderef.rs
浏览文件 @
2c4a75bf
...
...
@@ -10,7 +10,7 @@
use
astconv
::
AstConv
;
use
super
::{
FnCtxt
,
LvalueOp
,
LvaluePreference
};
use
super
::{
FnCtxt
,
LvalueOp
,
Needs
};
use
super
::
method
::
MethodCallee
;
use
rustc
::
infer
::
InferOk
;
...
...
@@ -162,19 +162,19 @@ pub fn step_count(&self) -> usize {
}
/// Returns the adjustment steps.
pub
fn
adjust_steps
(
&
self
,
pref
:
LvaluePreference
)
pub
fn
adjust_steps
(
&
self
,
needs
:
Needs
)
->
Vec
<
Adjustment
<
'tcx
>>
{
self
.fcx
.register_infer_ok_obligations
(
self
.adjust_steps_as_infer_ok
(
pref
))
self
.fcx
.register_infer_ok_obligations
(
self
.adjust_steps_as_infer_ok
(
needs
))
}
pub
fn
adjust_steps_as_infer_ok
(
&
self
,
pref
:
LvaluePreference
)
pub
fn
adjust_steps_as_infer_ok
(
&
self
,
needs
:
Needs
)
->
InferOk
<
'tcx
,
Vec
<
Adjustment
<
'tcx
>>>
{
let
mut
obligations
=
vec!
[];
let
targets
=
self
.steps
.iter
()
.skip
(
1
)
.map
(|
&
(
ty
,
_
)|
ty
)
.chain
(
iter
::
once
(
self
.cur_ty
));
let
steps
:
Vec
<
_
>
=
self
.steps
.iter
()
.map
(|
&
(
source
,
kind
)|
{
if
let
AutoderefKind
::
Overloaded
=
kind
{
self
.fcx
.try_overloaded_deref
(
self
.span
,
source
,
pref
)
self
.fcx
.try_overloaded_deref
(
self
.span
,
source
,
needs
)
.and_then
(|
InferOk
{
value
:
method
,
obligations
:
o
}|
{
obligations
.extend
(
o
);
if
let
ty
::
TyRef
(
region
,
mt
)
=
method
.sig
.output
()
.sty
{
...
...
src/librustc_typeck/check/callee.rs
浏览文件 @
2c4a75bf
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::{
Expectation
,
FnCtxt
,
LvaluePreference
,
TupleArgumentsFlag
};
use
super
::{
Expectation
,
FnCtxt
,
Needs
,
TupleArgumentsFlag
};
use
super
::
autoderef
::
Autoderef
;
use
super
::
method
::
MethodCallee
;
...
...
@@ -96,7 +96,7 @@ fn try_overloaded_call_step(&self,
// If the callee is a bare function or a closure, then we're all set.
match
adjusted_ty
.sty
{
ty
::
TyFnDef
(
..
)
|
ty
::
TyFnPtr
(
_
)
=>
{
let
adjustments
=
autoderef
.adjust_steps
(
LvaluePreference
::
NoPreferenc
e
);
let
adjustments
=
autoderef
.adjust_steps
(
Needs
::
Non
e
);
self
.apply_adjustments
(
callee_expr
,
adjustments
);
return
Some
(
CallStep
::
Builtin
(
adjusted_ty
));
}
...
...
@@ -113,7 +113,7 @@ fn try_overloaded_call_step(&self,
infer
::
FnCall
,
&
closure_ty
)
.0
;
let
adjustments
=
autoderef
.adjust_steps
(
LvaluePreference
::
NoPreferenc
e
);
let
adjustments
=
autoderef
.adjust_steps
(
Needs
::
Non
e
);
self
.record_deferred_call_resolution
(
def_id
,
DeferredCallResolution
{
call_expr
,
callee_expr
,
...
...
@@ -143,7 +143,7 @@ fn try_overloaded_call_step(&self,
}
self
.try_overloaded_call_traits
(
call_expr
,
adjusted_ty
)
.map
(|(
autoref
,
method
)|
{
let
mut
adjustments
=
autoderef
.adjust_steps
(
LvaluePreference
::
NoPreferenc
e
);
let
mut
adjustments
=
autoderef
.adjust_steps
(
Needs
::
Non
e
);
adjustments
.extend
(
autoref
);
self
.apply_adjustments
(
callee_expr
,
adjustments
);
CallStep
::
Overloaded
(
method
)
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
2c4a75bf
...
...
@@ -60,7 +60,7 @@
//! 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.
use
check
::{
Diverges
,
FnCtxt
,
LvaluePreference
};
use
check
::{
Diverges
,
FnCtxt
,
Needs
};
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
DefId
;
...
...
@@ -409,9 +409,9 @@ fn coerce_borrowed_pointer(&self,
return
success
(
vec!
[],
ty
,
obligations
);
}
let
pref
=
LvaluePreference
::
from_mutbl
(
mt_b
.mutbl
);
let
needs
=
Needs
::
maybe_mut_place
(
mt_b
.mutbl
);
let
InferOk
{
value
:
mut
adjustments
,
obligations
:
o
}
=
autoderef
.adjust_steps_as_infer_ok
(
pref
);
=
autoderef
.adjust_steps_as_infer_ok
(
needs
);
obligations
.extend
(
o
);
obligations
.extend
(
autoderef
.into_obligations
());
...
...
src/librustc_typeck/check/method/confirm.rs
浏览文件 @
2c4a75bf
...
...
@@ -11,7 +11,7 @@
use
super
::{
probe
,
MethodCallee
};
use
astconv
::
AstConv
;
use
check
::{
FnCtxt
,
LvalueOp
,
callee
,
LvaluePreference
,
PreferMutLvalue
};
use
check
::{
FnCtxt
,
LvalueOp
,
callee
,
Needs
};
use
hir
::
def_id
::
DefId
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
traits
;
...
...
@@ -155,7 +155,7 @@ fn adjust_self_ty(&mut self,
let
(
_
,
n
)
=
autoderef
.nth
(
pick
.autoderefs
)
.unwrap
();
assert_eq!
(
n
,
pick
.autoderefs
);
let
mut
adjustments
=
autoderef
.adjust_steps
(
LvaluePreference
::
NoPreferenc
e
);
let
mut
adjustments
=
autoderef
.adjust_steps
(
Needs
::
Non
e
);
let
mut
target
=
autoderef
.unambiguous_final_ty
();
...
...
@@ -449,10 +449,10 @@ fn convert_lvalue_derefs_to_mutable(&self) {
.adjustments_mut
()
.remove
(
expr
.hir_id
);
if
let
Some
(
mut
adjustments
)
=
previous_adjustments
{
let
pref
=
LvaluePreference
::
PreferMutLvalu
e
;
let
needs
=
Needs
::
MutPlac
e
;
for
adjustment
in
&
mut
adjustments
{
if
let
Adjust
::
Deref
(
Some
(
ref
mut
deref
))
=
adjustment
.kind
{
if
let
Some
(
ok
)
=
self
.try_overloaded_deref
(
expr
.span
,
source
,
pref
)
{
if
let
Some
(
ok
)
=
self
.try_overloaded_deref
(
expr
.span
,
source
,
needs
)
{
let
method
=
self
.register_infer_ok_obligations
(
ok
);
if
let
ty
::
TyRef
(
region
,
mt
)
=
method
.sig
.output
()
.sty
{
*
deref
=
OverloadedDeref
{
...
...
@@ -505,7 +505,7 @@ fn convert_lvalue_op_to_mutable(&self,
.ty
;
let
method
=
self
.try_overloaded_lvalue_op
(
expr
.span
,
base_ty
,
arg_tys
,
PreferMutLvalu
e
,
op
);
expr
.span
,
base_ty
,
arg_tys
,
Needs
::
MutPlac
e
,
op
);
let
method
=
match
method
{
Some
(
ok
)
=>
self
.register_infer_ok_obligations
(
ok
),
None
=>
return
self
.tcx.sess
.delay_span_bug
(
expr
.span
,
"re-trying op failed"
)
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
2c4a75bf
...
...
@@ -77,7 +77,6 @@
*/
pub
use
self
::
Expectation
::
*
;
use
self
::
LvaluePreference
::
*
;
use
self
::
autoderef
::
Autoderef
;
use
self
::
callee
::
DeferredCallResolution
;
use
self
::
coercion
::{
CoerceMany
,
DynamicCoerceMany
};
...
...
@@ -369,16 +368,16 @@ fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'t
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
Eq)]
pub
enum
LvaluePreference
{
PreferMutLvalu
e
,
No
Preferenc
e
pub
enum
Needs
{
MutPlac
e
,
No
n
e
}
impl
LvaluePreference
{
fn
from_mutbl
(
m
:
hir
::
Mutability
)
->
Self
{
impl
Needs
{
fn
maybe_mut_place
(
m
:
hir
::
Mutability
)
->
Self
{
match
m
{
hir
::
MutMutable
=>
PreferMutLvalu
e
,
hir
::
MutImmutable
=>
N
oPreferenc
e
,
hir
::
MutMutable
=>
Needs
::
MutPlac
e
,
hir
::
MutImmutable
=>
N
eeds
::
Non
e
,
}
}
}
...
...
@@ -2242,7 +2241,7 @@ fn lookup_indexing(&self,
base_expr
:
&
'gcx
hir
::
Expr
,
base_ty
:
Ty
<
'tcx
>
,
idx_ty
:
Ty
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
needs
:
Needs
)
->
Option
<
(
/*index type*/
Ty
<
'tcx
>
,
/*element type*/
Ty
<
'tcx
>
)
>
{
// FIXME(#18741) -- this is almost but not quite the same as the
...
...
@@ -2252,7 +2251,7 @@ fn lookup_indexing(&self,
let
mut
autoderef
=
self
.autoderef
(
base_expr
.span
,
base_ty
);
let
mut
result
=
None
;
while
result
.is_none
()
&&
autoderef
.next
()
.is_some
()
{
result
=
self
.try_index_step
(
expr
,
base_expr
,
&
autoderef
,
lvalue_pref
,
idx_ty
);
result
=
self
.try_index_step
(
expr
,
base_expr
,
&
autoderef
,
needs
,
idx_ty
);
}
autoderef
.finalize
();
result
...
...
@@ -2267,7 +2266,7 @@ fn try_index_step(&self,
expr
:
&
hir
::
Expr
,
base_expr
:
&
hir
::
Expr
,
autoderef
:
&
Autoderef
<
'a
,
'gcx
,
'tcx
>
,
lvalue_pref
:
LvaluePreference
,
needs
:
Needs
,
index_ty
:
Ty
<
'tcx
>
)
->
Option
<
(
/*index type*/
Ty
<
'tcx
>
,
/*element type*/
Ty
<
'tcx
>
)
>
{
...
...
@@ -2295,13 +2294,13 @@ fn try_index_step(&self,
// If some lookup succeeded, install method in table
let
input_ty
=
self
.next_ty_var
(
TypeVariableOrigin
::
AutoDeref
(
base_expr
.span
));
let
method
=
self
.try_overloaded_lvalue_op
(
expr
.span
,
self_ty
,
&
[
input_ty
],
lvalue_pref
,
LvalueOp
::
Index
);
expr
.span
,
self_ty
,
&
[
input_ty
],
needs
,
LvalueOp
::
Index
);
let
result
=
method
.map
(|
ok
|
{
debug!
(
"try_index_step: success, using overloaded indexing"
);
let
method
=
self
.register_infer_ok_obligations
(
ok
);
let
mut
adjustments
=
autoderef
.adjust_steps
(
lvalue_pref
);
let
mut
adjustments
=
autoderef
.adjust_steps
(
needs
);
if
let
ty
::
TyRef
(
region
,
mt
)
=
method
.sig
.inputs
()[
0
]
.sty
{
adjustments
.push
(
Adjustment
{
kind
:
Adjust
::
Borrow
(
AutoBorrow
::
Ref
(
region
,
mt
.mutbl
)),
...
...
@@ -2348,20 +2347,20 @@ fn try_overloaded_lvalue_op(&self,
span
:
Span
,
base_ty
:
Ty
<
'tcx
>
,
arg_tys
:
&
[
Ty
<
'tcx
>
],
lvalue_pref
:
LvaluePreference
,
needs
:
Needs
,
op
:
LvalueOp
)
->
Option
<
InferOk
<
'tcx
,
MethodCallee
<
'tcx
>>>
{
debug!
(
"try_overloaded_lvalue_op({:?},{:?},{:?},{:?})"
,
span
,
base_ty
,
lvalue_pref
,
needs
,
op
);
// Try Mut first, if
preferr
ed.
// Try Mut first, if
need
ed.
let
(
mut_tr
,
mut_op
)
=
self
.resolve_lvalue_op
(
op
,
true
);
let
method
=
match
(
lvalue_pref
,
mut_tr
)
{
(
PreferMutLvalu
e
,
Some
(
trait_did
))
=>
{
let
method
=
match
(
needs
,
mut_tr
)
{
(
Needs
::
MutPlac
e
,
Some
(
trait_did
))
=>
{
self
.lookup_method_in_trait
(
span
,
mut_op
,
trait_did
,
base_ty
,
Some
(
arg_tys
))
}
_
=>
None
,
...
...
@@ -2753,18 +2752,18 @@ fn check_expr_meets_expectation_or_error(&self,
fn
check_expr_coercable_to_type
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
self
.check_expr_coercable_to_type_with_
lvalue_pref
(
expr
,
expected
,
NoPreferenc
e
)
self
.check_expr_coercable_to_type_with_
needs
(
expr
,
expected
,
Needs
::
Non
e
)
}
fn
check_expr_coercable_to_type_with_
lvalue_pref
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Ty
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
->
Ty
<
'tcx
>
{
let
ty
=
self
.check_expr_with_expectation_and_
lvalue_pref
(
fn
check_expr_coercable_to_type_with_
needs
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Ty
<
'tcx
>
,
needs
:
Needs
)
->
Ty
<
'tcx
>
{
let
ty
=
self
.check_expr_with_expectation_and_
needs
(
expr
,
ExpectHasType
(
expected
),
lvalue_pref
);
needs
);
self
.demand_coerce
(
expr
,
ty
,
expected
)
}
...
...
@@ -2776,16 +2775,15 @@ fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
fn
check_expr_with_expectation
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Expectation
<
'tcx
>
)
->
Ty
<
'tcx
>
{
self
.check_expr_with_expectation_and_
lvalue_pref
(
expr
,
expected
,
NoPreferenc
e
)
self
.check_expr_with_expectation_and_
needs
(
expr
,
expected
,
Needs
::
Non
e
)
}
fn
check_expr
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
)
->
Ty
<
'tcx
>
{
self
.check_expr_with_expectation
(
expr
,
NoExpectation
)
}
fn
check_expr_with_lvalue_pref
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
lvalue_pref
:
LvaluePreference
)
->
Ty
<
'tcx
>
{
self
.check_expr_with_expectation_and_lvalue_pref
(
expr
,
NoExpectation
,
lvalue_pref
)
fn
check_expr_with_needs
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
needs
:
Needs
)
->
Ty
<
'tcx
>
{
self
.check_expr_with_expectation_and_needs
(
expr
,
NoExpectation
,
needs
)
}
// determine the `self` type, using fresh variables for all variables
...
...
@@ -2868,9 +2866,9 @@ fn check_method_call(&self,
span
:
Span
,
args
:
&
'gcx
[
hir
::
Expr
],
expected
:
Expectation
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
->
Ty
<
'tcx
>
{
needs
:
Needs
)
->
Ty
<
'tcx
>
{
let
rcvr
=
&
args
[
0
];
let
rcvr_t
=
self
.check_expr_with_
lvalue_pref
(
&
rcvr
,
lvalue_pref
);
let
rcvr_t
=
self
.check_expr_with_
needs
(
&
rcvr
,
needs
);
// no need to check for bot/err -- callee does that
let
rcvr_t
=
self
.structurally_resolved_type
(
expr
.span
,
rcvr_t
);
...
...
@@ -2980,10 +2978,10 @@ fn check_then_else(&self,
// Check field access expressions
fn
check_field
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
lvalue_pref
:
LvaluePreference
,
needs
:
Needs
,
base
:
&
'gcx
hir
::
Expr
,
field
:
&
Spanned
<
ast
::
Name
>
)
->
Ty
<
'tcx
>
{
let
expr_t
=
self
.check_expr_with_
lvalue_pref
(
base
,
lvalue_pref
);
let
expr_t
=
self
.check_expr_with_
needs
(
base
,
needs
);
let
expr_t
=
self
.structurally_resolved_type
(
expr
.span
,
expr_t
);
let
mut
private_candidate
=
None
;
...
...
@@ -2998,7 +2996,7 @@ fn check_field(&self,
if
let
Some
(
field
)
=
fields
.iter
()
.find
(|
f
|
f
.name
.to_ident
()
==
ident
)
{
let
field_ty
=
self
.field_ty
(
expr
.span
,
field
,
substs
);
if
field
.vis
.is_accessible_from
(
def_scope
,
self
.tcx
)
{
let
adjustments
=
autoderef
.adjust_steps
(
lvalue_pref
);
let
adjustments
=
autoderef
.adjust_steps
(
needs
);
self
.apply_adjustments
(
base
,
adjustments
);
autoderef
.finalize
();
...
...
@@ -3117,10 +3115,10 @@ fn name_series_display(&self, names: Vec<ast::Name>) -> String {
// Check tuple index expressions
fn
check_tup_field
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
lvalue_pref
:
LvaluePreference
,
needs
:
Needs
,
base
:
&
'gcx
hir
::
Expr
,
idx
:
codemap
::
Spanned
<
usize
>
)
->
Ty
<
'tcx
>
{
let
expr_t
=
self
.check_expr_with_
lvalue_pref
(
base
,
lvalue_pref
);
let
expr_t
=
self
.check_expr_with_
needs
(
base
,
needs
);
let
expr_t
=
self
.structurally_resolved_type
(
expr
.span
,
expr_t
);
let
mut
private_candidate
=
None
;
...
...
@@ -3161,7 +3159,7 @@ fn check_tup_field(&self,
};
if
let
Some
(
field_ty
)
=
field
{
let
adjustments
=
autoderef
.adjust_steps
(
lvalue_pref
);
let
adjustments
=
autoderef
.adjust_steps
(
needs
);
self
.apply_adjustments
(
base
,
adjustments
);
autoderef
.finalize
();
return
field_ty
;
...
...
@@ -3491,10 +3489,10 @@ fn check_expr_struct(&self,
/// Note that inspecting a type's structure *directly* may expose the fact
/// that there are actually multiple representations for `TyError`, so avoid
/// that when err needs to be handled differently.
fn
check_expr_with_expectation_and_
lvalue_pref
(
&
self
,
fn
check_expr_with_expectation_and_
needs
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Expectation
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
->
Ty
<
'tcx
>
{
needs
:
Needs
)
->
Ty
<
'tcx
>
{
debug!
(
">> typechecking: expr={:?} expected={:?}"
,
expr
,
expected
);
...
...
@@ -3507,7 +3505,7 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
self
.diverges
.set
(
Diverges
::
Maybe
);
self
.has_errors
.set
(
false
);
let
ty
=
self
.check_expr_kind
(
expr
,
expected
,
lvalue_pref
);
let
ty
=
self
.check_expr_kind
(
expr
,
expected
,
needs
);
// Warn for non-block expressions with diverging children.
match
expr
.node
{
...
...
@@ -3541,7 +3539,7 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
fn
check_expr_kind
(
&
self
,
expr
:
&
'gcx
hir
::
Expr
,
expected
:
Expectation
<
'tcx
>
,
lvalue_pref
:
LvaluePreference
)
->
Ty
<
'tcx
>
{
needs
:
Needs
)
->
Ty
<
'tcx
>
{
let
tcx
=
self
.tcx
;
let
id
=
expr
.id
;
match
expr
.node
{
...
...
@@ -3575,13 +3573,13 @@ fn check_expr_kind(&self,
NoExpectation
}
};
let
lvalue_pref
=
match
unop
{
hir
::
UnDeref
=>
lvalue_pref
,
_
=>
N
oPreferenc
e
let
needs
=
match
unop
{
hir
::
UnDeref
=>
needs
,
_
=>
N
eeds
::
Non
e
};
let
mut
oprnd_t
=
self
.check_expr_with_expectation_and_
lvalue_pref
(
&
oprnd
,
let
mut
oprnd_t
=
self
.check_expr_with_expectation_and_
needs
(
&
oprnd
,
expected_inner
,
lvalue_pref
);
needs
);
if
!
oprnd_t
.references_error
()
{
oprnd_t
=
self
.structurally_resolved_type
(
expr
.span
,
oprnd_t
);
...
...
@@ -3590,7 +3588,7 @@ fn check_expr_kind(&self,
if
let
Some
(
mt
)
=
oprnd_t
.builtin_deref
(
true
)
{
oprnd_t
=
mt
.ty
;
}
else
if
let
Some
(
ok
)
=
self
.try_overloaded_deref
(
expr
.span
,
oprnd_t
,
lvalue_pref
)
{
expr
.span
,
oprnd_t
,
needs
)
{
let
method
=
self
.register_infer_ok_obligations
(
ok
);
if
let
ty
::
TyRef
(
region
,
mt
)
=
method
.sig
.inputs
()[
0
]
.sty
{
self
.apply_adjustments
(
oprnd
,
vec!
[
Adjustment
{
...
...
@@ -3641,8 +3639,8 @@ fn check_expr_kind(&self,
_
=>
NoExpectation
}
});
let
lvalue_pref
=
LvaluePreference
::
from_mutbl
(
mutbl
);
let
ty
=
self
.check_expr_with_expectation_and_
lvalue_pref
(
&
oprnd
,
hint
,
lvalue_pref
);
let
needs
=
Needs
::
maybe_mut_place
(
mutbl
);
let
ty
=
self
.check_expr_with_expectation_and_
needs
(
&
oprnd
,
hint
,
needs
);
let
tm
=
ty
::
TypeAndMut
{
ty
:
ty
,
mutbl
:
mutbl
};
if
tm
.ty
.references_error
()
{
...
...
@@ -3786,7 +3784,7 @@ fn check_expr_kind(&self,
tcx
.types.never
}
hir
::
ExprAssign
(
ref
lhs
,
ref
rhs
)
=>
{
let
lhs_ty
=
self
.check_expr_with_
lvalue_pref
(
&
lhs
,
PreferMutLvalu
e
);
let
lhs_ty
=
self
.check_expr_with_
needs
(
&
lhs
,
Needs
::
MutPlac
e
);
let
rhs_ty
=
self
.check_expr_coercable_to_type
(
&
rhs
,
lhs_ty
);
...
...
@@ -3887,7 +3885,7 @@ fn check_expr_kind(&self,
self
.check_call
(
expr
,
&
callee
,
args
,
expected
)
}
hir
::
ExprMethodCall
(
ref
segment
,
span
,
ref
args
)
=>
{
self
.check_method_call
(
expr
,
segment
,
span
,
args
,
expected
,
lvalue_pref
)
self
.check_method_call
(
expr
,
segment
,
span
,
args
,
expected
,
needs
)
}
hir
::
ExprCast
(
ref
e
,
ref
t
)
=>
{
// Find the type of `e`. Supply hints based on the type we are casting to,
...
...
@@ -4030,13 +4028,13 @@ fn check_expr_kind(&self,
self
.check_expr_struct
(
expr
,
expected
,
qpath
,
fields
,
base_expr
)
}
hir
::
ExprField
(
ref
base
,
ref
field
)
=>
{
self
.check_field
(
expr
,
lvalue_pref
,
&
base
,
field
)
self
.check_field
(
expr
,
needs
,
&
base
,
field
)
}
hir
::
ExprTupField
(
ref
base
,
idx
)
=>
{
self
.check_tup_field
(
expr
,
lvalue_pref
,
&
base
,
idx
)
self
.check_tup_field
(
expr
,
needs
,
&
base
,
idx
)
}
hir
::
ExprIndex
(
ref
base
,
ref
idx
)
=>
{
let
base_t
=
self
.check_expr_with_
lvalue_pref
(
&
base
,
lvalue_pref
);
let
base_t
=
self
.check_expr_with_
needs
(
&
base
,
needs
);
let
idx_t
=
self
.check_expr
(
&
idx
);
if
base_t
.references_error
()
{
...
...
@@ -4045,7 +4043,7 @@ fn check_expr_kind(&self,
idx_t
}
else
{
let
base_t
=
self
.structurally_resolved_type
(
expr
.span
,
base_t
);
match
self
.lookup_indexing
(
expr
,
base
,
base_t
,
idx_t
,
lvalue_pref
)
{
match
self
.lookup_indexing
(
expr
,
base
,
base_t
,
idx_t
,
needs
)
{
Some
((
index_ty
,
element_ty
))
=>
{
self
.demand_coerce
(
idx
,
idx_t
,
index_ty
);
element_ty
...
...
@@ -4195,7 +4193,7 @@ pub fn check_decl_initializer(&self,
// referent for the reference that results is *equal to* the
// type of the lvalue it is referencing, and not some
// supertype thereof.
let
init_ty
=
self
.check_expr_with_
lvalue_pref
(
init
,
LvaluePreference
::
from_mutbl
(
m
));
let
init_ty
=
self
.check_expr_with_
needs
(
init
,
Needs
::
maybe_mut_place
(
m
));
self
.demand_eqtype
(
init
.span
,
local_ty
,
init_ty
);
init_ty
}
else
{
...
...
src/librustc_typeck/check/op.rs
浏览文件 @
2c4a75bf
...
...
@@ -10,7 +10,7 @@
//! Code related to processing overloaded binary and unary operators.
use
super
::{
FnCtxt
,
N
oPreference
,
PreferMutLvalue
};
use
super
::{
FnCtxt
,
N
eeds
};
use
super
::
method
::
MethodCallee
;
use
rustc
::
ty
::{
self
,
Ty
,
TypeFoldable
,
TypeVariants
};
use
rustc
::
ty
::
TypeVariants
::{
TyStr
,
TyRef
};
...
...
@@ -166,18 +166,18 @@ fn check_overloaded_binop(&self,
op
,
is_assign
);
let
lhs_
pref
=
match
is_assign
{
IsAssign
::
Yes
=>
PreferMutLvalu
e
,
IsAssign
::
No
=>
N
oPreferenc
e
let
lhs_
needs
=
match
is_assign
{
IsAssign
::
Yes
=>
Needs
::
MutPlac
e
,
IsAssign
::
No
=>
N
eeds
::
Non
e
};
// Find a suitable supertype of the LHS expression's type, by coercing to
// a type variable, to pass as the `Self` to the trait, avoiding invariant
// trait matching creating lifetime constraints that are too strict.
// E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
let
lhs_ty
=
self
.check_expr_coercable_to_type_with_
lvalue_pref
(
lhs_expr
,
let
lhs_ty
=
self
.check_expr_coercable_to_type_with_
needs
(
lhs_expr
,
self
.next_ty_var
(
TypeVariableOrigin
::
MiscVariable
(
lhs_expr
.span
)),
lhs_
pref
);
lhs_
needs
);
let
lhs_ty
=
self
.resolve_type_vars_with_obligations
(
lhs_ty
);
// NB: As we have not yet type-checked the RHS, we don't have the
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录