Clean up some builtin operator typeck logic

This commit is contained in:
Michael Goulet 2023-04-26 23:07:16 +00:00
parent 1c42cb4ef0
commit 3d80dd983d
3 changed files with 39 additions and 38 deletions

View File

@ -461,15 +461,9 @@ fn fatally_break_rust(sess: &Session) {
)); ));
} }
fn has_expected_num_generic_args( fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
tcx: TyCtxt<'_>, let generics = tcx.generics_of(trait_did);
trait_did: Option<DefId>, generics.count() == expected + if generics.has_self { 1 } else { 0 }
expected: usize,
) -> bool {
trait_did.map_or(true, |trait_did| {
let generics = tcx.generics_of(trait_did);
generics.count() == expected + if generics.has_self { 1 } else { 0 }
})
} }
pub fn provide(providers: &mut Providers) { pub fn provide(providers: &mut Providers) {

View File

@ -719,7 +719,10 @@ fn lookup_op_method(
Op::Binary(op, _) => op.span, Op::Binary(op, _) => op.span,
Op::Unary(_, span) => span, Op::Unary(_, span) => span,
}; };
let (opname, trait_did) = lang_item_for_op(self.tcx, op, span); let (opname, Some(trait_did)) = lang_item_for_op(self.tcx, op, span) else {
// Bail if the operator trait is not defined.
return Err(vec![]);
};
debug!( debug!(
"lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})", "lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
@ -759,18 +762,20 @@ fn lookup_op_method(
}, },
); );
let method = trait_did.and_then(|trait_did| { let method = self.lookup_method_in_trait(
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, Some(input_types)) cause.clone(),
}); opname,
trait_did,
match (method, trait_did) { lhs_ty,
(Some(ok), _) => { Some(input_types),
);
match method {
Some(ok) => {
let method = self.register_infer_ok_obligations(ok); let method = self.register_infer_ok_obligations(ok);
self.select_obligations_where_possible(|_| {}); self.select_obligations_where_possible(|_| {});
Ok(method) Ok(method)
} }
(None, None) => Err(vec![]), None => {
(None, Some(trait_did)) => {
let (obligation, _) = let (obligation, _) =
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types)); self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
// FIXME: This should potentially just add the obligation to the `FnCtxt` // FIXME: This should potentially just add the obligation to the `FnCtxt`

View File

@ -200,9 +200,12 @@ pub(super) fn try_overloaded_place_op(
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> { ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op); debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
let (imm_tr, imm_op) = match op { let (Some(imm_tr), imm_op) = (match op {
PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref), PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index), PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
}) else {
// Bail if `Deref` or `Index` isn't defined.
return None;
}; };
// If the lang item was declared incorrectly, stop here so that we don't // If the lang item was declared incorrectly, stop here so that we don't
@ -219,15 +222,13 @@ pub(super) fn try_overloaded_place_op(
return None; return None;
} }
imm_tr.and_then(|trait_did| { self.lookup_method_in_trait(
self.lookup_method_in_trait( self.misc(span),
self.misc(span), Ident::with_dummy_span(imm_op),
Ident::with_dummy_span(imm_op), imm_tr,
trait_did, base_ty,
base_ty, Some(arg_tys),
Some(arg_tys), )
)
})
} }
fn try_mutable_overloaded_place_op( fn try_mutable_overloaded_place_op(
@ -239,9 +240,12 @@ fn try_mutable_overloaded_place_op(
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> { ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op); debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
let (mut_tr, mut_op) = match op { let (Some(mut_tr), mut_op) = (match op {
PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut), PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut), PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
}) else {
// Bail if `DerefMut` or `IndexMut` isn't defined.
return None;
}; };
// If the lang item was declared incorrectly, stop here so that we don't // If the lang item was declared incorrectly, stop here so that we don't
@ -258,15 +262,13 @@ fn try_mutable_overloaded_place_op(
return None; return None;
} }
mut_tr.and_then(|trait_did| { self.lookup_method_in_trait(
self.lookup_method_in_trait( self.misc(span),
self.misc(span), Ident::with_dummy_span(mut_op),
Ident::with_dummy_span(mut_op), mut_tr,
trait_did, base_ty,
base_ty, Some(arg_tys),
Some(arg_tys), )
)
})
} }
/// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index` /// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index`