Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::Yes,
"#[rustc_fsa_entry_point] is used to determine when types should be checked by finaliser safety analysis."
),
rustc_attr!(
rustc_alloc_in, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes,
"#[rustc_alloc_in] is used to declare that a function uses a separate allocator."
),
rustc_attr!(
rustc_fsa_safe_fn, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,10 @@ lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`

lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´

lint_untracked_heap_allocation = uses a non-Alloy allocator
.note = Alloy must be able to track all heap allocations in order to correctly trace GC objects
.help = Disable this lint only if you are certain this not contain a pointer to a GC object

lint_untranslatable_diag = diagnostics should be created using translatable messages

lint_unused_allocation = unnecessary allocation, use `&` instead
Expand Down
46 changes: 46 additions & 0 deletions compiler/rustc_lint/src/incompatible_gc_features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use rustc_hir as hir;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;

use crate::lints::UntrackedHeapAllocation as AllocationLint;
use crate::{LateContext, LateLintPass, LintContext};

declare_lint! {
/// The `untracked_heap_allocation` lint checks that heap allocations use the BDWGC allocator.
///
/// ### Example
/// ```rust,compile_fail
/// #![feature(allocator_api)]
/// use std::rc::Rc;
/// use std::alloc::System;
///
/// static A: System = System;
///
/// fn foo() { Rc::new_in(123, A); }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Alloy must be able to track all heap allocations in order to correctly trace GC objects.
pub UNTRACKED_HEAP_ALLOCATION,
Deny,
"Allocations must go through the BDWGC allocator",
}

declare_lint_pass!(UntrackedHeapAllocation => [UNTRACKED_HEAP_ALLOCATION]);

impl<'tcx> LateLintPass<'tcx> for UntrackedHeapAllocation {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Call(ref callee, _) = expr.kind {
if let hir::ExprKind::Path(ref qpath) = callee.kind {
if let Some(def_id) = cx.qpath_res(qpath, callee.hir_id).opt_def_id() {
if let Some(_) = cx.tcx.get_attr(def_id, sym::rustc_alloc_in) {
cx.emit_span_lint(UNTRACKED_HEAP_ALLOCATION, expr.span, AllocationLint);
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ mod foreign_modules;
pub mod hidden_unicode_codepoints;
mod if_let_rescope;
mod impl_trait_overcaptures;
mod incompatible_gc_features;
mod internal;
mod invalid_from_utf8;
mod late;
Expand Down Expand Up @@ -94,6 +95,7 @@ use for_loops_over_fallibles::*;
use hidden_unicode_codepoints::*;
use if_let_rescope::IfLetRescope;
use impl_trait_overcaptures::ImplTraitOvercaptures;
use incompatible_gc_features::*;
use internal::*;
use invalid_from_utf8::*;
use let_underscore::*;
Expand Down Expand Up @@ -247,6 +249,7 @@ late_lint_methods!(
StaticMutRefs: StaticMutRefs,
UnqualifiedLocalImports: UnqualifiedLocalImports,
MisalignedGcPointers: MisalignedGcPointers,
UntrackedHeapAllocation: UntrackedHeapAllocation,
]
]
);
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,11 @@ impl<'a> LintDiagnostic<'a, ()> for MisalignedGcPointers<'_> {
}
}

#[derive(LintDiagnostic)]
#[diag(lint_untracked_heap_allocation)]
#[help]
pub(crate) struct UntrackedHeapAllocation;

#[derive(LintDiagnostic)]
#[diag(lint_variant_size_differences)]
pub(crate) struct VariantSizeDifferencesDiag {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ symbols! {
all,
alloc,
alloc_error_handler,
alloc_in,
alloc_layout,
alloc_zeroed,
allocator,
Expand Down Expand Up @@ -1723,6 +1724,7 @@ symbols! {
rust_out,
rustc,
rustc_abi,
rustc_alloc_in,
rustc_allocator,
rustc_allocator_zeroed,
rustc_allow_const_fn_unstable,
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#![warn(rustdoc::unescaped_backticks)]
#![deny(ffi_unwind_calls)]
#![warn(unreachable_pub)]
#![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
//
// Library features:
// tidy-alphabetical-start
Expand Down
29 changes: 29 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
//! [fully qualified syntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name

#![stable(feature = "rust1", since = "1.0.0")]
#![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]

use core::any::Any;
use core::cell::Cell;
Expand Down Expand Up @@ -658,12 +659,14 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
/// use std::rc::Rc;
/// use std::alloc::System;
///
/// let five = Rc::new_in(5, System);
/// ```
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
pub fn new_in(value: T, alloc: A) -> Rc<T, A> {
Expand All @@ -682,6 +685,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// ```
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -699,6 +703,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub fn new_uninit_in(alloc: A) -> Rc<mem::MaybeUninit<T>, A> {
Expand All @@ -724,6 +729,7 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -736,6 +742,7 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// [zeroed]: mem::MaybeUninit::zeroed
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
Expand Down Expand Up @@ -838,13 +845,15 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
/// use std::rc::Rc;
/// use std::alloc::System;
///
/// let five = Rc::try_new_in(5, System);
/// # Ok::<(), std::alloc::AllocError>(())
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[inline]
pub fn try_new_in(value: T, alloc: A) -> Result<Self, AllocError> {
// There is an implicit weak pointer owned by all the strong
Expand All @@ -867,6 +876,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// ```
/// #![feature(allocator_api)]
/// #![feature(get_mut_unchecked)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -884,6 +894,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// # Ok::<(), std::alloc::AllocError>(())
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub fn try_new_uninit_in(alloc: A) -> Result<Rc<mem::MaybeUninit<T>, A>, AllocError> {
Expand All @@ -910,6 +921,7 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -923,6 +935,7 @@ impl<T, A: Allocator> Rc<T, A> {
///
/// [zeroed]: mem::MaybeUninit::zeroed
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
//#[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
pub fn try_new_zeroed_in(alloc: A) -> Result<Rc<mem::MaybeUninit<T>, A>, AllocError> {
Expand All @@ -941,6 +954,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// Constructs a new `Pin<Rc<T>>` in the provided allocator. If `T` does not implement `Unpin`, then
/// `value` will be pinned in memory and unable to be moved.
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
pub fn pin_in(value: T, alloc: A) -> Pin<Self>
Expand Down Expand Up @@ -1122,6 +1136,7 @@ impl<T, A: Allocator> Rc<[T], A> {
/// ```
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1140,6 +1155,7 @@ impl<T, A: Allocator> Rc<[T], A> {
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
Expand All @@ -1157,6 +1173,7 @@ impl<T, A: Allocator> Rc<[T], A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1169,6 +1186,7 @@ impl<T, A: Allocator> Rc<[T], A> {
///
/// [zeroed]: mem::MaybeUninit::zeroed
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[inline]
Expand Down Expand Up @@ -1447,6 +1465,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
/// use std::rc::Rc;
/// use std::alloc::System;
///
Expand Down Expand Up @@ -1526,6 +1545,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1548,6 +1568,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1561,6 +1582,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// }
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {
let offset = unsafe { data_offset(ptr) };

Expand Down Expand Up @@ -1644,6 +1666,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1662,6 +1685,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// ```
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A)
where
A: Clone,
Expand All @@ -1687,6 +1711,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
///
/// use std::rc::Rc;
/// use std::alloc::System;
Expand All @@ -1705,6 +1730,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// ```
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) {
unsafe { drop(Rc::from_raw_in(ptr, alloc)) };
}
Expand Down Expand Up @@ -2114,6 +2140,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
}

#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
fn from_box_in(src: Box<T, A>) -> Rc<T, A> {
unsafe {
let value_size = size_of_val(&*src);
Expand Down Expand Up @@ -2215,6 +2242,7 @@ impl<T, A: Allocator> Rc<[T], A> {
/// Allocates an `RcInner<[T]>` with the given length.
#[inline]
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(not(bootstrap), rustc_alloc_in)]
unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcInner<[T]> {
unsafe {
Rc::<[T]>::allocate_for_layout(
Expand Down Expand Up @@ -3221,6 +3249,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
///
/// ```
/// #![feature(allocator_api)]
/// #![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
/// use std::rc::{Rc, Weak};
/// use std::alloc::System;
///
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/rc/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
use std::cell::RefCell;
use std::clone::Clone;

Expand Down
1 change: 1 addition & 0 deletions library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#![feature(vec_deque_pop_if)]
#![feature(unique_rc_arc)]
#![feature(macro_metavar_expr_concat)]
#![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
#![allow(internal_features)]
#![deny(fuzzy_provenance_casts)]
#![deny(unsafe_op_in_unsafe_fn)]
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![cfg_attr(not(bootstrap), allow(untracked_heap_allocation))]
#![allow(explicit_outlives_requirements)]
#![allow(unused_lifetimes)]
#![allow(internal_features)]
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/static/gc/tracing/untracked_allocations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![deny(untracked_heap_allocation)]
#![feature(allocator_api)]
#![feature(gc)]

use std::alloc::System;
use std::rc::Rc;

static A: System = System;

fn main() {
let rc = Rc::new_in(123, A); //~ ERROR: uses a non-Alloy allocator
}
Loading