From 3d80dd983d4048f0a480a76421cf30773d2a9081 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 26 Apr 2023 23:07:16 +0000 Subject: [PATCH] Clean up some builtin operator typeck logic --- compiler/rustc_hir_typeck/src/lib.rs | 12 ++----- compiler/rustc_hir_typeck/src/op.rs | 23 ++++++++----- compiler/rustc_hir_typeck/src/place_op.rs | 42 ++++++++++++----------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 5ccac9a6925..46318043b78 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -461,15 +461,9 @@ fn fatally_break_rust(sess: &Session) { )); } -fn has_expected_num_generic_args( - tcx: TyCtxt<'_>, - trait_did: Option, - 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 } - }) +fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool { + let generics = tcx.generics_of(trait_did); + generics.count() == expected + if generics.has_self { 1 } else { 0 } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index a52c94cb00c..9b6c1077a40 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -719,7 +719,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Op::Binary(op, _) => op.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!( "lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})", @@ -759,18 +762,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, ); - let method = trait_did.and_then(|trait_did| { - self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, Some(input_types)) - }); - - match (method, trait_did) { - (Some(ok), _) => { + let method = self.lookup_method_in_trait( + cause.clone(), + opname, + trait_did, + lhs_ty, + Some(input_types), + ); + match method { + Some(ok) => { let method = self.register_infer_ok_obligations(ok); self.select_obligations_where_possible(|_| {}); Ok(method) } - (None, None) => Err(vec![]), - (None, Some(trait_did)) => { + None => { let (obligation, _) = self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types)); // FIXME: This should potentially just add the obligation to the `FnCtxt` diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 2cca45de5e9..1f7e7ba9f5b 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -200,9 +200,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option>> { 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::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 @@ -219,15 +222,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - imm_tr.and_then(|trait_did| { - self.lookup_method_in_trait( - self.misc(span), - Ident::with_dummy_span(imm_op), - trait_did, - base_ty, - Some(arg_tys), - ) - }) + self.lookup_method_in_trait( + self.misc(span), + Ident::with_dummy_span(imm_op), + imm_tr, + base_ty, + Some(arg_tys), + ) } fn try_mutable_overloaded_place_op( @@ -239,9 +240,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option>> { 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::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 @@ -258,15 +262,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - mut_tr.and_then(|trait_did| { - self.lookup_method_in_trait( - self.misc(span), - Ident::with_dummy_span(mut_op), - trait_did, - base_ty, - Some(arg_tys), - ) - }) + self.lookup_method_in_trait( + self.misc(span), + Ident::with_dummy_span(mut_op), + mut_tr, + base_ty, + Some(arg_tys), + ) } /// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index`