Skip to content

Commit 6473c6a

Browse files
committed
Encode some rules to help guide integral type inference
1 parent baf605b commit 6473c6a

File tree

1 file changed

+60
-21
lines changed
  • src/librustc_typeck/check

1 file changed

+60
-21
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2926,39 +2926,78 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
29262926
lhs_expr: &'tcx ast::Expr,
29272927
lhs_resolved_t: Ty<'tcx>,
29282928
op: ast::BinOp,
2929-
rhs: &'tcx P<ast::Expr>) -> Ty<'tcx> {
2929+
rhs: &'tcx P<ast::Expr>)
2930+
-> Ty<'tcx>
2931+
{
29302932
let tcx = fcx.ccx.tcx;
29312933
let lang = &tcx.lang_items;
2932-
let (name, trait_did) = match op.node {
2933-
ast::BiAdd => ("add", lang.add_trait()),
2934-
ast::BiSub => ("sub", lang.sub_trait()),
2935-
ast::BiMul => ("mul", lang.mul_trait()),
2936-
ast::BiDiv => ("div", lang.div_trait()),
2937-
ast::BiRem => ("rem", lang.rem_trait()),
2938-
ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
2939-
ast::BiBitAnd => ("bitand", lang.bitand_trait()),
2940-
ast::BiBitOr => ("bitor", lang.bitor_trait()),
2941-
ast::BiShl => ("shl", lang.shl_trait()),
2942-
ast::BiShr => ("shr", lang.shr_trait()),
2943-
ast::BiLt => ("lt", lang.ord_trait()),
2944-
ast::BiLe => ("le", lang.ord_trait()),
2945-
ast::BiGe => ("ge", lang.ord_trait()),
2946-
ast::BiGt => ("gt", lang.ord_trait()),
2947-
ast::BiEq => ("eq", lang.eq_trait()),
2948-
ast::BiNe => ("ne", lang.eq_trait()),
2934+
let (name, trait_did, is_comparison) = match op.node {
2935+
ast::BiAdd => ("add", lang.add_trait(), false),
2936+
ast::BiSub => ("sub", lang.sub_trait(), false),
2937+
ast::BiMul => ("mul", lang.mul_trait(), false),
2938+
ast::BiDiv => ("div", lang.div_trait(), false),
2939+
ast::BiRem => ("rem", lang.rem_trait(), false),
2940+
ast::BiBitXor => ("bitxor", lang.bitxor_trait(), false),
2941+
ast::BiBitAnd => ("bitand", lang.bitand_trait(), false),
2942+
ast::BiBitOr => ("bitor", lang.bitor_trait(), false),
2943+
ast::BiShl => ("shl", lang.shl_trait(), false),
2944+
ast::BiShr => ("shr", lang.shr_trait(), false),
2945+
ast::BiLt => ("lt", lang.ord_trait(), true),
2946+
ast::BiLe => ("le", lang.ord_trait(), true),
2947+
ast::BiGe => ("ge", lang.ord_trait(), true),
2948+
ast::BiGt => ("gt", lang.ord_trait(), true),
2949+
ast::BiEq => ("eq", lang.eq_trait(), true),
2950+
ast::BiNe => ("ne", lang.eq_trait(), true),
29492951
ast::BiAnd | ast::BiOr => {
29502952
// TODO(japaric) use span_bug
29512953
unreachable!();
29522954
}
29532955
};
2954-
lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
2955-
trait_did, lhs_expr, Some(rhs), || {
2956+
2957+
let autoref_args =
2958+
if ast_util::is_by_value_binop(op.node) {
2959+
AutorefArgs::No
2960+
} else {
2961+
AutorefArgs::Yes
2962+
};
2963+
2964+
let report_error = || {
29562965
fcx.type_error_message(ex.span, |actual| {
29572966
format!("binary operation `{}` cannot be applied to type `{}`",
29582967
ast_util::binop_to_string(op.node),
29592968
actual)
29602969
}, lhs_resolved_t, None)
2961-
}, if ast_util::is_by_value_binop(op.node) { AutorefArgs::No } else { AutorefArgs::Yes })
2970+
};
2971+
2972+
let output_ty =
2973+
lookup_op_method(fcx,
2974+
ex,
2975+
lhs_resolved_t,
2976+
token::intern(name),
2977+
trait_did,
2978+
lhs_expr,
2979+
Some(rhs),
2980+
report_error,
2981+
autoref_args);
2982+
2983+
// Special case rule to aid type inference: operational
2984+
// operators always yield boolean; for non-operational
2985+
// operators, if both left and right hand side types are
2986+
// integral, then the result type also be the same as the LHS.
2987+
if
2988+
is_comparison
2989+
{
2990+
demand::eqtype(fcx, ex.span, ty::mk_bool(fcx.tcx()), output_ty);
2991+
} else if
2992+
ty::type_is_integral(lhs_resolved_t) && {
2993+
let rhs_resolved_t = fcx.resolve_type_vars_if_possible(fcx.expr_ty(rhs));
2994+
ty::type_is_integral(rhs_resolved_t)
2995+
}
2996+
{
2997+
demand::eqtype(fcx, ex.span, lhs_resolved_t, output_ty);
2998+
}
2999+
3000+
output_ty
29623001
}
29633002

29643003
fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,

0 commit comments

Comments
 (0)