Remove most uses of expr_ty
This commit is contained in:
parent
0ddf060b6d
commit
b93435fd79
@ -37,12 +37,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.write_ty(pat.id, expected);
|
self.write_ty(pat.id, expected);
|
||||||
}
|
}
|
||||||
PatKind::Lit(ref lt) => {
|
PatKind::Lit(ref lt) => {
|
||||||
self.check_expr(<);
|
let expr_t = self.check_expr(<);
|
||||||
let expr_ty = self.expr_ty(<);
|
|
||||||
|
|
||||||
// Byte string patterns behave the same way as array patterns
|
// Byte string patterns behave the same way as array patterns
|
||||||
// They can denote both statically and dynamically sized byte arrays
|
// They can denote both statically and dynamically sized byte arrays
|
||||||
let mut pat_ty = expr_ty;
|
let mut pat_ty = expr_t;
|
||||||
if let hir::ExprLit(ref lt) = lt.node {
|
if let hir::ExprLit(ref lt) = lt.node {
|
||||||
if let ast::LitKind::ByteStr(_) = lt.node {
|
if let ast::LitKind::ByteStr(_) = lt.node {
|
||||||
let expected_ty = self.structurally_resolved_type(pat.span, expected);
|
let expected_ty = self.structurally_resolved_type(pat.span, expected);
|
||||||
@ -63,7 +62,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// relation at all but rather that there exists a LUB (so
|
// relation at all but rather that there exists a LUB (so
|
||||||
// that they can be compared). However, in practice,
|
// that they can be compared). However, in practice,
|
||||||
// constants are always scalars or strings. For scalars
|
// constants are always scalars or strings. For scalars
|
||||||
// subtyping is irrelevant, and for strings `expr_ty` is
|
// subtyping is irrelevant, and for strings `expr_t` is
|
||||||
// type is `&'static str`, so if we say that
|
// type is `&'static str`, so if we say that
|
||||||
//
|
//
|
||||||
// &'static str <: expected
|
// &'static str <: expected
|
||||||
@ -72,11 +71,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.demand_suptype(pat.span, expected, pat_ty);
|
self.demand_suptype(pat.span, expected, pat_ty);
|
||||||
}
|
}
|
||||||
PatKind::Range(ref begin, ref end) => {
|
PatKind::Range(ref begin, ref end) => {
|
||||||
self.check_expr(begin);
|
let lhs_ty = self.check_expr(begin);
|
||||||
self.check_expr(end);
|
let rhs_ty = self.check_expr(end);
|
||||||
|
|
||||||
let lhs_ty = self.expr_ty(begin);
|
|
||||||
let rhs_ty = self.expr_ty(end);
|
|
||||||
|
|
||||||
// Check that both end-points are of numeric or char type.
|
// Check that both end-points are of numeric or char type.
|
||||||
let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char();
|
let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char();
|
||||||
@ -385,8 +381,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
});
|
});
|
||||||
let discrim_ty;
|
let discrim_ty;
|
||||||
if let Some(m) = contains_ref_bindings {
|
if let Some(m) = contains_ref_bindings {
|
||||||
self.check_expr_with_lvalue_pref(discrim, LvaluePreference::from_mutbl(m));
|
discrim_ty = self.check_expr_with_lvalue_pref(discrim, LvaluePreference::from_mutbl(m));
|
||||||
discrim_ty = self.expr_ty(discrim);
|
|
||||||
} else {
|
} else {
|
||||||
// ...but otherwise we want to use any supertype of the
|
// ...but otherwise we want to use any supertype of the
|
||||||
// discriminant. This is sort of a workaround, see note (*) in
|
// discriminant. This is sort of a workaround, see note (*) in
|
||||||
@ -429,8 +424,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
if let Some(ref e) = arm.guard {
|
if let Some(ref e) = arm.guard {
|
||||||
self.check_expr_has_type(e, tcx.types.bool);
|
self.check_expr_has_type(e, tcx.types.bool);
|
||||||
}
|
}
|
||||||
self.check_expr_with_expectation(&arm.body, expected);
|
let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
|
||||||
let arm_ty = self.expr_ty(&arm.body);
|
|
||||||
|
|
||||||
if result_ty.references_error() || arm_ty.references_error() {
|
if result_ty.references_error() || arm_ty.references_error() {
|
||||||
result_ty = tcx.types.err;
|
result_ty = tcx.types.err;
|
||||||
|
@ -47,8 +47,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
arg_exprs: &'gcx [P<hir::Expr>],
|
arg_exprs: &'gcx [P<hir::Expr>],
|
||||||
expected: Expectation<'tcx>) -> Ty<'tcx>
|
expected: Expectation<'tcx>) -> Ty<'tcx>
|
||||||
{
|
{
|
||||||
self.check_expr(callee_expr);
|
let original_callee_ty = self.check_expr(callee_expr);
|
||||||
let original_callee_ty = self.expr_ty(callee_expr);
|
|
||||||
|
|
||||||
let mut autoderef = self.autoderef(callee_expr.span, original_callee_ty);
|
let mut autoderef = self.autoderef(callee_expr.span, original_callee_ty);
|
||||||
let result = autoderef.by_ref().flat_map(|(adj_ty, idx)| {
|
let result = autoderef.by_ref().flat_map(|(adj_ty, idx)| {
|
||||||
|
@ -1750,13 +1750,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.require_type_meets(ty, span, code, ty::BoundSized);
|
self.require_type_meets(ty, span, code, ty::BoundSized);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn require_expr_have_sized_type(&self,
|
|
||||||
expr: &hir::Expr,
|
|
||||||
code: traits::ObligationCauseCode<'tcx>)
|
|
||||||
{
|
|
||||||
self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_builtin_bound(&self,
|
pub fn register_builtin_bound(&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
builtin_bound: ty::BuiltinBound,
|
builtin_bound: ty::BuiltinBound,
|
||||||
@ -1801,7 +1794,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
|
adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
|
||||||
-> Ty<'tcx>
|
-> Ty<'tcx>
|
||||||
{
|
{
|
||||||
let raw_ty = self.expr_ty(expr);
|
let raw_ty = self.node_ty(expr.id);
|
||||||
let raw_ty = self.shallow_resolve(raw_ty);
|
let raw_ty = self.shallow_resolve(raw_ty);
|
||||||
let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
|
let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
|
||||||
raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| {
|
raw_ty.adjust(self.tcx, expr.span, expr.id, adjustment, |method_call| {
|
||||||
@ -2623,12 +2616,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// arguments which we skipped above.
|
// arguments which we skipped above.
|
||||||
if variadic {
|
if variadic {
|
||||||
for arg in args.iter().skip(expected_arg_count) {
|
for arg in args.iter().skip(expected_arg_count) {
|
||||||
self.check_expr(&arg);
|
let arg_ty = self.check_expr(&arg);
|
||||||
|
|
||||||
// There are a few types which get autopromoted when passed via varargs
|
// There are a few types which get autopromoted when passed via varargs
|
||||||
// in C but we just error out instead and require explicit casts.
|
// in C but we just error out instead and require explicit casts.
|
||||||
let arg_ty = self.structurally_resolved_type(arg.span,
|
let arg_ty = self.structurally_resolved_type(arg.span,
|
||||||
self.expr_ty(&arg));
|
arg_ty);
|
||||||
match arg_ty.sty {
|
match arg_ty.sty {
|
||||||
ty::TyFloat(ast::FloatTy::F32) => {
|
ty::TyFloat(ast::FloatTy::F32) => {
|
||||||
self.type_error_message(arg.span, |t| {
|
self.type_error_message(arg.span, |t| {
|
||||||
@ -2718,15 +2711,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn check_expr_eq_type(&self,
|
fn check_expr_eq_type(&self,
|
||||||
expr: &'gcx hir::Expr,
|
expr: &'gcx hir::Expr,
|
||||||
expected: Ty<'tcx>) {
|
expected: Ty<'tcx>) {
|
||||||
self.check_expr_with_hint(expr, expected);
|
let ty = self.check_expr_with_hint(expr, expected);
|
||||||
self.demand_eqtype(expr.span, expected, self.expr_ty(expr));
|
self.demand_eqtype(expr.span, expected, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_expr_has_type(&self,
|
pub fn check_expr_has_type(&self,
|
||||||
expr: &'gcx hir::Expr,
|
expr: &'gcx hir::Expr,
|
||||||
expected: Ty<'tcx>) -> Ty<'tcx> {
|
expected: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
let ty = self.check_expr_with_hint(expr, expected);
|
let ty = self.check_expr_with_hint(expr, expected);
|
||||||
self.demand_suptype(expr.span, expected, self.expr_ty(expr));
|
self.demand_suptype(expr.span, expected, ty);
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2821,10 +2814,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
lvalue_pref: LvaluePreference) -> Ty<'tcx> {
|
lvalue_pref: LvaluePreference) -> Ty<'tcx> {
|
||||||
let rcvr = &args[0];
|
let rcvr = &args[0];
|
||||||
self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
|
let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
|
||||||
|
|
||||||
// no need to check for bot/err -- callee does that
|
// no need to check for bot/err -- callee does that
|
||||||
let expr_t = self.structurally_resolved_type(expr.span, self.expr_ty(&rcvr));
|
let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
|
||||||
|
|
||||||
let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
|
let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
|
||||||
let fn_ty = match self.lookup_method(method_name.span,
|
let fn_ty = match self.lookup_method(method_name.span,
|
||||||
@ -2867,7 +2860,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
expected: Expectation<'tcx>) -> Ty<'tcx> {
|
expected: Expectation<'tcx>) -> Ty<'tcx> {
|
||||||
self.check_expr_has_type(cond_expr, self.tcx.types.bool);
|
let cond_ty = self.check_expr_has_type(cond_expr, self.tcx.types.bool);
|
||||||
|
|
||||||
let expected = expected.adjust_for_branches(self);
|
let expected = expected.adjust_for_branches(self);
|
||||||
self.check_block_with_expected(then_blk, expected);
|
self.check_block_with_expected(then_blk, expected);
|
||||||
@ -2876,8 +2869,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let unit = self.tcx.mk_nil();
|
let unit = self.tcx.mk_nil();
|
||||||
let (origin, expected, found, result) =
|
let (origin, expected, found, result) =
|
||||||
if let Some(else_expr) = opt_else_expr {
|
if let Some(else_expr) = opt_else_expr {
|
||||||
self.check_expr_with_expectation(else_expr, expected);
|
let else_ty = self.check_expr_with_expectation(else_expr, expected);
|
||||||
let else_ty = self.expr_ty(else_expr);
|
|
||||||
let origin = TypeOrigin::IfExpression(sp);
|
let origin = TypeOrigin::IfExpression(sp);
|
||||||
|
|
||||||
// Only try to coerce-unify if we have a then expression
|
// Only try to coerce-unify if we have a then expression
|
||||||
@ -2919,7 +2911,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let if_ty = match result {
|
let if_ty = match result {
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
if self.expr_ty(cond_expr).references_error() {
|
if cond_ty.references_error() {
|
||||||
self.tcx.types.err
|
self.tcx.types.err
|
||||||
} else {
|
} else {
|
||||||
ty
|
ty
|
||||||
@ -2940,9 +2932,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
lvalue_pref: LvaluePreference,
|
lvalue_pref: LvaluePreference,
|
||||||
base: &'gcx hir::Expr,
|
base: &'gcx hir::Expr,
|
||||||
field: &Spanned<ast::Name>) -> Ty<'tcx> {
|
field: &Spanned<ast::Name>) -> Ty<'tcx> {
|
||||||
self.check_expr_with_lvalue_pref(base, lvalue_pref);
|
let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
|
||||||
let expr_t = self.structurally_resolved_type(expr.span,
|
let expr_t = self.structurally_resolved_type(expr.span,
|
||||||
self.expr_ty(base));
|
expr_t);
|
||||||
let mut private_candidate = None;
|
let mut private_candidate = None;
|
||||||
let mut autoderef = self.autoderef(expr.span, expr_t);
|
let mut autoderef = self.autoderef(expr.span, expr_t);
|
||||||
while let Some((base_t, autoderefs)) = autoderef.next() {
|
while let Some((base_t, autoderefs)) = autoderef.next() {
|
||||||
@ -3038,9 +3030,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
lvalue_pref: LvaluePreference,
|
lvalue_pref: LvaluePreference,
|
||||||
base: &'gcx hir::Expr,
|
base: &'gcx hir::Expr,
|
||||||
idx: codemap::Spanned<usize>) -> Ty<'tcx> {
|
idx: codemap::Spanned<usize>) -> Ty<'tcx> {
|
||||||
self.check_expr_with_lvalue_pref(base, lvalue_pref);
|
let expr_t = self.check_expr_with_lvalue_pref(base, lvalue_pref);
|
||||||
let expr_t = self.structurally_resolved_type(expr.span,
|
let expr_t = self.structurally_resolved_type(expr.span,
|
||||||
self.expr_ty(base));
|
expr_t);
|
||||||
let mut private_candidate = None;
|
let mut private_candidate = None;
|
||||||
let mut tuple_like = false;
|
let mut tuple_like = false;
|
||||||
let mut autoderef = self.autoderef(expr.span, expr_t);
|
let mut autoderef = self.autoderef(expr.span, expr_t);
|
||||||
@ -3272,18 +3264,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
|
base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
|
||||||
{
|
{
|
||||||
// Find the relevant variant
|
// Find the relevant variant
|
||||||
let (variant, expr_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id,
|
let (variant, expr_t) = if let Some(variant_ty) = self.check_struct_path(path, expr.id,
|
||||||
expr.span) {
|
expr.span) {
|
||||||
variant_ty
|
variant_ty
|
||||||
} else {
|
} else {
|
||||||
return self.check_struct_fields_on_error(expr.id, fields, base_expr);
|
return self.check_struct_fields_on_error(expr.id, fields, base_expr);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
|
self.check_expr_struct_fields(expr_t, path.span, variant, fields,
|
||||||
base_expr.is_none());
|
base_expr.is_none());
|
||||||
if let &Some(ref base_expr) = base_expr {
|
if let &Some(ref base_expr) = base_expr {
|
||||||
self.check_expr_has_type(base_expr, expr_ty);
|
self.check_expr_has_type(base_expr, expr_t);
|
||||||
match expr_ty.sty {
|
match expr_t.sty {
|
||||||
ty::TyStruct(adt, substs) => {
|
ty::TyStruct(adt, substs) => {
|
||||||
self.tables.borrow_mut().fru_field_types.insert(
|
self.tables.borrow_mut().fru_field_types.insert(
|
||||||
expr.id,
|
expr.id,
|
||||||
@ -3300,7 +3292,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr_ty
|
expr_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3331,8 +3323,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
_ => NoExpectation
|
_ => NoExpectation
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.check_expr_with_expectation(subexpr, expected_inner);
|
let referent_ty = self.check_expr_with_expectation(subexpr, expected_inner);
|
||||||
let referent_ty = self.expr_ty(&subexpr);
|
|
||||||
self.write_ty(id, tcx.mk_box(referent_ty))
|
self.write_ty(id, tcx.mk_box(referent_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3510,7 +3501,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
|
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
|
||||||
|
|
||||||
self.require_expr_have_sized_type(&lhs, traits::AssignmentLhsSized);
|
self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
|
||||||
|
|
||||||
if lhs_ty.references_error() || rhs_ty.references_error() {
|
if lhs_ty.references_error() || rhs_ty.references_error() {
|
||||||
self.write_error(id)
|
self.write_error(id)
|
||||||
@ -3523,9 +3514,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
id, expr.span, expected)
|
id, expr.span, expected)
|
||||||
}
|
}
|
||||||
hir::ExprWhile(ref cond, ref body, _) => {
|
hir::ExprWhile(ref cond, ref body, _) => {
|
||||||
self.check_expr_has_type(&cond, tcx.types.bool);
|
let cond_ty = self.check_expr_has_type(&cond, tcx.types.bool);
|
||||||
self.check_block_no_value(&body);
|
self.check_block_no_value(&body);
|
||||||
let cond_ty = self.expr_ty(&cond);
|
|
||||||
let body_ty = self.node_ty(body.id);
|
let body_ty = self.node_ty(body.id);
|
||||||
if cond_ty.references_error() || body_ty.references_error() {
|
if cond_ty.references_error() || body_ty.references_error() {
|
||||||
self.write_error(id)
|
self.write_error(id)
|
||||||
@ -3714,7 +3704,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
hir::ExprStruct(ref path, ref fields, ref base_expr) => {
|
hir::ExprStruct(ref path, ref fields, ref base_expr) => {
|
||||||
let ty = self.check_expr_struct(expr, path, fields, base_expr);
|
let ty = self.check_expr_struct(expr, path, fields, base_expr);
|
||||||
|
|
||||||
self.require_expr_have_sized_type(expr, traits::StructInitializerSized);
|
self.require_type_is_sized(ty, expr.span, traits::StructInitializerSized);
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
hir::ExprField(ref base, ref field) => {
|
hir::ExprField(ref base, ref field) => {
|
||||||
@ -3735,8 +3725,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let base_t = self.structurally_resolved_type(expr.span, base_t);
|
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, lvalue_pref) {
|
||||||
Some((index_ty, element_ty)) => {
|
Some((index_ty, element_ty)) => {
|
||||||
let idx_expr_ty = self.expr_ty(idx);
|
self.demand_eqtype(expr.span, index_ty, idx_t);
|
||||||
self.demand_eqtype(expr.span, index_ty, idx_expr_ty);
|
|
||||||
self.write_ty(id, element_ty)
|
self.write_ty(id, element_ty)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -3865,7 +3854,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn check_decl_initializer(&self,
|
pub fn check_decl_initializer(&self,
|
||||||
local: &'gcx hir::Local,
|
local: &'gcx hir::Local,
|
||||||
init: &'gcx hir::Expr)
|
init: &'gcx hir::Expr) -> Ty<'tcx>
|
||||||
{
|
{
|
||||||
let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat);
|
let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat);
|
||||||
|
|
||||||
@ -3884,7 +3873,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
init_ty
|
init_ty
|
||||||
} else {
|
} else {
|
||||||
self.check_expr_coercable_to_type(init, local_ty)
|
self.check_expr_coercable_to_type(init, local_ty)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_decl_local(&self, local: &'gcx hir::Local) {
|
pub fn check_decl_local(&self, local: &'gcx hir::Local) {
|
||||||
@ -3892,8 +3881,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.write_ty(local.id, t);
|
self.write_ty(local.id, t);
|
||||||
|
|
||||||
if let Some(ref init) = local.init {
|
if let Some(ref init) = local.init {
|
||||||
self.check_decl_initializer(local, &init);
|
let init_ty = self.check_decl_initializer(local, &init);
|
||||||
let init_ty = self.expr_ty(&init);
|
|
||||||
if init_ty.references_error() {
|
if init_ty.references_error() {
|
||||||
self.write_ty(local.id, init_ty);
|
self.write_ty(local.id, init_ty);
|
||||||
}
|
}
|
||||||
@ -3926,17 +3914,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
hir::StmtExpr(ref expr, id) => {
|
hir::StmtExpr(ref expr, id) => {
|
||||||
node_id = id;
|
node_id = id;
|
||||||
// Check with expected type of ()
|
// Check with expected type of ()
|
||||||
self.check_expr_has_type(&expr, self.tcx.mk_nil());
|
let expr_t = self.check_expr_has_type(&expr, self.tcx.mk_nil());
|
||||||
let expr_ty = self.expr_ty(&expr);
|
saw_bot = saw_bot || self.type_var_diverges(expr_t);
|
||||||
saw_bot = saw_bot || self.type_var_diverges(expr_ty);
|
saw_err = saw_err || expr_t.references_error();
|
||||||
saw_err = saw_err || expr_ty.references_error();
|
|
||||||
}
|
}
|
||||||
hir::StmtSemi(ref expr, id) => {
|
hir::StmtSemi(ref expr, id) => {
|
||||||
node_id = id;
|
node_id = id;
|
||||||
self.check_expr(&expr);
|
let expr_t = self.check_expr(&expr);
|
||||||
let expr_ty = self.expr_ty(&expr);
|
saw_bot |= self.type_var_diverges(expr_t);
|
||||||
saw_bot |= self.type_var_diverges(expr_ty);
|
saw_err |= expr_t.references_error();
|
||||||
saw_err |= expr_ty.references_error();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if saw_bot {
|
if saw_bot {
|
||||||
@ -4023,8 +4009,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
ety
|
ety
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.check_expr_with_expectation(&e, expected);
|
self.check_expr_with_expectation(&e, expected)
|
||||||
self.expr_ty(&e)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
lhs_expr: &'gcx hir::Expr,
|
lhs_expr: &'gcx hir::Expr,
|
||||||
rhs_expr: &'gcx hir::Expr) -> Ty<'tcx>
|
rhs_expr: &'gcx hir::Expr) -> Ty<'tcx>
|
||||||
{
|
{
|
||||||
self.check_expr_with_lvalue_pref(lhs_expr, PreferMutLvalue);
|
let lhs_ty = self.check_expr_with_lvalue_pref(lhs_expr, PreferMutLvalue);
|
||||||
|
|
||||||
let lhs_ty = self.resolve_type_vars_with_obligations(self.expr_ty(lhs_expr));
|
let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
|
||||||
let (rhs_ty, return_ty) =
|
let (rhs_ty, return_ty) =
|
||||||
self.check_overloaded_binop(expr, lhs_expr, lhs_ty, rhs_expr, op, IsAssign::Yes);
|
self.check_overloaded_binop(expr, lhs_expr, lhs_ty, rhs_expr, op, IsAssign::Yes);
|
||||||
let rhs_ty = self.resolve_type_vars_with_obligations(rhs_ty);
|
let rhs_ty = self.resolve_type_vars_with_obligations(rhs_ty);
|
||||||
@ -69,8 +69,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
lhs_expr,
|
lhs_expr,
|
||||||
rhs_expr);
|
rhs_expr);
|
||||||
|
|
||||||
self.check_expr(lhs_expr);
|
let lhs_ty = self.check_expr(lhs_expr);
|
||||||
let lhs_ty = self.resolve_type_vars_with_obligations(self.expr_ty(lhs_expr));
|
let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
|
||||||
|
|
||||||
let ty = match BinOpCategory::from(op) {
|
let ty = match BinOpCategory::from(op) {
|
||||||
BinOpCategory::Shortcircuit => {
|
BinOpCategory::Shortcircuit => {
|
||||||
|
Loading…
Reference in New Issue
Block a user