Skip to content

Commit 1e3c0da

Browse files
authored
Rollup merge of #132274 - compiler-errors:cleanup-op-lookup, r=nnethercote
Cleanup op lookup in HIR typeck Minor cleanup for some redundant methods involved with looking up the `Operator::operator` methods for operators.
2 parents f9fdd63 + 3240fe2 commit 1e3c0da

File tree

5 files changed

+65
-83
lines changed

5 files changed

+65
-83
lines changed

compiler/rustc_hir_typeck/src/autoderef.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2323
span: Span,
2424
base_ty: Ty<'tcx>,
2525
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
26-
self.try_overloaded_place_op(span, base_ty, &[], PlaceOp::Deref)
26+
self.try_overloaded_place_op(span, base_ty, None, PlaceOp::Deref)
2727
}
2828

2929
/// Returns the adjustment steps.

compiler/rustc_hir_typeck/src/callee.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{iter, slice};
1+
use std::iter;
22

33
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
44
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
@@ -300,7 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
300300
Ident::with_dummy_span(method_name),
301301
trait_def_id,
302302
adjusted_ty,
303-
opt_input_type.as_ref().map(slice::from_ref),
303+
opt_input_type,
304304
) {
305305
let method = self.register_infer_ok_obligations(ok);
306306
let mut autoref = None;

compiler/rustc_hir_typeck/src/method/mod.rs

+31-60
Original file line numberDiff line numberDiff line change
@@ -324,35 +324,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
324324
Ok(pick)
325325
}
326326

327-
pub(super) fn obligation_for_method(
328-
&self,
329-
cause: ObligationCause<'tcx>,
330-
trait_def_id: DefId,
331-
self_ty: Ty<'tcx>,
332-
opt_input_types: Option<&[Ty<'tcx>]>,
333-
) -> (traits::PredicateObligation<'tcx>, ty::GenericArgsRef<'tcx>) {
334-
// Construct a trait-reference `self_ty : Trait<input_tys>`
335-
let args = GenericArgs::for_item(self.tcx, trait_def_id, |param, _| {
336-
match param.kind {
337-
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {}
338-
GenericParamDefKind::Type { .. } => {
339-
if param.index == 0 {
340-
return self_ty.into();
341-
} else if let Some(input_types) = opt_input_types {
342-
return input_types[param.index as usize - 1].into();
343-
}
344-
}
345-
}
346-
self.var_for_def(cause.span, param)
347-
});
348-
349-
let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, args);
350-
351-
// Construct an obligation
352-
let poly_trait_ref = ty::Binder::dummy(trait_ref);
353-
(traits::Obligation::new(self.tcx, cause, self.param_env, poly_trait_ref), args)
354-
}
355-
356327
/// `lookup_method_in_trait` is used for overloaded operators.
357328
/// It does a very narrow slice of what the normal probe/confirm path does.
358329
/// In particular, it doesn't really do any probing: it simply constructs
@@ -365,24 +336,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
365336
m_name: Ident,
366337
trait_def_id: DefId,
367338
self_ty: Ty<'tcx>,
368-
opt_input_types: Option<&[Ty<'tcx>]>,
339+
opt_rhs_ty: Option<Ty<'tcx>>,
369340
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
370-
let (obligation, args) =
371-
self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types);
372-
self.construct_obligation_for_trait(m_name, trait_def_id, obligation, args)
373-
}
341+
// Construct a trait-reference `self_ty : Trait<input_tys>`
342+
let args = GenericArgs::for_item(self.tcx, trait_def_id, |param, _| match param.kind {
343+
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {
344+
unreachable!("did not expect operator trait to have lifetime/const")
345+
}
346+
GenericParamDefKind::Type { .. } => {
347+
if param.index == 0 {
348+
self_ty.into()
349+
} else if let Some(rhs_ty) = opt_rhs_ty {
350+
assert_eq!(param.index, 1, "did not expect >1 param on operator trait");
351+
rhs_ty.into()
352+
} else {
353+
// FIXME: We should stop passing `None` for the failure case
354+
// when probing for call exprs. I.e. `opt_rhs_ty` should always
355+
// be set when it needs to be.
356+
self.var_for_def(cause.span, param)
357+
}
358+
}
359+
});
374360

375-
// FIXME(#18741): it seems likely that we can consolidate some of this
376-
// code with the other method-lookup code. In particular, the second half
377-
// of this method is basically the same as confirmation.
378-
fn construct_obligation_for_trait(
379-
&self,
380-
m_name: Ident,
381-
trait_def_id: DefId,
382-
obligation: traits::PredicateObligation<'tcx>,
383-
args: ty::GenericArgsRef<'tcx>,
384-
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
385-
debug!(?obligation);
361+
let obligation = traits::Obligation::new(
362+
self.tcx,
363+
cause,
364+
self.param_env,
365+
ty::TraitRef::new_from_args(self.tcx, trait_def_id, args),
366+
);
386367

387368
// Now we want to know if this can be matched
388369
if !self.predicate_may_hold(&obligation) {
@@ -406,8 +387,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
406387
debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
407388
let mut obligations = PredicateObligations::new();
408389

409-
// FIXME(effects): revisit when binops get `#[const_trait]`
410-
411390
// Instantiate late-bound regions and instantiate the trait
412391
// parameters into the method type to get the actual method type.
413392
//
@@ -418,12 +397,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
418397
let fn_sig =
419398
self.instantiate_binder_with_fresh_vars(obligation.cause.span, infer::FnCall, fn_sig);
420399

421-
let InferOk { value, obligations: o } =
400+
let InferOk { value: fn_sig, obligations: o } =
422401
self.at(&obligation.cause, self.param_env).normalize(fn_sig);
423-
let fn_sig = {
424-
obligations.extend(o);
425-
value
426-
};
402+
obligations.extend(o);
427403

428404
// Register obligations for the parameters. This will include the
429405
// `Self` parameter, which in turn has a bound of the main trait,
@@ -435,13 +411,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
435411
// any late-bound regions appearing in its bounds.
436412
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, args);
437413

438-
let InferOk { value, obligations: o } =
414+
let InferOk { value: bounds, obligations: o } =
439415
self.at(&obligation.cause, self.param_env).normalize(bounds);
440-
let bounds = {
441-
obligations.extend(o);
442-
value
443-
};
444-
416+
obligations.extend(o);
445417
assert!(!bounds.has_escaping_bound_vars());
446418

447419
let predicates_cause = obligation.cause.clone();
@@ -454,7 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
454426
// Also add an obligation for the method type being well-formed.
455427
let method_ty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(fn_sig));
456428
debug!(
457-
"lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
429+
"lookup_method_in_trait: matched method method_ty={:?} obligation={:?}",
458430
method_ty, obligation
459431
);
460432
obligations.push(traits::Obligation::new(
@@ -467,7 +439,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
467439
));
468440

469441
let callee = MethodCallee { def_id, args, sig: fn_sig };
470-
471442
debug!("callee = {:?}", callee);
472443

473444
Some(InferOk { obligations, value: callee })

compiler/rustc_hir_typeck/src/op.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_span::Span;
1515
use rustc_span::source_map::Spanned;
1616
use rustc_span::symbol::{Ident, sym};
1717
use rustc_trait_selection::infer::InferCtxtExt;
18-
use rustc_trait_selection::traits::{FulfillmentError, ObligationCtxt};
18+
use rustc_trait_selection::traits::{FulfillmentError, Obligation, ObligationCtxt};
1919
use rustc_type_ir::TyKind::*;
2020
use tracing::debug;
2121
use {rustc_ast as ast, rustc_hir as hir};
@@ -895,7 +895,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895895

896896
let opname = Ident::with_dummy_span(opname);
897897
let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
898-
let input_types = opt_rhs_ty.as_slice();
899898
let cause = self.cause(span, ObligationCauseCode::BinOp {
900899
lhs_hir_id: lhs_expr.hir_id,
901900
rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
@@ -904,13 +903,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
904903
output_ty: expected.only_has_type(self),
905904
});
906905

907-
let method = self.lookup_method_in_trait(
908-
cause.clone(),
909-
opname,
910-
trait_did,
911-
lhs_ty,
912-
Some(input_types),
913-
);
906+
let method =
907+
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, opt_rhs_ty);
914908
match method {
915909
Some(ok) => {
916910
let method = self.register_infer_ok_obligations(ok);
@@ -931,9 +925,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
931925
self.check_expr_coercible_to_type(rhs_expr, rhs_ty, None);
932926
}
933927

934-
let (obligation, _) =
935-
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
936-
// FIXME: This should potentially just add the obligation to the `FnCtxt`
928+
// Construct an obligation `self_ty : Trait<input_tys>`
929+
let args =
930+
ty::GenericArgs::for_item(self.tcx, trait_did, |param, _| match param.kind {
931+
ty::GenericParamDefKind::Lifetime
932+
| ty::GenericParamDefKind::Const { .. } => {
933+
unreachable!("did not expect operand trait to have lifetime/const args")
934+
}
935+
ty::GenericParamDefKind::Type { .. } => {
936+
if param.index == 0 {
937+
lhs_ty.into()
938+
} else {
939+
opt_rhs_ty.expect("expected RHS for binop").into()
940+
}
941+
}
942+
});
943+
let obligation = Obligation::new(
944+
self.tcx,
945+
cause,
946+
self.param_env,
947+
ty::TraitRef::new_from_args(self.tcx, trait_did, args),
948+
);
937949
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
938950
ocx.register_obligation(obligation);
939951
Err(ocx.select_all_or_error())

compiler/rustc_hir_typeck/src/place_op.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149149
// If some lookup succeeded, install method in table
150150
let input_ty = self.next_ty_var(base_expr.span);
151151
let method =
152-
self.try_overloaded_place_op(expr.span, self_ty, &[input_ty], PlaceOp::Index);
152+
self.try_overloaded_place_op(expr.span, self_ty, Some(input_ty), PlaceOp::Index);
153153

154154
if let Some(result) = method {
155155
debug!("try_index_step: success, using overloaded indexing");
@@ -189,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
189189
&self,
190190
span: Span,
191191
base_ty: Ty<'tcx>,
192-
arg_tys: &[Ty<'tcx>],
192+
opt_rhs_ty: Option<Ty<'tcx>>,
193193
op: PlaceOp,
194194
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
195195
debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
@@ -207,15 +207,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
207207
Ident::with_dummy_span(imm_op),
208208
imm_tr,
209209
base_ty,
210-
Some(arg_tys),
210+
opt_rhs_ty,
211211
)
212212
}
213213

214214
fn try_mutable_overloaded_place_op(
215215
&self,
216216
span: Span,
217217
base_ty: Ty<'tcx>,
218-
arg_tys: &[Ty<'tcx>],
218+
opt_rhs_ty: Option<Ty<'tcx>>,
219219
op: PlaceOp,
220220
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
221221
debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
@@ -233,7 +233,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
233233
Ident::with_dummy_span(mut_op),
234234
mut_tr,
235235
base_ty,
236-
Some(arg_tys),
236+
opt_rhs_ty,
237237
)
238238
}
239239

@@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
284284
&& let Some(ok) = self.try_mutable_overloaded_place_op(
285285
expr.span,
286286
source,
287-
&[],
287+
None,
288288
PlaceOp::Deref,
289289
)
290290
{
@@ -359,8 +359,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
359359
Some(self.typeck_results.borrow().node_args(expr.hir_id).type_at(1))
360360
}
361361
};
362-
let arg_tys = arg_ty.as_slice();
363-
let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op);
362+
let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_ty, op);
364363
let method = match method {
365364
Some(ok) => self.register_infer_ok_obligations(ok),
366365
// Couldn't find the mutable variant of the place op, keep the

0 commit comments

Comments
 (0)