Report an error if a lang item has the wrong number of generic arguments
This commit is contained in:
parent
b439be03c9
commit
7217d767b2
12 changed files with 212 additions and 7 deletions
|
@ -303,8 +303,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
opt_input_types: Option<&[Ty<'tcx>]>,
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
debug!(
|
||||
"lookup_in_trait_adjusted(self_ty={:?}, m_name={}, trait_def_id={:?})",
|
||||
self_ty, m_name, trait_def_id
|
||||
"lookup_in_trait_adjusted(self_ty={:?}, m_name={}, trait_def_id={:?}, opt_input_types={:?})",
|
||||
self_ty, m_name, trait_def_id, opt_input_types
|
||||
);
|
||||
|
||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||
|
|
|
@ -795,6 +795,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
lhs_ty, op, opname, trait_did
|
||||
);
|
||||
|
||||
// Catches cases like #83893, where a lang item is declared with the
|
||||
// wrong number of generic arguments. Should have yielded an error
|
||||
// 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 {
|
||||
// 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(());
|
||||
}
|
||||
}
|
||||
|
||||
let method = trait_did.and_then(|trait_did| {
|
||||
let opname = Ident::with_dummy_span(opname);
|
||||
self.lookup_method_in_trait(span, opname, trait_did, lhs_ty, Some(other_tys))
|
||||
|
|
|
@ -153,6 +153,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
|
||||
PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
|
||||
};
|
||||
|
||||
// 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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
imm_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
span,
|
||||
|
@ -177,6 +193,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
|
||||
PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
|
||||
};
|
||||
|
||||
// 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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
mut_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
span,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue