1
Fork 0

Implement changes suggested by varkor

This commit is contained in:
Fabian Wolff 2021-05-16 18:16:00 +02:00
parent 7217d767b2
commit 4efa4a5273
4 changed files with 86 additions and 31 deletions

View file

@ -1190,3 +1190,17 @@ fn fatally_break_rust(sess: &Session) {
fn potentially_plural_count(count: usize, word: &str) -> String {
format!("{} {}{}", count, word, pluralize!(count))
}
fn has_expected_num_generic_args<'tcx>(
tcx: TyCtxt<'tcx>,
trait_did: Option<DefId>,
mut expected: usize,
) -> bool {
trait_did.map_or(true, |trait_did| {
let generics = tcx.generics_of(trait_did);
if generics.has_self {
expected += 1;
}
generics.count() == expected
})
}

View file

@ -1,7 +1,7 @@
//! Code related to processing overloaded binary and unary operators.
use super::method::MethodCallee;
use super::FnCtxt;
use super::{has_expected_num_generic_args, FnCtxt};
use rustc_ast as ast;
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
@ -800,17 +800,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// elsewhere by now, but we have to catch it here so that we do not
// index `other_tys` out of bounds (if the lang item has too many
// generic arguments, `other_tys` is too short).
if let Some(trait_did) = trait_did {
let generics = self.tcx.generics_of(trait_did);
let expected_num = match op {
if !has_expected_num_generic_args(
self.tcx,
trait_did,
match op {
// Binary ops have a generic right-hand side, unary ops don't
Op::Binary(..) => 1,
Op::Unary(..) => 0,
} + if generics.has_self { 1 } else { 0 };
let num_generics = generics.count();
if num_generics != expected_num {
return Err(());
}
},
) {
return Err(());
}
let method = trait_did.and_then(|trait_did| {

View file

@ -1,5 +1,5 @@
use crate::check::method::MethodCallee;
use crate::check::{FnCtxt, PlaceOp};
use crate::check::{has_expected_num_generic_args, FnCtxt, PlaceOp};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk;
@ -157,16 +157,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If the lang item was declared incorrectly, stop here so that we don't
// run into an ICE (#83893). The error is reported where the lang item is
// declared.
if let Some(trait_did) = imm_tr {
let generics = self.tcx.generics_of(trait_did);
let expected_num = match op {
if !has_expected_num_generic_args(
self.tcx,
imm_tr,
match op {
PlaceOp::Deref => 0,
PlaceOp::Index => 1,
} + if generics.has_self { 1 } else { 0 };
let num_generics = generics.count();
if num_generics != expected_num {
return None;
}
},
) {
return None;
}
imm_tr.and_then(|trait_did| {
@ -197,16 +196,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If the lang item was declared incorrectly, stop here so that we don't
// run into an ICE (#83893). The error is reported where the lang item is
// declared.
if let Some(trait_did) = mut_tr {
let generics = self.tcx.generics_of(trait_did);
let expected_num = match op {
if !has_expected_num_generic_args(
self.tcx,
mut_tr,
match op {
PlaceOp::Deref => 0,
PlaceOp::Index => 1,
} + if generics.has_self { 1 } else { 0 };
let num_generics = generics.count();
if num_generics != expected_num {
return None;
}
},
) {
return None;
}
mut_tr.and_then(|trait_did| {