Skip to content

Commit 43b2486

Browse files
Clean up operator type checking
1 parent 58f5a01 commit 43b2486

File tree

2 files changed

+27
-87
lines changed

2 files changed

+27
-87
lines changed

compiler/rustc_hir_typeck/src/method/mod.rs

+16-55
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
306306
span: Span,
307307
trait_def_id: DefId,
308308
self_ty: Ty<'tcx>,
309-
opt_input_type: Option<Ty<'tcx>>,
310-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
309+
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
311310
expected: Expectation<'tcx>,
312311
) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>)
313312
{
@@ -318,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
318317
GenericParamDefKind::Type { .. } => {
319318
if param.index == 0 {
320319
return self_ty.into();
321-
} else if let Some(input_type) = opt_input_type {
320+
} else if let Some((_, input_type)) = opt_rhs {
322321
return input_type.into();
323322
}
324323
}
@@ -339,9 +338,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339338
span,
340339
self.body_id,
341340
traits::BinOp {
342-
rhs_span: opt_input_expr.map(|expr| expr.span),
343-
is_lit: opt_input_expr
344-
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
341+
rhs_span: opt_rhs.map(|(expr, _)| expr.span),
342+
is_lit: opt_rhs
343+
.map_or(false, |(expr, _)| matches!(expr.kind, hir::ExprKind::Lit(_))),
345344
output_ty,
346345
},
347346
),
@@ -368,15 +367,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
368367
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
369368
let (obligation, substs) =
370369
self.obligation_for_method(span, trait_def_id, self_ty, opt_input_types);
371-
self.construct_obligation_for_trait(
372-
span,
373-
m_name,
374-
trait_def_id,
375-
obligation,
376-
substs,
377-
None,
378-
false,
379-
)
370+
self.construct_obligation_for_trait(span, m_name, trait_def_id, obligation, substs)
380371
}
381372

382373
pub(super) fn lookup_op_method_in_trait(
@@ -385,27 +376,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
385376
m_name: Ident,
386377
trait_def_id: DefId,
387378
self_ty: Ty<'tcx>,
388-
opt_input_type: Option<Ty<'tcx>>,
389-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
379+
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
390380
expected: Expectation<'tcx>,
391381
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
392-
let (obligation, substs) = self.obligation_for_op_method(
393-
span,
394-
trait_def_id,
395-
self_ty,
396-
opt_input_type,
397-
opt_input_expr,
398-
expected,
399-
);
400-
self.construct_obligation_for_trait(
401-
span,
402-
m_name,
403-
trait_def_id,
404-
obligation,
405-
substs,
406-
opt_input_expr,
407-
true,
408-
)
382+
let (obligation, substs) =
383+
self.obligation_for_op_method(span, trait_def_id, self_ty, opt_rhs, expected);
384+
self.construct_obligation_for_trait(span, m_name, trait_def_id, obligation, substs)
409385
}
410386

411387
// FIXME(#18741): it seems likely that we can consolidate some of this
@@ -418,8 +394,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
418394
trait_def_id: DefId,
419395
obligation: traits::PredicateObligation<'tcx>,
420396
substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
421-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
422-
is_op: bool,
423397
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
424398
debug!(?obligation);
425399

@@ -463,22 +437,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
463437
let fn_sig = fn_sig.subst(self.tcx, substs);
464438
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig);
465439

466-
let cause = if is_op {
467-
ObligationCause::new(
468-
span,
469-
self.body_id,
470-
traits::BinOp {
471-
rhs_span: opt_input_expr.map(|expr| expr.span),
472-
is_lit: opt_input_expr
473-
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
474-
output_ty: None,
475-
},
476-
)
477-
} else {
478-
traits::ObligationCause::misc(span, self.body_id)
479-
};
480-
481-
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig);
440+
let InferOk { value, obligations: o } =
441+
self.at(&obligation.cause, self.param_env).normalize(fn_sig);
482442
let fn_sig = {
483443
obligations.extend(o);
484444
value
@@ -494,15 +454,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
494454
// any late-bound regions appearing in its bounds.
495455
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
496456

497-
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds);
457+
let InferOk { value, obligations: o } =
458+
self.at(&obligation.cause, self.param_env).normalize(bounds);
498459
let bounds = {
499460
obligations.extend(o);
500461
value
501462
};
502463

503464
assert!(!bounds.has_escaping_bound_vars());
504465

505-
let predicates_cause = cause.clone();
466+
let predicates_cause = obligation.cause.clone();
506467
obligations.extend(traits::predicates_for_generics(
507468
move |_, _| predicates_cause.clone(),
508469
self.param_env,
@@ -517,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
517478
);
518479
obligations.push(traits::Obligation::new(
519480
tcx,
520-
cause,
481+
obligation.cause,
521482
self.param_env,
522483
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
523484
));

compiler/rustc_hir_typeck/src/op.rs

+11-32
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4848
if self
4949
.lookup_op_method(
5050
lhs_deref_ty,
51-
Some(rhs_ty),
52-
Some(rhs),
51+
Some((rhs, rhs_ty)),
5352
Op::Binary(op, IsAssign::Yes),
5453
expected,
5554
)
@@ -60,8 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6059
if self
6160
.lookup_op_method(
6261
lhs_ty,
63-
Some(rhs_ty),
64-
Some(rhs),
62+
Some((rhs, rhs_ty)),
6563
Op::Binary(op, IsAssign::Yes),
6664
expected,
6765
)
@@ -248,8 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248246

249247
let result = self.lookup_op_method(
250248
lhs_ty,
251-
Some(rhs_ty_var),
252-
Some(rhs_expr),
249+
Some((rhs_expr, rhs_ty_var)),
253250
Op::Binary(op, is_assign),
254251
expected,
255252
);
@@ -382,8 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
382379
if self
383380
.lookup_op_method(
384381
lhs_deref_ty,
385-
Some(rhs_ty),
386-
Some(rhs_expr),
382+
Some((rhs_expr, rhs_ty)),
387383
Op::Binary(op, is_assign),
388384
expected,
389385
)
@@ -410,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410406
let is_compatible = |lhs_ty, rhs_ty| {
411407
self.lookup_op_method(
412408
lhs_ty,
413-
Some(rhs_ty),
414-
Some(rhs_expr),
409+
Some((rhs_expr, rhs_ty)),
415410
Op::Binary(op, is_assign),
416411
expected,
417412
)
@@ -471,8 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
471466
let errors = self
472467
.lookup_op_method(
473468
lhs_ty,
474-
Some(rhs_ty),
475-
Some(rhs_expr),
469+
Some((rhs_expr, rhs_ty)),
476470
Op::Binary(op, is_assign),
477471
expected,
478472
)
@@ -625,7 +619,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
625619
expected: Expectation<'tcx>,
626620
) -> Ty<'tcx> {
627621
assert!(op.is_by_value());
628-
match self.lookup_op_method(operand_ty, None, None, Op::Unary(op, ex.span), expected) {
622+
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
629623
Ok(method) => {
630624
self.write_method_call(ex.hir_id, method);
631625
method.sig.output()
@@ -712,8 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
712706
fn lookup_op_method(
713707
&self,
714708
lhs_ty: Ty<'tcx>,
715-
other_ty: Option<Ty<'tcx>>,
716-
other_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
709+
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
717710
op: Op,
718711
expected: Expectation<'tcx>,
719712
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
@@ -747,15 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
747740

748741
let opname = Ident::with_dummy_span(opname);
749742
let method = trait_did.and_then(|trait_did| {
750-
self.lookup_op_method_in_trait(
751-
span,
752-
opname,
753-
trait_did,
754-
lhs_ty,
755-
other_ty,
756-
other_ty_expr,
757-
expected,
758-
)
743+
self.lookup_op_method_in_trait(span, opname, trait_did, lhs_ty, opt_rhs, expected)
759744
});
760745

761746
match (method, trait_did) {
@@ -766,14 +751,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
766751
}
767752
(None, None) => Err(vec![]),
768753
(None, Some(trait_did)) => {
769-
let (obligation, _) = self.obligation_for_op_method(
770-
span,
771-
trait_did,
772-
lhs_ty,
773-
other_ty,
774-
other_ty_expr,
775-
expected,
776-
);
754+
let (obligation, _) =
755+
self.obligation_for_op_method(span, trait_did, lhs_ty, opt_rhs, expected);
777756
Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation))
778757
}
779758
}

0 commit comments

Comments
 (0)