Skip to content

Commit

Permalink
Rollup merge of rust-lang#120476 - compiler-errors:lang-items-yeet, r…
Browse files Browse the repository at this point in the history
…=Nilstrieb

Remove some unnecessary check logic for lang items in HIR typeck

Obvious bugs with `#[no_core]` do not deserve customized recovery logic, since they are bugs we do not expect users to ever encounter, and if users are experimenting with `#[no_core]`, they should really be familiar with the compiler implementation.

These error recoveries are implemented now only where issues have been reported in the past, rather than systematically validating lang items.

See rust-lang/compiler-team#620
> In particular, one-off fixes for particular assumptions about lang items or intrinsics that introduce additional complexity into the compiler are not accepted.

r? Nilstrieb
  • Loading branch information
GuillaumeGomez committed Jan 30, 2024
2 parents 399b81f + b4efe07 commit f3f1472
Show file tree
Hide file tree
Showing 27 changed files with 21 additions and 445 deletions.
5 changes: 0 additions & 5 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand All @@ -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}`
Expand Down
25 changes: 6 additions & 19 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,28 +254,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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
Expand Down Expand Up @@ -949,9 +934,11 @@ impl<'a, 'tcx> DeferredCallResolution<'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
)
}
}
}
Expand Down
16 changes: 4 additions & 12 deletions compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
);
Expand Down
16 changes: 0 additions & 16 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
21 changes: 3 additions & 18 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ mod suggest;
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;
Expand Down Expand Up @@ -385,26 +384,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 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);
Expand Down
21 changes: 1 addition & 20 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -887,25 +887,6 @@ 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 !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();
Expand Down
30 changes: 1 addition & 29 deletions compiler/rustc_hir_typeck/src/place_op.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -209,20 +209,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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),
Expand All @@ -249,20 +235,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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),
Expand Down
18 changes: 0 additions & 18 deletions tests/ui/lang-items/bad-add-impl.rs

This file was deleted.

11 changes: 0 additions & 11 deletions tests/ui/lang-items/bad-add-impl.stderr

This file was deleted.

18 changes: 0 additions & 18 deletions tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr

This file was deleted.

18 changes: 0 additions & 18 deletions tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr

This file was deleted.

18 changes: 0 additions & 18 deletions tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr

This file was deleted.

18 changes: 0 additions & 18 deletions tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr

This file was deleted.

Loading

0 comments on commit f3f1472

Please sign in to comment.