///
/// Perma-unstable: do not use.
pub fn miri_start_panic(payload: *mut u8) -> !;
-}
-/// Defines the `count_code_region` intrinsic as a `LangItem`. `LangItem`s require a function body
-/// to register its DefId with the LangItem entry. The function body is never actually called (and
-/// is therefore implemented as an aborting stub) because it is replaced with the LLVM intrinsic
-/// `llvm.instrprof.increment` by
-/// `rustc_codegen_llvm::intrinsic::IntrinsicCallMethods::codegen_intrinsic_call()`.
-#[cfg(not(bootstrap))]
-#[cfg_attr(not(bootstrap), lang = "count_code_region")]
-fn count_code_region(_index: u32) {
- // remove `unsafe` (and safety comment) on bootstrap bump
- #[cfg_attr(not(bootstrap), allow(unused_unsafe))]
- // SAFETY: the `abort` intrinsic has no requirements to be called.
- unsafe {
- abort()
- }
+ /// Internal placeholder for injecting code coverage counters when the "instrument-coverage"
+ /// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code
+ /// generation.
+ #[cfg(not(bootstrap))]
+ #[cfg_attr(not(bootstrap), lang = "count_code_region")]
+ pub fn count_code_region(_index: u32);
}
// Some functions are defined here because they accidentally got made
// Handle intrinsics old codegen wants Expr's for, ourselves.
let intrinsic = match def {
- Some(ty::InstanceDef::Intrinsic(def_id))
- | Some(ty::InstanceDef::InjectedCode(def_id)) => {
- Some(bx.tcx().item_name(def_id).as_str())
- }
+ Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id).as_str()),
_ => None,
};
let intrinsic = intrinsic.as_ref().map(|s| &s[..]);
InstanceDef::VtableShim(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::Intrinsic(..)
- | InstanceDef::InjectedCode(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::ClosureOnceShim { .. }
Item(DefId),
Intrinsic(DefId),
- /// Injected call to a placeholder function that is replaced with
- /// For example: `core::intrinsic::count_code_region()` for code coverage.
- InjectedCode(DefId),
-
/// `<T as Trait>::method` where `method` receives unsizeable `self: Self`.
VtableShim(DefId),
| InstanceDef::FnPtrShim(def_id, _)
| InstanceDef::Virtual(def_id, _)
| InstanceDef::Intrinsic(def_id)
- | InstanceDef::InjectedCode(def_id)
| InstanceDef::ClosureOnceShim { call_once: def_id }
| InstanceDef::DropGlue(def_id, _)
| InstanceDef::CloneShim(def_id, _) => def_id,
InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"),
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
- InstanceDef::InjectedCode(_) => write!(f, " - injected-code"),
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({:?})", ty),
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
| InstanceDef::FnPtrShim(..)
| InstanceDef::Item(_)
| InstanceDef::Intrinsic(..)
- | InstanceDef::InjectedCode(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::VtableShim(..) => Some(self.substs),
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::Intrinsic(..)
- | ty::InstanceDef::InjectedCode(..)
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::ClosureOnceShim { .. }
ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)),
ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
- ty::InstanceDef::InjectedCode(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
ty::InstanceDef::FnPtrShim(def_id, ref ty) => {
Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
}
VtableShim(did) => VtableShim(did.fold_with(folder)),
ReifyShim(did) => ReifyShim(did.fold_with(folder)),
Intrinsic(did) => Intrinsic(did.fold_with(folder)),
- InjectedCode(did) => InjectedCode(did.fold_with(folder)),
FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
Virtual(did, i) => Virtual(did.fold_with(folder), i),
ClosureOnceShim { call_once } => {
use crate::ty::InstanceDef::*;
self.substs.visit_with(visitor)
|| match self.def {
- Item(did)
- | VtableShim(did)
- | ReifyShim(did)
- | Intrinsic(did)
- | InjectedCode(did)
- | Virtual(did, _) => did.visit_with(visitor),
+ Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
+ did.visit_with(visitor)
+ }
FnPtrShim(did, ty) | CloneShim(did, ty) => {
did.visit_with(visitor) || ty.visit_with(visitor)
}
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
M::call_intrinsic(self, instance, args, ret, unwind)
}
- ty::InstanceDef::InjectedCode(..) => {
- M::call_intrinsic(self, instance, args, ret, unwind)
- }
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }
}
match instance.def {
- ty::InstanceDef::Virtual(..)
- | ty::InstanceDef::Intrinsic(_)
- | ty::InstanceDef::InjectedCode(_) => {
+ ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => {
if !is_direct_call {
bug!("{:?} being reified", instance);
}
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Intrinsic(_)
- | ty::InstanceDef::InjectedCode(_)
| ty::InstanceDef::CloneShim(..) => return true,
};
| InstanceDef::FnPtrShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::Intrinsic(..)
- | InstanceDef::InjectedCode(..)
| InstanceDef::ClosureOnceShim { .. }
| InstanceDef::DropGlue(..)
| InstanceDef::CloneShim(..) => return Visibility::Hidden,
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::Intrinsic(..)
- | ty::InstanceDef::InjectedCode(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::CloneShim(..) => return None,
ty::InstanceDef::Intrinsic(_) => {
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
}
- ty::InstanceDef::InjectedCode(_) => {
- bug!("creating shims from injected code ({:?}) is unsupported", instance)
- }
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
use rustc_hir as hir;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::lang_items;
+use rustc_hir::lang_items::ITEM_REFS;
use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
use rustc_middle::middle::lang_items::whitelisted;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::CrateType;
+use rustc_span::symbol::sym;
use rustc_span::symbol::Symbol;
use rustc_span::Span;
}
impl<'a, 'tcx> Context<'a, 'tcx> {
- fn register(&mut self, name: Symbol, span: Span) {
+ fn register(&mut self, name: Symbol, span: Span, hir_id: hir::HirId) {
if let Some(&item) = WEAK_ITEMS_REFS.get(&name) {
if self.items.require(item).is_err() {
self.items.missing.push(item);
}
+ } else if name == sym::count_code_region {
+ // `core::intrinsics::code_count_region()` is (currently) the only `extern` lang item
+ // that is never actually linked. It is not a `weak_lang_item` that can be registered
+ // when used, and should be registered here instead.
+ if let Some((item_index, _)) = ITEM_REFS.get(&*name.as_str()).cloned() {
+ if self.items.items[item_index].is_none() {
+ let item_def_id = self.tcx.hir().local_def_id(hir_id).to_def_id();
+ self.items.items[item_index] = Some(item_def_id);
+ }
+ }
} else {
struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name)
.emit();
fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
if let Some((lang_item, _)) = hir::lang_items::extract(&i.attrs) {
- self.register(lang_item, i.span);
+ self.register(lang_item, i.span, i.hir_id);
}
intravisit::walk_foreign_item(self, i)
}
debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def_id)
}
- ty::FnDef(def_id, _) if Some(def_id) == tcx.lang_items().count_code_region_fn() => {
- debug!(" => injected placeholder function to be replaced");
- ty::InstanceDef::InjectedCode(def_id)
- }
ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
let ty = substs.type_at(0);
return;
}
+ "count_code_region" => (0, vec![tcx.types.u32], tcx.mk_unit()),
+
ref other => {
struct_span_err!(
tcx.sess,