Skip to content

Commit c991c24

Browse files
authored
Rollup merge of #106173 - compiler-errors:deduplicate-op-methods, r=jackh726
Deduplicate `op` methods There are some operator-checking flavored methods in `FnCtxt` that can be deduplicated.
2 parents 31f5e75 + 8bf7ec7 commit c991c24

File tree

4 files changed

+52
-159
lines changed

4 files changed

+52
-159
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
241241
});
242242

243243
if let Some(ok) = self.lookup_method_in_trait(
244-
call_expr.span,
244+
self.misc(call_expr.span),
245245
method_name,
246246
trait_def_id,
247247
adjusted_ty,

compiler/rustc_hir_typeck/src/method/mod.rs

+18-122
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use self::suggest::SelfSource;
1111
pub use self::MethodError::*;
1212

1313
use crate::errors::OpMethodGenericParams;
14-
use crate::{Expectation, FnCtxt};
14+
use crate::FnCtxt;
1515
use rustc_data_structures::sync::Lrc;
1616
use rustc_errors::{Applicability, Diagnostic};
1717
use rustc_hir as hir;
@@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
264264

265265
pub(super) fn obligation_for_method(
266266
&self,
267-
span: Span,
267+
cause: ObligationCause<'tcx>,
268268
trait_def_id: DefId,
269269
self_ty: Ty<'tcx>,
270270
opt_input_types: Option<&[Ty<'tcx>]>,
@@ -282,71 +282,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
282282
}
283283
}
284284
}
285-
self.var_for_def(span, param)
286-
});
287-
288-
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
289-
290-
// Construct an obligation
291-
let poly_trait_ref = ty::Binder::dummy(trait_ref);
292-
(
293-
traits::Obligation::misc(
294-
self.tcx,
295-
span,
296-
self.body_id,
297-
self.param_env,
298-
poly_trait_ref.without_const(),
299-
),
300-
substs,
301-
)
302-
}
303-
304-
pub(super) fn obligation_for_op_method(
305-
&self,
306-
span: Span,
307-
trait_def_id: DefId,
308-
self_ty: Ty<'tcx>,
309-
opt_input_type: Option<Ty<'tcx>>,
310-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
311-
expected: Expectation<'tcx>,
312-
) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>)
313-
{
314-
// Construct a trait-reference `self_ty : Trait<input_tys>`
315-
let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
316-
match param.kind {
317-
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {}
318-
GenericParamDefKind::Type { .. } => {
319-
if param.index == 0 {
320-
return self_ty.into();
321-
} else if let Some(input_type) = opt_input_type {
322-
return input_type.into();
323-
}
324-
}
325-
}
326-
self.var_for_def(span, param)
285+
self.var_for_def(cause.span, param)
327286
});
328287

329288
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
330289

331290
// Construct an obligation
332291
let poly_trait_ref = ty::Binder::dummy(trait_ref);
333-
let output_ty = expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
334-
335292
(
336293
traits::Obligation::new(
337294
self.tcx,
338-
traits::ObligationCause::new(
339-
span,
340-
self.body_id,
341-
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(_))),
345-
output_ty,
346-
},
347-
),
295+
cause,
348296
self.param_env,
349-
poly_trait_ref,
297+
poly_trait_ref.without_const(),
350298
),
351299
substs,
352300
)
@@ -357,69 +305,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
357305
/// In particular, it doesn't really do any probing: it simply constructs
358306
/// an obligation for a particular trait with the given self type and checks
359307
/// whether that trait is implemented.
360-
#[instrument(level = "debug", skip(self, span))]
308+
#[instrument(level = "debug", skip(self))]
361309
pub(super) fn lookup_method_in_trait(
362310
&self,
363-
span: Span,
311+
cause: ObligationCause<'tcx>,
364312
m_name: Ident,
365313
trait_def_id: DefId,
366314
self_ty: Ty<'tcx>,
367315
opt_input_types: Option<&[Ty<'tcx>]>,
368316
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
369317
let (obligation, substs) =
370-
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-
)
380-
}
381-
382-
pub(super) fn lookup_op_method_in_trait(
383-
&self,
384-
span: Span,
385-
m_name: Ident,
386-
trait_def_id: DefId,
387-
self_ty: Ty<'tcx>,
388-
opt_input_type: Option<Ty<'tcx>>,
389-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
390-
expected: Expectation<'tcx>,
391-
) -> 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-
)
318+
self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types);
319+
self.construct_obligation_for_trait(m_name, trait_def_id, obligation, substs)
409320
}
410321

411322
// FIXME(#18741): it seems likely that we can consolidate some of this
412323
// code with the other method-lookup code. In particular, the second half
413324
// of this method is basically the same as confirmation.
414325
fn construct_obligation_for_trait(
415326
&self,
416-
span: Span,
417327
m_name: Ident,
418328
trait_def_id: DefId,
419329
obligation: traits::PredicateObligation<'tcx>,
420330
substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
421-
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
422-
is_op: bool,
423331
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
424332
debug!(?obligation);
425333

@@ -435,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
435343
let tcx = self.tcx;
436344
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
437345
tcx.sess.delay_span_bug(
438-
span,
346+
obligation.cause.span,
439347
"operator trait does not have corresponding operator method",
440348
);
441349
return None;
@@ -461,24 +369,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
461369
// with bound regions.
462370
let fn_sig = tcx.bound_fn_sig(def_id);
463371
let fn_sig = fn_sig.subst(self.tcx, substs);
464-
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig);
465-
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-
};
372+
let fn_sig =
373+
self.replace_bound_vars_with_fresh_vars(obligation.cause.span, infer::FnCall, fn_sig);
480374

481-
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig);
375+
let InferOk { value, obligations: o } =
376+
self.at(&obligation.cause, self.param_env).normalize(fn_sig);
482377
let fn_sig = {
483378
obligations.extend(o);
484379
value
@@ -494,15 +389,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
494389
// any late-bound regions appearing in its bounds.
495390
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
496391

497-
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds);
392+
let InferOk { value, obligations: o } =
393+
self.at(&obligation.cause, self.param_env).normalize(bounds);
498394
let bounds = {
499395
obligations.extend(o);
500396
value
501397
};
502398

503399
assert!(!bounds.has_escaping_bound_vars());
504400

505-
let predicates_cause = cause.clone();
401+
let predicates_cause = obligation.cause.clone();
506402
obligations.extend(traits::predicates_for_generics(
507403
move |_, _| predicates_cause.clone(),
508404
self.param_env,
@@ -517,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
517413
);
518414
obligations.push(traits::Obligation::new(
519415
tcx,
520-
cause,
416+
obligation.cause,
521417
self.param_env,
522418
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
523419
));

0 commit comments

Comments
 (0)