1
Fork 0

Rollup merge of #123603 - compiler-errors:no-intrinsic, r=estebank

Don't even parse an intrinsic unless the feature gate is enabled

Don't return true in `tcx.is_intrinsic` if the function is defined locally and `#![feature(intrinsics)]` is not enabled. This is a slightly more general fix than #123526, since #123587 shows that we have simplifying assumptions about intrinsics elsewhere in the compiler.

This will make the code ICE again if the user **enables** `#[feature(intrinsics)]`, but I kind of feel like if we want to fix that, we should make the `INTERNAL_FEATURES` lint `Deny` again. Perhaps we could do that on non-nightly compilers. Or we should just stop compilation altogether if they have `#![feature]` enabled on a non-nightly compiler.

As for the UX of *real* cases of hitting these ICEs, I believe pretty strongly that if a compiler/stdlib dev is modifying internal intrinsics (intentionally, like when making a change to rustc) we have no guarantee to make the ICE better looking for them. Honestly, *not* spitting out a stack trace is probably a disservice to the people who hit those ICEs in that case.

r? `@Nilstrieb` `@estebank`
This commit is contained in:
León Orell Valerian Liehr 2024-04-16 01:12:37 +02:00 committed by GitHub
commit 1ad9fea871
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 67 additions and 78 deletions

View file

@ -54,7 +54,6 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
@ -539,16 +538,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let ty::FnDef(did, _) = *ty.kind() {
let fn_sig = ty.fn_sig(tcx);
if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic
&& tcx.item_name(did) == sym::transmute
{
if tcx.is_intrinsic(did, sym::transmute) {
let Some(from) = fn_sig.inputs().skip_binder().get(0) else {
let e = self.dcx().span_delayed_bug(
span_bug!(
tcx.def_span(did),
"intrinsic fn `transmute` defined with no parameters",
"intrinsic fn `transmute` defined with no parameters"
);
self.set_tainted_by_errors(e);
return Ty::new_error(tcx, e);
};
let to = fn_sig.output().skip_binder();
// We defer the transmute to the end of typeck, once all inference vars have

View file

@ -1684,10 +1684,15 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
.any(|items| items.iter().any(|item| item.has_name(sym::notable_trait)))
}
/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute)
/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute).
///
/// We double check the feature gate here because whether a function may be defined as an intrinsic causes
/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
/// cause an ICE that we otherwise may want to prevent.
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
|| tcx.has_attr(def_id, sym::rustc_intrinsic)
if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
&& tcx.features().intrinsics)
|| (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs)
{
Some(ty::IntrinsicDef {
name: tcx.item_name(def_id.into()),