when an intrinsic has a const-stable fallback body, we can easily expose it on stable
This commit is contained in:
parent
5069434c81
commit
a741b33c14
@ -739,6 +739,12 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
|||||||
// We use `intrinsic.const_stable` to determine if this can be safely exposed to
|
// We use `intrinsic.const_stable` to determine if this can be safely exposed to
|
||||||
// stable code, rather than `const_stable_indirect`. This is to make
|
// stable code, rather than `const_stable_indirect`. This is to make
|
||||||
// `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
|
// `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
|
||||||
|
// We also ask is_safe_to_expose_on_stable_const_fn; this determines whether the intrinsic
|
||||||
|
// fallback body is safe to expose on stable.
|
||||||
|
let is_const_stable = intrinsic.const_stable
|
||||||
|
|| (!intrinsic.must_be_overridden
|
||||||
|
&& tcx.is_const_fn(callee)
|
||||||
|
&& is_safe_to_expose_on_stable_const_fn(tcx, callee));
|
||||||
match tcx.lookup_const_stability(callee) {
|
match tcx.lookup_const_stability(callee) {
|
||||||
None => {
|
None => {
|
||||||
// Non-const intrinsic.
|
// Non-const intrinsic.
|
||||||
@ -748,7 +754,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
|||||||
// Intrinsic does not need a separate feature gate (we rely on the
|
// Intrinsic does not need a separate feature gate (we rely on the
|
||||||
// regular stability checker). However, we have to worry about recursive
|
// regular stability checker). However, we have to worry about recursive
|
||||||
// const stability.
|
// const stability.
|
||||||
if !intrinsic.const_stable && self.enforce_recursive_const_stability() {
|
if !is_const_stable && self.enforce_recursive_const_stability() {
|
||||||
self.dcx().emit_err(errors::UnmarkedIntrinsicExposed {
|
self.dcx().emit_err(errors::UnmarkedIntrinsicExposed {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
def_path: self.tcx.def_path_str(callee),
|
def_path: self.tcx.def_path_str(callee),
|
||||||
@ -763,12 +769,14 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
|||||||
self.check_op(ops::IntrinsicUnstable {
|
self.check_op(ops::IntrinsicUnstable {
|
||||||
name: intrinsic.name,
|
name: intrinsic.name,
|
||||||
feature,
|
feature,
|
||||||
const_stable: intrinsic.const_stable,
|
const_stable: is_const_stable,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
|
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
|
||||||
// All good. But ensure this is indeed a const-stable intrinsic.
|
// All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
|
||||||
assert!(intrinsic.const_stable);
|
// can be *directly* invoked from stable const code) does not always
|
||||||
|
// have the `#[rustc_const_stable_intrinsic]` attribute (which controls
|
||||||
|
// exposing an intrinsic indirectly); we accept this call anyway.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This completes the checks for intrinsics.
|
// This completes the checks for intrinsics.
|
||||||
|
@ -1789,8 +1789,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
|
|||||||
Some(ty::IntrinsicDef {
|
Some(ty::IntrinsicDef {
|
||||||
name: tcx.item_name(def_id.into()),
|
name: tcx.item_name(def_id.into()),
|
||||||
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
|
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
|
||||||
const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic)
|
const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic),
|
||||||
|| tcx.lookup_const_stability(def_id).is_some_and(|s| s.is_const_stable()),
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
#[unstable(feature = "unstable", issue = "42")]
|
#[unstable(feature = "unstable", issue = "42")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
|
pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
|
||||||
|
|
||||||
#[unstable(feature = "unstable", issue = "42")]
|
#[unstable(feature = "unstable", issue = "42")]
|
||||||
#[rustc_const_unstable(feature = "unstable", issue = "42")]
|
#[rustc_const_unstable(feature = "unstable", issue = "42")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
|
pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
|
||||||
|
@ -30,11 +30,13 @@ const fn const_main() {
|
|||||||
|
|
||||||
#[unstable(feature = "local", issue = "42")]
|
#[unstable(feature = "local", issue = "42")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
|
pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
|
||||||
|
|
||||||
#[unstable(feature = "local", issue = "42")]
|
#[unstable(feature = "local", issue = "42")]
|
||||||
#[rustc_const_unstable(feature = "local", issue = "42")]
|
#[rustc_const_unstable(feature = "local", issue = "42")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
|
pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -43,6 +45,7 @@ const fn const_main() {
|
|||||||
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
// Const stability attributes are not inherited from parent items.
|
// Const stability attributes are not inherited from parent items.
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
@ -50,3 +53,12 @@ const fn const_main() {
|
|||||||
unsafe { copy(src, dst, count) }
|
unsafe { copy(src, dst, count) }
|
||||||
//~^ ERROR cannot be (indirectly) exposed to stable
|
//~^ ERROR cannot be (indirectly) exposed to stable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that a fallback body is recursively-const-checked.
|
||||||
|
mod fallback {
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
const unsafe fn copy<T>(src: *const T, _dst: *mut T, _count: usize) {
|
||||||
|
super::size_of_val(src);
|
||||||
|
//~^ ERROR cannot be (indirectly) exposed to stable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -60,13 +60,21 @@ LL | const fn const_main() {
|
|||||||
|
|
|
|
||||||
|
|
||||||
error: intrinsic `copy::copy` cannot be (indirectly) exposed to stable
|
error: intrinsic `copy::copy` cannot be (indirectly) exposed to stable
|
||||||
--> $DIR/const-unstable-intrinsic.rs:50:14
|
--> $DIR/const-unstable-intrinsic.rs:53:14
|
||||||
|
|
|
|
||||||
LL | unsafe { copy(src, dst, count) }
|
LL | unsafe { copy(src, dst, count) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
|
= help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: intrinsic `size_of_val` cannot be (indirectly) exposed to stable
|
||||||
|
--> $DIR/const-unstable-intrinsic.rs:61:9
|
||||||
|
|
|
||||||
|
LL | super::size_of_val(src);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
Loading…
Reference in New Issue
Block a user