Remove some unnecessary check logic for lang items in HIR typeck

This commit is contained in:
Michael Goulet 2024-01-29 19:31:29 +00:00
parent fb4bca04fa
commit b4efe07006
27 changed files with 21 additions and 445 deletions

View file

@ -96,9 +96,6 @@ hir_typeck_lossy_provenance_ptr2int =
hir_typeck_method_call_on_unknown_raw_pointee =
cannot call a method on a raw pointer with an unknown pointee type
hir_typeck_missing_fn_lang_items = failed to find an overloaded call trait for closure call
.help = make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
@ -108,8 +105,6 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters
hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}`
hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`

View file

@ -253,28 +253,13 @@ fn try_overloaded_call_traits(
adjusted_ty,
opt_input_type.as_ref().map(slice::from_ref),
) {
// Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait.
if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter {
self.dcx().span_delayed_bug(
call_expr.span,
"input to overloaded call fn is not a self receiver",
);
return None;
}
let method = self.register_infer_ok_obligations(ok);
let mut autoref = None;
if borrow {
// Check for &self vs &mut self in the method signature. Since this is either
// the Fn or FnMut trait, it should be one of those.
let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
// The `fn`/`fn_mut` lang item is ill-formed, which should have
// caused an error elsewhere.
self.dcx().span_delayed_bug(
call_expr.span,
"input to call/call_mut is not a ref",
);
return None;
bug!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut")
};
// For initial two-phase borrow
@ -948,9 +933,11 @@ pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
);
}
None => {
// This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
// lang items are not defined (issue #86238).
fcx.dcx().emit_err(errors::MissingFnLangItems { span: self.call_expr.span });
span_bug!(
self.call_expr.span,
"Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{}`",
self.adjusted_ty
)
}
}
}

View file

@ -152,26 +152,22 @@ pub(super) fn check_fn<'a, 'tcx>(
}
fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {
let span = tcx.def_span(fn_id);
let DefKind::Fn = tcx.def_kind(fn_id) else {
let span = tcx.def_span(fn_id);
tcx.dcx().span_err(span, "should be a function");
return;
};
let generic_counts = tcx.generics_of(fn_id).own_counts();
if generic_counts.types != 0 {
let span = tcx.def_span(fn_id);
tcx.dcx().span_err(span, "should have no type parameters");
}
if generic_counts.consts != 0 {
let span = tcx.def_span(fn_id);
tcx.dcx().span_err(span, "should have no const parameters");
}
let Some(panic_info_did) = tcx.lang_items().panic_info() else {
tcx.dcx().err("language item required, but not found: `panic_info`");
return;
};
let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
@ -203,11 +199,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
let _ = check_function_signature(
tcx,
ObligationCause::new(
tcx.def_span(fn_id),
fn_id,
ObligationCauseCode::LangFunctionType(sym::panic_impl),
),
ObligationCause::new(span, fn_id, ObligationCauseCode::LangFunctionType(sym::panic_impl)),
fn_id.into(),
expected_sig,
);

View file

@ -83,14 +83,6 @@ pub struct MethodCallOnUnknownRawPointee {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_missing_fn_lang_items)]
#[help]
pub struct MissingFnLangItems {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
pub struct FunctionalRecordUpdateOnNonStruct {
@ -193,14 +185,6 @@ pub struct AddMissingParenthesesInRange {
pub right: Span,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_op_trait_generic_params)]
pub struct OpMethodGenericParams {
#[primary_span]
pub span: Span,
pub method_name: String,
}
pub struct TypeMismatchFruTypo {
/// Span of the LHS of the range
pub expr_span: Span,

View file

@ -444,15 +444,6 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
diag.emit()
}
/// `expected` here is the expected number of explicit generic arguments on the trait.
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 }
+ if generics.host_effect_index.is_some() { 1 } else { 0 }
}
pub fn provide(providers: &mut Providers) {
method::provide(providers);
*providers = Providers {

View file

@ -10,7 +10,6 @@
pub use self::suggest::SelfSource;
pub use self::MethodError::*;
use crate::errors::OpMethodGenericParams;
use crate::FnCtxt;
use rustc_errors::{Applicability, Diagnostic, SubdiagnosticMessage};
use rustc_hir as hir;
@ -385,26 +384,12 @@ fn construct_obligation_for_trait(
// type parameters or early-bound regions.
let tcx = self.tcx;
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
tcx.dcx().span_delayed_bug(
obligation.cause.span,
"operator trait does not have corresponding operator method",
);
return None;
bug!("expected associated item for operator trait")
};
if method_item.kind != ty::AssocKind::Fn {
self.dcx().span_delayed_bug(tcx.def_span(method_item.def_id), "not a method");
return None;
}
let def_id = method_item.def_id;
let generics = tcx.generics_of(def_id);
if generics.params.len() != 0 {
tcx.dcx().emit_fatal(OpMethodGenericParams {
span: tcx.def_span(method_item.def_id),
method_name: m_name.to_string(),
});
if method_item.kind != ty::AssocKind::Fn {
span_bug!(tcx.def_span(def_id), "expected `{m_name}` to be an associated function");
}
debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);

View file

@ -1,7 +1,7 @@
//! Code related to processing overloaded binary and unary operators.
use super::method::MethodCallee;
use super::{has_expected_num_generic_args, FnCtxt};
use super::FnCtxt;
use crate::Expectation;
use rustc_ast as ast;
use rustc_data_structures::packed::Pu128;
@ -887,25 +887,6 @@ fn lookup_op_method(
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 !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,
},
) {
self.dcx()
.span_delayed_bug(span, "operator didn't have the right number of generic args");
return Err(vec![]);
}
let opname = Ident::with_dummy_span(opname);
let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
let input_types = opt_rhs_ty.as_slice();

View file

@ -1,5 +1,5 @@
use crate::method::MethodCallee;
use crate::{has_expected_num_generic_args, FnCtxt, PlaceOp};
use crate::{FnCtxt, PlaceOp};
use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir as hir;
@ -209,20 +209,6 @@ pub(super) fn try_overloaded_place_op(
return None;
};
// 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 !has_expected_num_generic_args(
self.tcx,
imm_tr,
match op {
PlaceOp::Deref => 0,
PlaceOp::Index => 1,
},
) {
return None;
}
self.lookup_method_in_trait(
self.misc(span),
Ident::with_dummy_span(imm_op),
@ -249,20 +235,6 @@ fn try_mutable_overloaded_place_op(
return None;
};
// 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 !has_expected_num_generic_args(
self.tcx,
mut_tr,
match op {
PlaceOp::Deref => 0,
PlaceOp::Index => 1,
},
) {
return None;
}
self.lookup_method_in_trait(
self.misc(span),
Ident::with_dummy_span(mut_op),

View file

@ -1,18 +0,0 @@
#![feature(no_core)]
#![feature(lang_items)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "add"]
trait Add<T> {
const add: u32 = 1u32;
}
impl Add<u32> for u32 {}
fn main() {
1u32 + 1u32;
//~^ ERROR cannot add `u32` to `u32`
}

View file

@ -1,11 +0,0 @@
error[E0369]: cannot add `u32` to `u32`
--> $DIR/bad-add-impl.rs:16:10
|
LL | 1u32 + 1u32;
| ---- ^ ---- u32
| |
| u32
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0369`.

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,18 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
|
LL | a();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: failed to find an overloaded call trait for closure call
--> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
|
LL | b();
| ^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 2 previous errors

View file

@ -1,49 +0,0 @@
// revisions: fn_once_bad_item fn_once_bad_sig fn_mut_bad_item fn_mut_bad_sig fn_bad_item fn_bad_sig
#![feature(lang_items)]
#![feature(no_core)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[cfg(any(fn_bad_item, fn_bad_sig))]
#[lang = "fn"]
trait MyFn<T> {
#[cfg(fn_bad_sig)]
fn call(i: i32) -> i32 { 0 }
#[cfg(fn_bad_item)]
const call: i32 = 42;
}
#[cfg(any(fn_mut_bad_item, fn_mut_bad_sig))]
#[lang = "fn_mut"]
trait MyFnMut<T> {
#[cfg(fn_mut_bad_sig)]
fn call_mut(i: i32) -> i32 { 0 }
#[cfg(fn_mut_bad_item)]
const call_mut: i32 = 42;
}
#[cfg(any(fn_once_bad_item, fn_once_bad_sig))]
#[lang = "fn_once"]
trait MyFnOnce<T> {
#[cfg(fn_once_bad_sig)]
fn call_once(i: i32) -> i32 { 0 }
#[cfg(fn_once_bad_item)]
const call_once: i32 = 42;
}
fn main() {
let a = || 42;
a();
//~^ ERROR failed to find an overloaded call trait for closure call
let mut i = 0;
let mut b = || { };
b();
//~^ ERROR failed to find an overloaded call trait for closure call
}

View file

@ -1,17 +0,0 @@
#![feature(no_core, lang_items)]
#![no_core]
#[lang="sized"]
trait Sized {}
#[lang="add"]
trait Add<T> {}
impl Add<i32> for i32 {}
fn main() {
let x = 5 + 6;
//~^ ERROR cannot add `i32` to `{integer}`
let y = 5i32 + 6i32;
//~^ ERROR cannot add `i32` to `i32`
}

View file

@ -1,19 +0,0 @@
error[E0369]: cannot add `i32` to `{integer}`
--> $DIR/issue-31076.rs:13:15
|
LL | let x = 5 + 6;
| - ^ - i32
| |
| {integer}
error[E0369]: cannot add `i32` to `i32`
--> $DIR/issue-31076.rs:15:18
|
LL | let y = 5i32 + 6i32;
| ---- ^ ---- i32
| |
| i32
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0369`.

View file

@ -1,16 +0,0 @@
// Regression test for the ICE described in issue #86238.
#![feature(lang_items)]
#![feature(no_core)]
#![no_core]
fn main() {
let one = || {};
one()
//~^ ERROR: failed to find an overloaded call trait for closure call
//~| HELP: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

View file

@ -1,10 +0,0 @@
error: failed to find an overloaded call trait for closure call
--> $DIR/issue-86238.rs:9:5
|
LL | one()
| ^^^^^
|
= help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
error: aborting due to 1 previous error

View file

@ -1,5 +1,4 @@
// compile-flags:-C panic=abort
// error-pattern: language item required, but not found: `panic_info`
#![feature(lang_items)]
#![feature(no_core)]
@ -8,6 +7,7 @@
#[panic_handler]
fn panic() -> ! {
//~^ ERROR requires `panic_info` lang_item
loop {}
}

View file

@ -1,4 +1,8 @@
error: language item required, but not found: `panic_info`
error: requires `panic_info` lang_item
--> $DIR/panic-handler-requires-panic-info.rs:9:1
|
LL | fn panic() -> ! {
| ^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,23 +0,0 @@
#![crate_type = "lib"]
#![feature(lang_items)]
#![feature(no_core)]
#![no_core]
#[lang="sized"]
pub trait Sized {
// Empty.
}
#[lang = "add"]
trait Add<RHS=Self> {
type Output;
fn add<Y>(self, _: RHS) -> Self::Output;
//~^ ERROR `add` must not have any generic parameters
}
#[allow(unreachable_code)]
fn ice(a: usize) {
let r = loop {};
r = r + a;
}

View file

@ -1,8 +0,0 @@
error: `add` must not have any generic parameters
--> $DIR/invalid_operator_trait.rs:15:5
|
LL | fn add<Y>(self, _: RHS) -> Self::Output;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error