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:
commit
1ad9fea871
10 changed files with 67 additions and 78 deletions
|
@ -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
|
||||
|
|
|
@ -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()),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue