mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Implement changes suggested by varkor
This commit is contained in:
parent
7217d767b2
commit
4efa4a5273
@ -182,6 +182,8 @@ impl LanguageItemCollector<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like collect_item() above, but also checks whether the lang item is declared
|
||||||
|
// with the right number of generic arguments if it is a trait.
|
||||||
fn collect_item_extended(&mut self, item_index: usize, hir_id: HirId, span: Span) {
|
fn collect_item_extended(&mut self, item_index: usize, hir_id: HirId, span: Span) {
|
||||||
let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
|
let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
|
||||||
let lang_item = LangItem::from_u32(item_index as u32).unwrap();
|
let lang_item = LangItem::from_u32(item_index as u32).unwrap();
|
||||||
@ -190,10 +192,15 @@ impl LanguageItemCollector<'tcx> {
|
|||||||
self.collect_item(item_index, item_def_id);
|
self.collect_item(item_index, item_def_id);
|
||||||
|
|
||||||
// Now check whether the lang_item has the expected number of generic
|
// Now check whether the lang_item has the expected number of generic
|
||||||
// arguments. Binary and indexing operations have one (for the RHS/index),
|
// arguments if it is a trait. Generally speaking, binary and indexing
|
||||||
// unary operations have no generic arguments.
|
// operations have one (for the RHS/index), unary operations have none,
|
||||||
|
// and the rest also have none except for the closure traits (one for
|
||||||
|
// the argument list), generators (one for the resume argument),
|
||||||
|
// ordering/equality relations (one for the RHS), and various conversion
|
||||||
|
// traits.
|
||||||
|
|
||||||
let expected_num = match lang_item {
|
let expected_num = match lang_item {
|
||||||
|
// Binary operations
|
||||||
LangItem::Add
|
LangItem::Add
|
||||||
| LangItem::Sub
|
| LangItem::Sub
|
||||||
| LangItem::Mul
|
| LangItem::Mul
|
||||||
@ -215,11 +222,48 @@ impl LanguageItemCollector<'tcx> {
|
|||||||
| LangItem::ShlAssign
|
| LangItem::ShlAssign
|
||||||
| LangItem::ShrAssign
|
| LangItem::ShrAssign
|
||||||
| LangItem::Index
|
| LangItem::Index
|
||||||
| LangItem::IndexMut => Some(1),
|
| LangItem::IndexMut
|
||||||
|
|
||||||
LangItem::Neg | LangItem::Not | LangItem::Deref | LangItem::DerefMut => Some(0),
|
// Miscellaneous
|
||||||
|
| LangItem::Unsize
|
||||||
|
| LangItem::CoerceUnsized
|
||||||
|
| LangItem::DispatchFromDyn
|
||||||
|
| LangItem::Fn
|
||||||
|
| LangItem::FnMut
|
||||||
|
| LangItem::FnOnce
|
||||||
|
| LangItem::Generator
|
||||||
|
| LangItem::PartialEq
|
||||||
|
| LangItem::PartialOrd
|
||||||
|
=> Some(1),
|
||||||
|
|
||||||
// FIXME: add more cases?
|
// Unary operations
|
||||||
|
LangItem::Neg
|
||||||
|
| LangItem::Not
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
|
| LangItem::Deref
|
||||||
|
| LangItem::DerefMut
|
||||||
|
| LangItem::Sized
|
||||||
|
| LangItem::StructuralPeq
|
||||||
|
| LangItem::StructuralTeq
|
||||||
|
| LangItem::Copy
|
||||||
|
| LangItem::Clone
|
||||||
|
| LangItem::Sync
|
||||||
|
| LangItem::DiscriminantKind
|
||||||
|
| LangItem::PointeeTrait
|
||||||
|
| LangItem::Freeze
|
||||||
|
| LangItem::Drop
|
||||||
|
| LangItem::Receiver
|
||||||
|
| LangItem::Future
|
||||||
|
| LangItem::Unpin
|
||||||
|
| LangItem::Termination
|
||||||
|
| LangItem::Try
|
||||||
|
| LangItem::Send
|
||||||
|
| LangItem::UnwindSafe
|
||||||
|
| LangItem::RefUnwindSafe
|
||||||
|
=> Some(0),
|
||||||
|
|
||||||
|
// Not a trait
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1190,3 +1190,17 @@ fn fatally_break_rust(sess: &Session) {
|
|||||||
fn potentially_plural_count(count: usize, word: &str) -> String {
|
fn potentially_plural_count(count: usize, word: &str) -> String {
|
||||||
format!("{} {}{}", count, word, pluralize!(count))
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Code related to processing overloaded binary and unary operators.
|
//! Code related to processing overloaded binary and unary operators.
|
||||||
|
|
||||||
use super::method::MethodCallee;
|
use super::method::MethodCallee;
|
||||||
use super::FnCtxt;
|
use super::{has_expected_num_generic_args, FnCtxt};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
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
|
// 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
|
// index `other_tys` out of bounds (if the lang item has too many
|
||||||
// generic arguments, `other_tys` is too short).
|
// generic arguments, `other_tys` is too short).
|
||||||
if let Some(trait_did) = trait_did {
|
if !has_expected_num_generic_args(
|
||||||
let generics = self.tcx.generics_of(trait_did);
|
self.tcx,
|
||||||
let expected_num = match op {
|
trait_did,
|
||||||
|
match op {
|
||||||
// Binary ops have a generic right-hand side, unary ops don't
|
// Binary ops have a generic right-hand side, unary ops don't
|
||||||
Op::Binary(..) => 1,
|
Op::Binary(..) => 1,
|
||||||
Op::Unary(..) => 0,
|
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| {
|
let method = trait_did.and_then(|trait_did| {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::check::method::MethodCallee;
|
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_hir as hir;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::InferOk;
|
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
|
// 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
|
// run into an ICE (#83893). The error is reported where the lang item is
|
||||||
// declared.
|
// declared.
|
||||||
if let Some(trait_did) = imm_tr {
|
if !has_expected_num_generic_args(
|
||||||
let generics = self.tcx.generics_of(trait_did);
|
self.tcx,
|
||||||
let expected_num = match op {
|
imm_tr,
|
||||||
|
match op {
|
||||||
PlaceOp::Deref => 0,
|
PlaceOp::Deref => 0,
|
||||||
PlaceOp::Index => 1,
|
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| {
|
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
|
// 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
|
// run into an ICE (#83893). The error is reported where the lang item is
|
||||||
// declared.
|
// declared.
|
||||||
if let Some(trait_did) = mut_tr {
|
if !has_expected_num_generic_args(
|
||||||
let generics = self.tcx.generics_of(trait_did);
|
self.tcx,
|
||||||
let expected_num = match op {
|
mut_tr,
|
||||||
|
match op {
|
||||||
PlaceOp::Deref => 0,
|
PlaceOp::Deref => 0,
|
||||||
PlaceOp::Index => 1,
|
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| {
|
mut_tr.and_then(|trait_did| {
|
||||||
|
Loading…
Reference in New Issue
Block a user