提交 2c4a75bf 编写于 作者: E Eduard-Mihai Burtescu

rustc_typeck: rename `LvaluePreference::PreferMutLvalue` to `Needs::MutPlace`.

上级 800166cf
......@@ -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
......
......@@ -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 {
......
......@@ -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::NoPreference);
let adjustments = autoderef.adjust_steps(Needs::None);
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::NoPreference);
let adjustments = autoderef.adjust_steps(Needs::None);
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::NoPreference);
let mut adjustments = autoderef.adjust_steps(Needs::None);
adjustments.extend(autoref);
self.apply_adjustments(callee_expr, adjustments);
CallStep::Overloaded(method)
......
......@@ -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());
......
......@@ -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::NoPreference);
let mut adjustments = autoderef.adjust_steps(Needs::None);
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::PreferMutLvalue;
let needs = Needs::MutPlace;
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, PreferMutLvalue, op);
expr.span, base_ty, arg_tys, Needs::MutPlace, 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")
......
......@@ -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 {
PreferMutLvalue,
NoPreference
pub enum Needs {
MutPlace,
None
}
impl LvaluePreference {
fn from_mutbl(m: hir::Mutability) -> Self {
impl Needs {
fn maybe_mut_place(m: hir::Mutability) -> Self {
match m {
hir::MutMutable => PreferMutLvalue,
hir::MutImmutable => NoPreference,
hir::MutMutable => Needs::MutPlace,
hir::MutImmutable => Needs::None,
}
}
}
......@@ -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 preferred.
// Try Mut first, if needed.
let (mut_tr, mut_op) = self.resolve_lvalue_op(op, true);
let method = match (lvalue_pref, mut_tr) {
(PreferMutLvalue, Some(trait_did)) => {
let method = match (needs, mut_tr) {
(Needs::MutPlace, 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, NoPreference)
self.check_expr_coercable_to_type_with_needs(expr, expected, Needs::None)
}
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, NoPreference)
self.check_expr_with_expectation_and_needs(expr, expected, Needs::None)
}
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,
_ => NoPreference
let needs = match unop {
hir::UnDeref => needs,
_ => Needs::None
};
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, PreferMutLvalue);
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
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 {
......
......@@ -10,7 +10,7 @@
//! Code related to processing overloaded binary and unary operators.
use super::{FnCtxt, NoPreference, PreferMutLvalue};
use super::{FnCtxt, Needs};
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 => PreferMutLvalue,
IsAssign::No => NoPreference
let lhs_needs = match is_assign {
IsAssign::Yes => Needs::MutPlace,
IsAssign::No => Needs::None
};
// 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.
先完成此消息的编辑!
想要评论请 注册